commit d72dfdcf5722884a1fe79ea41343baa3673786a1
Author: Matthew Hague <matthewhague@zoho.com>
Date:   Tue Mar 29 01:32:21 2016 +0100

    fixed  segfault causes by using current_vcard when parse doesn't match anything, changed file location tracking mechanism so that reading extra large vcards doesn't cause the parsing to fail early

diff --git a/src/vc_parse.y b/src/vc_parse.y
index b628b6b..e5d89cf 100644
--- a/src/vc_parse.y
+++ b/src/vc_parse.y
@@ -98,7 +98,7 @@ group_contentline
 
 contentline
         : name params ':' value '\n'
-        | name ':' value '\n' 
+        | name ':' value '\n'
         ;
 
 name
@@ -160,15 +160,20 @@ vc_component *
 parse_vcard_file (FILE * fp)
 {
   vc_component *vc = NULL;
+  current_vcard = NULL;
 
   yyin = fp;
 
+  long pos = ftell(fp);
+  start_track_position(&pos);
+
   if (0 == yyparse ())
     {
       vc = current_vcard;
     }
-  
-  fseek(yyin, -chars_in_buffer(), SEEK_CUR);
+
+  fseek(yyin, pos, SEEK_SET);
+  stop_track_position();
   flush_buffer();
 
   return vc;
diff --git a/src/vc_scan.l b/src/vc_scan.l
index 6ea02dd..3fe6d71 100644
--- a/src/vc_scan.l
+++ b/src/vc_scan.l
@@ -24,14 +24,23 @@
 #include "vc_parse.h"
 
 /**
- * Two functions to enable only buffering one card at a time
+ * Functions to enable only buffering one card at a time
  */
 
-int chars_in_buffer()
-  {
-    return YY_CURRENT_BUFFER->yy_n_chars -
-           (yytext - YY_CURRENT_BUFFER->yy_ch_buf);
-  }
+long *track_pos = NULL;
+
+void start_track_position(long *pos) {
+    track_pos = pos;
+}
+
+void stop_track_position() {
+    track_pos = NULL;
+}
+
+static void move_pos(char *read) {
+    if (track_pos != NULL)
+        *track_pos += strlen(read);
+}
 
 void flush_buffer()
   {
@@ -62,36 +71,75 @@ NAME-CHAR       [\x21-\x2B\x2D\x2F-\x39\x3C\x3E-\x5A\x5C\x5E-\x7E]
 
 %%
 
-"BEGIN:VCARD"             { yylval = NULL; return TOK_BEGIN_VCARD; }
-"END:VCARD"               { yylval = NULL; return TOK_END_VCARD; }
-"\n"                      { yylval = NULL; return yytext[0]; }
-"."                       { yylval = NULL; return yytext[0]; }
-({ALPHA}|{DIGIT}|-)+/"."  { yylval = yytext; return TOK_GROUP; }
-{NAME-CHAR}+              { yylval = yytext; return TOK_NAME; }
-";"                       { yylval = NULL; BEGIN(SC_PARAM); return yytext[0]; }
-":"                       { yylval = NULL; BEGIN(SC_VALUE); return yytext[0]; }
+"BEGIN:VCARD"             { move_pos("BEGIN:VCARD");
+                            yylval = NULL;
+                            return TOK_BEGIN_VCARD; }
+"END:VCARD"               { move_pos("END:VCARD");
+                            yylval = NULL;
+                            return TOK_END_VCARD; }
+"\n"                      { move_pos("\n"); yylval = NULL; return yytext[0]; }
+"."                       { move_pos("."); yylval = NULL; return yytext[0]; }
+({ALPHA}|{DIGIT}|-)+/"."  { move_pos(yytext);
+                            yylval = yytext;
+                            return TOK_GROUP; }
+{NAME-CHAR}+              { move_pos(yytext);
+                            yylval = yytext;
+                            return TOK_NAME; }
+";"                       { move_pos(";");
+                            yylval = NULL;
+                            BEGIN(SC_PARAM);
+                            return yytext[0]; }
+":"                       { move_pos(":");
+                            yylval = NULL;
+                            BEGIN(SC_VALUE);
+                            return yytext[0]; }
 
 <SC_VALUE>
 {
-({VALUE-CHAR}|"\n ")*     { yylval = yytext; return TOK_VALUE; }
-"\n"                      { yylval = NULL; BEGIN(INITIAL); return yytext[0]; }
+({VALUE-CHAR}|"\n ")*     { move_pos(yytext);
+                            yylval = yytext;
+                            return TOK_VALUE; }
+"\n"                      { move_pos("\n");
+                            yylval = NULL;
+                            BEGIN(INITIAL);
+                            return yytext[0]; }
 }
 
 <SC_PARAM>
 {
-({ALPHA}|{DIGIT}|-)+      { yylval = yytext; return TOK_PARAM_NAME; }
-"="                       { yylval = NULL; BEGIN(SC_PARAM_VALUE);
+({ALPHA}|{DIGIT}|-)+      { move_pos(yytext);
+                            yylval = yytext;
+                            return TOK_PARAM_NAME; }
+"="                       { move_pos("=");
+                            yylval = NULL;
+                            BEGIN(SC_PARAM_VALUE);
+                            return yytext[0]; }
+";"                       { move_pos(";");
+                            yylval = NULL;
+                            BEGIN(SC_PARAM);
+                            return yytext[0]; }
+":"                       { move_pos(":");
+                            yylval = NULL;
+                            BEGIN(SC_VALUE);
                             return yytext[0]; }
-";"                       { yylval = NULL; BEGIN(SC_PARAM); return yytext[0]; }
-":"                       { yylval = NULL; BEGIN(SC_VALUE); return yytext[0]; }
 }
 
 <SC_PARAM_VALUE>
 {
-{SAFE-CHAR}*              { yylval = yytext; return TOK_PARAM_VALUE; }
-","                       { yylval = NULL; return yytext[0]; }
-";"                       { yylval = NULL; BEGIN(SC_PARAM); return yytext[0]; }
-":"                       { yylval = NULL; BEGIN(SC_VALUE); return yytext[0]; }
+{SAFE-CHAR}*              { move_pos(yytext);
+                            yylval = yytext;
+                            return TOK_PARAM_VALUE; }
+","                       { move_pos(",");
+                            yylval = NULL;
+                            return yytext[0]; }
+";"                       { move_pos(";");
+                            yylval = NULL;
+                            BEGIN(SC_PARAM);
+                            return yytext[0]; }
+":"                       { move_pos(":");
+                            yylval = NULL;
+                            BEGIN(SC_VALUE);
+                            return yytext[0]; }
 }
 
 %%
