-rw-r--r-- | library/backend/vcc.y | 53 |
1 files changed, 41 insertions, 12 deletions
diff --git a/library/backend/vcc.y b/library/backend/vcc.y index eca7c32..00e8fed 100644 --- a/library/backend/vcc.y +++ b/library/backend/vcc.y @@ -50,6 +50,8 @@ DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable. /* debugging utilities */ +#define __DEBUG 1
+
#if __DEBUG #define DBG_(x) printf x #else @@ -135,6 +137,7 @@ DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable. /**** Global Variables ****/ +int q_DontDecodeBase64Photo = 0;
int mime_lineNum, mime_numErrors; /* yyerror() can use these */ static VObject* vObjList; static VObject *curProp; @@ -158,6 +161,7 @@ int yyparse(); enum LexMode { L_NORMAL, + L_PARAMWORD,
L_VCARD, L_VCAL, L_VEVENT, @@ -289,10 +293,14 @@ attr: name { enterAttr($1,0); } - | name EQ name + | name EQ
{ - enterAttr($1,$3); - + lexPushMode(L_PARAMWORD);
+ }
+ name
+ {
+ lexPopMode(0);
+ enterAttr($1,$4);
} ; @@ -451,10 +459,15 @@ static void enterAttr(const char *s1, const char *s2) } else addProp(curProp,p1); - if (qstricmp(p1,VCBase64Prop) == 0 || (s2 && qstricmp(p2,VCBase64Prop)==0)) + /* Lookup strings so we can quickly use pointer comparison */
+ static const char* base64 = lookupProp_(VCBase64Prop);
+ static const char* qp = lookupProp_(VCQuotedPrintableProp);
+ static const char* photo = lookupProp_(VCPhotoProp);
+ static const char* encoding = lookupProp_(VCEncodingProp);
+ if ((!q_DontDecodeBase64Photo || vObjectName(curProp) != photo)
+ && (p1 == base64 || p1 == encoding && p2 == base64))
lexPushMode(L_BASE64); - else if (qstricmp(p1,VCQuotedPrintableProp) == 0 - || (s2 && qstricmp(p2,VCQuotedPrintableProp)==0)) + else if (p1 == qp || p1 == encoding && p2 == qp)
lexPushMode(L_QUOTED_PRINTABLE); deleteStr(s1); deleteStr(s2); } @@ -641,6 +654,20 @@ static char* lexGetWord() { return lexStr(); } +static char* lexGetParamWord()
+{
+ int c;
+ lexClearToken();
+ c = lexLookahead();
+ while (c >= ' ' && c < 127 && !strchr("[]:=,.;",c)) {
+ lexAppendc(c);
+ lexSkipLookahead();
+ c = lexLookahead();
+ }
+ lexAppendc(0);
+ return lexStr();
+}
+
static void lexPushLookaheadc(int c) { int putptr; /* can't putback EOF, because it never leaves lookahead buffer */ @@ -1010,6 +1037,7 @@ static int yylex() { int lexmode = LEXMODE(); if (lexmode == L_VALUES) { int c = lexGetc(); + int c2;
if (c == ';' && fieldedProp) { DBG_(("db: SEMICOLON\n")); lexPushLookaheadc(c); @@ -1017,13 +1045,12 @@ static int yylex() { lexSkipLookahead(); return SEMICOLON; } - else if (strchr("\n",c)) { + else if (strchr("\n",c) && (c2 = lexLookahead()) != ' ' && c2 != '\t') {
++mime_lineNum; /* consume all line separator(s) adjacent to each other */ - c = lexLookahead(); - while (strchr("\n",c)) { + while (strchr("\n",c2)) {
lexSkipLookahead(); - c = lexLookahead(); + c2 = lexLookahead();
++mime_lineNum; } DBG_(("db: LINESEP\n")); @@ -1054,8 +1081,10 @@ static int yylex() { } else return 0; } - } - else { + } else if (lexmode == L_PARAMWORD) {
+ yylval.str = lexGetParamWord();
+ return ID;
+ } else {
/* normal mode */ while (1) { int c = lexGetc(); |