chiark / gitweb /
@@ -1,3 +1,12 @@
authorian <ian>
Sun, 7 Nov 1999 15:39:53 +0000 (15:39 +0000)
committerian <ian>
Sun, 7 Nov 1999 15:39:53 +0000 (15:39 +0000)
+userv (0.65.3) unstable; urgency=low
+
+  * Count \-continued lines properly in error message line numbers.
+  * Fix lexing bugs with "-quoted strings and \-continuation.
+  * Fix interpretation of \n etc. in "-quoted strings.
+  * Fix bug which ignored erroneous read/write after ignore-fd/reject-fd.
+
+ --
+
 userv (0.65.2) unstable; urgency=high

   * In client, copy results from getpw* when necessary.  This fixes what

daemon.h
debian/changelog
lexer.l.m4
parser.c

index a8f53445787e82173dbe90d33986bd8581df3e7e..235271eca43675cf62454a506e8c3d4813471673 100644 (file)
--- a/daemon.h
+++ b/daemon.h
 #define ERRMSG_RESERVE_ERRNO 128
 
 int parse_string(const char *string, const char *descrip, int isinternal);
 #define ERRMSG_RESERVE_ERRNO 128
 
 int parse_string(const char *string, const char *descrip, int isinternal);
-void parseerrprint(const char *fmt, ...) PRINTFFORMAT(1,2);
+int parseerrprint(const char *fmt, ...) PRINTFFORMAT(1,2);
 void ensurelogopen(int wantfacility);
 void ensurefdarray(int fd);
 const char *printtoken(int token);
 void ensurelogopen(int wantfacility);
 void ensurefdarray(int fd);
 const char *printtoken(int token);
index e1d734f7d927b3fea75fc779501a498490176137..657c57e4572b3d47849132b58e8e05b1305889de 100644 (file)
@@ -1,3 +1,12 @@
+userv (0.65.3) unstable; urgency=low
+
+  * Count \-continued lines properly in error message line numbers.
+  * Fix lexing bugs with "-quoted strings and \-continuation.
+  * Fix interpretation of \n etc. in "-quoted strings.
+  * Fix bug which ignored erroneous read/write after ignore-fd/reject-fd.
+
+ --
+
 userv (0.65.2) unstable; urgency=high
 
   * In client, copy results from getpw* when necessary.  This fixes what
 userv (0.65.2) unstable; urgency=high
 
   * In client, copy results from getpw* when necessary.  This fixes what
index 22ad0e0ead615ba0f4becb522d88a60c8e655b74..78aab9d4020f4ced1b63aa6942844679f82e6aa0 100644 (file)
@@ -132,6 +132,7 @@ struct error_handling {
 static struct error_handling eh = { tokv_word_errorstostderr, 0,0,0,0,0 };
 
 static int dequote(char *inplace);
 static struct error_handling eh = { tokv_word_errorstostderr, 0,0,0,0,0 };
 
 static int dequote(char *inplace);
+static void countnewlines(void);
 
 #define YY_NO_UNPUT
 
 
 #define YY_NO_UNPUT
 
@@ -158,10 +159,8 @@ changequote({*,*})
                          assert(*++ep);
                          lr_max= (int)strtoul(ep,&ep,10);
                          assert(!*ep);
                          assert(*++ep);
                          lr_max= (int)strtoul(ep,&ep,10);
                          assert(!*ep);
-                         if (lr_max < lr_min) {
-                           parseerrprint("fd range has min > max");
-                           return tokv_error;
-                         }
+                         if (lr_max < lr_min)
+                           return parseerrprint("fd range has min > max");
                          return tokv_fdrange;
                        }
 [0-9]{1,8}-            {
                          return tokv_fdrange;
                        }
 [0-9]{1,8}-            {
@@ -172,23 +171,20 @@ changequote({*,*})
                          lr_max=-1;
                          return tokv_fdstoend;
                        }
                          lr_max=-1;
                          return tokv_fdstoend;
                        }
-([\ \t]*\\[\ \t]*\n[\ \t]*)+   return tokv_lwsp;
+([\ \t]*\\[\ \t]*\n[\ \t]*)+   countnewlines(); return tokv_lwsp;
 [\ \t]+                                return tokv_lwsp;
 [\ \t]*\n              cstate->lineno++; return tokv_newline;
 [\ \t]*\#[^\n]*\n      cstate->lineno++; return tokv_newline;
 [\ \t]+                                return tokv_lwsp;
 [\ \t]*\n              cstate->lineno++; return tokv_newline;
 [\ \t]*\#[^\n]*\n      cstate->lineno++; return tokv_newline;
-[\ \t]*\#[^\n]*                {
-                         parseerrprint("missing newline at eof after comment");
-                         return tokv_error;
-                       }
+[\ \t]*\#[^\n]*                return parseerrprint("missing newline at eof after comment");
 \"([^\\\"\n]|\\[a-z]|\\[0-9]{3}|\\x[0-9A-Fa-f]{2}|\\[[:punct:]]|\\[ \t]*\n)*\" {
 \"([^\\\"\n]|\\[a-z]|\\[0-9]{3}|\\x[0-9A-Fa-f]{2}|\\[[:punct:]]|\\[ \t]*\n)*\" {
+                         countnewlines();
                          return dequote(yytext);
                        }
                          return dequote(yytext);
                        }
-\".*                   {
-                         parseerrprint("misquoted or unterminated string");
-                         return tokv_error;
-                       }
-[^\ \t\n\\]+           return tokv_barestring;
-<<EOF>>                        return tokv_eof;
+[^\ \t\n\\\"]+         return tokv_barestring;
+<<EOF>>                        return tokv_eof;
+\"                     return parseerrprint("misquoted or unterminated string");
+\\                     return parseerrprint("unexpected backslash");
+.                      abort(); /* expect lex warning "rule cannot be matched" */
 *}
 changequote(`,')
 %%
 *}
 changequote(`,')
 %%
index 0d1054ff29ae454f92474e6711e711549a4ab0e6..b2c2b03896c41bb3c3450cf8d12d08d1b8f6128e 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -98,7 +98,7 @@ static void errwhere(struct parser_state *tstate, char *bufput, int bufputlen) {
            tstate->filename,tstate->reportlineno);
 }
 
            tstate->filename,tstate->reportlineno);
 }
 
-void parseerrprint(const char *fmt, ...) {
+int parseerrprint(const char *fmt, ...) {
   va_list al;
   char errmsg[MAX_ERRMSG_LEN];
 
   va_list al;
   char errmsg[MAX_ERRMSG_LEN];
 
@@ -107,6 +107,8 @@ void parseerrprint(const char *fmt, ...) {
   vsnytprintfcat(errmsg,sizeof(errmsg),fmt,al);
   senderrmsg(errmsg,eh.handling);
   va_end(al);
   vsnytprintfcat(errmsg,sizeof(errmsg),fmt,al);
   senderrmsg(errmsg,eh.handling);
   va_end(al);
+
+  return tokv_error;
 }
 
 static int unexpected(int found, int wanted, const char *wantedstr) {
 }
 
 static int unexpected(int found, int wanted, const char *wantedstr) {
@@ -115,13 +117,11 @@ static int unexpected(int found, int wanted, const char *wantedstr) {
    */
   if (found == wanted) return 0;
   if (found == tokv_error) return found;
    */
   if (found == wanted) return 0;
   if (found == tokv_error) return found;
-  parseerrprint("found %s, expected %s",printtoken(found),wantedstr);
-  return tokv_error;
+  return parseerrprint("found %s, expected %s",printtoken(found),wantedstr);
 }
 
 static int stringoverflow(const char *where) {
 }
 
 static int stringoverflow(const char *where) {
-  parseerrprint("string buffer became far too large building %s",where);
-  return tokv_error;
+  return parseerrprint("string buffer became far too large building %s",where);
 }
 
 /*
 }
 
 /*
@@ -136,6 +136,13 @@ static void freecharparray(char **array) {
   free(array);
 }
 
   free(array);
 }
 
+static void countnewlines(void) {
+  char *p;
+  for (p=yytext; *p; p++)
+    if (*p == '\n')
+      cstate->lineno++;
+}
+
 static int dequote(char *inplace) {
   char *p, *q, buf[4], *bep;
   int v;
 static int dequote(char *inplace) {
   char *p, *q, buf[4], *bep;
   int v;
@@ -145,35 +152,28 @@ static int dequote(char *inplace) {
   while (*p && *p != '"') {
     if (*p != '\\') { *q++= *p++; continue; }
     switch (*++p) {
   while (*p && *p != '"') {
     if (*p != '\\') { *q++= *p++; continue; }
     switch (*++p) {
-    case 'n': *q++= '\n'; continue;
-    case 'r': *q++= '\r'; continue;
-    case 't': *q++= '\t'; continue;
+    case 'n': *q++= '\n'; p++; continue;
+    case 'r': *q++= '\r'; p++; continue;
+    case 't': *q++= '\t'; p++; continue;
     case 'x':
       p++;
     case 'x':
       p++;
-      if (!((buf[0]= *p++) && (buf[1]= *p++))) {
-       parseerrprint("quoted string ends inside \\x<hex> sequence");
-       return tokv_error;
-      }
+      if (!((buf[0]= *p++) && (buf[1]= *p++)))
+       return parseerrprint("quoted string ends inside \\x<hex> sequence");
       buf[2]= 0;
       v= strtoul(buf,&bep,16);
       buf[2]= 0;
       v= strtoul(buf,&bep,16);
-      if (bep != buf+2) {
-       parseerrprint("invalid \\<hex> sequence \\x%s in quoted string",buf);
-       return tokv_error;
-      }
+      if (bep != buf+2)
+       return parseerrprint("invalid \\<hex> sequence \\x%s in quoted string",buf);
       assert(!(v & ~0xff));
       *q++= v;
       continue;
     default:
       assert(!(v & ~0xff));
       *q++= v;
       continue;
     default:
-      if (isalpha(*p)) {
-        parseerrprint("unknown \\<letter> sequence \\%c in quoted string",*p);
-        return tokv_error;
-      } else if (isdigit(*p)) {
+      if (isalpha(*p))
+        return parseerrprint("unknown \\<letter> sequence \\%c in quoted string",*p);
+      if (isdigit(*p)) {
         if (!((buf[0]= *p++) && (buf[1]= *p++) && (buf[2]= *p++))) abort();
         buf[3]= 0; v= strtoul(buf,&bep,8);
         if (!((buf[0]= *p++) && (buf[1]= *p++) && (buf[2]= *p++))) abort();
         buf[3]= 0; v= strtoul(buf,&bep,8);
-        if (bep != buf+3 || (v & ~0xff)) {
-          parseerrprint("invalid \\<octal> sequence \\%s in quoted string",buf);
-          return tokv_error;
-        }
+        if (bep != buf+3 || (v & ~0xff))
+          return parseerrprint("invalid \\<octal> sequence \\%s in quoted string",buf);
         *q++= v; continue;
       } else if (ispunct(*p)) {
         *q++= *p++; continue;
         *q++= v; continue;
       } else if (ispunct(*p)) {
         *q++= *p++; continue;
@@ -348,8 +348,8 @@ static int paa_pathargs(const char **path_r, char ***newargs_r) {
     }
     if (used>=size) {
       if (used >= MAX_ARGSDEFVAR) {
     }
     if (used>=size) {
       if (used >= MAX_ARGSDEFVAR) {
-       parseerrprint("far too many arguments to service program");
-       r= tokv_error; goto error;
+       r= parseerrprint("far too many arguments to service program");
+       goto error;
       }
       size= (used+5)<<1;
       newargs= xrealloc(newargs,sizeof(char*)*(size+1));
       }
       size= (used+5)<<1;
       newargs= xrealloc(newargs,sizeof(char*)*(size+1));
@@ -380,10 +380,8 @@ static int paa_message(const char **message_r) {
   buildbuf[0]= 0;
   for (;;) {
     r= yylex(); if (r == tokv_error) return r;
   buildbuf[0]= 0;
   for (;;) {
     r= yylex(); if (r == tokv_error) return r;
-    if (r == tokv_eof) {
-      parseerrprint("unexpected end of file in message text");
-      return tokv_error;
-    }
+    if (r == tokv_eof)
+      return parseerrprint("unexpected end of file in message text");
     if (r == tokv_newline) break;
     usetext= r == tokv_lwsp ? " " : yytext;
     tl+= strlen(usetext);
     if (r == tokv_newline) break;
     usetext= r == tokv_lwsp ? " " : yytext;
     tl+= strlen(usetext);
@@ -410,8 +408,7 @@ static int skiptoeol(void) {
   if (token == tokv_newline) return 0;
   if (token == tokv_error) return token;
   assert(token == tokv_eof);
   if (token == tokv_newline) return 0;
   if (token == tokv_error) return token;
   assert(token == tokv_eof);
-  parseerrprint("unexpected end of file while looking for end of line");
-  return tokv_error;
+  return parseerrprint("unexpected end of file while looking for end of line");
 }
 
 static int skip(int allowce) {
 }
 
 static int skip(int allowce) {
@@ -439,9 +436,8 @@ static int skip(int allowce) {
         r= skip(token); if (r & tokt_exception) return r;
       }
     } else if (!(token & tokt_directive) && !(token & tokt_condop)) {
         r= skip(token); if (r & tokt_exception) return r;
       }
     } else if (!(token & tokt_directive) && !(token & tokt_condop)) {
-      parseerrprint("not a directive (or conditional operator) "
-                   "while looking for control structure end");
-      return tokv_error;
+      return parseerrprint("not a directive (or conditional operator) "
+                          "while looking for control structure end");
     }
     r= skiptoeol(); if (r) return r;
   }
     }
     r= skiptoeol(); if (r) return r;
   }
@@ -616,10 +612,8 @@ int pcf_grep(int ctoken, char *const *pv, int *rtrue) {
   
   r= paa_1path(&cp); if (r) return r;
   file= fopen(cp,"r");
   
   r= paa_1path(&cp); if (r) return r;
   file= fopen(cp,"r");
-  if (!file) {
-    parseerrprint("unable to open file `%s' for grep: %s",cp,strerror(errno));
-    return tokv_error;
-  }
+  if (!file)
+    return parseerrprint("unable to open file `%s' for grep: %s",cp,strerror(errno));
   maxlen= 0;
   for (pp= pv; *pp; pp++) { l= strlen(*pp); if (l > maxlen) maxlen= l; }
   buf= xmalloc(maxlen+2); actrue= 0; c= 0;
   maxlen= 0;
   for (pp= pv; *pp; pp++) { l= strlen(*pp); if (l > maxlen) maxlen= l; }
   buf= xmalloc(maxlen+2); actrue= 0; c= 0;
@@ -864,21 +858,16 @@ int dfg_fdwant(int dtoken) {
   if (!(r & tokt_fdrange)) return unexpected(r,-1,"file descriptor range");
   fdmin= lr_min; fdmax= lr_max;
   if (fdmin<0 || fdmin>MAX_ALLOW_FD ||
   if (!(r & tokt_fdrange)) return unexpected(r,-1,"file descriptor range");
   fdmin= lr_min; fdmax= lr_max;
   if (fdmin<0 || fdmin>MAX_ALLOW_FD ||
-      (fdmax != -1 && fdmax<0) || fdmax>MAX_ALLOW_FD) {
-    parseerrprint("file descriptor in range is negative or far too large");
-    return tokv_error;
-  }
+      (fdmax != -1 && fdmax<0) || fdmax>MAX_ALLOW_FD)
+    return parseerrprint("file descriptor in range is negative or far too large");
   r= yylex(); if (r == tokv_error) return r;
   if (r == tokv_newline) {
   r= yylex(); if (r == tokv_error) return r;
   if (r == tokv_newline) {
-    if (needreadwrite > 0) {
-      parseerrprint("read or write is required");
-      return tokv_error;
-    }
+    if (needreadwrite > 0)
+      return parseerrprint("read or write is required");
     havereadwrite= 0;
   } else if (r == tokv_lwsp) {
     havereadwrite= 0;
   } else if (r == tokv_lwsp) {
-    if (needreadwrite < 0) {
-      parseerrprint("read or write not allowed"); return tokv_error;
-    }
+    if (needreadwrite < 0)
+      return parseerrprint("read or write not allowed");
     r= yylex(); if (r == tokv_error) return r;
     if (!(r & tokt_readwrite))
       return unexpected(r,-1,"read or write (or perhaps newline)");
     r= yylex(); if (r == tokv_error) return r;
     if (!(r & tokt_readwrite))
       return unexpected(r,-1,"read or write (or perhaps newline)");
@@ -890,7 +879,8 @@ int dfg_fdwant(int dtoken) {
   ensurefdarray(fdmin);
   if (fdmax == -1) {
     if (!(dtoken == tokv_word_rejectfd || dtoken == tokv_word_ignorefd))
   ensurefdarray(fdmin);
   if (fdmax == -1) {
     if (!(dtoken == tokv_word_rejectfd || dtoken == tokv_word_ignorefd))
-      parseerrprint("unspecified maximum only allowed with reject-fd and ignore-fd");
+      return parseerrprint("unspecified maximum only allowed"
+                          " with reject-fd and ignore-fd");
     fdmax= fdarrayused-1;
     restfdwantstate= dtoken;
     restfdwantrw= havereadwrite;
     fdmax= fdarrayused-1;
     restfdwantstate= dtoken;
     restfdwantrw= havereadwrite;
@@ -947,10 +937,8 @@ int df_errorstofile(int dtoken) {
   
   r= paa_1path(&cp); if (r) return r;
   file= fopen(cp,"a");
   
   r= paa_1path(&cp); if (r) return r;
   file= fopen(cp,"a");
-  if (!file) {
-    parseerrprint("unable to open error log file `%s': %s",cp,strerror(errno));
-    return tokv_error;
-  }
+  if (!file)
+    return parseerrprint("unable to open error log file `%s': %s",cp,strerror(errno));
   if (setvbuf(file,0,_IOLBF,MAX_ERRMSG_LEN)) {
     parseerrprint("unable to set line buffering on errors file: %s",strerror(errno));
     fclose(file); return tokv_error;
   if (setvbuf(file,0,_IOLBF,MAX_ERRMSG_LEN)) {
     parseerrprint("unable to set line buffering on errors file: %s",strerror(errno));
     fclose(file); return tokv_error;
@@ -985,11 +973,10 @@ int df_include(int dtoken) {
   r= paa_1path(&cp); if (r) return r;
   r= parse_file(cp,&found); if (r) return r;
   if (found || dtoken == tokv_word_includeifexist) return 0;
   r= paa_1path(&cp); if (r) return r;
   r= parse_file(cp,&found); if (r) return r;
   if (found || dtoken == tokv_word_includeifexist) return 0;
-  parseerrprint(dtoken == tokv_word_includesysconfig ?
-               "system configuration file `%s' does not exist" :
-               "included file `%s' does not exist",
-               cp);
-  return tokv_error;
+  return parseerrprint(dtoken == tokv_word_includesysconfig ?
+                      "system configuration file `%s' does not exist" :
+                      "included file `%s' does not exist",
+                      cp);
 }
 
 int df_includedirectory(int dtoken) {
 }
 
 int df_includedirectory(int dtoken) {
@@ -1004,10 +991,8 @@ int df_includedirectory(int dtoken) {
   
   r= paa_1path(&cpget); if (r) return r;
   d= opendir(cpget);
   
   r= paa_1path(&cpget); if (r) return r;
   d= opendir(cpget);
-  if (!d) {
-    parseerrprint("unable to open directory `%s': %s",cpget,strerror(errno));
-    return tokv_error;
-  }
+  if (!d)
+    return parseerrprint("unable to open directory `%s': %s",cpget,strerror(errno));
   cp= xstrsave(cpget);
   cpl= strlen(cp);
   while ((de= readdir(d))) {
   cp= xstrsave(cpget);
   cpl= strlen(cp);
   while ((de= readdir(d))) {
@@ -1024,9 +1009,9 @@ int df_includedirectory(int dtoken) {
     snyprintf(buildbuf,buildbuflen,"%s/%s",cp,de->d_name);
     r= parse_file(buildbuf,&found); if (r) goto x_err;
     if (!found) {
     snyprintf(buildbuf,buildbuflen,"%s/%s",cp,de->d_name);
     r= parse_file(buildbuf,&found); if (r) goto x_err;
     if (!found) {
-      parseerrprint("unable to open file `%s' in included directory `%s': %s",
-                   de->d_name,cp,strerror(errno));
-      r= tokv_error; goto x_err;
+      r= parseerrprint("unable to open file `%s' in included directory `%s': %s",
+                      de->d_name,cp,strerror(errno));
+      goto x_err;
     }
   }
   if (closedir(d)) {
     }
   }
   if (closedir(d)) {
@@ -1197,8 +1182,7 @@ int df_cd(int dtoken) {
 
   r= paa_1path(&cp); if (r) return r;
   if (!chdir(cp)) return 0;
 
   r= paa_1path(&cp); if (r) return r;
   if (!chdir(cp)) return 0;
-  parseerrprint("unable to change directory to `%s': %s",cp,strerror(errno));
-  return tokv_error;
+  return parseerrprint("unable to change directory to `%s': %s",cp,strerror(errno));
 }
 
 int df_userrcfile(int dtoken) {
 }
 
 int df_userrcfile(int dtoken) {
@@ -1224,8 +1208,7 @@ int df_error(int dtoken) {
   int r;
 
   r= paa_message(&mp); if (r) return r;
   int r;
 
   r= paa_message(&mp); if (r) return r;
-  parseerrprint("`error' directive: %s",mp);
-  return tokv_error;
+  return parseerrprint("`error' directive: %s",mp);
 }
 
 int df_eof(int dtoken) {
 }
 
 int df_eof(int dtoken) {
@@ -1311,27 +1294,23 @@ static int parse_file(const char *string, int *didexist) {
   char *filename;
   struct stat newstab;
 
   char *filename;
   struct stat newstab;
 
-  if (fileparselevel >= MAX_INCLUDE_NEST) {
-    parseerrprint("too many nested levels of included files");
-    return tokv_error;
-  }
+  if (fileparselevel >= MAX_INCLUDE_NEST)
+    return parseerrprint("too many nested levels of included files");
   file= fopen(string,"r");
   if (!file) {
     if (errno == ENOENT) {
       if (didexist) *didexist= 0;
       return 0;
     }
   file= fopen(string,"r");
   if (!file) {
     if (errno == ENOENT) {
       if (didexist) *didexist= 0;
       return 0;
     }
-    parseerrprint("unable to open config file `%s': %s",string,strerror(errno));
-    return tokv_error;
+    return parseerrprint("unable to open config file `%s': %s",string,strerror(errno));
   }
   r= fstat(fileno(file),&newstab); if (r) syscallerror("unable to fstat new file");
   for (checkrecurse= cstate; checkrecurse; checkrecurse= checkrecurse->upstate) {
     if (!checkrecurse->filestab.st_mode) continue;
     if (newstab.st_dev==checkrecurse->filestab.st_dev &&
        newstab.st_ino==checkrecurse->filestab.st_ino) {
   }
   r= fstat(fileno(file),&newstab); if (r) syscallerror("unable to fstat new file");
   for (checkrecurse= cstate; checkrecurse; checkrecurse= checkrecurse->upstate) {
     if (!checkrecurse->filestab.st_mode) continue;
     if (newstab.st_dev==checkrecurse->filestab.st_dev &&
        newstab.st_ino==checkrecurse->filestab.st_ino) {
-      parseerrprint("recursion detected - config file `%s' calls itself",string);
       fclose(file);
       fclose(file);
-      return tokv_error;
+      return parseerrprint("recursion detected - config file `%s' calls itself",string);
     }
   }
   
     }
   }
   
@@ -1344,10 +1323,8 @@ static int parse_file(const char *string, int *didexist) {
   fileparselevel++;
   
   r= parser(0);
   fileparselevel++;
   
   r= parser(0);
-  if (ferror(file)) {
-    parseerrprint("error reading configuration file `%s'",string);
-    r= tokv_error;
-  }
+  if (ferror(file))
+    r= parseerrprint("error reading configuration file `%s'",string);
 
   fileparselevel--;
   parser_pop();
 
   fileparselevel--;
   parser_pop();