Mercurial > emacs
comparison src/doprnt.c @ 4774:8e36034f65e2
(doprnt): Use a fixed buffer to store the format
specification, but only if we are sure it will fit. Otherwise,
use alloca () to get enouhg space. Don't allow negative size
specifications to core dump; instead, treat them as positive
("%-20d" == "%20d").
author | Brian Fox <bfox@gnu.org> |
---|---|
date | Wed, 22 Sep 1993 18:12:09 +0000 |
parents | b6c62e4abf59 |
children | ef34c5a4d264 |
comparison
equal
deleted
inserted
replaced
4773:ae7c67879859 | 4774:8e36034f65e2 |
---|---|
40 char **args; | 40 char **args; |
41 { | 41 { |
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 { |
68 int size_bound; | 80 int size_bound; |
69 | 81 |
70 fmt++; | 82 fmt++; |
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 { |
87 if (big_buffer) | 105 if (big_buffer) |
88 big_buffer = (char *) xrealloc (big_buffer, size_bound); | 106 big_buffer = (char *) xrealloc (big_buffer, size_bound); |