]> thyrsus.com Git - intercal.git/commitdiff
Prevent segfaults with non-text-file input
authorAlex Smith <ais523@bham.ac.uk>
Sat, 21 Jun 2008 22:08:17 +0000 (18:08 -0400)
committerEric S. Raymond <esr@thyrsus.com>
Thu, 26 Aug 2010 00:34:57 +0000 (20:34 -0400)
doc/ick.txi
src/ick_lose.h
src/lexer.l

index 0394456484f48137b53c19c75cc26313ab00b946..0fee8bde7c186581230637ae2f604fb5b2c84d29 100644 (file)
@@ -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
index 44165f12a7ae742965587c9cfb3862b431e9ac20..fae5c4eeed069d10f8ab7c44e421ee6e8cf8ee5d 100644 (file)
 /* 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. */
index 8f53d6adbd2673a09660fe2b177b3dea86eeb323..52b46883a1781bcd5e30f63b847560c718ec3cc9 100644 (file)
@@ -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);
+      }
     }
 }