summaryrefslogtreecommitdiff
path: root/src/shared/json.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2022-09-30 14:09:54 +0200
committerLennart Poettering <lennart@poettering.net>2022-09-30 14:17:15 +0200
commit0b8218b901a44f3e6a7d76f25038fb0526e8b1d7 (patch)
treeca2b0968b778dcc9bbdf583589bece23023d730a /src/shared/json.c
parent84738d864b6d96389ae6c5500be9a06f5a2d5927 (diff)
downloadsystemd-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.c15
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;