-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. | |||
50 | 50 | ||
51 | 51 | ||
52 | /* debugging utilities */ | 52 | /* debugging utilities */ |
53 | #define __DEBUG 1 | ||
54 | |||
53 | #if __DEBUG | 55 | #if __DEBUG |
54 | #define DBG_(x) printf x | 56 | #define DBG_(x) printf x |
55 | #else | 57 | #else |
@@ -135,6 +137,7 @@ DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable. | |||
135 | 137 | ||
136 | 138 | ||
137 | /**** Global Variables ****/ | 139 | /**** Global Variables ****/ |
140 | int q_DontDecodeBase64Photo = 0; | ||
138 | int mime_lineNum, mime_numErrors; /* yyerror() can use these */ | 141 | int mime_lineNum, mime_numErrors; /* yyerror() can use these */ |
139 | static VObject* vObjList; | 142 | static VObject* vObjList; |
140 | static VObject *curProp; | 143 | static VObject *curProp; |
@@ -158,6 +161,7 @@ int yyparse(); | |||
158 | 161 | ||
159 | enum LexMode { | 162 | enum LexMode { |
160 | L_NORMAL, | 163 | L_NORMAL, |
164 | L_PARAMWORD, | ||
161 | L_VCARD, | 165 | L_VCARD, |
162 | L_VCAL, | 166 | L_VCAL, |
163 | L_VEVENT, | 167 | L_VEVENT, |
@@ -289,10 +293,14 @@ attr: name | |||
289 | { | 293 | { |
290 | enterAttr($1,0); | 294 | enterAttr($1,0); |
291 | } | 295 | } |
292 | | name EQ name | 296 | | name EQ |
293 | { | 297 | { |
294 | enterAttr($1,$3); | 298 | lexPushMode(L_PARAMWORD); |
295 | 299 | } | |
300 | name | ||
301 | { | ||
302 | lexPopMode(0); | ||
303 | enterAttr($1,$4); | ||
296 | } | 304 | } |
297 | ; | 305 | ; |
298 | 306 | ||
@@ -451,10 +459,15 @@ static void enterAttr(const char *s1, const char *s2) | |||
451 | } | 459 | } |
452 | else | 460 | else |
453 | addProp(curProp,p1); | 461 | addProp(curProp,p1); |
454 | if (qstricmp(p1,VCBase64Prop) == 0 || (s2 && qstricmp(p2,VCBase64Prop)==0)) | 462 | /* Lookup strings so we can quickly use pointer comparison */ |
463 | static const char* base64 = lookupProp_(VCBase64Prop); | ||
464 | static const char* qp = lookupProp_(VCQuotedPrintableProp); | ||
465 | static const char* photo = lookupProp_(VCPhotoProp); | ||
466 | static const char* encoding = lookupProp_(VCEncodingProp); | ||
467 | if ((!q_DontDecodeBase64Photo || vObjectName(curProp) != photo) | ||
468 | && (p1 == base64 || p1 == encoding && p2 == base64)) | ||
455 | lexPushMode(L_BASE64); | 469 | lexPushMode(L_BASE64); |
456 | else if (qstricmp(p1,VCQuotedPrintableProp) == 0 | 470 | else if (p1 == qp || p1 == encoding && p2 == qp) |
457 | || (s2 && qstricmp(p2,VCQuotedPrintableProp)==0)) | ||
458 | lexPushMode(L_QUOTED_PRINTABLE); | 471 | lexPushMode(L_QUOTED_PRINTABLE); |
459 | deleteStr(s1); deleteStr(s2); | 472 | deleteStr(s1); deleteStr(s2); |
460 | } | 473 | } |
@@ -641,6 +654,20 @@ static char* lexGetWord() { | |||
641 | return lexStr(); | 654 | return lexStr(); |
642 | } | 655 | } |
643 | 656 | ||
657 | static char* lexGetParamWord() | ||
658 | { | ||
659 | int c; | ||
660 | lexClearToken(); | ||
661 | c = lexLookahead(); | ||
662 | while (c >= ' ' && c < 127 && !strchr("[]:=,.;",c)) { | ||
663 | lexAppendc(c); | ||
664 | lexSkipLookahead(); | ||
665 | c = lexLookahead(); | ||
666 | } | ||
667 | lexAppendc(0); | ||
668 | return lexStr(); | ||
669 | } | ||
670 | |||
644 | static void lexPushLookaheadc(int c) { | 671 | static void lexPushLookaheadc(int c) { |
645 | int putptr; | 672 | int putptr; |
646 | /* can't putback EOF, because it never leaves lookahead buffer */ | 673 | /* can't putback EOF, because it never leaves lookahead buffer */ |
@@ -1010,6 +1037,7 @@ static int yylex() { | |||
1010 | int lexmode = LEXMODE(); | 1037 | int lexmode = LEXMODE(); |
1011 | if (lexmode == L_VALUES) { | 1038 | if (lexmode == L_VALUES) { |
1012 | int c = lexGetc(); | 1039 | int c = lexGetc(); |
1040 | int c2; | ||
1013 | if (c == ';' && fieldedProp) { | 1041 | if (c == ';' && fieldedProp) { |
1014 | DBG_(("db: SEMICOLON\n")); | 1042 | DBG_(("db: SEMICOLON\n")); |
1015 | lexPushLookaheadc(c); | 1043 | lexPushLookaheadc(c); |
@@ -1017,13 +1045,12 @@ static int yylex() { | |||
1017 | lexSkipLookahead(); | 1045 | lexSkipLookahead(); |
1018 | return SEMICOLON; | 1046 | return SEMICOLON; |
1019 | } | 1047 | } |
1020 | else if (strchr("\n",c)) { | 1048 | else if (strchr("\n",c) && (c2 = lexLookahead()) != ' ' && c2 != '\t') { |
1021 | ++mime_lineNum; | 1049 | ++mime_lineNum; |
1022 | /* consume all line separator(s) adjacent to each other */ | 1050 | /* consume all line separator(s) adjacent to each other */ |
1023 | c = lexLookahead(); | 1051 | while (strchr("\n",c2)) { |
1024 | while (strchr("\n",c)) { | ||
1025 | lexSkipLookahead(); | 1052 | lexSkipLookahead(); |
1026 | c = lexLookahead(); | 1053 | c2 = lexLookahead(); |
1027 | ++mime_lineNum; | 1054 | ++mime_lineNum; |
1028 | } | 1055 | } |
1029 | DBG_(("db: LINESEP\n")); | 1056 | DBG_(("db: LINESEP\n")); |
@@ -1054,8 +1081,10 @@ static int yylex() { | |||
1054 | } | 1081 | } |
1055 | else return 0; | 1082 | else return 0; |
1056 | } | 1083 | } |
1057 | } | 1084 | } else if (lexmode == L_PARAMWORD) { |
1058 | else { | 1085 | yylval.str = lexGetParamWord(); |
1086 | return ID; | ||
1087 | } else { | ||
1059 | /* normal mode */ | 1088 | /* normal mode */ |
1060 | while (1) { | 1089 | while (1) { |
1061 | int c = lexGetc(); | 1090 | int c = lexGetc(); |