glib/gobject/tests/type-flags.c
Philip Withnall 251bab3e71 gobject: Add a missing NULL check for the return from lookup_type_node_I()
This can cause a `NULL` dereference on the next line if there is no
`TypeNode` for `iface_type`, for example if `iface_type ==
G_TYPE_INVALID`.

Unlikely, but possible since this API is public.

Spotted by Coverity.

Signed-off-by: Philip Withnall <pwithnall@endlessos.org>

Coverity CID: #1501602
2022-12-21 19:16:10 +00:00

210 lines
6.6 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// SPDX-License-Identifier: LGPL-2.1-or-later
// SPDX-FileCopyrightText: 2021 Emmanuele Bassi
#include <glib-object.h>
#define TEST_TYPE_FINAL (test_final_get_type())
G_DECLARE_FINAL_TYPE (TestFinal, test_final, TEST, FINAL, GObject)
struct _TestFinal
{
GObject parent_instance;
};
struct _TestFinalClass
{
GObjectClass parent_class;
};
G_DEFINE_FINAL_TYPE (TestFinal, test_final, G_TYPE_OBJECT)
static void
test_final_class_init (TestFinalClass *klass)
{
}
static void
test_final_init (TestFinal *self)
{
}
#define TEST_TYPE_FINAL2 (test_final2_get_type())
G_DECLARE_FINAL_TYPE (TestFinal2, test_final2, TEST, FINAL2, TestFinal)
struct _TestFinal2
{
TestFinal parent_instance;
};
struct _TestFinal2Class
{
TestFinalClass parent_class;
};
G_DEFINE_TYPE (TestFinal2, test_final2, TEST_TYPE_FINAL)
static void
test_final2_class_init (TestFinal2Class *klass)
{
}
static void
test_final2_init (TestFinal2 *self)
{
}
/* test_type_flags_final: Check that trying to derive from a final class
* will result in a warning from the type system
*/
static void
test_type_flags_final (void)
{
GType final2_type;
g_assert_true (G_TYPE_IS_FINAL (TEST_TYPE_FINAL));
g_assert_true (g_type_test_flags (TEST_TYPE_FINAL, G_TYPE_FLAG_FINAL));
g_assert_true (G_TYPE_IS_CLASSED (TEST_TYPE_FINAL));
g_assert_true (g_type_test_flags (TEST_TYPE_FINAL, G_TYPE_FLAG_CLASSED));
g_assert_true (G_TYPE_IS_INSTANTIATABLE (TEST_TYPE_FINAL));
g_assert_true (g_type_test_flags (TEST_TYPE_FINAL, G_TYPE_FLAG_INSTANTIATABLE));
g_assert_true (g_type_test_flags (TEST_TYPE_FINAL,
G_TYPE_FLAG_FINAL |
G_TYPE_FLAG_CLASSED |
G_TYPE_FLAG_INSTANTIATABLE));
g_assert_false (g_type_test_flags (TEST_TYPE_FINAL,
G_TYPE_FLAG_FINAL |
G_TYPE_FLAG_CLASSED |
G_TYPE_FLAG_DEPRECATED |
G_TYPE_FLAG_INSTANTIATABLE));
/* This is the message we print out when registering the type */
g_test_expect_message ("GLib-GObject", G_LOG_LEVEL_CRITICAL,
"*cannot derive*");
/* This is the message when we fail to return from the GOnce init
* block within the test_final2_get_type() function
*/
g_test_expect_message ("GLib", G_LOG_LEVEL_CRITICAL,
"*g_once_init_leave: assertion*");
final2_type = TEST_TYPE_FINAL2;
g_assert_true (final2_type == G_TYPE_INVALID);
g_test_assert_expected_messages ();
}
#define TEST_TYPE_DEPRECATED (test_deprecated_get_type())
G_DECLARE_FINAL_TYPE (TestDeprecated, test_deprecated, TEST, DEPRECATED, GObject)
struct _TestDeprecated
{
GObject parent_instance;
};
struct _TestDeprecatedClass
{
GObjectClass parent_class;
};
G_DEFINE_TYPE_EXTENDED (TestDeprecated, test_deprecated, G_TYPE_OBJECT, G_TYPE_FLAG_FINAL | G_TYPE_FLAG_DEPRECATED, {})
static void
test_deprecated_class_init (TestDeprecatedClass *klass)
{
}
static void
test_deprecated_init (TestDeprecated *self)
{
}
static void
test_type_flags_final_instance_check (void)
{
TestFinal *final;
final = g_object_new (TEST_TYPE_FINAL, NULL);
g_assert_true (g_type_check_instance_is_a ((GTypeInstance *) final,
TEST_TYPE_FINAL));
g_assert_false (g_type_check_instance_is_a ((GTypeInstance *) final,
TEST_TYPE_DEPRECATED));
g_assert_true (g_type_check_instance_is_a ((GTypeInstance *) final,
G_TYPE_OBJECT));
g_assert_false (g_type_check_instance_is_a ((GTypeInstance *) final,
G_TYPE_INVALID));
g_clear_object (&final);
}
static void
test_type_flags_deprecated (void)
{
GType deprecated_type;
GObject *deprecated_object = NULL;
g_test_summary ("Test that trying to instantiate a deprecated type results in a warning.");
/* This is the message we print out when registering the type */
g_test_expect_message ("GLib-GObject", G_LOG_LEVEL_WARNING,
"*The type TestDeprecated is deprecated and shouldnt be used any more*");
/* The type itself should not be considered invalid. */
deprecated_type = TEST_TYPE_DEPRECATED;
g_assert_false (deprecated_type == G_TYPE_INVALID);
g_assert_true (G_TYPE_IS_DEPRECATED (deprecated_type));
g_assert_true (G_TYPE_IS_FINAL (deprecated_type));
g_assert_true (g_type_test_flags (deprecated_type, G_TYPE_FLAG_FINAL));
g_assert_true (g_type_test_flags (deprecated_type,
G_TYPE_FLAG_DEPRECATED |
G_TYPE_FLAG_CLASSED |
G_TYPE_FLAG_FINAL |
G_TYPE_FLAG_INSTANTIATABLE));
g_assert_false (g_type_test_flags (deprecated_type,
G_TYPE_FLAG_DEPRECATED |
G_TYPE_FLAG_CLASSED |
G_TYPE_FLAG_FINAL |
G_TYPE_FLAG_ABSTRACT |
G_TYPE_FLAG_INSTANTIATABLE));
/* Instantiating it should work, but emit a warning. */
deprecated_object = g_object_new (deprecated_type, NULL);
g_assert_nonnull (deprecated_object);
g_test_assert_expected_messages ();
g_object_unref (deprecated_object);
/* Instantiating it again should not emit a second warning. */
deprecated_object = g_object_new (deprecated_type, NULL);
g_assert_nonnull (deprecated_object);
g_assert_true (g_type_check_instance_is_a ((GTypeInstance *) deprecated_object,
TEST_TYPE_DEPRECATED));
g_assert_true (g_type_check_instance_is_a ((GTypeInstance *) deprecated_object,
G_TYPE_OBJECT));
g_assert_false (g_type_check_instance_is_a ((GTypeInstance *) deprecated_object,
TEST_TYPE_FINAL));
g_assert_false (g_type_check_instance_is_a ((GTypeInstance *) deprecated_object,
G_TYPE_INVALID));
g_test_assert_expected_messages ();
g_object_unref (deprecated_object);
}
int
main (int argc, char *argv[])
{
g_test_init (&argc, &argv, NULL);
g_setenv ("G_ENABLE_DIAGNOSTIC", "1", TRUE);
g_test_add_func ("/type/flags/final", test_type_flags_final);
g_test_add_func ("/type/flags/final/instance-check", test_type_flags_final_instance_check);
g_test_add_func ("/type/flags/deprecated", test_type_flags_deprecated);
return g_test_run ();
}