-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 @@ -47,12 +47,14 @@ DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable. * in a debugger. However, if a bug is found it should * be fixed in vcc.y and this file regenerated. */ /* debugging utilities */ +#define __DEBUG 1
+
#if __DEBUG #define DBG_(x) printf x #else #define DBG_(x) #endif @@ -132,12 +134,13 @@ DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable. #define YYSTACKSIZE 100 // ~unref ? #define MAXLEVEL 10 /* max # of nested objects parseable */ /* (includes outermost) */ /**** Global Variables ****/ +int q_DontDecodeBase64Photo = 0;
int mime_lineNum, mime_numErrors; /* yyerror() can use these */ static VObject* vObjList; static VObject *curProp; static VObject *curObj; static VObject* ObjStack[MAXLEVEL]; static int ObjStackTop; @@ -155,12 +158,13 @@ extern "C" { #endif int yyparse(); enum LexMode { L_NORMAL, + L_PARAMWORD,
L_VCARD, L_VCAL, L_VEVENT, L_VTODO, L_VALUES, L_BASE64, @@ -286,16 +290,20 @@ attr_param: SEMICOLON attr ; attr: name { enterAttr($1,0); } - | name EQ name + | name EQ
{ - enterAttr($1,$3); - + lexPushMode(L_PARAMWORD);
+ }
+ name
+ {
+ lexPopMode(0);
+ enterAttr($1,$4);
} ; name: ID ; @@ -448,16 +456,21 @@ static void enterAttr(const char *s1, const char *s2) p2 = lookupProp_(s2); a = addProp(curProp,p1); setVObjectStringZValue(a,p2); } 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); } #define MAX_LEX_LOOKAHEAD_0 32 @@ -638,12 +651,26 @@ static char* lexGetWord() { c = lexLookahead(); } lexAppendc(0); 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 */ if (c == EOF) return; putptr = (int)lexBuf.getPtr - 1; if (putptr < 0) putptr += MAX_LEX_LOOKAHEAD; @@ -1007,26 +1034,26 @@ static char* lexGetQuotedPrintable() static int yylex() { int lexmode = LEXMODE(); if (lexmode == L_VALUES) { int c = lexGetc(); + int c2;
if (c == ';' && fieldedProp) { DBG_(("db: SEMICOLON\n")); lexPushLookaheadc(c); handleMoreRFC822LineBreak(c); 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")); return LINESEP; } else { @@ -1051,14 +1078,16 @@ static int yylex() { DBG_(("db: STRING: '%s'\n", p)); yylval.str = p; return STRING; } else return 0; } - } - else { + } else if (lexmode == L_PARAMWORD) {
+ yylval.str = lexGetParamWord();
+ return ID;
+ } else {
/* normal mode */ while (1) { int c = lexGetc(); switch(c) { case ':': { /* consume all line separator(s) adjacent to each other */ |