mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2026-10-24 00:49:00 +03:00
The array data can be `NULL` if its length is zero.
This fixes the following CI failure:
```
322/425 glib:gio / socket-address ERROR 0.08s killed by signal 6 SIGABRT
――――――――――――――――――――――――――――――――――――― ✀ ―――――――――――――――――――――――――――――――――――――
stderr:
../gio/tests/socket-address.c:201:19: runtime error: null pointer passed as argument 2, which is declared to never be null
/usr/include/string.h:160:33: note: nonnull attribute specified here
#0 0x000000431715 (/builds/GNOME/glib/_build/gio/tests/socket-address+0x431715) (BuildId: 7c5e418267aa2008af8e77f4d04c31913e26aad7)
#1 0x7fdabec8c862 (/builds/GNOME/glib/_build/glib/libglib-2.0.so.0+0x28c862) (BuildId: 12f0fded04a8c0437c073a267547f1cb487b1b1d)
#2 0x7fdabec7e1b2 (/builds/GNOME/glib/_build/glib/libglib-2.0.so.0+0x27e1b2) (BuildId: 12f0fded04a8c0437c073a267547f1cb487b1b1d)
#3 0x7fdabec7e533 (/builds/GNOME/glib/_build/glib/libglib-2.0.so.0+0x27e533) (BuildId: 12f0fded04a8c0437c073a267547f1cb487b1b1d)
#4 0x7fdabec7e533 (/builds/GNOME/glib/_build/glib/libglib-2.0.so.0+0x27e533) (BuildId: 12f0fded04a8c0437c073a267547f1cb487b1b1d)
#5 0x7fdabec7e533 (/builds/GNOME/glib/_build/glib/libglib-2.0.so.0+0x27e533) (BuildId: 12f0fded04a8c0437c073a267547f1cb487b1b1d)
#6 0x7fdabec7bc89 (/builds/GNOME/glib/_build/glib/libglib-2.0.so.0+0x27bc89) (BuildId: 12f0fded04a8c0437c073a267547f1cb487b1b1d)
#7 0x7fdabec7b785 (/builds/GNOME/glib/_build/glib/libglib-2.0.so.0+0x27b785) (BuildId: 12f0fded04a8c0437c073a267547f1cb487b1b1d)
#8 0x00000042de31 (/builds/GNOME/glib/_build/gio/tests/socket-address+0x42de31) (BuildId: 7c5e418267aa2008af8e77f4d04c31913e26aad7)
#9 0x7fdabd810447 (/lib64/libc.so.6+0x3447) (BuildId: dae6ae6929d69dca842288f5300af5a33d1bdcd7)
#10 0x7fdabd81050a (/lib64/libc.so.6+0x350a) (BuildId: dae6ae6929d69dca842288f5300af5a33d1bdcd7)
#11 0x0000004015a4 (/builds/GNOME/glib/_build/gio/tests/socket-address+0x4015a4) (BuildId: 7c5e418267aa2008af8e77f4d04c31913e26aad7)
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior ../gio/tests/socket-address.c:201:19
```
https://gitlab.gnome.org/GNOME/glib/-/jobs/7120334
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
265 lines
9.8 KiB
C
265 lines
9.8 KiB
C
#include <gio/gunixsocketaddress.h>
|
|
|
|
#include <sys/socket.h>
|
|
#include <sys/un.h>
|
|
|
|
#ifndef UNIX_PATH_MAX
|
|
#define UNIX_PATH_MAX G_SIZEOF_MEMBER (struct sockaddr_un, sun_path)
|
|
#endif
|
|
|
|
static void
|
|
test_socket_address_native_cornercases (void)
|
|
{
|
|
GSocketAddress *a;
|
|
struct sockaddr_un sun;
|
|
struct sockaddr_un too_big[2];
|
|
|
|
/* no data */
|
|
g_assert_null (g_socket_address_new_from_native (NULL, 0));
|
|
|
|
/* not null-terminated unix path */
|
|
memset (&sun, 'a', sizeof (struct sockaddr_un));
|
|
sun.sun_family = AF_UNIX;
|
|
a = g_socket_address_new_from_native (&sun, sizeof (sun));
|
|
g_assert_nonnull (a);
|
|
g_assert_true (G_IS_UNIX_SOCKET_ADDRESS (a));
|
|
/* ensure this gets null-terminated by the constructor */
|
|
g_assert_cmpuint (g_unix_socket_address_get_path_len (G_UNIX_SOCKET_ADDRESS (a)), ==, sizeof (sun.sun_path));
|
|
g_object_unref (a);
|
|
|
|
/* unix path with embedded NULL */
|
|
sun.sun_path[4] = 0;
|
|
a = g_socket_address_new_from_native (&sun, sizeof (sun));
|
|
g_assert_nonnull (a);
|
|
g_assert_true (G_IS_UNIX_SOCKET_ADDRESS (a));
|
|
g_assert_cmpuint (g_unix_socket_address_get_path_len (G_UNIX_SOCKET_ADDRESS (a)), ==, sizeof (sun.sun_path));
|
|
g_object_unref (a);
|
|
|
|
/* specific test for an error check in g_socket_address_new_from_native() */
|
|
g_assert_null (g_socket_address_new_from_native (&sun, G_STRUCT_OFFSET (struct sockaddr_un, sun_path) - 1));
|
|
|
|
/* not null-terminated unix path */
|
|
memset (&too_big, 'b', sizeof (too_big));
|
|
too_big[0].sun_family = AF_UNIX;
|
|
a = g_socket_address_new_from_native (too_big, sizeof (too_big));
|
|
g_assert_nonnull (a);
|
|
g_assert_true (G_IS_UNIX_SOCKET_ADDRESS (a));
|
|
g_assert_cmpuint (g_unix_socket_address_get_path_len (G_UNIX_SOCKET_ADDRESS (a)), ==, sizeof (sun.sun_path));
|
|
g_object_unref (a);
|
|
}
|
|
|
|
static void
|
|
test_unix_socket_address_construct (void)
|
|
{
|
|
GUnixSocketAddress *a;
|
|
|
|
a = g_object_new (G_TYPE_UNIX_SOCKET_ADDRESS, NULL);
|
|
g_assert_cmpint (g_unix_socket_address_get_address_type (a), ==, G_UNIX_SOCKET_ADDRESS_PATH);
|
|
g_object_unref (a);
|
|
|
|
/* Try passing some default values for the arguments explicitly and
|
|
* make sure it makes no difference.
|
|
*/
|
|
a = g_object_new (G_TYPE_UNIX_SOCKET_ADDRESS, "address-type", G_UNIX_SOCKET_ADDRESS_PATH, NULL);
|
|
g_assert_cmpint (g_unix_socket_address_get_address_type (a), ==, G_UNIX_SOCKET_ADDRESS_PATH);
|
|
g_object_unref (a);
|
|
|
|
a = g_object_new (G_TYPE_UNIX_SOCKET_ADDRESS, "abstract", FALSE, NULL);
|
|
g_assert_cmpint (g_unix_socket_address_get_address_type (a), ==, G_UNIX_SOCKET_ADDRESS_PATH);
|
|
g_object_unref (a);
|
|
|
|
a = g_object_new (G_TYPE_UNIX_SOCKET_ADDRESS,
|
|
"abstract", FALSE,
|
|
"address-type", G_UNIX_SOCKET_ADDRESS_PATH,
|
|
NULL);
|
|
g_assert_cmpint (g_unix_socket_address_get_address_type (a), ==, G_UNIX_SOCKET_ADDRESS_PATH);
|
|
g_object_unref (a);
|
|
|
|
a = g_object_new (G_TYPE_UNIX_SOCKET_ADDRESS,
|
|
"address-type", G_UNIX_SOCKET_ADDRESS_PATH,
|
|
"abstract", FALSE,
|
|
NULL);
|
|
g_assert_cmpint (g_unix_socket_address_get_address_type (a), ==, G_UNIX_SOCKET_ADDRESS_PATH);
|
|
g_object_unref (a);
|
|
|
|
/* Try explicitly setting abstract to TRUE */
|
|
a = g_object_new (G_TYPE_UNIX_SOCKET_ADDRESS,
|
|
"abstract", TRUE,
|
|
NULL);
|
|
g_assert_cmpint (g_unix_socket_address_get_address_type (a), ==, G_UNIX_SOCKET_ADDRESS_ABSTRACT_PADDED);
|
|
g_object_unref (a);
|
|
|
|
/* Try explicitly setting a different kind of address */
|
|
a = g_object_new (G_TYPE_UNIX_SOCKET_ADDRESS,
|
|
"address-type", G_UNIX_SOCKET_ADDRESS_ANONYMOUS,
|
|
NULL);
|
|
g_assert_cmpint (g_unix_socket_address_get_address_type (a), ==, G_UNIX_SOCKET_ADDRESS_ANONYMOUS);
|
|
g_object_unref (a);
|
|
|
|
/* Now try explicitly setting a different type of address after
|
|
* setting abstract to FALSE.
|
|
*/
|
|
a = g_object_new (G_TYPE_UNIX_SOCKET_ADDRESS,
|
|
"abstract", FALSE,
|
|
"address-type", G_UNIX_SOCKET_ADDRESS_ANONYMOUS,
|
|
NULL);
|
|
g_assert_cmpint (g_unix_socket_address_get_address_type (a), ==, G_UNIX_SOCKET_ADDRESS_ANONYMOUS);
|
|
g_object_unref (a);
|
|
|
|
/* And the other way around */
|
|
a = g_object_new (G_TYPE_UNIX_SOCKET_ADDRESS,
|
|
"address-type", G_UNIX_SOCKET_ADDRESS_ANONYMOUS,
|
|
"abstract", FALSE,
|
|
NULL);
|
|
g_assert_cmpint (g_unix_socket_address_get_address_type (a), ==, G_UNIX_SOCKET_ADDRESS_ANONYMOUS);
|
|
g_object_unref (a);
|
|
}
|
|
|
|
static void
|
|
test_unix_socket_address_construct_path (void)
|
|
{
|
|
struct {
|
|
GUnixSocketAddressType address_type;
|
|
gsize max_len;
|
|
} sizes[] = {
|
|
{ G_UNIX_SOCKET_ADDRESS_ANONYMOUS, 0 },
|
|
{ G_UNIX_SOCKET_ADDRESS_PATH, UNIX_PATH_MAX },
|
|
{ G_UNIX_SOCKET_ADDRESS_ABSTRACT, UNIX_PATH_MAX - 1 },
|
|
{ G_UNIX_SOCKET_ADDRESS_ABSTRACT_PADDED, UNIX_PATH_MAX - 1 },
|
|
};
|
|
gsize lengths[] = { 0, 1, 2, 4, 8, 15, 16, 32, 64, 128, 256,
|
|
UNIX_PATH_MAX - 2, UNIX_PATH_MAX - 1, UNIX_PATH_MAX, UNIX_PATH_MAX + 1, UNIX_PATH_MAX + 2 };
|
|
GByteArray *array;
|
|
GSocketAddress *a[4];
|
|
gsize i, j, k, l, path_len[4];
|
|
const char *path[4];
|
|
|
|
array = g_byte_array_new ();
|
|
|
|
for (i = 0; i < G_N_ELEMENTS (sizes); i++)
|
|
{
|
|
for (j = 0; j < G_N_ELEMENTS (lengths); j++)
|
|
{
|
|
g_byte_array_set_size (array, lengths[j]);
|
|
|
|
for (k = 0; k < G_N_ELEMENTS (lengths); k++)
|
|
{
|
|
gsize stringlen = lengths[k];
|
|
|
|
if (stringlen > array->len)
|
|
continue;
|
|
|
|
if (stringlen > 0)
|
|
memset (array->data, 'x', stringlen);
|
|
if (stringlen < array->len)
|
|
memset (array->data + stringlen, 0, array->len - stringlen);
|
|
|
|
if (stringlen < array->len)
|
|
{
|
|
a[0] = g_object_new (G_TYPE_UNIX_SOCKET_ADDRESS,
|
|
"address-type", sizes[i].address_type,
|
|
"path", array->len > 0 ? (char *) array->data : "",
|
|
NULL);
|
|
a[1] = g_object_new (G_TYPE_UNIX_SOCKET_ADDRESS,
|
|
"path", array->len > 0 ? (char *) array->data : "",
|
|
"address-type", sizes[i].address_type,
|
|
NULL);
|
|
}
|
|
else
|
|
{
|
|
a[0] = NULL;
|
|
a[1] = NULL;
|
|
}
|
|
a[2] = g_object_new (G_TYPE_UNIX_SOCKET_ADDRESS,
|
|
"address-type", sizes[i].address_type,
|
|
"path-as-array", array,
|
|
NULL);
|
|
a[3] = g_object_new (G_TYPE_UNIX_SOCKET_ADDRESS,
|
|
"path-as-array", array,
|
|
"address-type", sizes[i].address_type,
|
|
NULL);
|
|
|
|
for (l = 0; l < G_N_ELEMENTS (a); l++)
|
|
{
|
|
if (a[l] == NULL)
|
|
continue;
|
|
|
|
path[l] = g_unix_socket_address_get_path (G_UNIX_SOCKET_ADDRESS (a[l]));
|
|
path_len[l] = g_unix_socket_address_get_path_len (G_UNIX_SOCKET_ADDRESS (a[l]));
|
|
if (l < 2)
|
|
{
|
|
/* used path */
|
|
g_assert_cmpuint (path_len[l], ==, MIN (sizes[i].max_len, stringlen));
|
|
}
|
|
else
|
|
{
|
|
/* used path-as-array */
|
|
g_assert_cmpuint (path_len[l], ==, MIN (sizes[i].max_len, array->len));
|
|
}
|
|
g_assert_cmpuint (strlen (path[l]), <=, MIN (path_len[l], stringlen));
|
|
/* because there's no g_assert_cmpstrn() */
|
|
g_assert_cmpint (strncmp (path[l], array->len > 0 ? (char *) array->data : "", path_len[l]), ==, 0);
|
|
|
|
g_object_unref (a[l]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
g_byte_array_unref (array);
|
|
}
|
|
|
|
static void
|
|
test_unix_socket_address_to_string (void)
|
|
{
|
|
GSocketAddress *addr = NULL;
|
|
gchar *str = NULL;
|
|
|
|
/* ADDRESS_PATH. */
|
|
addr = g_unix_socket_address_new_with_type ("/some/path", -1,
|
|
G_UNIX_SOCKET_ADDRESS_PATH);
|
|
str = g_socket_connectable_to_string (G_SOCKET_CONNECTABLE (addr));
|
|
g_assert_cmpstr (str, ==, "/some/path");
|
|
g_free (str);
|
|
g_object_unref (addr);
|
|
|
|
/* ADDRESS_ANONYMOUS. */
|
|
addr = g_unix_socket_address_new_with_type ("", 0,
|
|
G_UNIX_SOCKET_ADDRESS_ANONYMOUS);
|
|
str = g_socket_connectable_to_string (G_SOCKET_CONNECTABLE (addr));
|
|
g_assert_cmpstr (str, ==, "anonymous");
|
|
g_free (str);
|
|
g_object_unref (addr);
|
|
|
|
/* ADDRESS_ABSTRACT. */
|
|
addr = g_unix_socket_address_new_with_type ("abstract-path\0✋", 17,
|
|
G_UNIX_SOCKET_ADDRESS_ABSTRACT);
|
|
str = g_socket_connectable_to_string (G_SOCKET_CONNECTABLE (addr));
|
|
g_assert_cmpstr (str, ==, "abstract-path\\x00\\xe2\\x9c\\x8b");
|
|
g_free (str);
|
|
g_object_unref (addr);
|
|
|
|
/* ADDRESS_ABSTRACT_PADDED. */
|
|
addr = g_unix_socket_address_new_with_type ("abstract-path\0✋", 17,
|
|
G_UNIX_SOCKET_ADDRESS_ABSTRACT_PADDED);
|
|
str = g_socket_connectable_to_string (G_SOCKET_CONNECTABLE (addr));
|
|
g_assert_cmpstr (str, ==, "abstract-path\\x00\\xe2\\x9c\\x8b");
|
|
g_free (str);
|
|
g_object_unref (addr);
|
|
}
|
|
|
|
int
|
|
main (int argc,
|
|
char **argv)
|
|
{
|
|
g_test_init (&argc, &argv, NULL);
|
|
|
|
g_test_add_func ("/socket/address/native/cornercases", test_socket_address_native_cornercases);
|
|
|
|
g_test_add_func ("/socket/address/unix/construct", test_unix_socket_address_construct);
|
|
g_test_add_func ("/socket/address/unix/construct-path", test_unix_socket_address_construct_path);
|
|
g_test_add_func ("/socket/address/unix/to-string", test_unix_socket_address_to_string);
|
|
|
|
return g_test_run ();
|
|
}
|