From da3510575e10e0358b26e27a653c806028fd7320 Mon Sep 17 00:00:00 2001 From: Andy Holmes Date: Thu, 13 Jun 2024 11:43:00 -0700 Subject: [PATCH 1/2] gthreadedresolver: ref-sink returned records in lookup_records() The return value to `lookup_records()` methods is set as `transfer full` but the code path in `g_resolver_records_from_res_query()` doesn't sink the GVariant. Add the `g_variant_ref_sink()` call when prepending the record, so the list hold a full reference on each records. closes #3393 --- gio/gthreadedresolver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gio/gthreadedresolver.c b/gio/gthreadedresolver.c index fc487583c..19c1f2f3d 100644 --- a/gio/gthreadedresolver.c +++ b/gio/gthreadedresolver.c @@ -1079,7 +1079,7 @@ g_resolver_records_from_res_query (const gchar *rrname, } if (record != NULL) - records = g_list_prepend (records, record); + records = g_list_prepend (records, g_variant_ref_sink (record)); if (parsing_error != NULL) break; From cdcb1798085902c0342ead65d16b5733357e48c1 Mon Sep 17 00:00:00 2001 From: Andy Holmes Date: Thu, 4 Jul 2024 17:35:28 -0700 Subject: [PATCH 2/2] tests: ensure DNS records are full-reference variants For each test expected to return valid DNS records, test that the record variants are not floating references. Also add an test which checks this explicitly for a simple TXT record. --- gio/tests/resolver-parsing.c | 41 ++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/gio/tests/resolver-parsing.c b/gio/tests/resolver-parsing.c index 488446fe7..babd9204a 100644 --- a/gio/tests/resolver-parsing.c +++ b/gio/tests/resolver-parsing.c @@ -177,6 +177,7 @@ assert_query_succeeds (const gchar *rrname, answer_variant = records->data; expected_answer_variant = g_variant_new_parsed (expected_answer_variant_str); g_assert_cmpvariant (answer_variant, expected_answer_variant); + g_assert_true (!g_variant_is_floating (answer_variant)); g_variant_unref (expected_answer_variant); g_list_free_full (records, (GDestroyNotify) g_variant_unref); @@ -223,6 +224,45 @@ test_invalid_header (void) } } +static void +test_record_ownership (void) +{ + GByteArray *answer = NULL, *txt_rdata = NULL; + GList *records = NULL; + GError *local_error = NULL; + uint16_t rrtype; + + rrtype = g_resolver_record_type_to_rrtype (G_RESOLVER_RECORD_TXT); + answer = dns_header (); + + /* Resource record */ + dns_builder_add_domain (answer, "example.org"); + dns_builder_add_uint16 (answer, rrtype); + dns_builder_add_uint16 (answer, 1); /* qclass=C_IN */ + dns_builder_add_uint32 (answer, 0); /* ttl (ignored) */ + + /* TXT rdata, https://datatracker.ietf.org/doc/html/rfc1035#section-3.3.14 */ + txt_rdata = g_byte_array_new (); + dns_builder_add_length_prefixed_string (txt_rdata, "some test content"); + dns_builder_add_answer_data (answer, txt_rdata); + g_byte_array_unref (txt_rdata); + + records = g_resolver_records_from_res_query ("example.org", + rrtype, + answer->data, + answer->len, + 0, + &local_error); + g_assert_no_error (local_error); + g_assert_nonnull (records); + + for (const GList *iter = records; iter != NULL; iter = iter->next) + g_assert_true (!g_variant_is_floating (records->data)); + + g_list_free_full (records, (GDestroyNotify) g_variant_unref); + g_byte_array_free (answer, TRUE); +} + static void test_unknown_record_type (void) { @@ -858,6 +898,7 @@ main (int argc, g_test_init (&argc, &argv, G_TEST_OPTION_ISOLATE_DIRS, NULL); g_test_add_func ("/gresolver/invalid-header", test_invalid_header); + g_test_add_func ("/gresolver/record-ownership", test_record_ownership); g_test_add_func ("/gresolver/unknown-record-type", test_unknown_record_type); g_test_add_func ("/gresolver/mx/valid", test_mx_valid); g_test_add_func ("/gresolver/mx/invalid", test_mx_invalid);