diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/doprnt.c | 28 |
1 files changed, 23 insertions, 5 deletions
diff --git a/src/doprnt.c b/src/doprnt.c index 2fe45cf7975..52a3ccebf36 100644 --- a/src/doprnt.c +++ b/src/doprnt.c | |||
| @@ -42,26 +42,38 @@ doprnt (buffer, bufsize, format, format_end, nargs, args) | |||
| 42 | int cnt = 0; /* Number of arg to gobble next */ | 42 | int cnt = 0; /* Number of arg to gobble next */ |
| 43 | register char *fmt = format; /* Pointer into format string */ | 43 | register char *fmt = format; /* Pointer into format string */ |
| 44 | register char *bufptr = buffer; /* Pointer into output buffer.. */ | 44 | register char *bufptr = buffer; /* Pointer into output buffer.. */ |
| 45 | |||
| 45 | /* Use this for sprintf unless we need something really big. */ | 46 | /* Use this for sprintf unless we need something really big. */ |
| 46 | char tembuf[100]; | 47 | char tembuf[100]; |
| 48 | |||
| 47 | /* Size of sprintf_buffer. */ | 49 | /* Size of sprintf_buffer. */ |
| 48 | int size_allocated = 100; | 50 | int size_allocated = 100; |
| 51 | |||
| 49 | /* Buffer to use for sprintf. Either tembuf or same as BIG_BUFFER. */ | 52 | /* Buffer to use for sprintf. Either tembuf or same as BIG_BUFFER. */ |
| 50 | char *sprintf_buffer = tembuf; | 53 | char *sprintf_buffer = tembuf; |
| 54 | |||
| 51 | /* Buffer we have got with malloc. */ | 55 | /* Buffer we have got with malloc. */ |
| 52 | char *big_buffer = 0; | 56 | char *big_buffer = 0; |
| 57 | |||
| 53 | register int tem; | 58 | register int tem; |
| 54 | char *string; | 59 | char *string; |
| 55 | char fmtcpy[20]; | 60 | char fixed_buffer[20]; /* Default buffer for small formatting. */ |
| 61 | char *fmtcpy; | ||
| 56 | int minlen; | 62 | int minlen; |
| 57 | int size; /* Field width factor; e.g., %90d */ | 63 | int size; /* Field width factor; e.g., %90d */ |
| 58 | 64 | ||
| 59 | if (format_end == 0) | 65 | if (format_end == 0) |
| 60 | format_end = format + strlen (format); | 66 | format_end = format + strlen (format); |
| 61 | 67 | ||
| 68 | if ((format_end - format + 1) < sizeof (fixed_buffer)) | ||
| 69 | fmtcpy = fixed_buffer; | ||
| 70 | else | ||
| 71 | fmtcpy = alloca (format_end - format + 1); | ||
| 72 | |||
| 62 | bufsize--; | 73 | bufsize--; |
| 63 | while (fmt != format_end && bufsize > 0) /* Loop until end of format | 74 | |
| 64 | string or buffer full */ | 75 | /* Loop until end of format string or buffer full. */ |
| 76 | while (fmt != format_end && bufsize > 0) | ||
| 65 | { | 77 | { |
| 66 | if (*fmt == '%') /* Check for a '%' character */ | 78 | if (*fmt == '%') /* Check for a '%' character */ |
| 67 | { | 79 | { |
| @@ -71,16 +83,22 @@ doprnt (buffer, bufsize, format, format_end, nargs, args) | |||
| 71 | /* Copy this one %-spec into fmtcpy. */ | 83 | /* Copy this one %-spec into fmtcpy. */ |
| 72 | string = fmtcpy; | 84 | string = fmtcpy; |
| 73 | *string++ = '%'; | 85 | *string++ = '%'; |
| 74 | while (string < fmtcpy + sizeof fmtcpy - 1) | 86 | while (1) |
| 75 | { | 87 | { |
| 76 | *string++ = *fmt; | 88 | *string++ = *fmt; |
| 77 | if (! (*fmt >= '0' && *fmt <= '9') && *fmt != '-' && *fmt != ' ') | 89 | if (! (*fmt >= '0' && *fmt <= '9') |
| 90 | && *fmt != '-' && *fmt != ' '&& *fmt != '.') | ||
| 78 | break; | 91 | break; |
| 79 | fmt++; | 92 | fmt++; |
| 80 | } | 93 | } |
| 81 | *string = 0; | 94 | *string = 0; |
| 82 | /* Get an idea of how much space we might need. */ | 95 | /* Get an idea of how much space we might need. */ |
| 83 | size_bound = atoi (&fmtcpy[1]) + 50; | 96 | size_bound = atoi (&fmtcpy[1]) + 50; |
| 97 | |||
| 98 | /* Avoid pitfall of negative "size" parameter ("%-200d"). */ | ||
| 99 | if (size_bound < 0) | ||
| 100 | size_bound = -size_bound; | ||
| 101 | |||
| 84 | /* Make sure we have that much. */ | 102 | /* Make sure we have that much. */ |
| 85 | if (size_bound > size_allocated) | 103 | if (size_bound > size_allocated) |
| 86 | { | 104 | { |