From de10444111d8158b3bddc4b456cad732c3608a5b Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sat, 11 Jan 1997 20:32:00 +0000 Subject: Eliminate bug reported by Steven Trainoff svn path=/trunk/; revision=742 --- rfc822.c | 59 +++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 18 deletions(-) diff --git a/rfc822.c b/rfc822.c index 8497c54b..d4342afb 100644 --- a/rfc822.c +++ b/rfc822.c @@ -158,9 +158,8 @@ const char *hdr; /* header to be parsed, NUL to continue previous hdr */ int parendepth; /* - * Note 1: RFC822 escaping with \ is *not* handled. Note 2: it is - * important that this routine not stop on \r, since we use \r as - * a marker for RFC822 continuations elsewhere. + * Note: it is important that this routine not stop on \r, since + * we use \r as a marker for RFC822 continuations elsewhere. */ #define START_HDR 0 /* before header colon */ #define SKIP_JUNK 1 /* skip whitespace, \n, and junk */ @@ -199,6 +198,11 @@ const char *hdr; /* header to be parsed, NUL to continue previous hdr */ state = ENDIT_ALL; return(NULL); } + else if (*hp == '\\') /* handle RFC822 escaping */ + { + *tp++ = *hp++; /* take the escape */ + *tp++ = *hp; /* take following char */ + } else if (*hp == '"') /* quoted string */ { oldstate = SKIP_JUNK; @@ -222,13 +226,18 @@ const char *hdr; /* header to be parsed, NUL to continue previous hdr */ } break; - case BARE_ADDRESS: /* collecting address without delimiters */ - if (*hp == '\n') /* end of bare address */ + case BARE_ADDRESS: /* collecting address without delimiters */ + if (*hp == '\n') /* end of bare address */ { *tp++ = '\0'; state = ENDIT_ALL; return(tp = address); } + else if (*hp == '\\') /* handle RFC822 escaping */ + { + *tp++ = *hp++; /* take the escape */ + *tp++ = *hp; /* take following char */ + } else if (*hp == ',' || isspace(*hp)) /* end of address */ { if (tp > address) @@ -241,18 +250,22 @@ const char *hdr; /* header to be parsed, NUL to continue previous hdr */ } else /* just take it */ { - state = BARE_ADDRESS; *tp++ = *hp; } break; - case INSIDE_DQUOTE: /* we're in a quoted string, copy verbatim */ - if (*hp == '\n') + case INSIDE_DQUOTE: /* we're in a quoted string, copy verbatim */ + if (*hp == '\n') /* premature end of string */ { state = ENDIT_ALL; return(NULL); } - if (*hp != '"') + else if (*hp == '\\') /* handle RFC822 escaping */ + { + *tp++ = *hp++; /* take the escape */ + *tp++ = *hp; /* take following char */ + } + else if (*hp != '"') *tp++ = *hp; else { @@ -261,9 +274,14 @@ const char *hdr; /* header to be parsed, NUL to continue previous hdr */ } break; - case INSIDE_PARENS: /* we're in a parenthesized comment, ignore */ - if (*hp == '\n') + case INSIDE_PARENS: /* we're in a parenthesized comment, ignore */ + if (*hp == '\n') /* end of line, just bomb out */ return(NULL); + else if (*hp == '\\') /* handle RFC822 escaping */ + { + *tp++ = *hp++; /* take the escape */ + *tp++ = *hp; /* take following char */ + } else if (*hp == '(') ++parendepth; else if (*hp == ')') @@ -272,27 +290,32 @@ const char *hdr; /* header to be parsed, NUL to continue previous hdr */ state = SKIP_JUNK; break; - case INSIDE_BRACKETS: /* possible <>-enclosed address */ - if (*hp == '>') /* end of address */ + case INSIDE_BRACKETS: /* possible <>-enclosed address */ + if (*hp == '\\') /* handle RFC822 escaping */ + { + *tp++ = *hp++; /* take the escape */ + *tp++ = *hp; /* take following char */ + } + else if (*hp == '>') /* end of address */ { *tp++ = '\0'; state = SKIP_JUNK; ++hp; return(tp = address); } - else if (*hp == '<') /* nested <> */ + else if (*hp == '<') /* nested <> */ tp = address; - else if (*hp == '"') /* quoted address */ + else if (*hp == '"') /* quoted address */ { *tp++ = *hp; oldstate = INSIDE_BRACKETS; state = INSIDE_DQUOTE; } - else /* just copy address */ + else /* just copy address */ *tp++ = *hp; break; - case ENDIT_ALL: /* after last address */ + case ENDIT_ALL: /* after last address */ return(NULL); break; } @@ -319,7 +342,7 @@ main(int argc, char *argv[]) fputs(buf, stdout); if ((cp = nxtaddr(buf)) != (char *)NULL) do { - printf("%s\n", cp); + printf("\t%s\n", cp); } while ((cp = nxtaddr((char *)NULL)) != (char *)NULL); } -- cgit v1.2.3