diff options
author | Paul Smith <psmith@gnu.org> | 2022-10-24 00:48:47 -0400 |
---|---|---|
committer | Paul Smith <psmith@gnu.org> | 2022-10-24 01:50:12 -0400 |
commit | d18a87d0a40f326d219c7dbabc50e824956f4497 (patch) | |
tree | 164e3ea4712d603c569ba63278e80cce262076df /src/output.c | |
parent | 41c35f2ffe58a5b90b63256a199d674696f8a743 (diff) | |
download | make-git-d18a87d0a40f326d219c7dbabc50e824956f4497.tar.gz |
[SV 63260] Don't recurse forever if setup_tmpfile() fails
If we fail during setup_tmpfile() we'll try to write an error, which
will invoke setup_tmpfile() again, etc. Avoid infinite recursion.
Original patch by Dmitry Goncharov <dgoncharov@users.sf.net>
* src/output.c (setup_tmpfile): Remember we're in this function and
return immediately if we enter it during recursion.
(message): Remember the starting location and use that instead of
fmtbuf.buffer.
(error): Ditto.
(fatal): Ditto.
Diffstat (limited to 'src/output.c')
-rw-r--r-- | src/output.c | 34 |
1 files changed, 24 insertions, 10 deletions
diff --git a/src/output.c b/src/output.c index a88f537a..43eb2f06 100644 --- a/src/output.c +++ b/src/output.c @@ -202,7 +202,16 @@ output_tmpfd (void) static void setup_tmpfile (struct output *out) { - unsigned int io_state = check_io_state (); + static unsigned int in_setup = 0; + unsigned int io_state; + + /* If something fails during setup we might recurse back into this function + while writing errors. Make sure we don't do so infinitely. */ + if (in_setup) + return; + in_setup = 1; + + io_state = check_io_state (); if (NONE_SET (io_state, IO_STDOUT_OK|IO_STDERR_OK)) { @@ -234,6 +243,7 @@ setup_tmpfile (struct output *out) } } + in_setup = 0; return; /* If we failed to create a temp file, disable output sync going forward. */ @@ -241,6 +251,7 @@ setup_tmpfile (struct output *out) output_close (out); output_sync = OUTPUT_SYNC_NONE; osync_clear (); + in_setup = 0; } /* Synchronize the output of jobs in -j mode to keep the results of @@ -398,10 +409,11 @@ void message (int prefix, size_t len, const char *fmt, ...) { va_list args; + char *start; char *p; len += strlen (fmt) + strlen (program) + INTSTR_LENGTH + 4 + 1 + 1; - p = get_buffer (len); + start = p = get_buffer (len); if (prefix) { @@ -418,8 +430,8 @@ message (int prefix, size_t len, const char *fmt, ...) strcat (p, "\n"); - assert (fmtbuf.buffer[len-1] == '\0'); - outputs (0, fmtbuf.buffer); + assert (start[len-1] == '\0'); + outputs (0, start); } /* Print an error message. */ @@ -428,12 +440,13 @@ void error (const floc *flocp, size_t len, const char *fmt, ...) { va_list args; + char *start; char *p; len += (strlen (fmt) + strlen (program) + (flocp && flocp->filenm ? strlen (flocp->filenm) : 0) + INTSTR_LENGTH + 4 + 1 + 1); - p = get_buffer (len); + start = p = get_buffer (len); if (flocp && flocp->filenm) sprintf (p, "%s:%lu: ", flocp->filenm, flocp->lineno + flocp->offset); @@ -449,8 +462,8 @@ error (const floc *flocp, size_t len, const char *fmt, ...) strcat (p, "\n"); - assert (fmtbuf.buffer[len-1] == '\0'); - outputs (1, fmtbuf.buffer); + assert (start[len-1] == '\0'); + outputs (1, start); } /* Print an error message and exit. */ @@ -460,12 +473,13 @@ fatal (const floc *flocp, size_t len, const char *fmt, ...) { va_list args; const char *stop = _(". Stop.\n"); + char *start; char *p; len += (strlen (fmt) + strlen (program) + (flocp && flocp->filenm ? strlen (flocp->filenm) : 0) + INTSTR_LENGTH + 8 + strlen (stop) + 1); - p = get_buffer (len); + start = p = get_buffer (len); if (flocp && flocp->filenm) sprintf (p, "%s:%lu: *** ", flocp->filenm, flocp->lineno + flocp->offset); @@ -481,8 +495,8 @@ fatal (const floc *flocp, size_t len, const char *fmt, ...) strcat (p, stop); - assert (fmtbuf.buffer[len-1] == '\0'); - outputs (1, fmtbuf.buffer); + assert (start[len-1] == '\0'); + outputs (1, start); die (MAKE_FAILURE); } |