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;