summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/reference/glib/meson.build1
-rw-r--r--gio/gdbusconnection.c5
-rw-r--r--gio/gdbusinterfaceskeleton.c3
-rw-r--r--gio/gfile.c7
-rw-r--r--gio/gsettingsschema.c5
-rw-r--r--gio/gwin32appinfo.c2
-rw-r--r--gio/gwin32registrykey.c10
-rw-r--r--gio/tests/async-close-output-stream.c6
-rw-r--r--gio/tests/gdbus-export.c5
-rw-r--r--gio/win32/gwinhttpfile.c9
-rw-r--r--glib/garray.c6
-rw-r--r--glib/gbytes.c10
-rw-r--r--glib/gdir.c3
-rw-r--r--glib/ghash.c3
-rw-r--r--glib/gslice.c3
-rw-r--r--glib/gstrfuncsprivate.h55
-rw-r--r--glib/gtestutils.c3
-rw-r--r--glib/gvariant.c7
-rw-r--r--glib/gvarianttype.c3
-rw-r--r--glib/meson.build1
-rw-r--r--glib/tests/array-test.c4
-rw-r--r--glib/tests/bytes.c37
-rw-r--r--glib/tests/gvariant.c9
-rw-r--r--glib/tests/option-context.c6
-rw-r--r--glib/tests/strfuncs.c23
-rw-r--r--gobject/gsignal.c3
-rw-r--r--gobject/gtype.c9
-rw-r--r--gobject/gtypemodule.c3
-rw-r--r--gobject/tests/param.c4
29 files changed, 198 insertions, 47 deletions
diff --git a/docs/reference/glib/meson.build b/docs/reference/glib/meson.build
index f14824bff..f0b0cb526 100644
--- a/docs/reference/glib/meson.build
+++ b/docs/reference/glib/meson.build
@@ -20,6 +20,7 @@ if get_option('gtk_doc')
'gprintfint.h',
'gmirroringtable.h',
'gscripttable.h',
+ 'gstrfuncsprivate.h',
'glib-mirroring-tab',
'gnulib',
'pcre',
diff --git a/gio/gdbusconnection.c b/gio/gdbusconnection.c
index 7270365b6..85ed1a3b3 100644
--- a/gio/gdbusconnection.c
+++ b/gio/gdbusconnection.c
@@ -110,6 +110,7 @@
#include "gasyncinitable.h"
#include "giostream.h"
#include "gasyncresult.h"
+#include "gstrfuncsprivate.h"
#include "gtask.h"
#ifdef G_OS_UNIX
@@ -3961,7 +3962,7 @@ _g_dbus_interface_vtable_copy (const GDBusInterfaceVTable *vtable)
/* Don't waste memory by copying padding - remember to update this
* when changing struct _GDBusInterfaceVTable in gdbusconnection.h
*/
- return g_memdup ((gconstpointer) vtable, 3 * sizeof (gpointer));
+ return g_memdup2 ((gconstpointer) vtable, 3 * sizeof (gpointer));
}
static void
@@ -3978,7 +3979,7 @@ _g_dbus_subtree_vtable_copy (const GDBusSubtreeVTable *vtable)
/* Don't waste memory by copying padding - remember to update this
* when changing struct _GDBusSubtreeVTable in gdbusconnection.h
*/
- return g_memdup ((gconstpointer) vtable, 3 * sizeof (gpointer));
+ return g_memdup2 ((gconstpointer) vtable, 3 * sizeof (gpointer));
}
static void
diff --git a/gio/gdbusinterfaceskeleton.c b/gio/gdbusinterfaceskeleton.c
index 96bd520aa..672604c49 100644
--- a/gio/gdbusinterfaceskeleton.c
+++ b/gio/gdbusinterfaceskeleton.c
@@ -27,6 +27,7 @@
#include "gdbusprivate.h"
#include "gdbusmethodinvocation.h"
#include "gdbusconnection.h"
+#include "gstrfuncsprivate.h"
#include "gtask.h"
#include "gioerror.h"
@@ -697,7 +698,7 @@ add_connection_locked (GDBusInterfaceSkeleton *interface_,
* properly before building the hooked_vtable, so we create it
* once at the last minute.
*/
- interface_->priv->hooked_vtable = g_memdup (g_dbus_interface_skeleton_get_vtable (interface_), sizeof (GDBusInterfaceVTable));
+ interface_->priv->hooked_vtable = g_memdup2 (g_dbus_interface_skeleton_get_vtable (interface_), sizeof (GDBusInterfaceVTable));
interface_->priv->hooked_vtable->method_call = skeleton_intercept_handle_method_call;
}
diff --git a/gio/gfile.c b/gio/gfile.c
index a5709a4cc..d2314a463 100644
--- a/gio/gfile.c
+++ b/gio/gfile.c
@@ -60,6 +60,7 @@
#include "gasyncresult.h"
#include "gioerror.h"
#include "glibintl.h"
+#include "gstrfuncsprivate.h"
/**
@@ -7738,7 +7739,7 @@ measure_disk_usage_progress (gboolean reporting,
g_main_context_invoke_full (g_task_get_context (task),
g_task_get_priority (task),
measure_disk_usage_invoke_progress,
- g_memdup (&progress, sizeof progress),
+ g_memdup2 (&progress, sizeof progress),
g_free);
}
@@ -7756,7 +7757,7 @@ measure_disk_usage_thread (GTask *task,
data->progress_callback ? measure_disk_usage_progress : NULL, task,
&result.disk_usage, &result.num_dirs, &result.num_files,
&error))
- g_task_return_pointer (task, g_memdup (&result, sizeof result), g_free);
+ g_task_return_pointer (task, g_memdup2 (&result, sizeof result), g_free);
else
g_task_return_error (task, error);
}
@@ -7780,7 +7781,7 @@ g_file_real_measure_disk_usage_async (GFile *file,
task = g_task_new (file, cancellable, callback, user_data);
g_task_set_source_tag (task, g_file_real_measure_disk_usage_async);
- g_task_set_task_data (task, g_memdup (&data, sizeof data), g_free);
+ g_task_set_task_data (task, g_memdup2 (&data, sizeof data), g_free);
g_task_set_priority (task, io_priority);
g_task_run_in_thread (task, measure_disk_usage_thread);
diff --git a/gio/gsettingsschema.c b/gio/gsettingsschema.c
index 38c9d78b9..e23dd8c89 100644
--- a/gio/gsettingsschema.c
+++ b/gio/gsettingsschema.c
@@ -20,6 +20,7 @@
#include "gsettingsschema-internal.h"
#include "gsettings.h"
+#include "gstrfuncsprivate.h"
#include "gvdb/gvdb-reader.h"
#include "strinfo.c"
@@ -1057,9 +1058,9 @@ g_settings_schema_list_children (GSettingsSchema *schema)
if (g_str_has_suffix (key, "/"))
{
- gint length = strlen (key);
+ gsize length = strlen (key);
- strv[j] = g_memdup (key, length);
+ strv[j] = g_memdup2 (key, length);
strv[j][length - 1] = '\0';
j++;
}
diff --git a/gio/gwin32appinfo.c b/gio/gwin32appinfo.c
index 9f335b370..2a0fe380d 100644
--- a/gio/gwin32appinfo.c
+++ b/gio/gwin32appinfo.c
@@ -472,7 +472,7 @@ g_wcsdup (const gunichar2 *str, gssize str_size)
str_size = wcslen (str) + 1;
str_size *= sizeof (gunichar2);
}
- return g_memdup (str, str_size);
+ return g_memdup2 (str, str_size);
}
#define URL_ASSOCIATIONS L"HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\"
diff --git a/gio/gwin32registrykey.c b/gio/gwin32registrykey.c
index c19fede4e..1c5526315 100644
--- a/gio/gwin32registrykey.c
+++ b/gio/gwin32registrykey.c
@@ -28,6 +28,8 @@
#include <ntstatus.h>
#include <winternl.h>
+#include "gstrfuncsprivate.h"
+
#ifndef _WDMDDK_
typedef enum _KEY_INFORMATION_CLASS {
KeyBasicInformation,
@@ -134,7 +136,7 @@ g_wcsdup (const gunichar2 *str,
str_size = wcslen (str) + 1;
str_size *= sizeof (gunichar2);
}
- return g_memdup (str, str_size);
+ return g_memdup2 (str, str_size);
}
/**
@@ -247,7 +249,7 @@ g_win32_registry_value_iter_copy (const GWin32RegistryValueIter *iter)
new_iter->value_name_size = iter->value_name_size;
if (iter->value_data != NULL)
- new_iter->value_data = g_memdup (iter->value_data, iter->value_data_size);
+ new_iter->value_data = g_memdup2 (iter->value_data, iter->value_data_size);
new_iter->value_data_size = iter->value_data_size;
@@ -268,8 +270,8 @@ g_win32_registry_value_iter_copy (const GWin32RegistryValueIter *iter)
new_iter->value_data_expanded_charsize = iter->value_data_expanded_charsize;
if (iter->value_data_expanded_u8 != NULL)
- new_iter->value_data_expanded_u8 = g_memdup (iter->value_data_expanded_u8,
- iter->value_data_expanded_charsize);
+ new_iter->value_data_expanded_u8 = g_memdup2 (iter->value_data_expanded_u8,
+ iter->value_data_expanded_charsize);
new_iter->value_data_expanded_u8_size = iter->value_data_expanded_charsize;
diff --git a/gio/tests/async-close-output-stream.c b/gio/tests/async-close-output-stream.c
index 5f6620275..d3f97a119 100644
--- a/gio/tests/async-close-output-stream.c
+++ b/gio/tests/async-close-output-stream.c
@@ -24,6 +24,8 @@
#include <stdlib.h>
#include <string.h>
+#include "gstrfuncsprivate.h"
+
#define DATA_TO_WRITE "Hello world\n"
typedef struct
@@ -147,9 +149,9 @@ prepare_data (SetupData *data,
data->expected_size = g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (data->data_stream));
- g_assert_cmpint (data->expected_size, >, 0);
+ g_assert_cmpuint (data->expected_size, >, 0);
- data->expected_output = g_memdup (written, (guint)data->expected_size);
+ data->expected_output = g_memdup2 (written, data->expected_size);
/* then recreate the streams and prepare them for the asynchronous close */
destroy_streams (data);
diff --git a/gio/tests/gdbus-export.c b/gio/tests/gdbus-export.c
index 4d6d3a43e..544b88653 100644
--- a/gio/tests/gdbus-export.c
+++ b/gio/tests/gdbus-export.c
@@ -23,6 +23,7 @@
#include <string.h>
#include "gdbus-tests.h"
+#include "gstrfuncsprivate.h"
/* all tests rely on a shared mainloop */
static GMainLoop *loop = NULL;
@@ -652,7 +653,7 @@ subtree_introspect (GDBusConnection *connection,
g_assert_not_reached ();
}
- return g_memdup (interfaces, 2 * sizeof (void *));
+ return g_memdup2 (interfaces, 2 * sizeof (void *));
}
static const GDBusInterfaceVTable *
@@ -708,7 +709,7 @@ dynamic_subtree_introspect (GDBusConnection *connection,
{
const GDBusInterfaceInfo *interfaces[2] = { &dyna_interface_info, NULL };
- return g_memdup (interfaces, 2 * sizeof (void *));
+ return g_memdup2 (interfaces, 2 * sizeof (void *));
}
static const GDBusInterfaceVTable *
diff --git a/gio/win32/gwinhttpfile.c b/gio/win32/gwinhttpfile.c
index d5df16d91..e98031a98 100644
--- a/gio/win32/gwinhttpfile.c
+++ b/gio/win32/gwinhttpfile.c
@@ -29,6 +29,7 @@
#include "gio/gfile.h"
#include "gio/gfileattribute.h"
#include "gio/gfileinfo.h"
+#include "gstrfuncsprivate.h"
#include "gwinhttpfile.h"
#include "gwinhttpfileinputstream.h"
#include "gwinhttpfileoutputstream.h"
@@ -393,10 +394,10 @@ g_winhttp_file_resolve_relative_path (GFile *file,
child = g_object_new (G_TYPE_WINHTTP_FILE, NULL);
child->vfs = winhttp_file->vfs;
child->url = winhttp_file->url;
- child->url.lpszScheme = g_memdup (winhttp_file->url.lpszScheme, (winhttp_file->url.dwSchemeLength+1)*2);
- child->url.lpszHostName = g_memdup (winhttp_file->url.lpszHostName, (winhttp_file->url.dwHostNameLength+1)*2);
- child->url.lpszUserName = g_memdup (winhttp_file->url.lpszUserName, (winhttp_file->url.dwUserNameLength+1)*2);
- child->url.lpszPassword = g_memdup (winhttp_file->url.lpszPassword, (winhttp_file->url.dwPasswordLength+1)*2);
+ child->url.lpszScheme = g_memdup2 (winhttp_file->url.lpszScheme, ((gsize) winhttp_file->url.dwSchemeLength + 1) * 2);
+ child->url.lpszHostName = g_memdup2 (winhttp_file->url.lpszHostName, ((gsize) winhttp_file->url.dwHostNameLength + 1) * 2);
+ child->url.lpszUserName = g_memdup2 (winhttp_file->url.lpszUserName, ((gsize) winhttp_file->url.dwUserNameLength + 1) * 2);
+ child->url.lpszPassword = g_memdup2 (winhttp_file->url.lpszPassword, ((gsize) winhttp_file->url.dwPasswordLength + 1) * 2);
child->url.lpszUrlPath = wnew_path;
child->url.dwUrlPathLength = wcslen (wnew_path);
child->url.lpszExtraInfo = NULL;
diff --git a/glib/garray.c b/glib/garray.c
index a6cbd57bb..b00033a57 100644
--- a/glib/garray.c
+++ b/glib/garray.c
@@ -1755,6 +1755,10 @@ g_byte_array_new (void)
* Create byte array containing the data. The data will be owned by the array
* and will be freed with g_free(), i.e. it could be allocated using g_strdup().
*
+ * Do not use it if @len is greater than %G_MAXUINT. #GByteArray
+ * stores the length of its data in #guint, which may be shorter than
+ * #gsize.
+ *
* Since: 2.32
*
* Returns: (transfer full): a new #GByteArray
@@ -1766,6 +1770,8 @@ g_byte_array_new_take (guint8 *data,
GByteArray *array;
GRealArray *real;
+ g_return_val_if_fail (len <= G_MAXUINT, NULL);
+
array = g_byte_array_new ();
real = (GRealArray *)array;
g_assert (real->data == NULL);
diff --git a/glib/gbytes.c b/glib/gbytes.c
index 7b72886e5..dee494820 100644
--- a/glib/gbytes.c
+++ b/glib/gbytes.c
@@ -34,6 +34,8 @@
#include <string.h>
+#include "gstrfuncsprivate.h"
+
/**
* GBytes:
*
@@ -95,7 +97,7 @@ g_bytes_new (gconstpointer data,
{
g_return_val_if_fail (data != NULL || size == 0, NULL);
- return g_bytes_new_take (g_memdup (data, size), size);
+ return g_bytes_new_take (g_memdup2 (data, size), size);
}
/**
@@ -499,7 +501,7 @@ g_bytes_unref_to_data (GBytes *bytes,
* Copy: Non g_malloc (or compatible) allocator, or static memory,
* so we have to copy, and then unref.
*/
- result = g_memdup (bytes->data, bytes->size);
+ result = g_memdup2 (bytes->data, bytes->size);
*size = bytes->size;
g_bytes_unref (bytes);
}
@@ -519,6 +521,10 @@ g_bytes_unref_to_data (GBytes *bytes,
* g_bytes_new(), g_bytes_new_take() or g_byte_array_free_to_bytes(). In all
* other cases the data is copied.
*
+ * Do not use it if @bytes contains more than %G_MAXUINT
+ * bytes. #GByteArray stores the length of its data in #guint, which
+ * may be shorter than #gsize, that @bytes is using.
+ *
* Returns: (transfer full): a new mutable #GByteArray containing the same byte data
*
* Since: 2.32
diff --git a/glib/gdir.c b/glib/gdir.c
index cb4ad0b2f..9d955d57f 100644
--- a/glib/gdir.c
+++ b/glib/gdir.c
@@ -37,6 +37,7 @@
#include "gconvert.h"
#include "gfileutils.h"
#include "gstrfuncs.h"
+#include "gstrfuncsprivate.h"
#include "gtestutils.h"
#include "glibintl.h"
@@ -113,7 +114,7 @@ g_dir_open_with_errno (const gchar *path,
return NULL;
#endif
- return g_memdup (&dir, sizeof dir);
+ return g_memdup2 (&dir, sizeof dir);
}
/**
diff --git a/glib/ghash.c b/glib/ghash.c
index 433004cf8..e36a7a8ed 100644
--- a/glib/ghash.c
+++ b/glib/ghash.c
@@ -34,6 +34,7 @@
#include "glib-private.h"
#include "gstrfuncs.h"
+#include "gstrfuncsprivate.h"
#include "gatomic.h"
#include "gtestutils.h"
#include "gslice.h"
@@ -967,7 +968,7 @@ g_hash_table_insert_node (GHashTable *hash_table,
* split the table.
*/
if (G_UNLIKELY (hash_table->keys == hash_table->values && hash_table->keys[node_index] != new_value))
- hash_table->values = g_memdup (hash_table->keys, sizeof (gpointer) * hash_table->size);
+ hash_table->values = g_memdup2 (hash_table->keys, sizeof (gpointer) * hash_table->size);
/* Step 3: Actually do the write */
hash_table->values[node_index] = new_value;
diff --git a/glib/gslice.c b/glib/gslice.c
index d1b1fc639..db3331b10 100644
--- a/glib/gslice.c
+++ b/glib/gslice.c
@@ -41,6 +41,7 @@
#include "gmain.h"
#include "gmem.h" /* gslice.h */
#include "gstrfuncs.h"
+#include "gstrfuncsprivate.h"
#include "gutils.h"
#include "gtrashstack.h"
#include "gtestutils.h"
@@ -349,7 +350,7 @@ g_slice_get_config_state (GSliceConfig ckey,
array[i++] = allocator->contention_counters[address];
array[i++] = allocator_get_magazine_threshold (allocator, address);
*n_values = i;
- return g_memdup (array, sizeof (array[0]) * *n_values);
+ return g_memdup2 (array, sizeof (array[0]) * *n_values);
default:
return NULL;
}
diff --git a/glib/gstrfuncsprivate.h b/glib/gstrfuncsprivate.h
new file mode 100644
index 000000000..85c88328a
--- /dev/null
+++ b/glib/gstrfuncsprivate.h
@@ -0,0 +1,55 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <glib.h>
+#include <string.h>
+
+/*
+ * g_memdup2:
+ * @mem: (nullable): the memory to copy.
+ * @byte_size: the number of bytes to copy.
+ *
+ * Allocates @byte_size bytes of memory, and copies @byte_size bytes into it
+ * from @mem. If @mem is %NULL it returns %NULL.
+ *
+ * This replaces g_memdup(), which was prone to integer overflows when
+ * converting the argument from a #gsize to a #guint.
+ *
+ * This static inline version is a backport of the new public API from
+ * GLib 2.68, kept internal to GLib for backport to older stable releases.
+ * See https://gitlab.gnome.org/GNOME/glib/-/issues/2319.
+ *
+ * Returns: (nullable): a pointer to the newly-allocated copy of the memory,
+ * or %NULL if @mem is %NULL.
+ * Since: 2.68
+ */
+static inline gpointer
+g_memdup2 (gconstpointer mem,
+ gsize byte_size)
+{
+ gpointer new_mem;
+
+ if (mem && byte_size != 0)
+ {
+ new_mem = g_malloc (byte_size);
+ memcpy (new_mem, mem, byte_size);
+ }
+ else
+ new_mem = NULL;
+
+ return new_mem;
+}
diff --git a/glib/gtestutils.c b/glib/gtestutils.c
index 7b29c274e..f484fd321 100644
--- a/glib/gtestutils.c
+++ b/glib/gtestutils.c
@@ -49,6 +49,7 @@
#include "gpattern.h"
#include "grand.h"
#include "gstrfuncs.h"
+#include "gstrfuncsprivate.h"
#include "gtimer.h"
#include "gslice.h"
#include "gspawn.h"
@@ -3461,7 +3462,7 @@ g_test_log_extract (GTestLogBuffer *tbuffer)
if (p <= tbuffer->data->str + mlength)
{
g_string_erase (tbuffer->data, 0, mlength);
- tbuffer->msgs = g_slist_prepend (tbuffer->msgs, g_memdup (&msg, sizeof (msg)));
+ tbuffer->msgs = g_slist_prepend (tbuffer->msgs, g_memdup2 (&msg, sizeof (msg)));
return TRUE;
}
diff --git a/glib/gvariant.c b/glib/gvariant.c
index d45b487ad..de35c3edc 100644
--- a/glib/gvariant.c
+++ b/glib/gvariant.c
@@ -33,6 +33,7 @@
#include <string.h>
+#include "gstrfuncsprivate.h"
/**
* SECTION:gvariant
@@ -720,7 +721,7 @@ g_variant_new_variant (GVariant *value)
g_variant_ref_sink (value);
return g_variant_new_from_children (G_VARIANT_TYPE_VARIANT,
- g_memdup (&value, sizeof value),
+ g_memdup2 (&value, sizeof value),
1, g_variant_is_trusted (value));
}
@@ -1224,7 +1225,7 @@ g_variant_new_fixed_array (const GVariantType *element_type,
return NULL;
}
- data = g_memdup (elements, n_elements * element_size);
+ data = g_memdup2 (elements, n_elements * element_size);
value = g_variant_new_from_data (array_type, data,
n_elements * element_size,
FALSE, g_free, data);
@@ -1901,7 +1902,7 @@ g_variant_dup_bytestring (GVariant *value,
if (length)
*length = size;
- return g_memdup (original, size + 1);
+ return g_memdup2 (original, size + 1);
}
/**
diff --git a/glib/gvarianttype.c b/glib/gvarianttype.c
index f64be97f9..59ae6aa44 100644
--- a/glib/gvarianttype.c
+++ b/glib/gvarianttype.c
@@ -28,6 +28,7 @@
#include <string.h>
+#include "gstrfuncsprivate.h"
/**
* SECTION:gvarianttype
@@ -1177,7 +1178,7 @@ g_variant_type_new_tuple (const GVariantType * const *items,
g_assert (offset < sizeof buffer);
buffer[offset++] = ')';
- return (GVariantType *) g_memdup (buffer, offset);
+ return (GVariantType *) g_memdup2 (buffer, offset);
}
/**
diff --git a/glib/meson.build b/glib/meson.build
index 6fc56da7c..dcbd20e34 100644
--- a/glib/meson.build
+++ b/glib/meson.build
@@ -182,6 +182,7 @@ glib_sources = files(
'gslist.c',
'gstdio.c',
'gstrfuncs.c',
+ 'gstrfuncsprivate.h',
'gstring.c',
'gstringchunk.c',
'gtestutils.c',
diff --git a/glib/tests/array-test.c b/glib/tests/array-test.c
index e0a6109eb..faa60610d 100644
--- a/glib/tests/array-test.c
+++ b/glib/tests/array-test.c
@@ -30,6 +30,8 @@
#include <string.h>
#include "glib.h"
+#include "gstrfuncsprivate.h"
+
/* Test data to be passed to any function which calls g_array_new(), providing
* the parameters for that call. Most #GArray tests should be repeated for all
* possible values of #ArrayTestData. */
@@ -1177,7 +1179,7 @@ byte_array_new_take (void)
GByteArray *gbarray;
guint8 *data;
- data = g_memdup ("woooweeewow", 11);
+ data = g_memdup2 ("woooweeewow", 11);
gbarray = g_byte_array_new_take (data, 11);
g_assert (gbarray->data == data);
g_assert_cmpuint (gbarray->len, ==, 11);
diff --git a/glib/tests/bytes.c b/glib/tests/bytes.c
index 5ea5c2b35..9e2638291 100644
--- a/glib/tests/bytes.c
+++ b/glib/tests/bytes.c
@@ -10,12 +10,12 @@
*/
#undef G_DISABLE_ASSERT
-#undef G_LOG_DOMAIN
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "glib.h"
+#include "glib/gstrfuncsprivate.h"
/* Keep in sync with glib/gbytes.c */
struct _GBytes
@@ -334,6 +334,38 @@ test_to_array_transferred (void)
}
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;
@@ -407,7 +439,8 @@ main (int argc, char *argv[])
g_test_add_func ("/bytes/to-data/transfered", 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-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);
diff --git a/glib/tests/gvariant.c b/glib/tests/gvariant.c
index 18800f980..e6ac3241b 100644
--- a/glib/tests/gvariant.c
+++ b/glib/tests/gvariant.c
@@ -17,6 +17,7 @@
#include <string.h>
#include <stdlib.h>
#include <glib.h>
+#include "gstrfuncsprivate.h"
#define BASIC "bynqiuxthdsog?"
#define N_BASIC (G_N_ELEMENTS (BASIC) - 1)
@@ -4779,7 +4780,7 @@ test_normal_checking_tuples (void)
GVariant *variant = NULL;
GVariant *normal_variant = NULL;
- aligned_data = g_memdup (data, size); /* guarantee alignment */
+ aligned_data = g_memdup2 (data, size); /* guarantee alignment */
variant = g_variant_new_from_data (G_VARIANT_TYPE_VARIANT, aligned_data, size,
FALSE, NULL, NULL);
g_assert_nonnull (variant);
@@ -4908,7 +4909,7 @@ test_normal_checking_array_offsets (void)
GVariant *variant = NULL;
GVariant *normal_variant = NULL;
- aligned_data = g_memdup (data, size); /* guarantee alignment */
+ aligned_data = g_memdup2 (data, size); /* guarantee alignment */
variant = g_variant_new_from_data (G_VARIANT_TYPE_VARIANT, aligned_data, size,
FALSE, NULL, NULL);
g_assert_nonnull (variant);
@@ -4935,7 +4936,7 @@ test_normal_checking_tuple_offsets (void)
GVariant *variant = NULL;
GVariant *normal_variant = NULL;
- aligned_data = g_memdup (data, size); /* guarantee alignment */
+ aligned_data = g_memdup2 (data, size); /* guarantee alignment */
variant = g_variant_new_from_data (G_VARIANT_TYPE_VARIANT, aligned_data,
size, FALSE, NULL, NULL);
g_assert_nonnull (variant);
@@ -4962,7 +4963,7 @@ test_normal_checking_empty_object_path (void)
GVariant *variant = NULL;
GVariant *normal_variant = NULL;
- aligned_data = g_memdup (data, size); /* guarantee alignment */
+ aligned_data = g_memdup2 (data, size); /* guarantee alignment */
variant = g_variant_new_from_data (G_VARIANT_TYPE_VARIANT, aligned_data, size,
FALSE, NULL, NULL);
g_assert_nonnull (variant);
diff --git a/glib/tests/option-context.c b/glib/tests/option-context.c
index 34ebfaaf6..7125e2285 100644
--- a/glib/tests/option-context.c
+++ b/glib/tests/option-context.c
@@ -27,6 +27,8 @@
#include <string.h>
#include <locale.h>
+#include "gstrfuncsprivate.h"
+
static GOptionEntry main_entries[] = {
{ "main-switch", 0, 0,
G_OPTION_ARG_NONE, NULL,
@@ -256,7 +258,7 @@ join_stringv (int argc, char **argv)
static char **
copy_stringv (char **argv, int argc)
{
- return g_memdup (argv, sizeof (char *) * (argc + 1));
+ return g_memdup2 (argv, sizeof (char *) * (argc + 1));
}
static void
@@ -2318,7 +2320,7 @@ test_group_parse (void)
g_option_context_add_group (context, group);
argv = split_string ("program --test arg1 -f arg2 --group-test arg3 --frob arg4 -z arg5", &argc);
- orig_argv = g_memdup (argv, (argc + 1) * sizeof (char *));
+ orig_argv = g_memdup2 (argv, (argc + 1) * sizeof (char *));
retval = g_option_context_parse (context, &argc, &argv, &error);
diff --git a/glib/tests/strfuncs.c b/glib/tests/strfuncs.c
index d974ad436..1111226de 100644
--- a/glib/tests/strfuncs.c
+++ b/glib/tests/strfuncs.c
@@ -32,6 +32,8 @@
#include <string.h>
#include "glib.h"
+#include "gstrfuncsprivate.h"
+
#if defined (_MSC_VER) && (_MSC_VER <= 1800)
#define isnan(x) _isnan(x)
@@ -199,6 +201,26 @@ test_is_to_digit (void)
#undef TEST_DIGIT
}
+/* Testing g_memdup2() function with various positive and negative cases */
+static void
+test_memdup2 (void)
+{
+ gchar *str_dup = NULL;
+ const gchar *str = "The quick brown fox jumps over the lazy dog";
+
+ /* Testing negative cases */
+ g_assert_null (g_memdup2 (NULL, 1024));
+ g_assert_null (g_memdup2 (str, 0));
+ g_assert_null (g_memdup2 (NULL, 0));
+
+ /* Testing normal usage cases */
+ str_dup = g_memdup2 (str, strlen (str) + 1);
+ g_assert_nonnull (str_dup);
+ g_assert_cmpstr (str, ==, str_dup);
+
+ g_free (str_dup);
+}
+
static void
test_strdup (void)
{
@@ -1731,6 +1753,7 @@ main (int argc,
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/strfuncs/test-is-to-digit", test_is_to_digit);
+ g_test_add_func ("/strfuncs/memdup2", test_memdup2);
g_test_add_func ("/strfuncs/strdup", test_strdup);
g_test_add_func ("/strfuncs/strndup", test_strndup);
g_test_add_func ("/strfuncs/strdup-printf", test_strdup_printf);
diff --git a/gobject/gsignal.c b/gobject/gsignal.c
index 76f1dc93c..4296eb290 100644
--- a/gobject/gsignal.c
+++ b/gobject/gsignal.c
@@ -28,6 +28,7 @@
#include <signal.h>
#include "gsignal.h"
+#include "gstrfuncsprivate.h"
#include "gtype-private.h"
#include "gbsearcharray.h"
#include "gvaluecollector.h"
@@ -1724,7 +1725,7 @@ g_signal_newv (const gchar *signal_name,
node->single_va_closure_is_valid = FALSE;
node->flags = signal_flags & G_SIGNAL_FLAGS_MASK;
node->n_params = n_params;
- node->param_types = g_memdup (param_types, sizeof (GType) * n_params);
+ node->param_types = g_memdup2 (param_types, sizeof (GType) * n_params);
node->return_type = return_type;
node->class_closure_bsa = NULL;
if (accumulator)
diff --git a/gobject/gtype.c b/gobject/gtype.c
index 1acc0a075..bee83bdf5 100644
--- a/gobject/gtype.c
+++ b/gobject/gtype.c
@@ -33,6 +33,7 @@
#include "glib-private.h"
#include "gconstructor.h"
+#include "gstrfuncsprivate.h"
#ifdef G_OS_WIN32
#include <windows.h>
@@ -1467,7 +1468,7 @@ type_add_interface_Wm (TypeNode *node,
iholder->next = iface_node_get_holders_L (iface);
iface_node_set_holders_W (iface, iholder);
iholder->instance_type = NODE_TYPE (node);
- iholder->info = info ? g_memdup (info, sizeof (*info)) : NULL;
+ iholder->info = info ? g_memdup2 (info, sizeof (*info)) : NULL;
iholder->plugin = plugin;
/* create an iface entry for this type */
@@ -1728,7 +1729,7 @@ type_iface_retrieve_holder_info_Wm (TypeNode *iface,
INVALID_RECURSION ("g_type_plugin_*", iholder->plugin, NODE_NAME (iface));
check_interface_info_I (iface, instance_type, &tmp_info);
- iholder->info = g_memdup (&tmp_info, sizeof (tmp_info));
+ iholder->info = g_memdup2 (&tmp_info, sizeof (tmp_info));
}
return iholder; /* we don't modify write lock upon returning NULL */
@@ -2013,10 +2014,10 @@ type_iface_vtable_base_init_Wm (TypeNode *iface,
IFaceEntry *pentry = type_lookup_iface_entry_L (pnode, iface);
if (pentry)
- vtable = g_memdup (pentry->vtable, iface->data->iface.vtable_size);
+ vtable = g_memdup2 (pentry->vtable, iface->data->iface.vtable_size);
}
if (!vtable)
- vtable = g_memdup (iface->data->iface.dflt_vtable, iface->data->iface.vtable_size);
+ vtable = g_memdup2 (iface->data->iface.dflt_vtable, iface->data->iface.vtable_size);
entry->vtable = vtable;
vtable->g_type = NODE_TYPE (iface);
vtable->g_instance_type = NODE_TYPE (node);
diff --git a/gobject/gtypemodule.c b/gobject/gtypemodule.c
index 4ecaf8c88..20911fafd 100644
--- a/gobject/gtypemodule.c
+++ b/gobject/gtypemodule.c
@@ -19,6 +19,7 @@
#include <stdlib.h>
+#include "gstrfuncsprivate.h"
#include "gtypeplugin.h"
#include "gtypemodule.h"
@@ -436,7 +437,7 @@ g_type_module_register_type (GTypeModule *module,
module_type_info->loaded = TRUE;
module_type_info->info = *type_info;
if (type_info->value_table)
- module_type_info->info.value_table = g_memdup (type_info->value_table,
+ module_type_info->info.value_table = g_memdup2 (type_info->value_table,
sizeof (GTypeValueTable));
return module_type_info->type;
diff --git a/gobject/tests/param.c b/gobject/tests/param.c
index 758289bf8..971cff162 100644
--- a/gobject/tests/param.c
+++ b/gobject/tests/param.c
@@ -2,6 +2,8 @@
#include <glib-object.h>
#include <stdlib.h>
+#include "gstrfuncsprivate.h"
+
static void
test_param_value (void)
{
@@ -851,7 +853,7 @@ main (int argc, char *argv[])
test_path = g_strdup_printf ("/param/implement/subprocess/%d-%d-%d-%d",
data.change_this_flag, data.change_this_type,
data.use_this_flag, data.use_this_type);
- test_data = g_memdup (&data, sizeof (TestParamImplementData));
+ test_data = g_memdup2 (&data, sizeof (TestParamImplementData));
g_test_add_data_func_full (test_path, test_data, test_param_implement_child, g_free);
g_free (test_path);
}