Branch data Line data Source code
1 : : #include <gio/gunixsocketaddress.h>
2 : :
3 : : #include <sys/socket.h>
4 : : #include <sys/un.h>
5 : :
6 : : #ifndef UNIX_PATH_MAX
7 : : #define UNIX_PATH_MAX G_SIZEOF_MEMBER (struct sockaddr_un, sun_path)
8 : : #endif
9 : :
10 : : static void
11 : 1 : test_socket_address_native_cornercases (void)
12 : : {
13 : : GSocketAddress *a;
14 : : struct sockaddr_un sun;
15 : : struct sockaddr_un too_big[2];
16 : :
17 : : /* no data */
18 : 1 : g_assert_null (g_socket_address_new_from_native (NULL, 0));
19 : :
20 : : /* not null-terminated unix path */
21 : 1 : memset (&sun, 'a', sizeof (struct sockaddr_un));
22 : 1 : sun.sun_family = AF_UNIX;
23 : 1 : a = g_socket_address_new_from_native (&sun, sizeof (sun));
24 : 1 : g_assert_nonnull (a);
25 : 1 : g_assert_true (G_IS_UNIX_SOCKET_ADDRESS (a));
26 : : /* ensure this gets null-terminated by the constructor */
27 : 1 : g_assert_cmpuint (g_unix_socket_address_get_path_len (G_UNIX_SOCKET_ADDRESS (a)), ==, sizeof (sun.sun_path));
28 : 1 : g_object_unref (a);
29 : :
30 : : /* unix path with embedded NULL */
31 : 1 : sun.sun_path[4] = 0;
32 : 1 : a = g_socket_address_new_from_native (&sun, sizeof (sun));
33 : 1 : g_assert_nonnull (a);
34 : 1 : g_assert_true (G_IS_UNIX_SOCKET_ADDRESS (a));
35 : 1 : g_assert_cmpuint (g_unix_socket_address_get_path_len (G_UNIX_SOCKET_ADDRESS (a)), ==, sizeof (sun.sun_path));
36 : 1 : g_object_unref (a);
37 : :
38 : : /* specific test for an error check in g_socket_address_new_from_native() */
39 : 1 : g_assert_null (g_socket_address_new_from_native (&sun, G_STRUCT_OFFSET (struct sockaddr_un, sun_path) - 1));
40 : :
41 : : /* not null-terminated unix path */
42 : 1 : memset (&too_big, 'b', sizeof (too_big));
43 : 1 : too_big[0].sun_family = AF_UNIX;
44 : 1 : a = g_socket_address_new_from_native (too_big, sizeof (too_big));
45 : 1 : g_assert_nonnull (a);
46 : 1 : g_assert_true (G_IS_UNIX_SOCKET_ADDRESS (a));
47 : 1 : g_assert_cmpuint (g_unix_socket_address_get_path_len (G_UNIX_SOCKET_ADDRESS (a)), ==, sizeof (sun.sun_path));
48 : 1 : g_object_unref (a);
49 : 1 : }
50 : :
51 : : static void
52 : 1 : test_unix_socket_address_construct (void)
53 : : {
54 : : GUnixSocketAddress *a;
55 : :
56 : 1 : a = g_object_new (G_TYPE_UNIX_SOCKET_ADDRESS, NULL);
57 : 1 : g_assert_cmpint (g_unix_socket_address_get_address_type (a), ==, G_UNIX_SOCKET_ADDRESS_PATH);
58 : 1 : g_object_unref (a);
59 : :
60 : : /* Try passing some default values for the arguments explicitly and
61 : : * make sure it makes no difference.
62 : : */
63 : 1 : a = g_object_new (G_TYPE_UNIX_SOCKET_ADDRESS, "address-type", G_UNIX_SOCKET_ADDRESS_PATH, NULL);
64 : 1 : g_assert_cmpint (g_unix_socket_address_get_address_type (a), ==, G_UNIX_SOCKET_ADDRESS_PATH);
65 : 1 : g_object_unref (a);
66 : :
67 : 1 : a = g_object_new (G_TYPE_UNIX_SOCKET_ADDRESS, "abstract", FALSE, NULL);
68 : 1 : g_assert_cmpint (g_unix_socket_address_get_address_type (a), ==, G_UNIX_SOCKET_ADDRESS_PATH);
69 : 1 : g_object_unref (a);
70 : :
71 : 1 : a = g_object_new (G_TYPE_UNIX_SOCKET_ADDRESS,
72 : : "abstract", FALSE,
73 : : "address-type", G_UNIX_SOCKET_ADDRESS_PATH,
74 : : NULL);
75 : 1 : g_assert_cmpint (g_unix_socket_address_get_address_type (a), ==, G_UNIX_SOCKET_ADDRESS_PATH);
76 : 1 : g_object_unref (a);
77 : :
78 : 1 : a = g_object_new (G_TYPE_UNIX_SOCKET_ADDRESS,
79 : : "address-type", G_UNIX_SOCKET_ADDRESS_PATH,
80 : : "abstract", FALSE,
81 : : NULL);
82 : 1 : g_assert_cmpint (g_unix_socket_address_get_address_type (a), ==, G_UNIX_SOCKET_ADDRESS_PATH);
83 : 1 : g_object_unref (a);
84 : :
85 : : /* Try explicitly setting abstract to TRUE */
86 : 1 : a = g_object_new (G_TYPE_UNIX_SOCKET_ADDRESS,
87 : : "abstract", TRUE,
88 : : NULL);
89 : 1 : g_assert_cmpint (g_unix_socket_address_get_address_type (a), ==, G_UNIX_SOCKET_ADDRESS_ABSTRACT_PADDED);
90 : 1 : g_object_unref (a);
91 : :
92 : : /* Try explicitly setting a different kind of address */
93 : 1 : a = g_object_new (G_TYPE_UNIX_SOCKET_ADDRESS,
94 : : "address-type", G_UNIX_SOCKET_ADDRESS_ANONYMOUS,
95 : : NULL);
96 : 1 : g_assert_cmpint (g_unix_socket_address_get_address_type (a), ==, G_UNIX_SOCKET_ADDRESS_ANONYMOUS);
97 : 1 : g_object_unref (a);
98 : :
99 : : /* Now try explicitly setting a different type of address after
100 : : * setting abstract to FALSE.
101 : : */
102 : 1 : a = g_object_new (G_TYPE_UNIX_SOCKET_ADDRESS,
103 : : "abstract", FALSE,
104 : : "address-type", G_UNIX_SOCKET_ADDRESS_ANONYMOUS,
105 : : NULL);
106 : 1 : g_assert_cmpint (g_unix_socket_address_get_address_type (a), ==, G_UNIX_SOCKET_ADDRESS_ANONYMOUS);
107 : 1 : g_object_unref (a);
108 : :
109 : : /* And the other way around */
110 : 1 : a = g_object_new (G_TYPE_UNIX_SOCKET_ADDRESS,
111 : : "address-type", G_UNIX_SOCKET_ADDRESS_ANONYMOUS,
112 : : "abstract", FALSE,
113 : : NULL);
114 : 1 : g_assert_cmpint (g_unix_socket_address_get_address_type (a), ==, G_UNIX_SOCKET_ADDRESS_ANONYMOUS);
115 : 1 : g_object_unref (a);
116 : 1 : }
117 : :
118 : : static void
119 : 1 : test_unix_socket_address_construct_path (void)
120 : : {
121 : : struct {
122 : : GUnixSocketAddressType address_type;
123 : : gsize max_len;
124 : 1 : } sizes[] = {
125 : : { G_UNIX_SOCKET_ADDRESS_ANONYMOUS, 0 },
126 : : { G_UNIX_SOCKET_ADDRESS_PATH, UNIX_PATH_MAX },
127 : : { G_UNIX_SOCKET_ADDRESS_ABSTRACT, UNIX_PATH_MAX - 1 },
128 : : { G_UNIX_SOCKET_ADDRESS_ABSTRACT_PADDED, UNIX_PATH_MAX - 1 },
129 : : };
130 : 1 : gsize lengths[] = { 0, 1, 2, 4, 8, 15, 16, 32, 64, 128, 256,
131 : : UNIX_PATH_MAX - 2, UNIX_PATH_MAX - 1, UNIX_PATH_MAX, UNIX_PATH_MAX + 1, UNIX_PATH_MAX + 2 };
132 : : GByteArray *array;
133 : : GSocketAddress *a[4];
134 : : gsize i, j, k, l, path_len[4];
135 : : const char *path[4];
136 : :
137 : 1 : array = g_byte_array_new ();
138 : :
139 : 5 : for (i = 0; i < G_N_ELEMENTS (sizes); i++)
140 : : {
141 : 68 : for (j = 0; j < G_N_ELEMENTS (lengths); j++)
142 : : {
143 : 64 : g_byte_array_set_size (array, lengths[j]);
144 : :
145 : 1088 : for (k = 0; k < G_N_ELEMENTS (lengths); k++)
146 : : {
147 : 1024 : gsize stringlen = lengths[k];
148 : :
149 : 1024 : if (stringlen > array->len)
150 : 480 : continue;
151 : :
152 : 544 : if (stringlen > 0)
153 : 480 : memset (array->data, 'x', stringlen);
154 : 544 : if (stringlen < array->len)
155 : 480 : memset (array->data + stringlen, 0, array->len - stringlen);
156 : :
157 : 544 : if (stringlen < array->len)
158 : : {
159 : 960 : a[0] = g_object_new (G_TYPE_UNIX_SOCKET_ADDRESS,
160 : 480 : "address-type", sizes[i].address_type,
161 : 480 : "path", array->len > 0 ? (char *) array->data : "",
162 : : NULL);
163 : 480 : a[1] = g_object_new (G_TYPE_UNIX_SOCKET_ADDRESS,
164 : 480 : "path", array->len > 0 ? (char *) array->data : "",
165 : 480 : "address-type", sizes[i].address_type,
166 : : NULL);
167 : : }
168 : : else
169 : : {
170 : 64 : a[0] = NULL;
171 : 64 : a[1] = NULL;
172 : : }
173 : 544 : a[2] = g_object_new (G_TYPE_UNIX_SOCKET_ADDRESS,
174 : 544 : "address-type", sizes[i].address_type,
175 : : "path-as-array", array,
176 : : NULL);
177 : 544 : a[3] = g_object_new (G_TYPE_UNIX_SOCKET_ADDRESS,
178 : : "path-as-array", array,
179 : 544 : "address-type", sizes[i].address_type,
180 : : NULL);
181 : :
182 : 2720 : for (l = 0; l < G_N_ELEMENTS (a); l++)
183 : : {
184 : 2176 : if (a[l] == NULL)
185 : 128 : continue;
186 : :
187 : 2048 : path[l] = g_unix_socket_address_get_path (G_UNIX_SOCKET_ADDRESS (a[l]));
188 : 2048 : path_len[l] = g_unix_socket_address_get_path_len (G_UNIX_SOCKET_ADDRESS (a[l]));
189 : 2048 : if (l < 2)
190 : : {
191 : : /* used path */
192 : 960 : g_assert_cmpuint (path_len[l], ==, MIN (sizes[i].max_len, stringlen));
193 : : }
194 : : else
195 : : {
196 : : /* used path-as-array */
197 : 1088 : g_assert_cmpuint (path_len[l], ==, MIN (sizes[i].max_len, array->len));
198 : : }
199 : 2048 : g_assert_cmpuint (strlen (path[l]), <=, MIN (path_len[l], stringlen));
200 : : /* because there's no g_assert_cmpstrn() */
201 : 2048 : g_assert_cmpint (strncmp (path[l], array->len > 0 ? (char *) array->data : "", path_len[l]), ==, 0);
202 : :
203 : 2048 : g_object_unref (a[l]);
204 : : }
205 : : }
206 : : }
207 : : }
208 : :
209 : 1 : g_byte_array_unref (array);
210 : 1 : }
211 : :
212 : : static void
213 : 1 : test_unix_socket_address_to_string (void)
214 : : {
215 : 1 : GSocketAddress *addr = NULL;
216 : 1 : gchar *str = NULL;
217 : :
218 : : /* ADDRESS_PATH. */
219 : 1 : addr = g_unix_socket_address_new_with_type ("/some/path", -1,
220 : : G_UNIX_SOCKET_ADDRESS_PATH);
221 : 1 : str = g_socket_connectable_to_string (G_SOCKET_CONNECTABLE (addr));
222 : 1 : g_assert_cmpstr (str, ==, "/some/path");
223 : 1 : g_free (str);
224 : 1 : g_object_unref (addr);
225 : :
226 : : /* ADDRESS_ANONYMOUS. */
227 : 1 : addr = g_unix_socket_address_new_with_type ("", 0,
228 : : G_UNIX_SOCKET_ADDRESS_ANONYMOUS);
229 : 1 : str = g_socket_connectable_to_string (G_SOCKET_CONNECTABLE (addr));
230 : 1 : g_assert_cmpstr (str, ==, "anonymous");
231 : 1 : g_free (str);
232 : 1 : g_object_unref (addr);
233 : :
234 : : /* ADDRESS_ABSTRACT. */
235 : 1 : addr = g_unix_socket_address_new_with_type ("abstract-path\0✋", 17,
236 : : G_UNIX_SOCKET_ADDRESS_ABSTRACT);
237 : 1 : str = g_socket_connectable_to_string (G_SOCKET_CONNECTABLE (addr));
238 : 1 : g_assert_cmpstr (str, ==, "abstract-path\\x00\\xe2\\x9c\\x8b");
239 : 1 : g_free (str);
240 : 1 : g_object_unref (addr);
241 : :
242 : : /* ADDRESS_ABSTRACT_PADDED. */
243 : 1 : addr = g_unix_socket_address_new_with_type ("abstract-path\0✋", 17,
244 : : G_UNIX_SOCKET_ADDRESS_ABSTRACT_PADDED);
245 : 1 : str = g_socket_connectable_to_string (G_SOCKET_CONNECTABLE (addr));
246 : 1 : g_assert_cmpstr (str, ==, "abstract-path\\x00\\xe2\\x9c\\x8b");
247 : 1 : g_free (str);
248 : 1 : g_object_unref (addr);
249 : 1 : }
250 : :
251 : : int
252 : 1 : main (int argc,
253 : : char **argv)
254 : : {
255 : 1 : g_test_init (&argc, &argv, NULL);
256 : :
257 : 1 : g_test_add_func ("/socket/address/native/cornercases", test_socket_address_native_cornercases);
258 : :
259 : 1 : g_test_add_func ("/socket/address/unix/construct", test_unix_socket_address_construct);
260 : 1 : g_test_add_func ("/socket/address/unix/construct-path", test_unix_socket_address_construct_path);
261 : 1 : g_test_add_func ("/socket/address/unix/to-string", test_unix_socket_address_to_string);
262 : :
263 : 1 : return g_test_run ();
264 : : }
|