From: Alex Smith Date: Sat, 21 Jun 2008 22:08:17 +0000 (-0400) Subject: Prevent segfaults with non-text-file input X-Git-Tag: 0.29~228 X-Git-Url: http://thyrsus.com/gitweb/?a=commitdiff_plain;h=75ca44775e572f310f3525da06ccf775fd6c3522;p=intercal.git Prevent segfaults with non-text-file input --- diff --git a/doc/ick.txi b/doc/ick.txi index 0394456..0fee8bd 100644 --- a/doc/ick.txi +++ b/doc/ick.txi @@ -1848,6 +1848,8 @@ instead. This error may also be a clue that you are trying to compile a @ieanchor E666 @cindex out of memory, during compile +@cindex too many input files +@cindex line too long @quotation COMPILER HAS INDIGESTION @end quotation @@ -1858,7 +1860,9 @@ compilation, it causes this error. This error can also be caused if too many input files are specified on the command line; if you suspect this is the problem, split the compilation into separate compilations if you can, or otherwise you may be able to concatenate together your -input files into larger but fewer files. +input files into larger but fewer files. Yet another potential cause +of this error is if a line in an input program is too long; sensible +line-wrapping techniques are encouraged. @ieanchor E774 @cindex random bug, error message diff --git a/src/ick_lose.h b/src/ick_lose.h index 44165f1..fae5c4e 100644 --- a/src/ick_lose.h +++ b/src/ick_lose.h @@ -121,7 +121,8 @@ /* More than one COME FROM references the same label. */ #define IE555 "555 FLOW DIAGRAM IS EXCESSIVELY CONNECTED\n\ ON THE WAY TO %d\n" -/* Too many source lines, or too many input files. */ +/* Too many source lines, or too many input files, or source line is + too long. */ #define IE666 "666 COMPILER HAS INDIGESTION\n\ ON THE WAY TO %d\n" /* No such source file. */ diff --git a/src/lexer.l b/src/lexer.l index 8f53d6a..52b4688 100644 --- a/src/lexer.l +++ b/src/lexer.l @@ -113,6 +113,11 @@ int getc(FILE *fp) static ick_bool bangflag = ick_FALSE; static ick_bool backflag = ick_FALSE; + static ick_bool eolflag = ick_FALSE; + + if ((size_t)(lineptr - linebuf) > sizeof linebuf) + ick_lose(IE666, iyylineno, (char *)NULL); + if (bangflag) { bangflag = ick_FALSE; @@ -133,74 +138,66 @@ int getc(FILE *fp) c_char=0; /* AIS */ (void)fread(&c_char,1,1,fp); - /* AIS: ignore the ick_first \r in a row to deal with DOS newlines. The + /* AIS: ignore the first \r in a row to deal with DOS newlines. The second in a row is definitely an error, though, and will be caught later on. */ if(c_char=='\r') (void)fread(&c_char,1,1,fp); c = c_char; - /*if(!c) c=' '; AIS */ - if(feof(fp)) c=EOF; - - /*fprintf(stderr,"getc input a character: %c\n",c);*/ - if (feof(yyin)) - { - *lineptr = '\0'; - return(EOF); - } -#ifdef BACKSLASH_CONTINUATION - else if (c == '\\') - { - do { - c = fgetc(fp); - if( c == '\n' ) iyylineno++; - } while - (c != '\\' && isspace(c)); - } -#endif /* BACKSLASH_CONTINUATION */ - if (c == '!') - { - *lineptr++ = '!'; - bangflag = ick_TRUE; - return(c = '\''); - } - else if (c == '\b') /* convert ctrl-H (backspace) to + if(feof(fp)) c=EOF; + if(!eolflag && c == EOF) c = '\n'; + + /*fprintf(stderr,"getc input a character: %c\n",c);*/ + + if (feof(yyin)) + { + *lineptr = '\0'; + if(eolflag) return(EOF); + if(c=='\0' || c==EOF) c='\n'; + } + + eolflag = ick_FALSE; + + if (c == '!') + { + *lineptr++ = '!'; + bangflag = ick_TRUE; + return(c = '\''); + } + else if (c == '\b') /* convert ctrl-H (backspace) to two chars "^" and "H" so lex can take it */ + { + *lineptr++ = '\b'; + backflag = ick_TRUE; + return(c = '^'); + } + else if (c == '\n') + { + *lineptr = '\0'; + lineptr = linebuf; + if (iyylineno >= textlinecount) { - *lineptr++ = '\b'; - backflag = ick_TRUE; - return(c = '^'); - } - else if (c == '\n') - { - *lineptr = '\0'; - lineptr = linebuf; - if (iyylineno >= textlinecount) - { - textlinecount += ALLOC_CHUNK; - if (textlines) - textlines = realloc(textlines, - textlinecount * sizeof(char*)); - else - textlines = malloc(textlinecount * sizeof(char*)); - if (!textlines) - ick_lose(IE666, iyylineno, (char *)NULL); - } - textlines[iyylineno] = malloc(1 + strlen(linebuf)); - if (!textlines[iyylineno]) - ick_lose(IE666, iyylineno, (char *)NULL); - strcpy(textlines[iyylineno], linebuf); - iyylineno++; - return('\n'); - } - else - { -#ifdef ACCEPT_LOWERCASE - if (islower(c)) - c = toupper(c); -#endif /* ACCEPT_LOWERCASE */ - return(*lineptr++ = c); + textlinecount += ALLOC_CHUNK; + if (textlines) + textlines = realloc(textlines, + textlinecount * sizeof(char*)); + else + textlines = malloc(textlinecount * sizeof(char*)); + if (!textlines) + ick_lose(IE666, iyylineno, (char *)NULL); } + textlines[iyylineno] = malloc(1 + strlen(linebuf)); + if (!textlines[iyylineno]) + ick_lose(IE666, iyylineno, (char *)NULL); + strcpy(textlines[iyylineno], linebuf); + iyylineno++; + eolflag=ick_TRUE; + return('\n'); + } + else + { + return(*lineptr++ = c); + } } }