comparison directive.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
112 { 112 {
113 size_t pos; 113 size_t pos;
114 114
115 pos = strcspn(line, ws); 115 pos = strcspn(line, ws);
116 if (line[pos] != '\0') { 116 if (line[pos] != '\0') {
117 p2->column += pos; 117 place_addcolumns(p2, pos);
118 complain(p2, "Garbage after %s argument", what); 118 complain(p2, "Garbage after %s argument", what);
119 complain_fail(); 119 complain_fail();
120 line[pos] = '\0'; 120 line[pos] = '\0';
121 } 121 }
122 } 122 }
346 if (line[pos] == '(') { 346 if (line[pos] == '(') {
347 line[pos++] = '\0'; 347 line[pos++] = '\0';
348 argpos = pos; 348 argpos = pos;
349 pos = pos + strcspn(line+pos, "()"); 349 pos = pos + strcspn(line+pos, "()");
350 if (line[pos] == '(') { 350 if (line[pos] == '(') {
351 p2->column += pos; 351 place_addcolumns(p2, pos);
352 complain(p2, "Left parenthesis in macro parameters"); 352 complain(p2, "Left parenthesis in macro parameters");
353 complain_fail(); 353 complain_fail();
354 return; 354 return;
355 } 355 }
356 if (line[pos] != ')') { 356 if (line[pos] != ')') {
357 p2->column += pos; 357 place_addcolumns(p2, pos);
358 complain(p2, "Unclosed macro parameter list"); 358 complain(p2, "Unclosed macro parameter list");
359 complain_fail(); 359 complain_fail();
360 return; 360 return;
361 } 361 }
362 line[pos++] = '\0'; 362 line[pos++] = '\0';
376 } 376 }
377 377
378 pos += strspn(line+pos, ws); 378 pos += strspn(line+pos, ws);
379 379
380 p3 = *p2; 380 p3 = *p2;
381 p3.column += argpos; 381 place_addcolumns(&p3, argpos);
382 382
383 p4 = *p2; 383 p4 = *p2;
384 p4.column += pos; 384 place_addcolumns(&p4, pos);
385 385
386 if (argpos) { 386 if (argpos) {
387 debuglog(&lp->current, "Defining %s()", line); 387 debuglog(&lp->current, "Defining %s()", line);
388 macro_define_params(p2, line, &p3, 388 macro_define_params(p2, line, &p3,
389 line + argpos, &p4, 389 line + argpos, &p4,
488 */ 488 */
489 489
490 errno = 0; 490 errno = 0;
491 val = strtoul(text, &moretext, 10); 491 val = strtoul(text, &moretext, 10);
492 if (errno) { 492 if (errno) {
493 complain(&lp->current, "No line number in #line directive"); 493 complain(&lp->current,
494 "Invalid line number in #line directive");
494 goto fail; 495 goto fail;
495 } 496 }
496 #if UINT_MAX < ULONG_MAX 497 #if UINT_MAX < ULONG_MAX
497 if (val > UINT_MAX) { 498 if (val > UINT_MAX) {
498 complain(&lp->current, 499 complain(&lp->current,
500 goto fail; 501 goto fail;
501 } 502 }
502 #endif 503 #endif
503 moretext += strspn(moretext, ws); 504 moretext += strspn(moretext, ws);
504 moretextlen = strlen(moretext); 505 moretextlen = strlen(moretext);
505 lp->current.column += (moretext - text); 506 place_addcolumns(&lp->current, moretext - text);
506 507
507 if (moretextlen > 2 && 508 if (moretextlen > 2 &&
508 moretext[0] == '"' && moretext[moretextlen-1] == '"') { 509 moretext[0] == '"' && moretext[moretextlen-1] == '"') {
509 filename = dostrndup(moretext+1, moretextlen-2); 510 filename = dostrndup(moretext+1, moretextlen-2);
510 place_changefile(&lp->nextline, filename); 511 place_changefile(&lp->nextline, filename);
608 strchr(ws, line[len])) { 609 strchr(ws, line[len])) {
609 if (directives[i].ifskip && !ifstate->curtrue) { 610 if (directives[i].ifskip && !ifstate->curtrue) {
610 return; 611 return;
611 } 612 }
612 skip = len + strspn(line+len, ws); 613 skip = len + strspn(line+len, ws);
613 p2.column += skip; 614 place_addcolumns(&p2, skip);
614 line += skip; 615 line += skip;
615 616
616 len = strlen(line); 617 len = strlen(line);
617 len = notrailingws(line, len); 618 len = notrailingws(line, len);
618 if (len < strlen(line)) { 619 if (len < strlen(line)) {
665 /* stray end-comment; should we care? */ 666 /* stray end-comment; should we care? */
666 } 667 }
667 pos++; 668 pos++;
668 } 669 }
669 if (line[pos] == '\n') { 670 if (line[pos] == '\n') {
670 p2.line++; 671 place_addlines(&p2, 1);
671 p2.column = 0; 672 p2.column = 0;
672 } else { 673 } else {
673 p2.column++; 674 place_addcolumns(&p2, 1);
674 } 675 }
675 } 676 }
676 677
677 /* multiline comments are supposed to arrive in a single buffer */ 678 /* multiline comments are supposed to arrive in a single buffer */
678 assert(!incomment); 679 assert(!incomment);
690 691
691 /* check if we have a directive line (# exactly in column 0) */ 692 /* check if we have a directive line (# exactly in column 0) */
692 if (len > 0 && line[0] == '#') { 693 if (len > 0 && line[0] == '#') {
693 skip = 1 + strspn(line + 1, ws); 694 skip = 1 + strspn(line + 1, ws);
694 assert(skip <= len); 695 assert(skip <= len);
695 lp->current.column += skip; 696 place_addcolumns(&lp->current, skip);
696 assert(line[len] == '\0'); 697 assert(line[len] == '\0');
697 directive_gotdirective(lp, line+skip /*, length = len-skip */); 698 directive_gotdirective(lp, line+skip /*, length = len-skip */);
698 lp->current.column += len-skip; 699 place_addcolumns(&lp->current, len-skip);
699 } else if (ifstate->curtrue) { 700 } else if (ifstate->curtrue) {
700 macro_sendline(&lp->current, line, len); 701 macro_sendline(&lp->current, line, len);
701 lp->current.column += len; 702 place_addcolumns(&lp->current, len);
702 } 703 }
703 } 704 }
704 705
705 void 706 void
706 directive_goteof(struct place *p) 707 directive_goteof(struct place *p)