summaryrefslogtreecommitdiff
path: root/library/backend/vcc.y
Unidiff
Diffstat (limited to 'library/backend/vcc.y') (more/less context) (show whitespace changes)
-rw-r--r--library/backend/vcc.y53
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.
47 * in a debugger. However, if a bug is found it should 47 * in a debugger. However, if a bug is found it should
48 * be fixed in vcc.y and this file regenerated. 48 * be fixed in vcc.y and this file regenerated.
49 */ 49 */
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
56#define DBG_(x) 58#define DBG_(x)
57#endif 59#endif
58 60
@@ -132,12 +134,13 @@ DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable.
132 #define YYSTACKSIZE 100// ~unref ? 134 #define YYSTACKSIZE 100// ~unref ?
133 #define MAXLEVEL 10/* max # of nested objects parseable */ 135 #define MAXLEVEL 10/* max # of nested objects parseable */
134 /* (includes outermost) */ 136 /* (includes outermost) */
135 137
136 138
137/**** Global Variables ****/ 139/**** Global Variables ****/
140int q_DontDecodeBase64Photo = 0;
138int mime_lineNum, mime_numErrors; /* yyerror() can use these */ 141int mime_lineNum, mime_numErrors; /* yyerror() can use these */
139static VObject* vObjList; 142static VObject* vObjList;
140static VObject *curProp; 143static VObject *curProp;
141static VObject *curObj; 144static VObject *curObj;
142static VObject* ObjStack[MAXLEVEL]; 145static VObject* ObjStack[MAXLEVEL];
143static int ObjStackTop; 146static int ObjStackTop;
@@ -155,12 +158,13 @@ extern "C" {
155#endif 158#endif
156 159
157int yyparse(); 160int yyparse();
158 161
159enum LexMode { 162enum 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,
164 L_VTODO, 168 L_VTODO,
165 L_VALUES, 169 L_VALUES,
166 L_BASE64, 170 L_BASE64,
@@ -286,16 +290,20 @@ attr_param: SEMICOLON attr
286 ; 290 ;
287 291
288attr: name 292attr: 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
299name: ID 307name: ID
300 ; 308 ;
301 309
@@ -448,16 +456,21 @@ static void enterAttr(const char *s1, const char *s2)
448 p2 = lookupProp_(s2); 456 p2 = lookupProp_(s2);
449 a = addProp(curProp,p1); 457 a = addProp(curProp,p1);
450 setVObjectStringZValue(a,p2); 458 setVObjectStringZValue(a,p2);
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 }
461 474
462 475
463#define MAX_LEX_LOOKAHEAD_0 32 476#define MAX_LEX_LOOKAHEAD_0 32
@@ -638,12 +651,26 @@ static char* lexGetWord() {
638 c = lexLookahead(); 651 c = lexLookahead();
639 } 652 }
640 lexAppendc(0); 653 lexAppendc(0);
641 return lexStr(); 654 return lexStr();
642 } 655 }
643 656
657static 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
644static void lexPushLookaheadc(int c) { 671static 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 */
647 if (c == EOF) return; 674 if (c == EOF) return;
648 putptr = (int)lexBuf.getPtr - 1; 675 putptr = (int)lexBuf.getPtr - 1;
649 if (putptr < 0) putptr += MAX_LEX_LOOKAHEAD; 676 if (putptr < 0) putptr += MAX_LEX_LOOKAHEAD;
@@ -1007,26 +1034,26 @@ static char* lexGetQuotedPrintable()
1007 1034
1008static int yylex() { 1035static int yylex() {
1009 1036
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);
1016 handleMoreRFC822LineBreak(c); 1044 handleMoreRFC822LineBreak(c);
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"));
1030 return LINESEP; 1057 return LINESEP;
1031 } 1058 }
1032 else { 1059 else {
@@ -1051,14 +1078,16 @@ static int yylex() {
1051 DBG_(("db: STRING: '%s'\n", p)); 1078 DBG_(("db: STRING: '%s'\n", p));
1052 yylval.str = p; 1079 yylval.str = p;
1053 return STRING; 1080 return STRING;
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();
1062 switch(c) { 1091 switch(c) {
1063 case ':': { 1092 case ':': {
1064 /* consume all line separator(s) adjacent to each other */ 1093 /* consume all line separator(s) adjacent to each other */