Skip to content

Commit

Permalink
jmap_contact.c: handle Apple X- properties inside of switch statement
Browse files Browse the repository at this point in the history
Also handle Apple ABADR (CC) property the same as grouped GEO and TZ
  • Loading branch information
ksmurchison committed Jun 20, 2023
1 parent ba6307a commit 1c60871
Showing 1 changed file with 61 additions and 72 deletions.
133 changes: 61 additions & 72 deletions imap/jmap_contact.c
Original file line number Diff line number Diff line change
Expand Up @@ -6102,8 +6102,7 @@ static void _unmapped_param(json_t *obj,
}

static void _add_vcard_params(json_t *obj, vcardproperty *prop,
const char *label, const char *cc,
unsigned param_flags)
const char *label, unsigned param_flags)
{
vcardproperty_kind prop_kind = vcardproperty_isa(prop);
vcardparameter *param;
Expand Down Expand Up @@ -6147,7 +6146,6 @@ static void _add_vcard_params(json_t *obj, vcardproperty *prop,
if (prop_kind == VCARD_ADR_PROPERTY) {
json_object_set_new(obj, "countryCode",
json_string(lcase(param_value)));
cc = NULL;
continue;
}
break;
Expand Down Expand Up @@ -6345,7 +6343,6 @@ static void _add_vcard_params(json_t *obj, vcardproperty *prop,
_unmapped_param(obj, param_kind, param_value);
}

if (cc) json_object_set_new(obj, "countryCode", json_string(cc));
if (label) json_object_set_new(obj, "label", jmap_utf8string(label));
}

Expand All @@ -6361,7 +6358,6 @@ static json_t *jmap_card_from_vcard(const char *userid,
{
json_t *obj = json_pack("{s:s s:s}", "@type", "Card", "@version", "1.0");
vcardproperty_version version = VCARD_VERSION_NONE;
hash_table countrycodes = HASH_TABLE_INITIALIZER;
hash_table labels = HASH_TABLE_INITIALIZER;
hash_table adrs = HASH_TABLE_INITIALIZER;
struct buf buf = BUF_INITIALIZER;
Expand All @@ -6371,7 +6367,6 @@ static json_t *jmap_card_from_vcard(const char *userid,
/* Get version and fetch any Apple-style labels & country codes */
construct_hash_table(&adrs, 10, 0);
construct_hash_table(&labels, 10, 0);
construct_hash_table(&countrycodes, 10, 0);
for (prop = vcardcomponent_get_first_property(vcard, VCARD_ANY_PROPERTY);
prop;
prop = vcardcomponent_get_next_property(vcard, VCARD_ANY_PROPERTY)) {
Expand All @@ -6390,26 +6385,19 @@ static json_t *jmap_card_from_vcard(const char *userid,
}
strarray_append(ids, _prop_id(prop));
}
else if (group && (prop_kind == VCARD_X_PROPERTY)) {
const char *prop_name = vcardproperty_get_property_name(prop);

if (!strcasecmp(prop_name, VCARD_APPLE_ABADR_PROPERTY)) {
const char *cc = vcardproperty_get_value_as_string(prop);
else if (group && (prop_kind == VCARD_X_PROPERTY) &&
!strcasecmp(VCARD_APPLE_LABEL_PROPERTY,
vcardproperty_get_property_name(prop))) {
const char *label = vcardproperty_get_value_as_string(prop);
size_t label_len = strlen(label);

hash_insert(group, lcase(xstrdup(cc)), &countrycodes);
/* Check and adjust for weird (localized?) labels */
if (label_len > 8 && !strncmp(label, "_$!<", 4)) {
label += 4; // skip "_$!<" prefix
label_len -= 8; // and trim ">!$_" suffix
}
else if (!strcasecmp(prop_name, VCARD_APPLE_LABEL_PROPERTY)) {
const char *label = vcardproperty_get_value_as_string(prop);
size_t label_len = strlen(label);

/* Check and adjust for weird (localized?) labels */
if (label_len > 8 && !strncmp(label, "_$!<", 4)) {
label += 4; // skip "_$!<" prefix
label_len -= 8; // and trim ">!$_" suffix
}

hash_insert(group, xstrndup(label, label_len), &labels);
}
hash_insert(group, xstrndup(label, label_len), &labels);
}
}

Expand Down Expand Up @@ -6442,28 +6430,35 @@ static json_t *jmap_card_from_vcard(const char *userid,
continue;
}

if (prop_kind == VCARD_X_PROPERTY) {
switch (prop_kind) {
/* Apple Properties */
case VCARD_X_PROPERTY: {
const char *prop_name = vcardproperty_get_property_name(prop);

if (!strcmp(prop_name, "X-ADDRESSBOOKSERVER-KIND")) {
prop_kind = VCARD_KIND_PROPERTY;
goto kind;
}
else if (!strcmp(prop_name, "X-ADDRESSBOOKSERVER-MEMBER")) {
prop_kind = VCARD_MEMBER_PROPERTY;
}
else if (prop_group &&
(!strcasecmp(prop_name, VCARD_APPLE_ABADR_PROPERTY) ||
!strcasecmp(prop_name, VCARD_APPLE_LABEL_PROPERTY))) {
/* Ignore -- handled elsewhere */
continue;
}
else {
goto unmapped;
goto member;
}
else if (prop_group) {
if (!strcasecmp(prop_name, VCARD_APPLE_ABADR_PROPERTY)) {
kind = "countryCode";
buf_setcstr(&buf, prop_value);
prop_value = buf_lcase(&buf);
goto grouped_geo;
}
else if (!strcasecmp(prop_name, VCARD_APPLE_LABEL_PROPERTY)) {
/* Ignore -- handled elsewhere */
continue;
}
}

goto unmapped;
}

switch (prop_kind) {
/* General Properties */
kind:
case VCARD_KIND_PROPERTY:
buf_setcstr(&buf, prop_value);
json_object_set_new(obj, "kind", json_string(buf_lcase(&buf)));
Expand Down Expand Up @@ -6862,21 +6857,21 @@ static json_t *jmap_card_from_vcard(const char *userid,
/* Geographical Properties */
case VCARD_GEO_PROPERTY: {
vcardgeotype geo = vcardproperty_get_geo(prop);
struct buf buf = BUF_INITIALIZER;
const char *val = NULL;
strarray_t *ids = NULL;

kind = "coordinates";

if (geo.uri) {
val = geo.uri;
prop_value = geo.uri;
}
else {
buf_printf(&buf, "geo:%s,%s", geo.coords.lat, geo.coords.lon);
val = buf_cstring(&buf);
buf_reset(&buf);
buf_printf(&buf, "geo:%s,%s",
geo.coords.lat, geo.coords.lon);
prop_value = buf_cstring(&buf);
}

GCC_FALLTHROUGH
}

case VCARD_TZ_PROPERTY:
if (!kind) {
Expand All @@ -6888,36 +6883,36 @@ static json_t *jmap_card_from_vcard(const char *userid,
goto unmapped;
}
else if (tz.tzid) {
val = tz.tzid;
prop_value = tz.tzid;
}
else if (!tz.utcoffset) {
val = "Etc/UTC";
prop_value = "Etc/UTC";
}
else {
buf_reset(&buf);
buf_printf(&buf, "Etc/GMT%+d", -tz.utcoffset / 3600);
val = buf_cstring(&buf);
prop_value = buf_cstring(&buf);
}
}

ids = hash_lookup(prop_group ? prop_group : "", &adrs);
if (ids) {
grouped_geo:
{
strarray_t *ids =
hash_lookup(prop_group ? prop_group : "", &adrs);

if (!ids) goto unmapped;

for (int i = 0; i < strarray_size(ids); i++) {
json_t *addrs =
json_object_get_vanew(obj, "addresses", "{}");
const char *prop_id = strarray_nth(ids, i);

jprop = json_object_get_vanew(addrs, prop_id, "{}");

json_object_set_new(jprop, kind, json_string(val));
json_object_set_new(jprop, kind, json_string(prop_value));
}

buf_free(&buf);
}
else {
goto unmapped;
}
break;
}

/* Organizational Properties */
case VCARD_CONTACTURI_PROPERTY:
Expand All @@ -6942,14 +6937,15 @@ static json_t *jmap_card_from_vcard(const char *userid,
kind = "logo";
goto media;

case VCARD_MEMBER_PROPERTY: {
if (strncmp(prop_value, "urn:uuid:", 9)) goto unmapped;
member:
case VCARD_MEMBER_PROPERTY:
if (!strncmp(prop_value, "urn:uuid:", 9)) {
json_t *members = json_object_get_vanew(obj, "members", "{}");

json_t *members = json_object_get_vanew(obj, "members", "{}");

json_object_set_new(members, prop_value+9, json_true());
json_object_set_new(members, prop_value+9, json_true());
}
else goto unmapped;
break;
}

case VCARD_ORG_PROPERTY: {
json_t *orgs = json_object_get_vanew(obj, "organizations", "{}");
Expand Down Expand Up @@ -7219,20 +7215,14 @@ static json_t *jmap_card_from_vcard(const char *userid,
}

if (jprop) {
const char *cc = NULL, *label = NULL;
const char *label = NULL;

if (prop_group) {
if (prop_kind == VCARD_ADR_PROPERTY) {
/* Apple country code? */
cc = hash_lookup(prop_group, &countrycodes);
}
if (param_flags & ALLOW_LABEL_PARAM) {
/* Apple label? */
label = hash_lookup(prop_group, &labels);
}
if (prop_group && (param_flags & ALLOW_LABEL_PARAM)) {
/* Apple label? */
label = hash_lookup(prop_group, &labels);
}

_add_vcard_params(jprop, prop, label, cc, param_flags);
_add_vcard_params(jprop, prop, label, param_flags);
}
}

Expand All @@ -7252,7 +7242,6 @@ static json_t *jmap_card_from_vcard(const char *userid,
done:
buf_free(&buf);
free_hash_table(&labels, &free);
free_hash_table(&countrycodes, &free);
free_hash_table(&adrs, (void (*)(void *)) &strarray_free);

return obj;
Expand Down

0 comments on commit 1c60871

Please sign in to comment.