From: Ralph Corderoy Date: Sat, 22 Oct 2016 16:47:06 +0000 (+0100) Subject: Merge .netrc's token() file-reading loops; quoted and not. X-Git-Url: https://diplodocus.org/git/nmh/commitdiff_plain/760caf0926e2dcc8931b631f07d2cb091922a295?ds=inline Merge .netrc's token() file-reading loops; quoted and not. Check for ferror(3) as well as feof(3) on entry. Comment on lack of definition of quoted-string syntax, e.g. «"foo""bar"» is two tokens without needing a separator. Add comments on bugs for first non-quote character of a token being backslash, and if a backslash escapes EOF. --- diff --git a/sbr/ruserpass.c b/sbr/ruserpass.c index f7f01792..fb786d0a 100644 --- a/sbr/ruserpass.c +++ b/sbr/ruserpass.c @@ -35,7 +35,7 @@ static FILE *cfile; #define ID 10 #define MACH 11 -#define MAX_TOKVAL_SIZE 1024 +#define MAX_TOKVAL_SIZE 1024 /* Including terminating NUL. */ struct toktab { char *tokstr; @@ -177,44 +177,44 @@ ruserpass(const char *host, char **aname, char **apass, int flags) static int token(char *tokval) { - char *cp; int c; + const char normalStop[] = "\t\n ,"; /* Each breaks a word. */ + const char *stop; + char *cp; struct toktab *t; - if (feof(cfile)) + if (feof(cfile) || ferror(cfile)) return TOK_EOF; - while ((c = getc(cfile)) != EOF && - (c == '\n' || c == '\t' || c == ' ' || c == ',')) - continue; + + stop = normalStop; + while ((c = getc(cfile)) != EOF && c && strchr(stop, c)) + ; if (c == EOF) return TOK_EOF; + cp = tokval; - if (c == '"') { - while ((c = getc(cfile)) != EOF && c != '"') { - if (c == '\\') - c = getc(cfile); - *cp++ = c; - if (cp - tokval > MAX_TOKVAL_SIZE-1) { - adios(NULL, "credential tokens restricted to length %d", - MAX_TOKVAL_SIZE - 1); - } - } - } else { - *cp++ = c; - while ((c = getc(cfile)) != EOF - && c != '\n' && c != '\t' && c != ' ' && c != ',') { - if (c == '\\') - c = getc(cfile); - *cp++ = c; - if (cp - tokval > MAX_TOKVAL_SIZE-1) { - adios(NULL, "credential tokens restricted to length %d", - MAX_TOKVAL_SIZE - 1); - } - } + if (c == '"') + /* FIXME: Where is the quoted-string syntax of netrc documented? + * This code treats «"foo""bar"» as two tokens without further + * separators. */ + stop = "\""; + else + *cp++ = c; /* BUG: If a backslash then it doesn't escape. */ + + while ((c = getc(cfile)) != EOF && c && !strchr(stop, c)) { + if (c == '\\') + c = getc(cfile); /* BUG: What if this is EOF. */ + *cp++ = c; + if (cp - tokval > MAX_TOKVAL_SIZE-1) { + adios(NULL, "credential tokens restricted to length %d", + MAX_TOKVAL_SIZE - 1); + } } - *cp = 0; + *cp = '\0'; + for (t = toktabs; t->tokstr; t++) if (!strcmp(t->tokstr, tokval)) return (t->tval); + return (ID); }