Merge branch 'upstream' into tizen
[platform/upstream/glib.git] / glib / tests / bytes.c
index 7e31ff0..561cc23 100644 (file)
@@ -10,7 +10,6 @@
  */
 
 #undef G_DISABLE_ASSERT
-#undef G_LOG_DOMAIN
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -44,8 +43,8 @@ test_new (void)
 
   data = "test";
   bytes = g_bytes_new (data, 4);
-  g_assert (bytes != NULL);
-  g_assert (g_bytes_get_data (bytes, &size) != data);
+  g_assert_nonnull (bytes);
+  g_assert_true (g_bytes_get_data (bytes, &size) != data);
   g_assert_cmpuint (size, ==, 4);
   g_assert_cmpuint (g_bytes_get_size (bytes), ==, 4);
   g_assert_cmpmem (data, 4, g_bytes_get_data (bytes, NULL), g_bytes_get_size (bytes));
@@ -62,8 +61,8 @@ test_new_take (void)
 
   data = g_strdup ("test");
   bytes = g_bytes_new_take (data, 4);
-  g_assert (bytes != NULL);
-  g_assert (g_bytes_get_data (bytes, &size) == data);
+  g_assert_nonnull (bytes);
+  g_assert_true (g_bytes_get_data (bytes, &size) == data);
   g_assert_cmpuint (size, ==, 4);
   g_assert_cmpuint (g_bytes_get_size (bytes), ==, 4);
 
@@ -79,8 +78,8 @@ test_new_static (void)
 
   data = "test";
   bytes = g_bytes_new_static (data, 4);
-  g_assert (bytes != NULL);
-  g_assert (g_bytes_get_data (bytes, &size) == data);
+  g_assert_nonnull (bytes);
+  g_assert_true (g_bytes_get_data (bytes, &size) == data);
   g_assert_cmpuint (size, ==, 4);
   g_assert_cmpuint (g_bytes_get_size (bytes), ==, 4);
 
@@ -97,8 +96,8 @@ test_new_from_bytes (void)
   bytes = g_bytes_new (data, 14);
   sub = g_bytes_new_from_bytes (bytes, 10, 4);
 
-  g_assert (sub != NULL);
-  g_assert (g_bytes_get_data (sub, NULL) == ((gchar *)g_bytes_get_data (bytes, NULL)) + 10);
+  g_assert_nonnull (sub);
+  g_assert_true (g_bytes_get_data (sub, NULL) == ((gchar *)g_bytes_get_data (bytes, NULL)) + 10);
   g_bytes_unref (bytes);
 
   g_assert_cmpmem (g_bytes_get_data (sub, NULL), g_bytes_get_size (sub), "wave", 4);
@@ -122,9 +121,9 @@ test_new_from_bytes_slice (void)
   g_assert_cmpint (bytes3->ref_count, ==, 1);
 
   g_assert_null (bytes->user_data);
-  g_assert (bytes1->user_data == bytes);
-  g_assert (bytes2->user_data == bytes);
-  g_assert (bytes3->user_data == bytes);
+  g_assert_true (bytes1->user_data == bytes);
+  g_assert_true (bytes2->user_data == bytes);
+  g_assert_true (bytes3->user_data == bytes);
 
   g_assert_cmpint (17, ==, g_bytes_get_size (bytes));
   g_assert_cmpint (13, ==, g_bytes_get_size (bytes1));
@@ -151,7 +150,7 @@ test_new_from_bytes_shared_ref (void)
   GBytes *bytes = g_bytes_new_static ("Some data", strlen ("Some data") + 1);
   GBytes *other = g_bytes_new_from_bytes (bytes, 0, g_bytes_get_size (bytes));
 
-  g_assert (bytes == other);
+  g_assert_true (bytes == other);
   g_assert_cmpint (bytes->ref_count, ==, 2);
 
   g_bytes_unref (bytes);
@@ -162,7 +161,7 @@ static void
 on_destroy_increment (gpointer data)
 {
   gint *count = data;
-  g_assert (count != NULL);
+  g_assert_nonnull (count);
   (*count)++;
 }
 
@@ -176,9 +175,9 @@ test_new_with_free_func (void)
 
   data = "test";
   bytes = g_bytes_new_with_free_func (data, 4, on_destroy_increment, &count);
-  g_assert (bytes != NULL);
+  g_assert_nonnull (bytes);
   g_assert_cmpint (count, ==, 0);
-  g_assert (g_bytes_get_data (bytes, &size) == data);
+  g_assert_true (g_bytes_get_data (bytes, &size) == data);
   g_assert_cmpuint (size, ==, 4);
   g_assert_cmpuint (g_bytes_get_size (bytes), ==, 4);
 
@@ -199,7 +198,7 @@ test_hash (void)
 
   hash1 = g_bytes_hash (bytes1);
   hash2 = g_bytes_hash (bytes2);
-  g_assert (hash1 == hash2);
+  g_assert_cmpuint (hash1,  ==, hash2);
 
   g_bytes_unref (bytes1);
   g_bytes_unref (bytes2);
@@ -214,18 +213,18 @@ test_equal (void)
   bytes = g_bytes_new ("blah", 4);
 
   bytes2 = g_bytes_new ("blah", 4);
-  g_assert (g_bytes_equal (bytes, bytes2));
-  g_assert (g_bytes_equal (bytes2, bytes));
+  g_assert_true (g_bytes_equal (bytes, bytes2));
+  g_assert_true (g_bytes_equal (bytes2, bytes));
   g_bytes_unref (bytes2);
 
   bytes2 = g_bytes_new ("bla", 3);
-  g_assert (!g_bytes_equal (bytes, bytes2));
-  g_assert (!g_bytes_equal (bytes2, bytes));
+  g_assert_false (g_bytes_equal (bytes, bytes2));
+  g_assert_false (g_bytes_equal (bytes2, bytes));
   g_bytes_unref (bytes2);
 
   bytes2 = g_bytes_new ("true", 4);
-  g_assert (!g_bytes_equal (bytes, bytes2));
-  g_assert (!g_bytes_equal (bytes2, bytes));
+  g_assert_false (g_bytes_equal (bytes, bytes2));
+  g_assert_false (g_bytes_equal (bytes2, bytes));
   g_bytes_unref (bytes2);
 
   g_bytes_unref (bytes);
@@ -278,7 +277,7 @@ test_to_data_transferred (void)
   bytes = g_bytes_new_take (g_memdup (NYAN, N_NYAN), N_NYAN);
   memory = g_bytes_get_data (bytes, NULL);
   data = g_bytes_unref_to_data (bytes, &size);
-  g_assert (data == memory);
+  g_assert_true (data == memory);
   g_assert_cmpmem (data, size, NYAN, N_NYAN);
   g_free (data);
 }
@@ -296,10 +295,10 @@ test_to_data_two_refs (void)
   bytes = g_bytes_ref (bytes);
   memory = g_bytes_get_data (bytes, NULL);
   data = g_bytes_unref_to_data (bytes, &size);
-  g_assert (data != memory);
+  g_assert_true (data != memory);
   g_assert_cmpmem (data, size, NYAN, N_NYAN);
   g_free (data);
-  g_assert (g_bytes_get_data (bytes, &size) == memory);
+  g_assert_true (g_bytes_get_data (bytes, &size) == memory);
   g_assert_cmpuint (size, ==, N_NYAN);
   g_assert_cmpuint (g_bytes_get_size (bytes), ==, N_NYAN);
   g_bytes_unref (bytes);
@@ -314,14 +313,38 @@ test_to_data_non_malloc (void)
 
   /* Memory copied: non malloc memory */
   bytes = g_bytes_new_static (NYAN, N_NYAN);
-  g_assert (g_bytes_get_data (bytes, NULL) == NYAN);
+  g_assert_true (g_bytes_get_data (bytes, NULL) == NYAN);
   data = g_bytes_unref_to_data (bytes, &size);
-  g_assert (data != (gpointer)NYAN);
+  g_assert_true (data != (gpointer)NYAN);
   g_assert_cmpmem (data, size, NYAN, N_NYAN);
   g_free (data);
 }
 
 static void
+test_to_data_different_free_func (void)
+{
+  gpointer data;
+  gsize size;
+  GBytes *bytes;
+  gchar *sentinel = g_strdup ("hello");
+
+  /* Memory copied: free func and user_data don’t point to the bytes data */
+  bytes = g_bytes_new_with_free_func (NYAN, N_NYAN, g_free, sentinel);
+  g_assert_true (g_bytes_get_data (bytes, NULL) == NYAN);
+
+  data = g_bytes_unref_to_data (bytes, &size);
+  g_assert_true (data != (gpointer)NYAN);
+  g_assert_cmpmem (data, size, NYAN, N_NYAN);
+  g_free (data);
+
+  /* @sentinel should not be leaked; testing that requires this test to be run
+   * under valgrind. We can’t use a custom free func to check it isn’t leaked,
+   * as the point of this test is to hit a condition in `try_steal_and_unref()`
+   * which is short-circuited if the free func isn’t g_free().
+   * See discussion in https://gitlab.gnome.org/GNOME/glib/-/merge_requests/2152 */
+}
+
+static void
 test_to_array_transferred (void)
 {
   gconstpointer memory;
@@ -332,13 +355,45 @@ test_to_array_transferred (void)
   bytes = g_bytes_new_take (g_memdup (NYAN, N_NYAN), N_NYAN);
   memory = g_bytes_get_data (bytes, NULL);
   array = g_bytes_unref_to_array (bytes);
-  g_assert (array != NULL);
-  g_assert (array->data == memory);
+  g_assert_nonnull (array);
+  g_assert_true (array->data == memory);
   g_assert_cmpmem (array->data, array->len, NYAN, N_NYAN);
   g_byte_array_unref (array);
 }
 
 static void
+test_to_array_transferred_oversize (void)
+{
+  g_test_message ("g_bytes_unref_to_array() can only take GBytes up to "
+                  "G_MAXUINT in length; test that longer ones are rejected");
+
+  if (sizeof (guint) >= sizeof (gsize))
+    {
+      g_test_skip ("Skipping test as guint is not smaller than gsize");
+    }
+  else if (g_test_undefined ())
+    {
+      GByteArray *array = NULL;
+      GBytes *bytes = NULL;
+      gpointer data = g_memdup2 (NYAN, N_NYAN);
+      gsize len = ((gsize) G_MAXUINT) + 1;
+
+      bytes = g_bytes_new_take (data, len);
+      g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
+                             "g_byte_array_new_take: assertion 'len <= G_MAXUINT' failed");
+      array = g_bytes_unref_to_array (g_steal_pointer (&bytes));
+      g_test_assert_expected_messages ();
+      g_assert_null (array);
+
+      g_free (data);
+    }
+  else
+    {
+      g_test_skip ("Skipping test as testing undefined behaviour is disabled");
+    }
+}
+
+static void
 test_to_array_two_refs (void)
 {
   gconstpointer memory;
@@ -351,11 +406,11 @@ test_to_array_two_refs (void)
   bytes = g_bytes_ref (bytes);
   memory = g_bytes_get_data (bytes, NULL);
   array = g_bytes_unref_to_array (bytes);
-  g_assert (array != NULL);
-  g_assert (array->data != memory);
+  g_assert_nonnull (array);
+  g_assert_true (array->data != memory);
   g_assert_cmpmem (array->data, array->len, NYAN, N_NYAN);
   g_byte_array_unref (array);
-  g_assert (g_bytes_get_data (bytes, &size) == memory);
+  g_assert_true (g_bytes_get_data (bytes, &size) == memory);
   g_assert_cmpuint (size, ==, N_NYAN);
   g_assert_cmpuint (g_bytes_get_size (bytes), ==, N_NYAN);
   g_bytes_unref (bytes);
@@ -369,10 +424,10 @@ test_to_array_non_malloc (void)
 
   /* Memory copied: non malloc memory */
   bytes = g_bytes_new_static (NYAN, N_NYAN);
-  g_assert (g_bytes_get_data (bytes, NULL) == NYAN);
+  g_assert_true (g_bytes_get_data (bytes, NULL) == NYAN);
   array = g_bytes_unref_to_array (bytes);
-  g_assert (array != NULL);
-  g_assert (array->data != (gpointer)NYAN);
+  g_assert_nonnull (array);
+  g_assert_true (array->data != (gpointer)NYAN);
   g_assert_cmpmem (array->data, array->len, NYAN, N_NYAN);
   g_byte_array_unref (array);
 }
@@ -388,8 +443,47 @@ test_null (void)
 
   data = g_bytes_unref_to_data (bytes, &size);
 
-  g_assert (data == NULL);
-  g_assert (size == 0);
+  g_assert_null (data);
+  g_assert_cmpuint (size, ==, 0);
+}
+
+static void
+test_get_region (void)
+{
+  GBytes *bytes;
+
+  bytes = g_bytes_new_static (NYAN, N_NYAN);
+
+  /* simple valid gets at the start */
+  g_assert_true (g_bytes_get_region (bytes, 1, 0, 1) == NYAN);
+  g_assert_true (g_bytes_get_region (bytes, 1, 0, N_NYAN) == NYAN);
+
+  /* an invalid get because the range is too wide */
+  g_assert_true (g_bytes_get_region (bytes, 1, 0, N_NYAN + 1) == NULL);
+
+  /* an valid get, but of a zero-byte range at the end */
+  g_assert_true (g_bytes_get_region (bytes, 1, N_NYAN, 0) == NYAN + N_NYAN);
+
+  /* not a valid get because it overlap ones byte */
+  g_assert_true (g_bytes_get_region (bytes, 1, N_NYAN, 1) == NULL);
+
+  /* let's try some multiplication overflow now */
+  g_assert_true (g_bytes_get_region (bytes, 32, 0, G_MAXSIZE / 32 + 1) == NULL);
+  g_assert_true (g_bytes_get_region (bytes, G_MAXSIZE / 32 + 1, 0, 32) == NULL);
+
+  /* and some addition overflow */
+  g_assert_true (g_bytes_get_region (bytes, 1, G_MAXSIZE, -G_MAXSIZE) == NULL);
+  g_assert_true (g_bytes_get_region (bytes, 1, G_MAXSSIZE, ((gsize) G_MAXSSIZE) + 1) == NULL);
+  g_assert_true (g_bytes_get_region (bytes, 1, G_MAXSIZE, 1) == NULL);
+
+  g_bytes_unref (bytes);
+}
+
+static void
+test_unref_null (void)
+{
+  g_test_summary ("Test that calling g_bytes_unref() on NULL is a no-op");
+  g_bytes_unref (NULL);
 }
 
 #ifdef GLIB_LINUX
@@ -437,8 +531,6 @@ main (int argc, char *argv[])
 {
   g_test_init (&argc, &argv, NULL);
 
-  g_test_bug_base ("https://bugzilla.gnome.org/");
-
   g_test_add_func ("/bytes/new", test_new);
   g_test_add_func ("/bytes/new-take", test_new_take);
   g_test_add_func ("/bytes/new-static", test_new_static);
@@ -449,16 +541,20 @@ main (int argc, char *argv[])
   g_test_add_func ("/bytes/hash", test_hash);
   g_test_add_func ("/bytes/equal", test_equal);
   g_test_add_func ("/bytes/compare", test_compare);
-  g_test_add_func ("/bytes/to-data/transfered", test_to_data_transferred);
+  g_test_add_func ("/bytes/to-data/transferred", test_to_data_transferred);
   g_test_add_func ("/bytes/to-data/two-refs", test_to_data_two_refs);
   g_test_add_func ("/bytes/to-data/non-malloc", test_to_data_non_malloc);
-  g_test_add_func ("/bytes/to-array/transfered", test_to_array_transferred);
+  g_test_add_func ("/bytes/to-data/different-free-func", test_to_data_different_free_func);
+  g_test_add_func ("/bytes/to-array/transferred", test_to_array_transferred);
+  g_test_add_func ("/bytes/to-array/transferred/oversize", test_to_array_transferred_oversize);
   g_test_add_func ("/bytes/to-array/two-refs", test_to_array_two_refs);
   g_test_add_func ("/bytes/to-array/non-malloc", test_to_array_non_malloc);
   g_test_add_func ("/bytes/null", test_null);
 #ifdef GLIB_LINUX
   g_test_add_func ("/bytes/memfd", test_memfd);
 #endif
+  g_test_add_func ("/bytes/get-region", test_get_region);
+  g_test_add_func ("/bytes/unref-null", test_unref_null);
 
   return g_test_run ();
 }