aboutsummaryrefslogtreecommitdiffstats
path: root/src/tparam.c
diff options
context:
space:
mode:
authorPaul Eggert2011-07-28 18:49:31 -0700
committerPaul Eggert2011-07-28 18:49:31 -0700
commit8fbadbe3d240897b2fb265e749cfc9bdeb4bac39 (patch)
tree695368909c048e89d2cf94fa35c392667d196ab3 /src/tparam.c
parent0d8f2df7c41d8904df693e4046849751adebd8ab (diff)
downloademacs-8fbadbe3d240897b2fb265e749cfc9bdeb4bac39.tar.gz
emacs-8fbadbe3d240897b2fb265e749cfc9bdeb4bac39.zip
* tparam.c: Integer and memory overflow fixes.
(tparam1): Use ptrdiff_t, not int, for sizes. Don't update size until alloc done. Redo size calculations to avoid overflow. Check for size calculation overflow.
Diffstat (limited to 'src/tparam.c')
-rw-r--r--src/tparam.c29
1 files changed, 21 insertions, 8 deletions
diff --git a/src/tparam.c b/src/tparam.c
index ed28cd7397f..06cec873153 100644
--- a/src/tparam.c
+++ b/src/tparam.c
@@ -79,33 +79,38 @@ tparam1 (const char *string, char *outstring, int len,
79 register const char *p = string; 79 register const char *p = string;
80 register char *op = outstring; 80 register char *op = outstring;
81 char *outend; 81 char *outend;
82 int outlen = 0; 82 char *new = 0;
83 ptrdiff_t outlen = 0;
83 84
84 register int tem; 85 register int tem;
85 int *old_argp = argp; /* can move */ 86 int *old_argp = argp; /* can move */
86 int *fixed_argp = argp; /* never moves */ 87 int *fixed_argp = argp; /* never moves */
87 int explicit_param_p = 0; /* set by %p */ 88 int explicit_param_p = 0; /* set by %p */
88 int doleft = 0; 89 ptrdiff_t doleft = 0;
89 int doup = 0; 90 ptrdiff_t doup = 0;
91 ptrdiff_t append_len = 0;
90 92
91 outend = outstring + len; 93 outend = outstring + len;
92 94
93 while (1) 95 while (1)
94 { 96 {
95 /* If the buffer might be too short, make it bigger. */ 97 /* If the buffer might be too short, make it bigger. */
96 if (op + 5 >= outend) 98 while (outend - op - append_len <= 5)
97 { 99 {
98 register char *new; 100 ptrdiff_t offset = op - outstring;
99 int offset = op - outstring;
100 101
101 if (outlen == 0) 102 if (outlen == 0)
102 { 103 {
104 if (min (PTRDIFF_MAX, SIZE_MAX) - 40 < len)
105 goto out_of_memory;
103 outlen = len + 40; 106 outlen = len + 40;
104 new = (char *) xmalloc (outlen); 107 new = (char *) xmalloc (outlen);
105 memcpy (new, outstring, offset); 108 memcpy (new, outstring, offset);
106 } 109 }
107 else 110 else
108 { 111 {
112 if (min (PTRDIFF_MAX, SIZE_MAX) / 2 < outlen)
113 goto out_of_memory;
109 outlen *= 2; 114 outlen *= 2;
110 new = (char *) xrealloc (outstring, outlen); 115 new = (char *) xrealloc (outstring, outlen);
111 } 116 }
@@ -167,11 +172,19 @@ tparam1 (const char *string, char *outstring, int len,
167 and this is one of them, increment it. */ 172 and this is one of them, increment it. */
168 while (tem == 0 || tem == '\n' || tem == '\t') 173 while (tem == 0 || tem == '\n' || tem == '\t')
169 { 174 {
175 ptrdiff_t append_len_incr;
170 tem++; 176 tem++;
171 if (argp == old_argp) 177 if (argp == old_argp)
172 doup++, outend -= strlen (up); 178 doup++, append_len_incr = strlen (up);
173 else 179 else
174 doleft++, outend -= strlen (left); 180 doleft++, append_len_incr = strlen (left);
181 if (PTRDIFF_MAX - append_len < append_len_incr)
182 {
183 out_of_memory:
184 xfree (new);
185 memory_full (SIZE_MAX);
186 }
187 append_len += append_len_incr;
175 } 188 }
176 } 189 }
177 *op++ = tem ? tem : 0200; 190 *op++ = tem ? tem : 0200;