GNOME Bugzilla – Bug 778674
json_gvariant_deserialize() leaks a variant on data type mismatch
Last modified: 2017-09-05 10:43:41 UTC
Created attachment 345814 [details] reproducer If json_gvariant_deserialize() gets a JsonNode whose type does not match the specified gvariant signature, it returns NULL and sets a GError (so far so good). However, for non-trivial data types that leaks a GVariant somewhere, presumably it's parsing/building it up in memory and then forgets to clean it up once it detects the type mismatch. The attached reproducer shows this. It reads the JSON data from the first command line argument, and either prints out the serialized GVariant if it matches "a{ss}", or shows the error if it doesn't. $ gcc -Wall json-gvariant-leak.c `pkg-config --cflags --libs json-glib-1.0 glib-2.0` Success case (matching data type): $ gcc -Wall json-gvariant-leak.c `pkg-config --cflags --libs json-glib-1.0 glib-2.0` && G_DEBUG=gc-friendly G_SLICE=always-malloc valgrind --leak-check=yes --show-leak-kinds=definite --errors-for-leak-kinds=definite ./a.out '{"blue": "a"}'G_DEBUG=gc-friendly G_SLICE=always-malloc valgrind --leak-check=yes --show-leak-kinds=definite --errors-for-leak-kinds=definite ./a.out '{"blue": "a"}' $ G_DEBUG=gc-friendly G_SLICE=always-malloc valgrind --leak-check=yes --show-leak-kinds=definite --errors-for-leak-kinds=definite ./a.out '{"blue": "a"}' variant from JSON: >{'blue': 'a'}< ==2754== LEAK SUMMARY: ==2754== definitely lost: 0 bytes in 0 blocks Failure case (non-matching data type): $ gcc -Wall json-gvariant-leak.c `pkg-config --cflags --libs json-glib-1.0 glib-2.0` && G_DEBUG=gc-friendly G_SLICE=always-malloc valgrind --leak-check=yes --show-leak-kinds=definite --errors-for-leak-kinds=definite ./a.out '{"blue": 1}' ** (process:2761): WARNING **: JSON does not match expected signature: Unexpected type 'gint64' in JSON node ==2761== 85 (40 direct, 45 indirect) bytes in 1 blocks are definitely lost in loss record 224 of 315 ==2761== at 0x4C2DB9D: malloc (vg_replace_malloc.c:299) ==2761== by 0x56965A8: g_malloc (in /usr/lib64/libglib-2.0.so.0.5000.2) ==2761== by 0x56AEB02: g_slice_alloc (in /usr/lib64/libglib-2.0.so.0.5000.2) ==2761== by 0x56CCBEC: g_variant_new_from_bytes (in /usr/lib64/libglib-2.0.so.0.5000.2) ==2761== by 0x56C5D86: ??? (in /usr/lib64/libglib-2.0.so.0.5000.2) ==2761== by 0x4E489E7: ??? (in /usr/lib64/libjson-glib-1.0.so.0.200.2) ==2761== by 0x4E48DDC: ??? (in /usr/lib64/libjson-glib-1.0.so.0.200.2) ==2761== by 0x4E4A0B0: json_gvariant_deserialize (in /usr/lib64/libjson-glib-1.0.so.0.200.2) ==2761== by 0x400B72: main (in /home/martin/a.out) ==2761== ==2761== LEAK SUMMARY: ==2761== definitely lost: 40 bytes in 1 blocks
Sorry, copy&paste fail. The "success case" is supposed to be $ G_DEBUG=gc-friendly G_SLICE=always-malloc valgrind --leak-check=yes --show-leak-kinds=definite --errors-for-leak-kinds=definite ./a.out '{"blue": "a"}'
-- GitLab Migration Automatic Message -- This bug has been migrated to GNOME's GitLab instance and has been closed from further activity. You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.gnome.org/GNOME/json-glib/issues/21.