comparison files.c @ 203:3a25180d3a5c

Abort on line numbering or column numbering overflow. Line numbers are limited to values that fit in "unsigned int". Also reject input lines longer than 2^32-1 characters. It seems reasonable to presume that any input that violates these constraints is someone screwing around and not a serious attempt to compile or preprocess anything useful. Done in response to n2129, but without getting into any of the silliness found there.
author David A. Holland
date Tue, 01 Aug 2017 14:51:04 -0400
parents 1d2bad7151f9
children
comparison
equal deleted inserted replaced
202:e200cb46ab23 203:3a25180d3a5c
161 unsigned count = 0; 161 unsigned count = 0;
162 162
163 for (i=start; i<limit; i++) { 163 for (i=start; i<limit; i++) {
164 if (buf[i] == '\n') { 164 if (buf[i] == '\n') {
165 count++; 165 count++;
166 if (count == 0) {
167 /* just return the max and error downstream */
168 return count - 1;
169 }
166 } 170 }
167 } 171 }
168 return count; 172 return count;
169 } 173 }
170 174
207 } 211 }
208 if (bufend >= bufmax) { 212 if (bufend >= bufmax) {
209 /* need bigger buffer */ 213 /* need bigger buffer */
210 buf = dorealloc(buf, bufmax, bufmax*2); 214 buf = dorealloc(buf, bufmax, bufmax*2);
211 bufmax = bufmax*2; 215 bufmax = bufmax*2;
216 /* just in case someone's screwing around */
217 if (bufmax > 0xffffffff) {
218 complain(&places.current,
219 "Input line too long");
220 die();
221 }
212 } 222 }
213 223
214 if (ateof) { 224 if (ateof) {
215 /* don't read again, in case it's a socket */ 225 /* don't read again, in case it's a socket */
216 result = 0; 226 result = 0;
229 break; 239 break;
230 } else if (result == 0) { 240 } else if (result == 0) {
231 /* eof in middle of line */ 241 /* eof in middle of line */
232 ateof = true; 242 ateof = true;
233 ptmp = places.current; 243 ptmp = places.current;
234 ptmp.column += bufend - linestart; 244 place_addcolumns(&ptmp, bufend - linestart);
235 if (buf[bufend - 1] == '\n') { 245 if (buf[bufend - 1] == '\n') {
236 complain(&ptmp, "Unclosed comment"); 246 complain(&ptmp, "Unclosed comment");
237 complain_fail(); 247 complain_fail();
238 } else { 248 } else {
239 complain(&ptmp, 249 complain(&ptmp,
255 265
256 /* have a line */ 266 /* have a line */
257 assert(buf[lineend] == '\n'); 267 assert(buf[lineend] == '\n');
258 buf[lineend] = '\0'; 268 buf[lineend] = '\0';
259 nextlinestart = lineend+1; 269 nextlinestart = lineend+1;
260 places.nextline.line++; 270 place_addlines(&places.nextline, 1);
261 271
262 /* check for CR/NL */ 272 /* check for CR/NL */
263 if (lineend > 0 && buf[lineend-1] == '\r') { 273 if (lineend > 0 && buf[lineend-1] == '\r') {
264 buf[lineend-1] = '\0'; 274 buf[lineend-1] = '\0';
265 lineend--; 275 lineend--;
282 292
283 /* line now goes from linestart to lineend */ 293 /* line now goes from linestart to lineend */
284 assert(buf[lineend] == '\0'); 294 assert(buf[lineend] == '\0');
285 295
286 /* count how many commented-out newlines we swallowed */ 296 /* count how many commented-out newlines we swallowed */
287 places.nextline.line += countnls(buf, linestart, lineend); 297 place_addlines(&places.nextline,
298 countnls(buf, linestart, lineend));
288 299
289 /* process the line (even if it's empty) */ 300 /* process the line (even if it's empty) */
290 directive_gotline(&places, buf+linestart, lineend-linestart); 301 directive_gotline(&places, buf+linestart, lineend-linestart);
291 302
292 linestart = nextlinestart; 303 linestart = nextlinestart;