summaryrefslogtreecommitdiff
path: root/library/backend/vcc.y
Side-by-side diff
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
@@ -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();