diff --git a/imap/http_caldav_sched.c b/imap/http_caldav_sched.c index 0b8eddfbfa..196f913462 100644 --- a/imap/http_caldav_sched.c +++ b/imap/http_caldav_sched.c @@ -622,7 +622,7 @@ static int imip_send(const char *cal_ownerid, const char *sched_userid, /* Updated event */ json_t *new_jsevent = jmapical_tojmap(sched_data->newical, NULL, NULL); - patch = jmap_patchobject_create(jsevent, new_jsevent); + patch = jmap_patchobject_create(jsevent, new_jsevent, 0/*no_remove*/); json_decref(new_jsevent); } else { diff --git a/imap/jmap_calendar.c b/imap/jmap_calendar.c index 01c4876c8d..4d7a1be659 100644 --- a/imap/jmap_calendar.c +++ b/imap/jmap_calendar.c @@ -4857,7 +4857,7 @@ static void updateevent_apply_patch_override(struct jmap_caleventid *eid, json_object_del(new_instance, "recurrenceRules"); json_object_del(new_instance, "recurrenceOverrides"); json_object_del(new_instance, "excludedRecurrenceRules"); - new_override = jmap_patchobject_create(old_event, new_instance); + new_override = jmap_patchobject_create(old_event, new_instance, 0/*no_remove*/); json_object_del(new_override, "@type"); json_object_del(new_override, "method"); json_object_del(new_override, "prodId"); @@ -4999,7 +4999,7 @@ static void updateevent_apply_patch_event(json_t *old_event, continue; } /* Diff updated override */ - json_t *new_override = jmap_patchobject_create(new_event, jval); + json_t *new_override = jmap_patchobject_create(new_event, jval, 0/*no_remove*/); if (!new_override) continue; json_object_set_new(new_overrides, recurid, new_override); } @@ -5114,7 +5114,7 @@ static void updateevent_bump_sequence(json_t *old_event, /* ... a non per-user property got updated */ int updates_shared_prop = 0; - json_t *jpatch = jmap_patchobject_create(old_event, new_event); + json_t *jpatch = jmap_patchobject_create(old_event, new_event, 0/*no_remove*/); const char *path; json_t *jval; void *tmp; diff --git a/imap/jmap_ical.c b/imap/jmap_ical.c index 23ccf9faca..c227b46243 100644 --- a/imap/jmap_ical.c +++ b/imap/jmap_ical.c @@ -2095,7 +2095,7 @@ overrides_from_ical(icalcomponent *comp, ptrarray_t *icaloverrides, } /* Create override patch */ - json_t *diff = jmap_patchobject_create(event, ex); + json_t *diff = jmap_patchobject_create(event, ex, 0/*no_remove*/); json_object_del(diff, "@type"); json_object_del(diff, "uid"); json_object_del(diff, "relatedTo"); diff --git a/imap/jmap_notif.c b/imap/jmap_notif.c index 4ab7689115..324c78dadf 100644 --- a/imap/jmap_notif.c +++ b/imap/jmap_notif.c @@ -386,7 +386,7 @@ HIDDEN int jmap_create_caldaveventnotif(struct transaction_t *txn, if (newical) { type = "updated"; json_t *tmp = jmapical_tojmap(newical, NULL, NULL); - jpatch = jmap_patchobject_create(jevent, tmp); + jpatch = jmap_patchobject_create(jevent, tmp, 0/*no_remove*/); json_decref(tmp); } else type = "destroyed"; diff --git a/imap/jmap_util.c b/imap/jmap_util.c index 8fdf1b0d9a..0d8032fdec 100644 --- a/imap/jmap_util.c +++ b/imap/jmap_util.c @@ -213,7 +213,7 @@ static void jmap_patchobject_set(json_t *diff, struct buf *path, } static void jmap_patchobject_diff(json_t *diff, struct buf *path, - json_t *src, json_t *dst) + json_t *src, json_t *dst, int no_remove) { if (!json_is_object(src) || !json_is_object(dst)) return; @@ -228,10 +228,12 @@ static void jmap_patchobject_diff(json_t *diff, struct buf *path, } } - // Remove any properties that are set in src but not in dst - json_object_foreach(src, key, val) { - if (json_object_get(dst, key) == NULL) { - jmap_patchobject_set(diff, path, key, json_null()); + if (!no_remove) { + // Remove any properties that are set in src but not in dst + json_object_foreach(src, key, val) { + if (json_object_get(dst, key) == NULL) { + jmap_patchobject_set(diff, path, key, json_null()); + } } } @@ -254,19 +256,19 @@ static void jmap_patchobject_diff(json_t *diff, struct buf *path, size_t len = buf_len(path); if (len) buf_appendcstr(path, "/"); buf_appendcstr(path, enckey); - jmap_patchobject_diff(diff, path, srcval, val); + jmap_patchobject_diff(diff, path, srcval, val, no_remove); buf_truncate(path, len); free(enckey); } } } -EXPORTED json_t *jmap_patchobject_create(json_t *src, json_t *dst) +EXPORTED json_t *jmap_patchobject_create(json_t *src, json_t *dst, int no_remove) { json_t *diff = json_object(); struct buf buf = BUF_INITIALIZER; - jmap_patchobject_diff(diff, &buf, src, dst); + jmap_patchobject_diff(diff, &buf, src, dst, no_remove); buf_free(&buf); return diff; diff --git a/imap/jmap_util.h b/imap/jmap_util.h index 1f32af1c52..901b8dba16 100644 --- a/imap/jmap_util.h +++ b/imap/jmap_util.h @@ -71,7 +71,7 @@ extern int jmap_readprop_full(json_t *root, const char *prefix, const char *name extern json_t* jmap_patchobject_apply(json_t *val, json_t *patch, json_t *invalid); /* Create a patch-object that transforms src into dst. */ -extern json_t *jmap_patchobject_create(json_t *src, json_t *dst); +extern json_t *jmap_patchobject_create(json_t *src, json_t *dst, int no_remove); /* Return non-zero src and its RFC 6901 encoding differ */ extern int jmap_pointer_needsencode(const char *src);