Hi Nabil,

Il giorno ven, 24/02/2006 alle 19.16 +0100, Nabil Sayegh ha scritto:
> Am Freitag, 24. Februar 2006 16:45 schrieben Sie:
> 
> In patch 013-vcard-multiline.diff you write:
> 
> --------------8<--------------------------------------
> @@ -1488,6 +1491,21 @@
>                                 {
>                                         value_end = p;
> 
> +          if (*(p+2) && myisblank(*(p+2)))
> --------------8<--------------------------------------
> 
> You don't check if p+2 is still in our memory, couldn't it be that (in rare 
> cases) this leads to a segmentation fault?

Yes, only if I parse malformed vCard, but there's a possibility.

> 
> rgds

A new patch is attached.

Regards
Sergio
--- ./lib/contact.c.Orig	2006-02-27 10:39:49.000000000 +0100
+++ ./lib/contact.c	2006-02-27 12:04:57.000000000 +0100
@@ -758,6 +758,7 @@ typedef enum _VcardState
 	VCARD_STATE_NAME,
 	VCARD_STATE_TYPE,
 	VCARD_STATE_VALUE,
+  VCARD_STATE_MULTILINE,
 } VcardState;
 
 #define myisblank(c)    ((c) == ' '  || (c) == '\t')
@@ -1455,6 +1456,7 @@ static bool rra_contact_from_vcard2(/*{{
 	Parser parser;
 	size_t max_field_count = *field_count;
 	const char* p = vcard;
+  const char* vcard_end = vcard + strlen(vcard);
 	int state = VCARD_STATE_NEWLINE;
   int count;
 	const char* name = NULL;
@@ -1463,6 +1465,7 @@ static bool rra_contact_from_vcard2(/*{{
 	const char* type_end = NULL;
 	const char* value = NULL;
 	const char* value_end = NULL;
+  char*       value_ml = NULL;
 
   struct FieldStrings *queue_field  = malloc( MAX_ENQUEUE_FIELD * sizeof( struct FieldStrings ) ); 
 	struct FieldStrings *tmp_field = malloc( 1 * sizeof( struct FieldStrings ) ); 
@@ -1504,7 +1507,7 @@ static bool rra_contact_from_vcard2(/*{{
 			case VCARD_STATE_NEWLINE:/*{{{*/
 				if (myisblank(*p))
 				{
-					synce_error("Can't handle multiline values");
+          synce_error("Failed to handle multiline values");
 					goto exit;
 				}
 
@@ -1520,6 +1523,7 @@ static bool rra_contact_from_vcard2(/*{{
 					type_end  = NULL;
 					value     = NULL;
 					value_end = NULL;
+          value_ml  = NULL;
 
 					state = VCARD_STATE_NAME;
 				}
@@ -1556,6 +1560,21 @@ static bool rra_contact_from_vcard2(/*{{
 				{
 					value_end = p;
 
+          if ((p+2) < vcard_end && myisblank(*(p+2)))
+          {
+            value_ml = malloc(strlen(vcard) - (value - vcard));
+            value_ml[0] = '\0';
+        
+            strncat(value_ml, value, value_end - value);
+        
+            p = p + 3;
+            value = p;
+        
+            state = VCARD_STATE_MULTILINE;
+        
+            break;
+          }
+
 					tmp_field->name  = strndup(name, name_end - name);
 					tmp_field->type  = type ? strndup(type, type_end - type) : strdup("");
 					tmp_field->value = strndup(value, value_end - value);
@@ -1564,10 +1583,35 @@ static bool rra_contact_from_vcard2(/*{{
           enqueue_field(queue_field, &count_field, tmp_field);
 
 					state = VCARD_STATE_NEWLINE;
+
+          if (value_ml)
+            free(value_ml);
 				}
 				p++;
 				break;/*}}}*/
 
+      case VCARD_STATE_MULTILINE:/*{{{*/
+        if (myisnewline(*p))
+        {
+          value_end = p;
+            
+          strncat(value_ml, value, value_end - value);
+            
+          if ((p+2) < vcard_end && myisblank(*(p+2)))
+          {
+            p = p + 3;
+            value = p;
+          }
+          else
+          {
+            value = value_ml;
+            state = VCARD_STATE_VALUE;
+          }
+        }
+        else
+          p++;
+        break;/*}}}*/
+
 			default:
 				synce_error("Unknown state: %i", state);
 				goto exit;

Reply via email to