diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2020-09-15 13:02:59 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2020-09-15 13:02:59 +0200 |
commit | 131c8cb4424c475bbdaf41912ba1ca66869322de (patch) | |
tree | 4f8f155a8c876e773c6acdadcee49b52cbf49340 /libbuild2 | |
parent | 3fb35dc4bd8949880e5e6c6cb4825442c7d78b7b (diff) |
Handle infinite output when extracting metadata (GitHub issue #102)
Diffstat (limited to 'libbuild2')
-rw-r--r-- | libbuild2/file.cxx | 24 |
1 files changed, 22 insertions, 2 deletions
diff --git a/libbuild2/file.cxx b/libbuild2/file.cxx index e1dde1f..2660b9e 100644 --- a/libbuild2/file.cxx +++ b/libbuild2/file.cxx @@ -3,6 +3,7 @@ #include <libbuild2/file.hxx> +#include <cerrno> #include <iomanip> // left, setw() #include <sstream> @@ -1713,9 +1714,28 @@ namespace build2 try { - ifdstream is (move (pr.in_ofd), fdstream_mode::skip); + ifdstream is (move (pr.in_ofd), ifdstream::badbit); // Note: no skip! + + // What are the odds that we will run some unrelated program which + // will keep writing to stdout until we run out of memory reading? + // Apparently non-negligible (see GitHub issue #102). + // string r; - getline (is, r, '\0'); // Will fail if there is no data. + { + char b[1024]; + while (!eof (is.read (b, sizeof (b)))) + { + r.append (b, sizeof (b)); + if (r.size () > 65536) + { + is.close (); + pr.kill (); + throw_generic_ios_failure (EFBIG, "output too large"); + } + } + r.append (b, static_cast<size_t> (is.gcount ())); + } + is.close (); // Detect errors. if (pr.wait ()) |