diff options
author | Lennart Poettering <lennart@poettering.net> | 2022-09-30 14:09:54 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2022-09-30 14:17:15 +0200 |
commit | 0b8218b901a44f3e6a7d76f25038fb0526e8b1d7 (patch) | |
tree | ca2b0968b778dcc9bbdf583589bece23023d730a /src/shared/json.c | |
parent | 84738d864b6d96389ae6c5500be9a06f5a2d5927 (diff) | |
download | systemd-0b8218b901a44f3e6a7d76f25038fb0526e8b1d7.tar.gz |
json: explicitly support offsets relative to NULL when dispatching
Let's trick out UndefinedBehaviourSanitizer:
https://github.com/systemd/systemd/pull/24853#issuecomment-1263380745
Diffstat (limited to 'src/shared/json.c')
-rw-r--r-- | src/shared/json.c | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/src/shared/json.c b/src/shared/json.c index 40c6f723ee..950be9485d 100644 --- a/src/shared/json.c +++ b/src/shared/json.c @@ -4211,6 +4211,19 @@ int json_log_internal( NULL); } +static void *dispatch_userdata(const JsonDispatch *p, void *userdata) { + + /* When the the userdata pointer is passed in as NULL, then we'll just use the offset as a literal + * address, and convert it to a pointer. Note that might as well just add the offset to the NULL + * pointer, but UndefinedBehaviourSanitizer doesn't like pointer arithmetics based on NULL pointers, + * hence we code this explicitly here. */ + + if (userdata) + return (uint8_t*) userdata + p->offset; + + return SIZE_TO_PTR(p->offset); +} + int json_dispatch(JsonVariant *v, const JsonDispatch table[], JsonDispatchCallback bad, JsonDispatchFlags flags, void *userdata) { size_t m; int r, done = 0; @@ -4274,7 +4287,7 @@ int json_dispatch(JsonVariant *v, const JsonDispatch table[], JsonDispatchCallba found[p-table] = true; if (p->callback) { - r = p->callback(json_variant_string(key), value, merged_flags, (uint8_t*) userdata + p->offset); + r = p->callback(json_variant_string(key), value, merged_flags, dispatch_userdata(p, userdata)); if (r < 0) { if (merged_flags & JSON_PERMISSIVE) continue; |