[BZ#778674] json_gvariant_deserialize() leaks a variant on data type mismatch
Submitted by Martin Pitt <<mar..@..org>>
Assigned to json-glib-maint@gnome.bugs
Link to original bug (#778674)
Description
Created attachment 345814 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
Edited by Emmanuele Bassi