diff options
Diffstat (limited to 'meta/recipes-core')
-rw-r--r-- | meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219.patch | 1444 | ||||
-rw-r--r-- | meta/recipes-core/glib-2.0/glib-2.0_2.64.5.bb | 1 |
2 files changed, 1445 insertions, 0 deletions
diff --git a/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219.patch b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219.patch new file mode 100644 index 0000000000..a4ec01134a --- /dev/null +++ b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219.patch | |||
@@ -0,0 +1,1444 @@ | |||
1 | commit b70039028b4a39ea071f6ed368a58ad5b5b90ba3 | ||
2 | Author: Anatol Belski <anbelski@microsoft.com> | ||
3 | Date: Sun Mar 14 17:51:53 2021 +0000 | ||
4 | |||
5 | backport: 2.64.5_CVE-2021-27219 | ||
6 | |||
7 | CVE: CVE-2021-27219 | ||
8 | Upstream-Status: Backport | ||
9 | [https://gitlab.gnome.org/GNOME/glib/-/merge_requests/1926] | ||
10 | |||
11 | Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com> | ||
12 | |||
13 | diff --git a/docs/reference/glib/meson.build b/docs/reference/glib/meson.build | ||
14 | index 62d95f78d..7eebb04ac 100644 | ||
15 | --- a/docs/reference/glib/meson.build | ||
16 | +++ b/docs/reference/glib/meson.build | ||
17 | @@ -22,6 +22,7 @@ if get_option('gtk_doc') | ||
18 | 'gprintfint.h', | ||
19 | 'gmirroringtable.h', | ||
20 | 'gscripttable.h', | ||
21 | + 'gstrfuncsprivate.h', | ||
22 | 'glib-mirroring-tab', | ||
23 | 'gnulib', | ||
24 | 'pcre', | ||
25 | diff --git a/gio/gdatainputstream.c b/gio/gdatainputstream.c | ||
26 | index 2e7750cb5..2cdcbda19 100644 | ||
27 | --- a/gio/gdatainputstream.c | ||
28 | +++ b/gio/gdatainputstream.c | ||
29 | @@ -27,6 +27,7 @@ | ||
30 | #include "gioenumtypes.h" | ||
31 | #include "gioerror.h" | ||
32 | #include "glibintl.h" | ||
33 | +#include "gstrfuncsprivate.h" | ||
34 | |||
35 | #include <string.h> | ||
36 | |||
37 | @@ -856,7 +857,7 @@ static gssize | ||
38 | scan_for_chars (GDataInputStream *stream, | ||
39 | gsize *checked_out, | ||
40 | const char *stop_chars, | ||
41 | - gssize stop_chars_len) | ||
42 | + gsize stop_chars_len) | ||
43 | { | ||
44 | GBufferedInputStream *bstream; | ||
45 | const char *buffer; | ||
46 | @@ -952,7 +953,7 @@ typedef struct | ||
47 | gsize checked; | ||
48 | |||
49 | gchar *stop_chars; | ||
50 | - gssize stop_chars_len; | ||
51 | + gsize stop_chars_len; | ||
52 | gsize length; | ||
53 | } GDataInputStreamReadData; | ||
54 | |||
55 | @@ -1078,12 +1079,17 @@ g_data_input_stream_read_async (GDataInputStream *stream, | ||
56 | { | ||
57 | GDataInputStreamReadData *data; | ||
58 | GTask *task; | ||
59 | + gsize stop_chars_len_unsigned; | ||
60 | |||
61 | data = g_slice_new0 (GDataInputStreamReadData); | ||
62 | - if (stop_chars_len == -1) | ||
63 | - stop_chars_len = strlen (stop_chars); | ||
64 | - data->stop_chars = g_memdup (stop_chars, stop_chars_len); | ||
65 | - data->stop_chars_len = stop_chars_len; | ||
66 | + | ||
67 | + if (stop_chars_len < 0) | ||
68 | + stop_chars_len_unsigned = strlen (stop_chars); | ||
69 | + else | ||
70 | + stop_chars_len_unsigned = (gsize) stop_chars_len; | ||
71 | + | ||
72 | + data->stop_chars = g_memdup2 (stop_chars, stop_chars_len_unsigned); | ||
73 | + data->stop_chars_len = stop_chars_len_unsigned; | ||
74 | data->last_saw_cr = FALSE; | ||
75 | |||
76 | task = g_task_new (stream, cancellable, callback, user_data); | ||
77 | @@ -1338,17 +1344,20 @@ g_data_input_stream_read_upto (GDataInputStream *stream, | ||
78 | gssize found_pos; | ||
79 | gssize res; | ||
80 | char *data_until; | ||
81 | + gsize stop_chars_len_unsigned; | ||
82 | |||
83 | g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (stream), NULL); | ||
84 | |||
85 | if (stop_chars_len < 0) | ||
86 | - stop_chars_len = strlen (stop_chars); | ||
87 | + stop_chars_len_unsigned = strlen (stop_chars); | ||
88 | + else | ||
89 | + stop_chars_len_unsigned = (gsize) stop_chars_len; | ||
90 | |||
91 | bstream = G_BUFFERED_INPUT_STREAM (stream); | ||
92 | |||
93 | checked = 0; | ||
94 | |||
95 | - while ((found_pos = scan_for_chars (stream, &checked, stop_chars, stop_chars_len)) == -1) | ||
96 | + while ((found_pos = scan_for_chars (stream, &checked, stop_chars, stop_chars_len_unsigned)) == -1) | ||
97 | { | ||
98 | if (g_buffered_input_stream_get_available (bstream) == | ||
99 | g_buffered_input_stream_get_buffer_size (bstream)) | ||
100 | diff --git a/gio/gdbusconnection.c b/gio/gdbusconnection.c | ||
101 | index 1a4dae3bd..9de661bde 100644 | ||
102 | --- a/gio/gdbusconnection.c | ||
103 | +++ b/gio/gdbusconnection.c | ||
104 | @@ -110,6 +110,7 @@ | ||
105 | #include "gasyncinitable.h" | ||
106 | #include "giostream.h" | ||
107 | #include "gasyncresult.h" | ||
108 | +#include "gstrfuncsprivate.h" | ||
109 | #include "gtask.h" | ||
110 | #include "gmarshal-internal.h" | ||
111 | |||
112 | @@ -4007,7 +4008,7 @@ _g_dbus_interface_vtable_copy (const GDBusInterfaceVTable *vtable) | ||
113 | /* Don't waste memory by copying padding - remember to update this | ||
114 | * when changing struct _GDBusInterfaceVTable in gdbusconnection.h | ||
115 | */ | ||
116 | - return g_memdup ((gconstpointer) vtable, 3 * sizeof (gpointer)); | ||
117 | + return g_memdup2 ((gconstpointer) vtable, 3 * sizeof (gpointer)); | ||
118 | } | ||
119 | |||
120 | static void | ||
121 | @@ -4024,7 +4025,7 @@ _g_dbus_subtree_vtable_copy (const GDBusSubtreeVTable *vtable) | ||
122 | /* Don't waste memory by copying padding - remember to update this | ||
123 | * when changing struct _GDBusSubtreeVTable in gdbusconnection.h | ||
124 | */ | ||
125 | - return g_memdup ((gconstpointer) vtable, 3 * sizeof (gpointer)); | ||
126 | + return g_memdup2 ((gconstpointer) vtable, 3 * sizeof (gpointer)); | ||
127 | } | ||
128 | |||
129 | static void | ||
130 | diff --git a/gio/gdbusinterfaceskeleton.c b/gio/gdbusinterfaceskeleton.c | ||
131 | index 4a06516c1..4a4b719a5 100644 | ||
132 | --- a/gio/gdbusinterfaceskeleton.c | ||
133 | +++ b/gio/gdbusinterfaceskeleton.c | ||
134 | @@ -28,6 +28,7 @@ | ||
135 | #include "gdbusmethodinvocation.h" | ||
136 | #include "gdbusconnection.h" | ||
137 | #include "gmarshal-internal.h" | ||
138 | +#include "gstrfuncsprivate.h" | ||
139 | #include "gtask.h" | ||
140 | #include "gioerror.h" | ||
141 | |||
142 | @@ -701,7 +702,7 @@ add_connection_locked (GDBusInterfaceSkeleton *interface_, | ||
143 | * properly before building the hooked_vtable, so we create it | ||
144 | * once at the last minute. | ||
145 | */ | ||
146 | - interface_->priv->hooked_vtable = g_memdup (g_dbus_interface_skeleton_get_vtable (interface_), sizeof (GDBusInterfaceVTable)); | ||
147 | + interface_->priv->hooked_vtable = g_memdup2 (g_dbus_interface_skeleton_get_vtable (interface_), sizeof (GDBusInterfaceVTable)); | ||
148 | interface_->priv->hooked_vtable->method_call = skeleton_intercept_handle_method_call; | ||
149 | } | ||
150 | |||
151 | diff --git a/gio/gfile.c b/gio/gfile.c | ||
152 | index a2ded14ea..25930435f 100644 | ||
153 | --- a/gio/gfile.c | ||
154 | +++ b/gio/gfile.c | ||
155 | @@ -60,6 +60,7 @@ | ||
156 | #include "gasyncresult.h" | ||
157 | #include "gioerror.h" | ||
158 | #include "glibintl.h" | ||
159 | +#include "gstrfuncsprivate.h" | ||
160 | |||
161 | |||
162 | /** | ||
163 | @@ -7854,7 +7855,7 @@ measure_disk_usage_progress (gboolean reporting, | ||
164 | g_main_context_invoke_full (g_task_get_context (task), | ||
165 | g_task_get_priority (task), | ||
166 | measure_disk_usage_invoke_progress, | ||
167 | - g_memdup (&progress, sizeof progress), | ||
168 | + g_memdup2 (&progress, sizeof progress), | ||
169 | g_free); | ||
170 | } | ||
171 | |||
172 | @@ -7872,7 +7873,7 @@ measure_disk_usage_thread (GTask *task, | ||
173 | data->progress_callback ? measure_disk_usage_progress : NULL, task, | ||
174 | &result.disk_usage, &result.num_dirs, &result.num_files, | ||
175 | &error)) | ||
176 | - g_task_return_pointer (task, g_memdup (&result, sizeof result), g_free); | ||
177 | + g_task_return_pointer (task, g_memdup2 (&result, sizeof result), g_free); | ||
178 | else | ||
179 | g_task_return_error (task, error); | ||
180 | } | ||
181 | @@ -7896,7 +7897,7 @@ g_file_real_measure_disk_usage_async (GFile *file, | ||
182 | |||
183 | task = g_task_new (file, cancellable, callback, user_data); | ||
184 | g_task_set_source_tag (task, g_file_real_measure_disk_usage_async); | ||
185 | - g_task_set_task_data (task, g_memdup (&data, sizeof data), g_free); | ||
186 | + g_task_set_task_data (task, g_memdup2 (&data, sizeof data), g_free); | ||
187 | g_task_set_priority (task, io_priority); | ||
188 | |||
189 | g_task_run_in_thread (task, measure_disk_usage_thread); | ||
190 | diff --git a/gio/giowin32-private.c b/gio/giowin32-private.c | ||
191 | index 7120ae0ea..47e840805 100644 | ||
192 | --- a/gio/giowin32-private.c | ||
193 | +++ b/gio/giowin32-private.c | ||
194 | @@ -16,11 +16,12 @@ | ||
195 | * along with this library; if not, see <http://www.gnu.org/licenses/>. | ||
196 | */ | ||
197 | |||
198 | +#include "gstrfuncsprivate.h" | ||
199 | |||
200 | -static gssize | ||
201 | +static gsize | ||
202 | g_utf16_len (const gunichar2 *str) | ||
203 | { | ||
204 | - gssize result; | ||
205 | + gsize result; | ||
206 | |||
207 | for (result = 0; str[0] != 0; str++, result++) | ||
208 | ; | ||
209 | @@ -31,17 +32,20 @@ g_utf16_len (const gunichar2 *str) | ||
210 | static gunichar2 * | ||
211 | g_wcsdup (const gunichar2 *str, gssize str_len) | ||
212 | { | ||
213 | - gssize str_size; | ||
214 | + gsize str_len_unsigned; | ||
215 | + gsize str_size; | ||
216 | |||
217 | g_return_val_if_fail (str != NULL, NULL); | ||
218 | |||
219 | - if (str_len == -1) | ||
220 | - str_len = g_utf16_len (str); | ||
221 | + if (str_len < 0) | ||
222 | + str_len_unsigned = g_utf16_len (str); | ||
223 | + else | ||
224 | + str_len_unsigned = (gsize) str_len; | ||
225 | |||
226 | - g_assert (str_len <= G_MAXSIZE / sizeof (gunichar2) - 1); | ||
227 | - str_size = (str_len + 1) * sizeof (gunichar2); | ||
228 | + g_assert (str_len_unsigned <= G_MAXSIZE / sizeof (gunichar2) - 1); | ||
229 | + str_size = (str_len_unsigned + 1) * sizeof (gunichar2); | ||
230 | |||
231 | - return g_memdup (str, str_size); | ||
232 | + return g_memdup2 (str, str_size); | ||
233 | } | ||
234 | |||
235 | static const gunichar2 * | ||
236 | diff --git a/gio/gkeyfilesettingsbackend.c b/gio/gkeyfilesettingsbackend.c | ||
237 | index cd5765afd..de216e615 100644 | ||
238 | --- a/gio/gkeyfilesettingsbackend.c | ||
239 | +++ b/gio/gkeyfilesettingsbackend.c | ||
240 | @@ -33,6 +33,7 @@ | ||
241 | #include "gfilemonitor.h" | ||
242 | #include "gsimplepermission.h" | ||
243 | #include "gsettingsbackendinternal.h" | ||
244 | +#include "gstrfuncsprivate.h" | ||
245 | #include "giomodule-priv.h" | ||
246 | #include "gportalsupport.h" | ||
247 | |||
248 | @@ -145,8 +146,8 @@ convert_path (GKeyfileSettingsBackend *kfsb, | ||
249 | gchar **group, | ||
250 | gchar **basename) | ||
251 | { | ||
252 | - gint key_len = strlen (key); | ||
253 | - gint i; | ||
254 | + gsize key_len = strlen (key); | ||
255 | + const gchar *last_slash; | ||
256 | |||
257 | if (key_len < kfsb->prefix_len || | ||
258 | memcmp (key, kfsb->prefix, kfsb->prefix_len) != 0) | ||
259 | @@ -155,38 +156,48 @@ convert_path (GKeyfileSettingsBackend *kfsb, | ||
260 | key_len -= kfsb->prefix_len; | ||
261 | key += kfsb->prefix_len; | ||
262 | |||
263 | - for (i = key_len; i >= 0; i--) | ||
264 | - if (key[i] == '/') | ||
265 | - break; | ||
266 | + last_slash = strrchr (key, '/'); | ||
267 | + | ||
268 | + /* Disallow empty group names or key names */ | ||
269 | + if (key_len == 0 || | ||
270 | + (last_slash != NULL && | ||
271 | + (*(last_slash + 1) == '\0' || | ||
272 | + last_slash == key))) | ||
273 | + return FALSE; | ||
274 | |||
275 | if (kfsb->root_group) | ||
276 | { | ||
277 | /* if a root_group was specified, make sure the user hasn't given | ||
278 | * a path that ghosts that group name | ||
279 | */ | ||
280 | - if (i == kfsb->root_group_len && memcmp (key, kfsb->root_group, i) == 0) | ||
281 | + if (last_slash != NULL && (last_slash - key) == kfsb->root_group_len && memcmp (key, kfsb->root_group, last_slash - key) == 0) | ||
282 | return FALSE; | ||
283 | } | ||
284 | else | ||
285 | { | ||
286 | /* if no root_group was given, ensure that the user gave a path */ | ||
287 | - if (i == -1) | ||
288 | + if (last_slash == NULL) | ||
289 | return FALSE; | ||
290 | } | ||
291 | |||
292 | if (group) | ||
293 | { | ||
294 | - if (i >= 0) | ||
295 | + if (last_slash != NULL) | ||
296 | { | ||
297 | - *group = g_memdup (key, i + 1); | ||
298 | - (*group)[i] = '\0'; | ||
299 | + *group = g_memdup2 (key, (last_slash - key) + 1); | ||
300 | + (*group)[(last_slash - key)] = '\0'; | ||
301 | } | ||
302 | else | ||
303 | *group = g_strdup (kfsb->root_group); | ||
304 | } | ||
305 | |||
306 | if (basename) | ||
307 | - *basename = g_memdup (key + i + 1, key_len - i); | ||
308 | + { | ||
309 | + if (last_slash != NULL) | ||
310 | + *basename = g_memdup2 (last_slash + 1, key_len - (last_slash - key)); | ||
311 | + else | ||
312 | + *basename = g_strdup (key); | ||
313 | + } | ||
314 | |||
315 | return TRUE; | ||
316 | } | ||
317 | diff --git a/gio/gsettingsschema.c b/gio/gsettingsschema.c | ||
318 | index 0b94f76f6..eb5a3b846 100644 | ||
319 | --- a/gio/gsettingsschema.c | ||
320 | +++ b/gio/gsettingsschema.c | ||
321 | @@ -20,6 +20,7 @@ | ||
322 | |||
323 | #include "gsettingsschema-internal.h" | ||
324 | #include "gsettings.h" | ||
325 | +#include "gstrfuncsprivate.h" | ||
326 | |||
327 | #include "gvdb/gvdb-reader.h" | ||
328 | #include "strinfo.c" | ||
329 | @@ -1067,9 +1068,9 @@ g_settings_schema_list_children (GSettingsSchema *schema) | ||
330 | |||
331 | if (g_str_has_suffix (key, "/")) | ||
332 | { | ||
333 | - gint length = strlen (key); | ||
334 | + gsize length = strlen (key); | ||
335 | |||
336 | - strv[j] = g_memdup (key, length); | ||
337 | + strv[j] = g_memdup2 (key, length); | ||
338 | strv[j][length - 1] = '\0'; | ||
339 | j++; | ||
340 | } | ||
341 | diff --git a/gio/gsocket.c b/gio/gsocket.c | ||
342 | index 2a15bdd22..554af026b 100644 | ||
343 | --- a/gio/gsocket.c | ||
344 | +++ b/gio/gsocket.c | ||
345 | @@ -75,6 +75,7 @@ | ||
346 | #include "gcredentialsprivate.h" | ||
347 | #include "glibintl.h" | ||
348 | #include "gioprivate.h" | ||
349 | +#include "gstrfuncsprivate.h" | ||
350 | |||
351 | #ifdef G_OS_WIN32 | ||
352 | /* For Windows XP runtime compatibility, but use the system's if_nametoindex() if available */ | ||
353 | @@ -174,7 +175,7 @@ static gboolean g_socket_datagram_based_condition_wait (GDatagramBased | ||
354 | GError **error); | ||
355 | |||
356 | static GSocketAddress * | ||
357 | -cache_recv_address (GSocket *socket, struct sockaddr *native, int native_len); | ||
358 | +cache_recv_address (GSocket *socket, struct sockaddr *native, size_t native_len); | ||
359 | |||
360 | static gssize | ||
361 | g_socket_receive_message_with_timeout (GSocket *socket, | ||
362 | @@ -260,7 +261,7 @@ struct _GSocketPrivate | ||
363 | struct { | ||
364 | GSocketAddress *addr; | ||
365 | struct sockaddr *native; | ||
366 | - gint native_len; | ||
367 | + gsize native_len; | ||
368 | guint64 last_used; | ||
369 | } recv_addr_cache[RECV_ADDR_CACHE_SIZE]; | ||
370 | }; | ||
371 | @@ -5259,14 +5260,14 @@ g_socket_send_messages_with_timeout (GSocket *socket, | ||
372 | } | ||
373 | |||
374 | static GSocketAddress * | ||
375 | -cache_recv_address (GSocket *socket, struct sockaddr *native, int native_len) | ||
376 | +cache_recv_address (GSocket *socket, struct sockaddr *native, size_t native_len) | ||
377 | { | ||
378 | GSocketAddress *saddr; | ||
379 | gint i; | ||
380 | guint64 oldest_time = G_MAXUINT64; | ||
381 | gint oldest_index = 0; | ||
382 | |||
383 | - if (native_len <= 0) | ||
384 | + if (native_len == 0) | ||
385 | return NULL; | ||
386 | |||
387 | saddr = NULL; | ||
388 | @@ -5274,7 +5275,7 @@ cache_recv_address (GSocket *socket, struct sockaddr *native, int native_len) | ||
389 | { | ||
390 | GSocketAddress *tmp = socket->priv->recv_addr_cache[i].addr; | ||
391 | gpointer tmp_native = socket->priv->recv_addr_cache[i].native; | ||
392 | - gint tmp_native_len = socket->priv->recv_addr_cache[i].native_len; | ||
393 | + gsize tmp_native_len = socket->priv->recv_addr_cache[i].native_len; | ||
394 | |||
395 | if (!tmp) | ||
396 | continue; | ||
397 | @@ -5304,7 +5305,7 @@ cache_recv_address (GSocket *socket, struct sockaddr *native, int native_len) | ||
398 | g_free (socket->priv->recv_addr_cache[oldest_index].native); | ||
399 | } | ||
400 | |||
401 | - socket->priv->recv_addr_cache[oldest_index].native = g_memdup (native, native_len); | ||
402 | + socket->priv->recv_addr_cache[oldest_index].native = g_memdup2 (native, native_len); | ||
403 | socket->priv->recv_addr_cache[oldest_index].native_len = native_len; | ||
404 | socket->priv->recv_addr_cache[oldest_index].addr = g_object_ref (saddr); | ||
405 | socket->priv->recv_addr_cache[oldest_index].last_used = g_get_monotonic_time (); | ||
406 | @@ -5452,6 +5453,9 @@ g_socket_receive_message_with_timeout (GSocket *socket, | ||
407 | /* do it */ | ||
408 | while (1) | ||
409 | { | ||
410 | + /* addrlen has to be of type int because that’s how WSARecvFrom() is defined */ | ||
411 | + G_STATIC_ASSERT (sizeof addr <= G_MAXINT); | ||
412 | + | ||
413 | addrlen = sizeof addr; | ||
414 | if (address) | ||
415 | result = WSARecvFrom (socket->priv->fd, | ||
416 | diff --git a/gio/gtlspassword.c b/gio/gtlspassword.c | ||
417 | index 1e437a7b6..bd86a6dfe 100644 | ||
418 | --- a/gio/gtlspassword.c | ||
419 | +++ b/gio/gtlspassword.c | ||
420 | @@ -23,6 +23,7 @@ | ||
421 | #include "glibintl.h" | ||
422 | |||
423 | #include "gioenumtypes.h" | ||
424 | +#include "gstrfuncsprivate.h" | ||
425 | #include "gtlspassword.h" | ||
426 | |||
427 | #include <string.h> | ||
428 | @@ -287,9 +288,14 @@ g_tls_password_set_value (GTlsPassword *password, | ||
429 | g_return_if_fail (G_IS_TLS_PASSWORD (password)); | ||
430 | |||
431 | if (length < 0) | ||
432 | - length = strlen ((gchar *)value); | ||
433 | + { | ||
434 | + /* FIXME: g_tls_password_set_value_full() doesn’t support unsigned gsize */ | ||
435 | + gsize length_unsigned = strlen ((gchar *) value); | ||
436 | + g_return_if_fail (length_unsigned <= G_MAXSSIZE); | ||
437 | + length = (gssize) length_unsigned; | ||
438 | + } | ||
439 | |||
440 | - g_tls_password_set_value_full (password, g_memdup (value, length), length, g_free); | ||
441 | + g_tls_password_set_value_full (password, g_memdup2 (value, (gsize) length), length, g_free); | ||
442 | } | ||
443 | |||
444 | /** | ||
445 | diff --git a/gio/gwin32registrykey.c b/gio/gwin32registrykey.c | ||
446 | index aa7819294..efb9ae713 100644 | ||
447 | --- a/gio/gwin32registrykey.c | ||
448 | +++ b/gio/gwin32registrykey.c | ||
449 | @@ -28,6 +28,8 @@ | ||
450 | #include <ntstatus.h> | ||
451 | #include <winternl.h> | ||
452 | |||
453 | +#include "gstrfuncsprivate.h" | ||
454 | + | ||
455 | #ifndef _WDMDDK_ | ||
456 | typedef enum _KEY_INFORMATION_CLASS { | ||
457 | KeyBasicInformation, | ||
458 | @@ -125,16 +127,34 @@ typedef enum | ||
459 | G_WIN32_REGISTRY_UPDATED_PATH = 1, | ||
460 | } GWin32RegistryKeyUpdateFlag; | ||
461 | |||
462 | +static gsize | ||
463 | +g_utf16_len (const gunichar2 *str) | ||
464 | +{ | ||
465 | + gsize result; | ||
466 | + | ||
467 | + for (result = 0; str[0] != 0; str++, result++) | ||
468 | + ; | ||
469 | + | ||
470 | + return result; | ||
471 | +} | ||
472 | + | ||
473 | static gunichar2 * | ||
474 | -g_wcsdup (const gunichar2 *str, | ||
475 | - gssize str_size) | ||
476 | +g_wcsdup (const gunichar2 *str, gssize str_len) | ||
477 | { | ||
478 | - if (str_size == -1) | ||
479 | - { | ||
480 | - str_size = wcslen (str) + 1; | ||
481 | - str_size *= sizeof (gunichar2); | ||
482 | - } | ||
483 | - return g_memdup (str, str_size); | ||
484 | + gsize str_len_unsigned; | ||
485 | + gsize str_size; | ||
486 | + | ||
487 | + g_return_val_if_fail (str != NULL, NULL); | ||
488 | + | ||
489 | + if (str_len < 0) | ||
490 | + str_len_unsigned = g_utf16_len (str); | ||
491 | + else | ||
492 | + str_len_unsigned = (gsize) str_len; | ||
493 | + | ||
494 | + g_assert (str_len_unsigned <= G_MAXSIZE / sizeof (gunichar2) - 1); | ||
495 | + str_size = (str_len_unsigned + 1) * sizeof (gunichar2); | ||
496 | + | ||
497 | + return g_memdup2 (str, str_size); | ||
498 | } | ||
499 | |||
500 | /** | ||
501 | @@ -247,7 +267,7 @@ g_win32_registry_value_iter_copy (const GWin32RegistryValueIter *iter) | ||
502 | new_iter->value_name_size = iter->value_name_size; | ||
503 | |||
504 | if (iter->value_data != NULL) | ||
505 | - new_iter->value_data = g_memdup (iter->value_data, iter->value_data_size); | ||
506 | + new_iter->value_data = g_memdup2 (iter->value_data, iter->value_data_size); | ||
507 | |||
508 | new_iter->value_data_size = iter->value_data_size; | ||
509 | |||
510 | @@ -268,8 +288,8 @@ g_win32_registry_value_iter_copy (const GWin32RegistryValueIter *iter) | ||
511 | new_iter->value_data_expanded_charsize = iter->value_data_expanded_charsize; | ||
512 | |||
513 | if (iter->value_data_expanded_u8 != NULL) | ||
514 | - new_iter->value_data_expanded_u8 = g_memdup (iter->value_data_expanded_u8, | ||
515 | - iter->value_data_expanded_charsize); | ||
516 | + new_iter->value_data_expanded_u8 = g_memdup2 (iter->value_data_expanded_u8, | ||
517 | + iter->value_data_expanded_charsize); | ||
518 | |||
519 | new_iter->value_data_expanded_u8_size = iter->value_data_expanded_charsize; | ||
520 | |||
521 | diff --git a/gio/tests/async-close-output-stream.c b/gio/tests/async-close-output-stream.c | ||
522 | index 5f6620275..d3f97a119 100644 | ||
523 | --- a/gio/tests/async-close-output-stream.c | ||
524 | +++ b/gio/tests/async-close-output-stream.c | ||
525 | @@ -24,6 +24,8 @@ | ||
526 | #include <stdlib.h> | ||
527 | #include <string.h> | ||
528 | |||
529 | +#include "gstrfuncsprivate.h" | ||
530 | + | ||
531 | #define DATA_TO_WRITE "Hello world\n" | ||
532 | |||
533 | typedef struct | ||
534 | @@ -147,9 +149,9 @@ prepare_data (SetupData *data, | ||
535 | |||
536 | data->expected_size = g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (data->data_stream)); | ||
537 | |||
538 | - g_assert_cmpint (data->expected_size, >, 0); | ||
539 | + g_assert_cmpuint (data->expected_size, >, 0); | ||
540 | |||
541 | - data->expected_output = g_memdup (written, (guint)data->expected_size); | ||
542 | + data->expected_output = g_memdup2 (written, data->expected_size); | ||
543 | |||
544 | /* then recreate the streams and prepare them for the asynchronous close */ | ||
545 | destroy_streams (data); | ||
546 | diff --git a/gio/tests/gdbus-export.c b/gio/tests/gdbus-export.c | ||
547 | index fda654c44..10dd6d82f 100644 | ||
548 | --- a/gio/tests/gdbus-export.c | ||
549 | +++ b/gio/tests/gdbus-export.c | ||
550 | @@ -23,6 +23,7 @@ | ||
551 | #include <string.h> | ||
552 | |||
553 | #include "gdbus-tests.h" | ||
554 | +#include "gstrfuncsprivate.h" | ||
555 | |||
556 | /* all tests rely on a shared mainloop */ | ||
557 | static GMainLoop *loop = NULL; | ||
558 | @@ -671,7 +672,7 @@ subtree_introspect (GDBusConnection *connection, | ||
559 | g_assert_not_reached (); | ||
560 | } | ||
561 | |||
562 | - return g_memdup (interfaces, 2 * sizeof (void *)); | ||
563 | + return g_memdup2 (interfaces, 2 * sizeof (void *)); | ||
564 | } | ||
565 | |||
566 | static const GDBusInterfaceVTable * | ||
567 | @@ -727,7 +728,7 @@ dynamic_subtree_introspect (GDBusConnection *connection, | ||
568 | { | ||
569 | const GDBusInterfaceInfo *interfaces[2] = { &dyna_interface_info, NULL }; | ||
570 | |||
571 | - return g_memdup (interfaces, 2 * sizeof (void *)); | ||
572 | + return g_memdup2 (interfaces, 2 * sizeof (void *)); | ||
573 | } | ||
574 | |||
575 | static const GDBusInterfaceVTable * | ||
576 | diff --git a/gio/tests/gsettings.c b/gio/tests/gsettings.c | ||
577 | index baadca8f5..afe594a23 100644 | ||
578 | --- a/gio/tests/gsettings.c | ||
579 | +++ b/gio/tests/gsettings.c | ||
580 | @@ -1,3 +1,4 @@ | ||
581 | +#include <errno.h> | ||
582 | #include <stdlib.h> | ||
583 | #include <locale.h> | ||
584 | #include <libintl.h> | ||
585 | @@ -1740,6 +1741,14 @@ key_changed_cb (GSettings *settings, const gchar *key, gpointer data) | ||
586 | (*b) = TRUE; | ||
587 | } | ||
588 | |||
589 | +typedef struct | ||
590 | +{ | ||
591 | + const gchar *path; | ||
592 | + const gchar *root_group; | ||
593 | + const gchar *keyfile_group; | ||
594 | + const gchar *root_path; | ||
595 | +} KeyfileTestData; | ||
596 | + | ||
597 | /* | ||
598 | * Test that using a keyfile works | ||
599 | */ | ||
600 | @@ -1834,7 +1843,11 @@ test_keyfile (Fixture *fixture, | ||
601 | g_free (str); | ||
602 | |||
603 | g_settings_set (settings, "farewell", "s", "cheerio"); | ||
604 | - | ||
605 | + | ||
606 | + /* Check that empty keys/groups are not allowed. */ | ||
607 | + g_assert_false (g_settings_is_writable (settings, "")); | ||
608 | + g_assert_false (g_settings_is_writable (settings, "/")); | ||
609 | + | ||
610 | /* When executing as root, changing the mode of the keyfile will have | ||
611 | * no effect on the writability of the settings. | ||
612 | */ | ||
613 | @@ -1866,6 +1879,149 @@ test_keyfile (Fixture *fixture, | ||
614 | g_free (keyfile_path); | ||
615 | } | ||
616 | |||
617 | +/* | ||
618 | + * Test that using a keyfile works with a schema with no path set. | ||
619 | + */ | ||
620 | +static void | ||
621 | +test_keyfile_no_path (Fixture *fixture, | ||
622 | + gconstpointer user_data) | ||
623 | +{ | ||
624 | + const KeyfileTestData *test_data = user_data; | ||
625 | + GSettingsBackend *kf_backend; | ||
626 | + GSettings *settings; | ||
627 | + GKeyFile *keyfile; | ||
628 | + gboolean writable; | ||
629 | + gchar *key = NULL; | ||
630 | + GError *error = NULL; | ||
631 | + gchar *keyfile_path = NULL, *store_path = NULL; | ||
632 | + | ||
633 | + keyfile_path = g_build_filename (fixture->tmp_dir, "keyfile", NULL); | ||
634 | + store_path = g_build_filename (keyfile_path, "gsettings.store", NULL); | ||
635 | + kf_backend = g_keyfile_settings_backend_new (store_path, test_data->root_path, test_data->root_group); | ||
636 | + settings = g_settings_new_with_backend_and_path ("org.gtk.test.no-path", kf_backend, test_data->path); | ||
637 | + g_object_unref (kf_backend); | ||
638 | + | ||
639 | + g_settings_reset (settings, "test-boolean"); | ||
640 | + g_assert_true (g_settings_get_boolean (settings, "test-boolean")); | ||
641 | + | ||
642 | + writable = g_settings_is_writable (settings, "test-boolean"); | ||
643 | + g_assert_true (writable); | ||
644 | + g_settings_set (settings, "test-boolean", "b", FALSE); | ||
645 | + | ||
646 | + g_assert_false (g_settings_get_boolean (settings, "test-boolean")); | ||
647 | + | ||
648 | + g_settings_delay (settings); | ||
649 | + g_settings_set (settings, "test-boolean", "b", TRUE); | ||
650 | + g_settings_apply (settings); | ||
651 | + | ||
652 | + keyfile = g_key_file_new (); | ||
653 | + g_assert_true (g_key_file_load_from_file (keyfile, store_path, 0, NULL)); | ||
654 | + | ||
655 | + g_assert_true (g_key_file_get_boolean (keyfile, test_data->keyfile_group, "test-boolean", NULL)); | ||
656 | + | ||
657 | + g_key_file_free (keyfile); | ||
658 | + | ||
659 | + g_settings_reset (settings, "test-boolean"); | ||
660 | + g_settings_apply (settings); | ||
661 | + keyfile = g_key_file_new (); | ||
662 | + g_assert_true (g_key_file_load_from_file (keyfile, store_path, 0, NULL)); | ||
663 | + | ||
664 | + g_assert_false (g_key_file_get_string (keyfile, test_data->keyfile_group, "test-boolean", &error)); | ||
665 | + g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND); | ||
666 | + g_clear_error (&error); | ||
667 | + | ||
668 | + /* Check that empty keys/groups are not allowed. */ | ||
669 | + g_assert_false (g_settings_is_writable (settings, "")); | ||
670 | + g_assert_false (g_settings_is_writable (settings, "/")); | ||
671 | + | ||
672 | + /* Keys which ghost the root group name are not allowed. This can only be | ||
673 | + * tested when the path is `/` as otherwise it acts as a prefix and prevents | ||
674 | + * any ghosting. */ | ||
675 | + if (g_str_equal (test_data->path, "/")) | ||
676 | + { | ||
677 | + key = g_strdup_printf ("%s/%s", test_data->root_group, ""); | ||
678 | + g_assert_false (g_settings_is_writable (settings, key)); | ||
679 | + g_free (key); | ||
680 | + | ||
681 | + key = g_strdup_printf ("%s/%s", test_data->root_group, "/"); | ||
682 | + g_assert_false (g_settings_is_writable (settings, key)); | ||
683 | + g_free (key); | ||
684 | + | ||
685 | + key = g_strdup_printf ("%s/%s", test_data->root_group, "test-boolean"); | ||
686 | + g_assert_false (g_settings_is_writable (settings, key)); | ||
687 | + g_free (key); | ||
688 | + } | ||
689 | + | ||
690 | + g_key_file_free (keyfile); | ||
691 | + g_object_unref (settings); | ||
692 | + | ||
693 | + /* Clean up the temporary directory. */ | ||
694 | + g_assert_cmpint (g_chmod (keyfile_path, 0777) == 0 ? 0 : errno, ==, 0); | ||
695 | + g_assert_cmpint (g_remove (store_path) == 0 ? 0 : errno, ==, 0); | ||
696 | + g_assert_cmpint (g_rmdir (keyfile_path) == 0 ? 0 : errno, ==, 0); | ||
697 | + g_free (store_path); | ||
698 | + g_free (keyfile_path); | ||
699 | +} | ||
700 | + | ||
701 | +/* | ||
702 | + * Test that a keyfile rejects writes to keys outside its root path. | ||
703 | + */ | ||
704 | +static void | ||
705 | +test_keyfile_outside_root_path (Fixture *fixture, | ||
706 | + gconstpointer user_data) | ||
707 | +{ | ||
708 | + GSettingsBackend *kf_backend; | ||
709 | + GSettings *settings; | ||
710 | + gchar *keyfile_path = NULL, *store_path = NULL; | ||
711 | + | ||
712 | + keyfile_path = g_build_filename (fixture->tmp_dir, "keyfile", NULL); | ||
713 | + store_path = g_build_filename (keyfile_path, "gsettings.store", NULL); | ||
714 | + kf_backend = g_keyfile_settings_backend_new (store_path, "/tests/basic-types/", "root"); | ||
715 | + settings = g_settings_new_with_backend_and_path ("org.gtk.test.no-path", kf_backend, "/tests/"); | ||
716 | + g_object_unref (kf_backend); | ||
717 | + | ||
718 | + g_assert_false (g_settings_is_writable (settings, "test-boolean")); | ||
719 | + | ||
720 | + g_object_unref (settings); | ||
721 | + | ||
722 | + /* Clean up the temporary directory. The keyfile probably doesn’t exist, so | ||
723 | + * don’t error on failure. */ | ||
724 | + g_remove (store_path); | ||
725 | + g_assert_cmpint (g_rmdir (keyfile_path) == 0 ? 0 : errno, ==, 0); | ||
726 | + g_free (store_path); | ||
727 | + g_free (keyfile_path); | ||
728 | +} | ||
729 | + | ||
730 | +/* | ||
731 | + * Test that a keyfile rejects writes to keys in the root if no root group is set. | ||
732 | + */ | ||
733 | +static void | ||
734 | +test_keyfile_no_root_group (Fixture *fixture, | ||
735 | + gconstpointer user_data) | ||
736 | +{ | ||
737 | + GSettingsBackend *kf_backend; | ||
738 | + GSettings *settings; | ||
739 | + gchar *keyfile_path = NULL, *store_path = NULL; | ||
740 | + | ||
741 | + keyfile_path = g_build_filename (fixture->tmp_dir, "keyfile", NULL); | ||
742 | + store_path = g_build_filename (keyfile_path, "gsettings.store", NULL); | ||
743 | + kf_backend = g_keyfile_settings_backend_new (store_path, "/", NULL); | ||
744 | + settings = g_settings_new_with_backend_and_path ("org.gtk.test.no-path", kf_backend, "/"); | ||
745 | + g_object_unref (kf_backend); | ||
746 | + | ||
747 | + g_assert_false (g_settings_is_writable (settings, "test-boolean")); | ||
748 | + g_assert_true (g_settings_is_writable (settings, "child/test-boolean")); | ||
749 | + | ||
750 | + g_object_unref (settings); | ||
751 | + | ||
752 | + /* Clean up the temporary directory. The keyfile probably doesn’t exist, so | ||
753 | + * don’t error on failure. */ | ||
754 | + g_remove (store_path); | ||
755 | + g_assert_cmpint (g_rmdir (keyfile_path) == 0 ? 0 : errno, ==, 0); | ||
756 | + g_free (store_path); | ||
757 | + g_free (keyfile_path); | ||
758 | +} | ||
759 | + | ||
760 | /* Test that getting child schemas works | ||
761 | */ | ||
762 | static void | ||
763 | @@ -2844,6 +3000,14 @@ main (int argc, char *argv[]) | ||
764 | gchar *override_text; | ||
765 | gchar *enums; | ||
766 | gint result; | ||
767 | + const KeyfileTestData keyfile_test_data_explicit_path = { "/tests/", "root", "tests", "/" }; | ||
768 | + const KeyfileTestData keyfile_test_data_empty_path = { "/", "root", "root", "/" }; | ||
769 | + const KeyfileTestData keyfile_test_data_long_path = { | ||
770 | + "/tests/path/is/very/long/and/this/makes/some/comparisons/take/a/different/branch/", | ||
771 | + "root", | ||
772 | + "tests/path/is/very/long/and/this/makes/some/comparisons/take/a/different/branch", | ||
773 | + "/" | ||
774 | + }; | ||
775 | |||
776 | /* Meson build sets this */ | ||
777 | #ifdef TEST_LOCALE_PATH | ||
778 | @@ -2967,6 +3131,11 @@ main (int argc, char *argv[]) | ||
779 | } | ||
780 | |||
781 | g_test_add ("/gsettings/keyfile", Fixture, NULL, setup, test_keyfile, teardown); | ||
782 | + g_test_add ("/gsettings/keyfile/explicit-path", Fixture, &keyfile_test_data_explicit_path, setup, test_keyfile_no_path, teardown); | ||
783 | + g_test_add ("/gsettings/keyfile/empty-path", Fixture, &keyfile_test_data_empty_path, setup, test_keyfile_no_path, teardown); | ||
784 | + g_test_add ("/gsettings/keyfile/long-path", Fixture, &keyfile_test_data_long_path, setup, test_keyfile_no_path, teardown); | ||
785 | + g_test_add ("/gsettings/keyfile/outside-root-path", Fixture, NULL, setup, test_keyfile_outside_root_path, teardown); | ||
786 | + g_test_add ("/gsettings/keyfile/no-root-group", Fixture, NULL, setup, test_keyfile_no_root_group, teardown); | ||
787 | g_test_add_func ("/gsettings/child-schema", test_child_schema); | ||
788 | g_test_add_func ("/gsettings/strinfo", test_strinfo); | ||
789 | g_test_add_func ("/gsettings/enums", test_enums); | ||
790 | diff --git a/gio/tests/tls-interaction.c b/gio/tests/tls-interaction.c | ||
791 | index 4f0737d7e..5661e8e0d 100644 | ||
792 | --- a/gio/tests/tls-interaction.c | ||
793 | +++ b/gio/tests/tls-interaction.c | ||
794 | @@ -174,6 +174,38 @@ test_interaction_ask_password_finish_failure (GTlsInteraction *interaction, | ||
795 | } | ||
796 | |||
797 | |||
798 | +/* Return a copy of @str that is allocated in a silly way, to exercise | ||
799 | + * custom free-functions. The returned pointer points to a copy of @str | ||
800 | + * in a buffer of the form "BEFORE \0 str \0 AFTER". */ | ||
801 | +static guchar * | ||
802 | +special_dup (const char *str) | ||
803 | +{ | ||
804 | + GString *buf = g_string_new ("BEFORE"); | ||
805 | + guchar *ret; | ||
806 | + | ||
807 | + g_string_append_c (buf, '\0'); | ||
808 | + g_string_append (buf, str); | ||
809 | + g_string_append_c (buf, '\0'); | ||
810 | + g_string_append (buf, "AFTER"); | ||
811 | + ret = (guchar *) g_string_free (buf, FALSE); | ||
812 | + return ret + strlen ("BEFORE") + 1; | ||
813 | +} | ||
814 | + | ||
815 | + | ||
816 | +/* Free a copy of @str that was made with special_dup(), after asserting | ||
817 | + * that it has not been corrupted. */ | ||
818 | +static void | ||
819 | +special_free (gpointer p) | ||
820 | +{ | ||
821 | + gchar *s = p; | ||
822 | + gchar *buf = s - strlen ("BEFORE") - 1; | ||
823 | + | ||
824 | + g_assert_cmpstr (buf, ==, "BEFORE"); | ||
825 | + g_assert_cmpstr (s + strlen (s) + 1, ==, "AFTER"); | ||
826 | + g_free (buf); | ||
827 | +} | ||
828 | + | ||
829 | + | ||
830 | static GTlsInteractionResult | ||
831 | test_interaction_ask_password_sync_success (GTlsInteraction *interaction, | ||
832 | GTlsPassword *password, | ||
833 | @@ -181,6 +213,8 @@ test_interaction_ask_password_sync_success (GTlsInteraction *interaction, | ||
834 | GError **error) | ||
835 | { | ||
836 | TestInteraction *self; | ||
837 | + const guchar *value; | ||
838 | + gsize len; | ||
839 | |||
840 | g_assert (TEST_IS_INTERACTION (interaction)); | ||
841 | self = TEST_INTERACTION (interaction); | ||
842 | @@ -192,6 +226,27 @@ test_interaction_ask_password_sync_success (GTlsInteraction *interaction, | ||
843 | g_assert (error != NULL); | ||
844 | g_assert (*error == NULL); | ||
845 | |||
846 | + /* Exercise different ways to set the value */ | ||
847 | + g_tls_password_set_value (password, (const guchar *) "foo", 4); | ||
848 | + len = 0; | ||
849 | + value = g_tls_password_get_value (password, &len); | ||
850 | + g_assert_cmpmem (value, len, "foo", 4); | ||
851 | + | ||
852 | + g_tls_password_set_value (password, (const guchar *) "bar", -1); | ||
853 | + len = 0; | ||
854 | + value = g_tls_password_get_value (password, &len); | ||
855 | + g_assert_cmpmem (value, len, "bar", 3); | ||
856 | + | ||
857 | + g_tls_password_set_value_full (password, special_dup ("baa"), 4, special_free); | ||
858 | + len = 0; | ||
859 | + value = g_tls_password_get_value (password, &len); | ||
860 | + g_assert_cmpmem (value, len, "baa", 4); | ||
861 | + | ||
862 | + g_tls_password_set_value_full (password, special_dup ("baz"), -1, special_free); | ||
863 | + len = 0; | ||
864 | + value = g_tls_password_get_value (password, &len); | ||
865 | + g_assert_cmpmem (value, len, "baz", 3); | ||
866 | + | ||
867 | /* Don't do this in real life. Include a null terminator for testing */ | ||
868 | g_tls_password_set_value (password, (const guchar *)"the password", 13); | ||
869 | return G_TLS_INTERACTION_HANDLED; | ||
870 | diff --git a/gio/win32/gwinhttpfile.c b/gio/win32/gwinhttpfile.c | ||
871 | index cf5eed31d..246ec0578 100644 | ||
872 | --- a/gio/win32/gwinhttpfile.c | ||
873 | +++ b/gio/win32/gwinhttpfile.c | ||
874 | @@ -29,6 +29,7 @@ | ||
875 | #include "gio/gfile.h" | ||
876 | #include "gio/gfileattribute.h" | ||
877 | #include "gio/gfileinfo.h" | ||
878 | +#include "gstrfuncsprivate.h" | ||
879 | #include "gwinhttpfile.h" | ||
880 | #include "gwinhttpfileinputstream.h" | ||
881 | #include "gwinhttpfileoutputstream.h" | ||
882 | @@ -393,10 +394,10 @@ g_winhttp_file_resolve_relative_path (GFile *file, | ||
883 | child = g_object_new (G_TYPE_WINHTTP_FILE, NULL); | ||
884 | child->vfs = winhttp_file->vfs; | ||
885 | child->url = winhttp_file->url; | ||
886 | - child->url.lpszScheme = g_memdup (winhttp_file->url.lpszScheme, (winhttp_file->url.dwSchemeLength+1)*2); | ||
887 | - child->url.lpszHostName = g_memdup (winhttp_file->url.lpszHostName, (winhttp_file->url.dwHostNameLength+1)*2); | ||
888 | - child->url.lpszUserName = g_memdup (winhttp_file->url.lpszUserName, (winhttp_file->url.dwUserNameLength+1)*2); | ||
889 | - child->url.lpszPassword = g_memdup (winhttp_file->url.lpszPassword, (winhttp_file->url.dwPasswordLength+1)*2); | ||
890 | + child->url.lpszScheme = g_memdup2 (winhttp_file->url.lpszScheme, ((gsize) winhttp_file->url.dwSchemeLength + 1) * 2); | ||
891 | + child->url.lpszHostName = g_memdup2 (winhttp_file->url.lpszHostName, ((gsize) winhttp_file->url.dwHostNameLength + 1) * 2); | ||
892 | + child->url.lpszUserName = g_memdup2 (winhttp_file->url.lpszUserName, ((gsize) winhttp_file->url.dwUserNameLength + 1) * 2); | ||
893 | + child->url.lpszPassword = g_memdup2 (winhttp_file->url.lpszPassword, ((gsize) winhttp_file->url.dwPasswordLength + 1) * 2); | ||
894 | child->url.lpszUrlPath = wnew_path; | ||
895 | child->url.dwUrlPathLength = wcslen (wnew_path); | ||
896 | child->url.lpszExtraInfo = NULL; | ||
897 | diff --git a/glib/gbytes.c b/glib/gbytes.c | ||
898 | index ec6923188..6f17d104c 100644 | ||
899 | --- a/glib/gbytes.c | ||
900 | +++ b/glib/gbytes.c | ||
901 | @@ -34,6 +34,8 @@ | ||
902 | |||
903 | #include <string.h> | ||
904 | |||
905 | +#include "gstrfuncsprivate.h" | ||
906 | + | ||
907 | /** | ||
908 | * GBytes: | ||
909 | * | ||
910 | @@ -95,7 +97,7 @@ g_bytes_new (gconstpointer data, | ||
911 | { | ||
912 | g_return_val_if_fail (data != NULL || size == 0, NULL); | ||
913 | |||
914 | - return g_bytes_new_take (g_memdup (data, size), size); | ||
915 | + return g_bytes_new_take (g_memdup2 (data, size), size); | ||
916 | } | ||
917 | |||
918 | /** | ||
919 | @@ -499,7 +501,7 @@ g_bytes_unref_to_data (GBytes *bytes, | ||
920 | * Copy: Non g_malloc (or compatible) allocator, or static memory, | ||
921 | * so we have to copy, and then unref. | ||
922 | */ | ||
923 | - result = g_memdup (bytes->data, bytes->size); | ||
924 | + result = g_memdup2 (bytes->data, bytes->size); | ||
925 | *size = bytes->size; | ||
926 | g_bytes_unref (bytes); | ||
927 | } | ||
928 | diff --git a/glib/gdir.c b/glib/gdir.c | ||
929 | index 6b85e99c8..6747a8c6f 100644 | ||
930 | --- a/glib/gdir.c | ||
931 | +++ b/glib/gdir.c | ||
932 | @@ -37,6 +37,7 @@ | ||
933 | #include "gconvert.h" | ||
934 | #include "gfileutils.h" | ||
935 | #include "gstrfuncs.h" | ||
936 | +#include "gstrfuncsprivate.h" | ||
937 | #include "gtestutils.h" | ||
938 | #include "glibintl.h" | ||
939 | |||
940 | @@ -112,7 +113,7 @@ g_dir_open_with_errno (const gchar *path, | ||
941 | return NULL; | ||
942 | #endif | ||
943 | |||
944 | - return g_memdup (&dir, sizeof dir); | ||
945 | + return g_memdup2 (&dir, sizeof dir); | ||
946 | } | ||
947 | |||
948 | /** | ||
949 | diff --git a/glib/ghash.c b/glib/ghash.c | ||
950 | index 0f1562a06..c1e15c957 100644 | ||
951 | --- a/glib/ghash.c | ||
952 | +++ b/glib/ghash.c | ||
953 | @@ -34,6 +34,7 @@ | ||
954 | #include "gmacros.h" | ||
955 | #include "glib-private.h" | ||
956 | #include "gstrfuncs.h" | ||
957 | +#include "gstrfuncsprivate.h" | ||
958 | #include "gatomic.h" | ||
959 | #include "gtestutils.h" | ||
960 | #include "gslice.h" | ||
961 | @@ -962,7 +963,7 @@ g_hash_table_ensure_keyval_fits (GHashTable *hash_table, gpointer key, gpointer | ||
962 | if (hash_table->have_big_keys) | ||
963 | { | ||
964 | if (key != value) | ||
965 | - hash_table->values = g_memdup (hash_table->keys, sizeof (gpointer) * hash_table->size); | ||
966 | + hash_table->values = g_memdup2 (hash_table->keys, sizeof (gpointer) * hash_table->size); | ||
967 | /* Keys and values are both big now, so no need for further checks */ | ||
968 | return; | ||
969 | } | ||
970 | @@ -970,7 +971,7 @@ g_hash_table_ensure_keyval_fits (GHashTable *hash_table, gpointer key, gpointer | ||
971 | { | ||
972 | if (key != value) | ||
973 | { | ||
974 | - hash_table->values = g_memdup (hash_table->keys, sizeof (guint) * hash_table->size); | ||
975 | + hash_table->values = g_memdup2 (hash_table->keys, sizeof (guint) * hash_table->size); | ||
976 | is_a_set = FALSE; | ||
977 | } | ||
978 | } | ||
979 | @@ -998,7 +999,7 @@ g_hash_table_ensure_keyval_fits (GHashTable *hash_table, gpointer key, gpointer | ||
980 | |||
981 | /* Just split if necessary */ | ||
982 | if (is_a_set && key != value) | ||
983 | - hash_table->values = g_memdup (hash_table->keys, sizeof (gpointer) * hash_table->size); | ||
984 | + hash_table->values = g_memdup2 (hash_table->keys, sizeof (gpointer) * hash_table->size); | ||
985 | |||
986 | #endif | ||
987 | } | ||
988 | diff --git a/glib/giochannel.c b/glib/giochannel.c | ||
989 | index d16399846..b41381d38 100644 | ||
990 | --- a/glib/giochannel.c | ||
991 | +++ b/glib/giochannel.c | ||
992 | @@ -37,6 +37,7 @@ | ||
993 | #include "giochannel.h" | ||
994 | |||
995 | #include "gstrfuncs.h" | ||
996 | +#include "gstrfuncsprivate.h" | ||
997 | #include "gtestutils.h" | ||
998 | #include "glibintl.h" | ||
999 | |||
1000 | @@ -886,17 +887,26 @@ g_io_channel_set_line_term (GIOChannel *channel, | ||
1001 | const gchar *line_term, | ||
1002 | gint length) | ||
1003 | { | ||
1004 | + guint length_unsigned; | ||
1005 | + | ||
1006 | g_return_if_fail (channel != NULL); | ||
1007 | g_return_if_fail (line_term == NULL || length != 0); /* Disallow "" */ | ||
1008 | |||
1009 | if (line_term == NULL) | ||
1010 | - length = 0; | ||
1011 | - else if (length < 0) | ||
1012 | - length = strlen (line_term); | ||
1013 | + length_unsigned = 0; | ||
1014 | + else if (length >= 0) | ||
1015 | + length_unsigned = (guint) length; | ||
1016 | + else | ||
1017 | + { | ||
1018 | + /* FIXME: We’re constrained by line_term_len being a guint here */ | ||
1019 | + gsize length_size = strlen (line_term); | ||
1020 | + g_return_if_fail (length_size <= G_MAXUINT); | ||
1021 | + length_unsigned = (guint) length_size; | ||
1022 | + } | ||
1023 | |||
1024 | g_free (channel->line_term); | ||
1025 | - channel->line_term = line_term ? g_memdup (line_term, length) : NULL; | ||
1026 | - channel->line_term_len = length; | ||
1027 | + channel->line_term = line_term ? g_memdup2 (line_term, length_unsigned) : NULL; | ||
1028 | + channel->line_term_len = length_unsigned; | ||
1029 | } | ||
1030 | |||
1031 | /** | ||
1032 | @@ -1673,10 +1683,10 @@ g_io_channel_read_line (GIOChannel *channel, | ||
1033 | |||
1034 | /* Copy the read bytes (including any embedded nuls) and nul-terminate. | ||
1035 | * `USE_BUF (channel)->str` is guaranteed to be nul-terminated as it’s a | ||
1036 | - * #GString, so it’s safe to call g_memdup() with +1 length to allocate | ||
1037 | + * #GString, so it’s safe to call g_memdup2() with +1 length to allocate | ||
1038 | * a nul-terminator. */ | ||
1039 | g_assert (USE_BUF (channel)); | ||
1040 | - line = g_memdup (USE_BUF (channel)->str, got_length + 1); | ||
1041 | + line = g_memdup2 (USE_BUF (channel)->str, got_length + 1); | ||
1042 | line[got_length] = '\0'; | ||
1043 | *str_return = g_steal_pointer (&line); | ||
1044 | g_string_erase (USE_BUF (channel), 0, got_length); | ||
1045 | diff --git a/glib/gslice.c b/glib/gslice.c | ||
1046 | index 4c758c3be..bcdbb8853 100644 | ||
1047 | --- a/glib/gslice.c | ||
1048 | +++ b/glib/gslice.c | ||
1049 | @@ -41,6 +41,7 @@ | ||
1050 | #include "gmain.h" | ||
1051 | #include "gmem.h" /* gslice.h */ | ||
1052 | #include "gstrfuncs.h" | ||
1053 | +#include "gstrfuncsprivate.h" | ||
1054 | #include "gutils.h" | ||
1055 | #include "gtrashstack.h" | ||
1056 | #include "gtestutils.h" | ||
1057 | @@ -350,7 +351,7 @@ g_slice_get_config_state (GSliceConfig ckey, | ||
1058 | array[i++] = allocator->contention_counters[address]; | ||
1059 | array[i++] = allocator_get_magazine_threshold (allocator, address); | ||
1060 | *n_values = i; | ||
1061 | - return g_memdup (array, sizeof (array[0]) * *n_values); | ||
1062 | + return g_memdup2 (array, sizeof (array[0]) * *n_values); | ||
1063 | default: | ||
1064 | return NULL; | ||
1065 | } | ||
1066 | diff --git a/glib/gstrfuncsprivate.h b/glib/gstrfuncsprivate.h | ||
1067 | new file mode 100644 | ||
1068 | index 000000000..85c88328a | ||
1069 | --- /dev/null | ||
1070 | +++ b/glib/gstrfuncsprivate.h | ||
1071 | @@ -0,0 +1,55 @@ | ||
1072 | +/* GLIB - Library of useful routines for C programming | ||
1073 | + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald | ||
1074 | + * | ||
1075 | + * This library is free software; you can redistribute it and/or | ||
1076 | + * modify it under the terms of the GNU Lesser General Public | ||
1077 | + * License as published by the Free Software Foundation; either | ||
1078 | + * version 2.1 of the License, or (at your option) any later version. | ||
1079 | + * | ||
1080 | + * This library is distributed in the hope that it will be useful, | ||
1081 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1082 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
1083 | + * Lesser General Public License for more details. | ||
1084 | + * | ||
1085 | + * You should have received a copy of the GNU Lesser General Public | ||
1086 | + * License along with this library; if not, see <http://www.gnu.org/licenses/>. | ||
1087 | + */ | ||
1088 | + | ||
1089 | +#include <glib.h> | ||
1090 | +#include <string.h> | ||
1091 | + | ||
1092 | +/* | ||
1093 | + * g_memdup2: | ||
1094 | + * @mem: (nullable): the memory to copy. | ||
1095 | + * @byte_size: the number of bytes to copy. | ||
1096 | + * | ||
1097 | + * Allocates @byte_size bytes of memory, and copies @byte_size bytes into it | ||
1098 | + * from @mem. If @mem is %NULL it returns %NULL. | ||
1099 | + * | ||
1100 | + * This replaces g_memdup(), which was prone to integer overflows when | ||
1101 | + * converting the argument from a #gsize to a #guint. | ||
1102 | + * | ||
1103 | + * This static inline version is a backport of the new public API from | ||
1104 | + * GLib 2.68, kept internal to GLib for backport to older stable releases. | ||
1105 | + * See https://gitlab.gnome.org/GNOME/glib/-/issues/2319. | ||
1106 | + * | ||
1107 | + * Returns: (nullable): a pointer to the newly-allocated copy of the memory, | ||
1108 | + * or %NULL if @mem is %NULL. | ||
1109 | + * Since: 2.68 | ||
1110 | + */ | ||
1111 | +static inline gpointer | ||
1112 | +g_memdup2 (gconstpointer mem, | ||
1113 | + gsize byte_size) | ||
1114 | +{ | ||
1115 | + gpointer new_mem; | ||
1116 | + | ||
1117 | + if (mem && byte_size != 0) | ||
1118 | + { | ||
1119 | + new_mem = g_malloc (byte_size); | ||
1120 | + memcpy (new_mem, mem, byte_size); | ||
1121 | + } | ||
1122 | + else | ||
1123 | + new_mem = NULL; | ||
1124 | + | ||
1125 | + return new_mem; | ||
1126 | +} | ||
1127 | diff --git a/glib/gtestutils.c b/glib/gtestutils.c | ||
1128 | index 18b117285..26d46ad75 100644 | ||
1129 | --- a/glib/gtestutils.c | ||
1130 | +++ b/glib/gtestutils.c | ||
1131 | @@ -49,6 +49,7 @@ | ||
1132 | #include "gpattern.h" | ||
1133 | #include "grand.h" | ||
1134 | #include "gstrfuncs.h" | ||
1135 | +#include "gstrfuncsprivate.h" | ||
1136 | #include "gtimer.h" | ||
1137 | #include "gslice.h" | ||
1138 | #include "gspawn.h" | ||
1139 | @@ -3803,7 +3804,7 @@ g_test_log_extract (GTestLogBuffer *tbuffer) | ||
1140 | if (p <= tbuffer->data->str + mlength) | ||
1141 | { | ||
1142 | g_string_erase (tbuffer->data, 0, mlength); | ||
1143 | - tbuffer->msgs = g_slist_prepend (tbuffer->msgs, g_memdup (&msg, sizeof (msg))); | ||
1144 | + tbuffer->msgs = g_slist_prepend (tbuffer->msgs, g_memdup2 (&msg, sizeof (msg))); | ||
1145 | return TRUE; | ||
1146 | } | ||
1147 | |||
1148 | diff --git a/glib/gvariant.c b/glib/gvariant.c | ||
1149 | index 77d7e746b..ef4257f6d 100644 | ||
1150 | --- a/glib/gvariant.c | ||
1151 | +++ b/glib/gvariant.c | ||
1152 | @@ -33,6 +33,7 @@ | ||
1153 | |||
1154 | #include <string.h> | ||
1155 | |||
1156 | +#include "gstrfuncsprivate.h" | ||
1157 | |||
1158 | /** | ||
1159 | * SECTION:gvariant | ||
1160 | @@ -725,7 +726,7 @@ g_variant_new_variant (GVariant *value) | ||
1161 | g_variant_ref_sink (value); | ||
1162 | |||
1163 | return g_variant_new_from_children (G_VARIANT_TYPE_VARIANT, | ||
1164 | - g_memdup (&value, sizeof value), | ||
1165 | + g_memdup2 (&value, sizeof value), | ||
1166 | 1, g_variant_is_trusted (value)); | ||
1167 | } | ||
1168 | |||
1169 | @@ -1229,7 +1230,7 @@ g_variant_new_fixed_array (const GVariantType *element_type, | ||
1170 | return NULL; | ||
1171 | } | ||
1172 | |||
1173 | - data = g_memdup (elements, n_elements * element_size); | ||
1174 | + data = g_memdup2 (elements, n_elements * element_size); | ||
1175 | value = g_variant_new_from_data (array_type, data, | ||
1176 | n_elements * element_size, | ||
1177 | FALSE, g_free, data); | ||
1178 | @@ -1908,7 +1909,7 @@ g_variant_dup_bytestring (GVariant *value, | ||
1179 | if (length) | ||
1180 | *length = size; | ||
1181 | |||
1182 | - return g_memdup (original, size + 1); | ||
1183 | + return g_memdup2 (original, size + 1); | ||
1184 | } | ||
1185 | |||
1186 | /** | ||
1187 | diff --git a/glib/gvarianttype.c b/glib/gvarianttype.c | ||
1188 | index c46f1a2c6..585e29ab2 100644 | ||
1189 | --- a/glib/gvarianttype.c | ||
1190 | +++ b/glib/gvarianttype.c | ||
1191 | @@ -28,6 +28,7 @@ | ||
1192 | |||
1193 | #include <string.h> | ||
1194 | |||
1195 | +#include "gstrfuncsprivate.h" | ||
1196 | |||
1197 | /** | ||
1198 | * SECTION:gvarianttype | ||
1199 | @@ -1181,7 +1182,7 @@ g_variant_type_new_tuple (const GVariantType * const *items, | ||
1200 | g_assert (offset < sizeof buffer); | ||
1201 | buffer[offset++] = ')'; | ||
1202 | |||
1203 | - return (GVariantType *) g_memdup (buffer, offset); | ||
1204 | + return (GVariantType *) g_memdup2 (buffer, offset); | ||
1205 | } | ||
1206 | |||
1207 | /** | ||
1208 | diff --git a/glib/meson.build b/glib/meson.build | ||
1209 | index 456e0c2a1..2e5cd77bb 100644 | ||
1210 | --- a/glib/meson.build | ||
1211 | +++ b/glib/meson.build | ||
1212 | @@ -268,6 +268,7 @@ glib_sources = files( | ||
1213 | 'gslist.c', | ||
1214 | 'gstdio.c', | ||
1215 | 'gstrfuncs.c', | ||
1216 | + 'gstrfuncsprivate.h', | ||
1217 | 'gstring.c', | ||
1218 | 'gstringchunk.c', | ||
1219 | 'gtestutils.c', | ||
1220 | diff --git a/glib/tests/array-test.c b/glib/tests/array-test.c | ||
1221 | index 1da514a3e..88f22de80 100644 | ||
1222 | --- a/glib/tests/array-test.c | ||
1223 | +++ b/glib/tests/array-test.c | ||
1224 | @@ -29,6 +29,8 @@ | ||
1225 | #include <string.h> | ||
1226 | #include "glib.h" | ||
1227 | |||
1228 | +#include "gstrfuncsprivate.h" | ||
1229 | + | ||
1230 | /* Test data to be passed to any function which calls g_array_new(), providing | ||
1231 | * the parameters for that call. Most #GArray tests should be repeated for all | ||
1232 | * possible values of #ArrayTestData. */ | ||
1233 | @@ -1917,7 +1919,7 @@ byte_array_new_take (void) | ||
1234 | GByteArray *gbarray; | ||
1235 | guint8 *data; | ||
1236 | |||
1237 | - data = g_memdup ("woooweeewow", 11); | ||
1238 | + data = g_memdup2 ("woooweeewow", 11); | ||
1239 | gbarray = g_byte_array_new_take (data, 11); | ||
1240 | g_assert (gbarray->data == data); | ||
1241 | g_assert_cmpuint (gbarray->len, ==, 11); | ||
1242 | diff --git a/glib/tests/io-channel.c b/glib/tests/io-channel.c | ||
1243 | index ff53fcef7..4a1b10876 100644 | ||
1244 | --- a/glib/tests/io-channel.c | ||
1245 | +++ b/glib/tests/io-channel.c | ||
1246 | @@ -49,8 +49,10 @@ test_read_line_embedded_nuls (void) | ||
1247 | channel = g_io_channel_new_file (filename, "r", &local_error); | ||
1248 | g_assert_no_error (local_error); | ||
1249 | |||
1250 | - /* Only break on newline characters, not nuls. */ | ||
1251 | - g_io_channel_set_line_term (channel, "\n", 1); | ||
1252 | + /* Only break on newline characters, not nuls. | ||
1253 | + * Use length -1 here to exercise glib#2323; the case where length > 0 | ||
1254 | + * is covered in glib/tests/protocol.c. */ | ||
1255 | + g_io_channel_set_line_term (channel, "\n", -1); | ||
1256 | g_io_channel_set_encoding (channel, NULL, &local_error); | ||
1257 | g_assert_no_error (local_error); | ||
1258 | |||
1259 | diff --git a/glib/tests/option-context.c b/glib/tests/option-context.c | ||
1260 | index 149d22353..88d2b80d1 100644 | ||
1261 | --- a/glib/tests/option-context.c | ||
1262 | +++ b/glib/tests/option-context.c | ||
1263 | @@ -27,6 +27,8 @@ | ||
1264 | #include <string.h> | ||
1265 | #include <locale.h> | ||
1266 | |||
1267 | +#include "gstrfuncsprivate.h" | ||
1268 | + | ||
1269 | static GOptionEntry main_entries[] = { | ||
1270 | { "main-switch", 0, 0, | ||
1271 | G_OPTION_ARG_NONE, NULL, | ||
1272 | @@ -256,7 +258,7 @@ join_stringv (int argc, char **argv) | ||
1273 | static char ** | ||
1274 | copy_stringv (char **argv, int argc) | ||
1275 | { | ||
1276 | - return g_memdup (argv, sizeof (char *) * (argc + 1)); | ||
1277 | + return g_memdup2 (argv, sizeof (char *) * (argc + 1)); | ||
1278 | } | ||
1279 | |||
1280 | static void | ||
1281 | @@ -2323,7 +2325,7 @@ test_group_parse (void) | ||
1282 | g_option_context_add_group (context, group); | ||
1283 | |||
1284 | argv = split_string ("program --test arg1 -f arg2 --group-test arg3 --frob arg4 -z arg5", &argc); | ||
1285 | - orig_argv = g_memdup (argv, (argc + 1) * sizeof (char *)); | ||
1286 | + orig_argv = g_memdup2 (argv, (argc + 1) * sizeof (char *)); | ||
1287 | |||
1288 | retval = g_option_context_parse (context, &argc, &argv, &error); | ||
1289 | |||
1290 | diff --git a/glib/tests/strfuncs.c b/glib/tests/strfuncs.c | ||
1291 | index e1f9619c7..d968afff9 100644 | ||
1292 | --- a/glib/tests/strfuncs.c | ||
1293 | +++ b/glib/tests/strfuncs.c | ||
1294 | @@ -32,6 +32,8 @@ | ||
1295 | #include <string.h> | ||
1296 | #include "glib.h" | ||
1297 | |||
1298 | +#include "gstrfuncsprivate.h" | ||
1299 | + | ||
1300 | #if defined (_MSC_VER) && (_MSC_VER <= 1800) | ||
1301 | #define isnan(x) _isnan(x) | ||
1302 | |||
1303 | @@ -219,6 +221,26 @@ test_memdup (void) | ||
1304 | g_free (str_dup); | ||
1305 | } | ||
1306 | |||
1307 | +/* Testing g_memdup2() function with various positive and negative cases */ | ||
1308 | +static void | ||
1309 | +test_memdup2 (void) | ||
1310 | +{ | ||
1311 | + gchar *str_dup = NULL; | ||
1312 | + const gchar *str = "The quick brown fox jumps over the lazy dog"; | ||
1313 | + | ||
1314 | + /* Testing negative cases */ | ||
1315 | + g_assert_null (g_memdup2 (NULL, 1024)); | ||
1316 | + g_assert_null (g_memdup2 (str, 0)); | ||
1317 | + g_assert_null (g_memdup2 (NULL, 0)); | ||
1318 | + | ||
1319 | + /* Testing normal usage cases */ | ||
1320 | + str_dup = g_memdup2 (str, strlen (str) + 1); | ||
1321 | + g_assert_nonnull (str_dup); | ||
1322 | + g_assert_cmpstr (str, ==, str_dup); | ||
1323 | + | ||
1324 | + g_free (str_dup); | ||
1325 | +} | ||
1326 | + | ||
1327 | /* Testing g_strpcpy() function with various positive and negative cases */ | ||
1328 | static void | ||
1329 | test_stpcpy (void) | ||
1330 | @@ -2523,6 +2545,7 @@ main (int argc, | ||
1331 | g_test_add_func ("/strfuncs/has-prefix", test_has_prefix); | ||
1332 | g_test_add_func ("/strfuncs/has-suffix", test_has_suffix); | ||
1333 | g_test_add_func ("/strfuncs/memdup", test_memdup); | ||
1334 | + g_test_add_func ("/strfuncs/memdup2", test_memdup2); | ||
1335 | g_test_add_func ("/strfuncs/stpcpy", test_stpcpy); | ||
1336 | g_test_add_func ("/strfuncs/str_match_string", test_str_match_string); | ||
1337 | g_test_add_func ("/strfuncs/str_tokenize_and_fold", test_str_tokenize_and_fold); | ||
1338 | diff --git a/gobject/gsignal.c b/gobject/gsignal.c | ||
1339 | index 45effa92d..effbfec62 100644 | ||
1340 | --- a/gobject/gsignal.c | ||
1341 | +++ b/gobject/gsignal.c | ||
1342 | @@ -28,6 +28,7 @@ | ||
1343 | #include <signal.h> | ||
1344 | |||
1345 | #include "gsignal.h" | ||
1346 | +#include "gstrfuncsprivate.h" | ||
1347 | #include "gtype-private.h" | ||
1348 | #include "gbsearcharray.h" | ||
1349 | #include "gvaluecollector.h" | ||
1350 | @@ -1809,7 +1810,7 @@ g_signal_newv (const gchar *signal_name, | ||
1351 | node->single_va_closure_is_valid = FALSE; | ||
1352 | node->flags = signal_flags & G_SIGNAL_FLAGS_MASK; | ||
1353 | node->n_params = n_params; | ||
1354 | - node->param_types = g_memdup (param_types, sizeof (GType) * n_params); | ||
1355 | + node->param_types = g_memdup2 (param_types, sizeof (GType) * n_params); | ||
1356 | node->return_type = return_type; | ||
1357 | node->class_closure_bsa = NULL; | ||
1358 | if (accumulator) | ||
1359 | diff --git a/gobject/gtype.c b/gobject/gtype.c | ||
1360 | index b5ef2d11e..8d152dccc 100644 | ||
1361 | --- a/gobject/gtype.c | ||
1362 | +++ b/gobject/gtype.c | ||
1363 | @@ -33,6 +33,7 @@ | ||
1364 | |||
1365 | #include "glib-private.h" | ||
1366 | #include "gconstructor.h" | ||
1367 | +#include "gstrfuncsprivate.h" | ||
1368 | |||
1369 | #ifdef G_OS_WIN32 | ||
1370 | #include <windows.h> | ||
1371 | @@ -1470,7 +1471,7 @@ type_add_interface_Wm (TypeNode *node, | ||
1372 | iholder->next = iface_node_get_holders_L (iface); | ||
1373 | iface_node_set_holders_W (iface, iholder); | ||
1374 | iholder->instance_type = NODE_TYPE (node); | ||
1375 | - iholder->info = info ? g_memdup (info, sizeof (*info)) : NULL; | ||
1376 | + iholder->info = info ? g_memdup2 (info, sizeof (*info)) : NULL; | ||
1377 | iholder->plugin = plugin; | ||
1378 | |||
1379 | /* create an iface entry for this type */ | ||
1380 | @@ -1731,7 +1732,7 @@ type_iface_retrieve_holder_info_Wm (TypeNode *iface, | ||
1381 | INVALID_RECURSION ("g_type_plugin_*", iholder->plugin, NODE_NAME (iface)); | ||
1382 | |||
1383 | check_interface_info_I (iface, instance_type, &tmp_info); | ||
1384 | - iholder->info = g_memdup (&tmp_info, sizeof (tmp_info)); | ||
1385 | + iholder->info = g_memdup2 (&tmp_info, sizeof (tmp_info)); | ||
1386 | } | ||
1387 | |||
1388 | return iholder; /* we don't modify write lock upon returning NULL */ | ||
1389 | @@ -2016,10 +2017,10 @@ type_iface_vtable_base_init_Wm (TypeNode *iface, | ||
1390 | IFaceEntry *pentry = type_lookup_iface_entry_L (pnode, iface); | ||
1391 | |||
1392 | if (pentry) | ||
1393 | - vtable = g_memdup (pentry->vtable, iface->data->iface.vtable_size); | ||
1394 | + vtable = g_memdup2 (pentry->vtable, iface->data->iface.vtable_size); | ||
1395 | } | ||
1396 | if (!vtable) | ||
1397 | - vtable = g_memdup (iface->data->iface.dflt_vtable, iface->data->iface.vtable_size); | ||
1398 | + vtable = g_memdup2 (iface->data->iface.dflt_vtable, iface->data->iface.vtable_size); | ||
1399 | entry->vtable = vtable; | ||
1400 | vtable->g_type = NODE_TYPE (iface); | ||
1401 | vtable->g_instance_type = NODE_TYPE (node); | ||
1402 | diff --git a/gobject/gtypemodule.c b/gobject/gtypemodule.c | ||
1403 | index 4ecaf8c88..20911fafd 100644 | ||
1404 | --- a/gobject/gtypemodule.c | ||
1405 | +++ b/gobject/gtypemodule.c | ||
1406 | @@ -19,6 +19,7 @@ | ||
1407 | |||
1408 | #include <stdlib.h> | ||
1409 | |||
1410 | +#include "gstrfuncsprivate.h" | ||
1411 | #include "gtypeplugin.h" | ||
1412 | #include "gtypemodule.h" | ||
1413 | |||
1414 | @@ -436,7 +437,7 @@ g_type_module_register_type (GTypeModule *module, | ||
1415 | module_type_info->loaded = TRUE; | ||
1416 | module_type_info->info = *type_info; | ||
1417 | if (type_info->value_table) | ||
1418 | - module_type_info->info.value_table = g_memdup (type_info->value_table, | ||
1419 | + module_type_info->info.value_table = g_memdup2 (type_info->value_table, | ||
1420 | sizeof (GTypeValueTable)); | ||
1421 | |||
1422 | return module_type_info->type; | ||
1423 | diff --git a/gobject/tests/param.c b/gobject/tests/param.c | ||
1424 | index 93c3f4b94..0a77e51b7 100644 | ||
1425 | --- a/gobject/tests/param.c | ||
1426 | +++ b/gobject/tests/param.c | ||
1427 | @@ -2,6 +2,8 @@ | ||
1428 | #include <glib-object.h> | ||
1429 | #include <stdlib.h> | ||
1430 | |||
1431 | +#include "gstrfuncsprivate.h" | ||
1432 | + | ||
1433 | static void | ||
1434 | test_param_value (void) | ||
1435 | { | ||
1436 | @@ -874,7 +876,7 @@ main (int argc, char *argv[]) | ||
1437 | test_path = g_strdup_printf ("/param/implement/subprocess/%d-%d-%d-%d", | ||
1438 | data.change_this_flag, data.change_this_type, | ||
1439 | data.use_this_flag, data.use_this_type); | ||
1440 | - test_data = g_memdup (&data, sizeof (TestParamImplementData)); | ||
1441 | + test_data = g_memdup2 (&data, sizeof (TestParamImplementData)); | ||
1442 | g_test_add_data_func_full (test_path, test_data, test_param_implement_child, g_free); | ||
1443 | g_free (test_path); | ||
1444 | } | ||
diff --git a/meta/recipes-core/glib-2.0/glib-2.0_2.64.5.bb b/meta/recipes-core/glib-2.0/glib-2.0_2.64.5.bb index b9462bc945..ed7b649dc6 100644 --- a/meta/recipes-core/glib-2.0/glib-2.0_2.64.5.bb +++ b/meta/recipes-core/glib-2.0/glib-2.0_2.64.5.bb | |||
@@ -18,6 +18,7 @@ SRC_URI = "${GNOME_MIRROR}/glib/${SHRT_VER}/glib-${PV}.tar.xz \ | |||
18 | file://0001-gio-tests-resources.c-comment-out-a-build-host-only-.patch \ | 18 | file://0001-gio-tests-resources.c-comment-out-a-build-host-only-.patch \ |
19 | file://tzdata-update.patch \ | 19 | file://tzdata-update.patch \ |
20 | file://CVE-2020-35457.patch \ | 20 | file://CVE-2020-35457.patch \ |
21 | file://CVE-2021-27219.patch \ | ||
21 | " | 22 | " |
22 | 23 | ||
23 | SRC_URI_append_class-native = " file://relocate-modules.patch" | 24 | SRC_URI_append_class-native = " file://relocate-modules.patch" |