X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=userv.git;a=blobdiff_plain;f=parser.c;h=5f6ebadc7da07b2f2efe6d09bbd7a1b1039b6c23;hp=ecfe32239aac292c8c4e313997c5f8320db397fc;hb=d237116707105a3ca6cf367a672bc5263cf7856d;hpb=1a01177d758ce6fe2ad86a7f223054d806787803 diff --git a/parser.c b/parser.c index ecfe322..5f6ebad 100644 --- a/parser.c +++ b/parser.c @@ -6,7 +6,7 @@ * about m4 quoting &c., but we have to #include it so that the C * objects from the lexer are available. * - * Copyright (C)1996-1997 Ian Jackson + * Copyright (C)1996-1999 Ian Jackson * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by @@ -139,7 +139,7 @@ static void freecharparray(char **array) { static int dequote(char *inplace) { char *p, *q, buf[4], *bep; int v; - + p=q=inplace; assert(*p++ = '"'); while (*p && *p != '"') { @@ -149,30 +149,42 @@ static int dequote(char *inplace) { case 'r': *q++= '\r'; continue; case 't': *q++= '\t'; continue; case 'x': - assert(buf[0]= *++p); assert(buf[1]= *++p); buf[2]= 0; - v= strtoul(buf,&bep,16); assert(bep == buf+2); - assert(!(v & ~0xff)); *q++= v; p++; continue; + p++; + if (!((buf[0]= *p++) && (buf[1]= *p++))) { + parseerrprint("quoted string ends inside \\x sequence"); + return tokv_error; + } + buf[2]= 0; + v= strtoul(buf,&bep,16); + if (bep != buf+2) { + parseerrprint("invalid \\ sequence \\x%s in quoted string",buf); + return tokv_error; + } + assert(!(v & ~0xff)); + *q++= v; + continue; default: if (isalpha(*p)) { parseerrprint("unknown \\ sequence \\%c in quoted string",*p); return tokv_error; } else if (isdigit(*p)) { - assert(buf[0]= *++p); assert(buf[1]= *++p); assert(buf[2]= *++p); + 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)); { + if (bep != buf+3 || (v & ~0xff)) { parseerrprint("invalid \\ sequence \\%s in quoted string",buf); return tokv_error; } - *q++= v; p++; continue; + *q++= v; continue; } else if (ispunct(*p)) { *q++= *p++; continue; } else { while (*p==' ' || *p=='\t') p++; - assert(*p=='\n'); + v= *p++; assert(v=='\n'); } } } assert(*p); assert(!*++p); + *q++= 0; return tokv_quotedstring; } @@ -487,7 +499,7 @@ static int pf_service(int ptoken, char ***rvalues) { } static int pf_callinguser(int ptoken, char ***rvalues) { - return parm_usernameuid(rvalues,logname,request_mbuf.callinguid); + return parm_usernameuid(rvalues,loginname,request_mbuf.callinguid); } static int pf_serviceuser(int ptoken, char ***rvalues) { @@ -838,8 +850,7 @@ int df_reset(int dtoken) { r= pa_mnl(); if (r) return r; r= parse_string(RESET_CONFIGURATION,"",1); - assert(!r); - return 0; + return r; } int dfg_fdwant(int dtoken) { @@ -986,14 +997,16 @@ int df_includedirectory(int dtoken) { int r, cpl, tel, c, found; DIR *d; struct dirent *de; - const char *p, *cp; + const char *p, *cpget; + char *cp; - r= paa_1path(&cp); if (r) return r; - d= opendir(cp); + r= paa_1path(&cpget); if (r) return r; + d= opendir(cpget); if (!d) { - parseerrprint("unable to open directory `%s': %s",cp,strerror(errno)); + parseerrprint("unable to open directory `%s': %s",cpget,strerror(errno)); return tokv_error; } + cp= xstrsave(cpget); cpl= strlen(cp); while ((de= readdir(d))) { tel= strlen(de->d_name); @@ -1002,60 +1015,72 @@ int df_includedirectory(int dtoken) { if (!*p || !isalnum(*p)) continue; while ((c= *++p)) if (!(isalnum(c) || c=='-')) break; if (c) continue; - if (makeroom(&buildbuf,&buildbuflen,cpl+1+tel+1)) - return stringoverflow("pathname in directory"); + if (makeroom(&buildbuf,&buildbuflen,cpl+1+tel+1)) { + stringoverflow("pathname in directory"); + r= tokv_error; goto x_err; + } snyprintf(buildbuf,buildbuflen,"%s/%s",cp,de->d_name); - r= parse_file(buildbuf,&found); if (r) { closedir(d); return r; } + 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)); - closedir(d); - return tokv_error; + r= tokv_error; goto x_err; } } if (closedir(d)) { parseerrprint("error closing directory `%s': %s",cp,strerror(errno)); + free(cp); return tokv_error; } + free(cp); return 0; + +x_err: + closedir(d); + free(cp); + return r; } int df_includelookup(int dtoken) { static char *buildbuf=0; int buildbuflen=0; - char **parmvalues, **pp, *p, *q; - const char *cp; + char **parmvalues, **pp, *p, *q, *cp; + const char *cpget; struct stat stab; int r, done, thisdone, cpl, c; r= pa_mwsp(); if (r) return r; r= pa_parameter(&parmvalues,0); if (r) return r; - r= paa_1path(&cp); if (r) { freecharparray(parmvalues); return r; } - if (stat(cp,&stab)) { - parseerrprint("unable to access directory `%s': %s",cp,strerror(errno)); + r= paa_1path(&cpget); if (r) { freecharparray(parmvalues); return r; } + if (stat(cpget,&stab)) { + parseerrprint("unable to access directory `%s': %s",cpget,strerror(errno)); freecharparray(parmvalues); return tokv_error; } if (!S_ISDIR(stab.st_mode)) { - parseerrprint("object `%s' is not a directory or link to one",cp); + parseerrprint("object `%s' is not a directory or link to one",cpget); freecharparray(parmvalues); return tokv_error; } done= 0; + cp= xstrsave(cpget); cpl= strlen(cp); if (!parmvalues[0]) { - if (makeroom(&buildbuf,&buildbuflen,cpl+1+sizeof(NONEINCLUDELOOKUP))) - return stringoverflow("pathname in directory for lookup of undefined parameter"); + if (makeroom(&buildbuf,&buildbuflen,cpl+1+sizeof(NONEINCLUDELOOKUP))) { + stringoverflow("pathname in directory for lookup of undefined parameter"); + r= tokv_error; goto x_err; + } snyprintf(buildbuf,buildbuflen,"%s/" NONEINCLUDELOOKUP,cp); - r= parse_file(buildbuf,&thisdone); - if (r) { freecharparray(parmvalues); return r; } + r= parse_file(buildbuf,&thisdone); if (r) goto x_err; if (thisdone) done= 1; } else { for (pp=parmvalues; *pp && (!done || dtoken == tokv_word_includelookupall); pp++) { if (makeroom(&buildbuf,&buildbuflen, - cpl+1+strlen(*pp)*2+3+sizeof(EMPTYINCLUDELOOKUP)+1)) - return stringoverflow("pathname in directory for lookup"); + cpl+1+strlen(*pp)*2+3+sizeof(EMPTYINCLUDELOOKUP)+1)) { + stringoverflow("pathname in directory for lookup"); + r= tokv_error; goto x_err; + } strcpy(buildbuf,cp); p= *pp; q= buildbuf+cpl; *q++= '/'; @@ -1071,19 +1096,25 @@ int df_includelookup(int dtoken) { *q++= 0; } r= parse_file(buildbuf,&thisdone); - if (r) { freecharparray(parmvalues); return r; } + if (r) goto x_err; if (thisdone) done= 1; } } - freecharparray(parmvalues); if (!done) { if (makeroom(&buildbuf,&buildbuflen, - cpl+1+sizeof(DEFAULTINCLUDELOOKUP))) - return stringoverflow("pathname in directory for lookup of default"); + cpl+1+sizeof(DEFAULTINCLUDELOOKUP))) { + stringoverflow("pathname in directory for lookup of default"); + r= tokv_error; goto x_err; + } snyprintf(buildbuf,buildbuflen,"%s/" DEFAULTINCLUDELOOKUP,cp); - r= parse_file(buildbuf,0); if (r) return r; + r= parse_file(buildbuf,0); if (r) goto x_err; } - return 0; + r= 0; + +x_err: + freecharparray(parmvalues); + free(cp); + return r; } /* Control constructs */ @@ -1298,9 +1329,9 @@ static int parse_file(const char *string, int *didexist) { if (didexist) *didexist= 1; - filename= xstrsave(file); ybuf= yy_create_buffer(file,YY_BUF_SIZE); if (!ybuf) syscallerror("unable to create flex buffer for file"); + filename= xstrsave(string); parser_push(&usestate,filename,&newstab,ybuf,0); fileparselevel++;