[gjs: 1/3] util: Add backported version of g_memdup2()




commit 686a9c89ddb4d660cc84b3c7015ddc290357e682
Author: Philip Chimento <philip chimento gmail com>
Date:   Fri Feb 12 22:23:21 2021 -0800

    util: Add backported version of g_memdup2()
    
    As per
    https://mail.gnome.org/archives/desktop-devel-list/2021-February/msg00000.html
    replace all use of g_memdup() inside GJS so that we don't use this
    bug-prone API that takes a 32-bit int for the size.
    
    Since we have a policy of depending on at most the previous stable version
    of GLib, we copy the g_memdup2() from the GLib backport as _gjs_memdup2(),
    and it can be replaced with g_memdup2() later when we have to depend on
    GLib 2.68 for something else.
    
    Closes: #375

 gjs/byteArray.cpp         |  5 +++--
 gjs/jsapi-util-string.cpp |  4 +++-
 util/misc.h               | 33 +++++++++++++++++++++++++++++++++
 3 files changed, 39 insertions(+), 3 deletions(-)
---
diff --git a/gjs/byteArray.cpp b/gjs/byteArray.cpp
index b1d27241..4fe361d1 100644
--- a/gjs/byteArray.cpp
+++ b/gjs/byteArray.cpp
@@ -28,6 +28,7 @@
 #include "gjs/deprecation.h"
 #include "gjs/jsapi-util-args.h"
 #include "gjs/jsapi-util.h"
+#include "util/misc.h"  // for _gjs_memdup2
 
 /* Callbacks to use with JS::NewExternalArrayBuffer() */
 
@@ -357,8 +358,8 @@ JSObject* gjs_byte_array_from_data(JSContext* cx, size_t nbytes, void* data) {
     JS::RootedObject array_buffer(cx);
     // a null data pointer takes precedence over whatever `nbytes` says
     if (data)
-        array_buffer =
-            JS::NewArrayBufferWithContents(cx, nbytes, g_memdup(data, nbytes));
+        array_buffer = JS::NewArrayBufferWithContents(
+            cx, nbytes, _gjs_memdup2(data, nbytes));
     else
         array_buffer = JS::NewArrayBuffer(cx, 0);
     if (!array_buffer)
diff --git a/gjs/jsapi-util-string.cpp b/gjs/jsapi-util-string.cpp
index 41fb7ef3..9d7d0a61 100644
--- a/gjs/jsapi-util-string.cpp
+++ b/gjs/jsapi-util-string.cpp
@@ -32,6 +32,7 @@
 
 #include "gjs/jsapi-util.h"
 #include "gjs/macros.h"
+#include "util/misc.h"  // for _gjs_memdup2
 
 // Avoid static_assert in MSVC builds
 namespace JS {
@@ -204,7 +205,8 @@ gjs_string_get_char16_data(JSContext       *context,
     if (js_data == NULL)
         return false;
 
-    *data_p = (char16_t *) g_memdup(js_data, sizeof(*js_data) * (*len_p));
+    *data_p = static_cast<char16_t*>(
+        _gjs_memdup2(js_data, sizeof(*js_data) * (*len_p)));
 
     return true;
 }
diff --git a/util/misc.h b/util/misc.h
index ca64d81c..b9b5b284 100644
--- a/util/misc.h
+++ b/util/misc.h
@@ -5,8 +5,41 @@
 #ifndef UTIL_MISC_H_
 #define UTIL_MISC_H_
 
+#include <stdlib.h>  // for size_t
+#include <string.h>  // for memcpy
+
+#include <glib.h>  // for g_malloc
+
 bool    gjs_environment_variable_is_set   (const char *env_variable_name);
 
 char** gjs_g_strv_concat(char*** strv_array, int len);
 
+/*
+ * _gjs_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 or @byte_size is 0 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 g_memdup2() API
+ * from GLib 2.68.
+ * See https://gitlab.gnome.org/GNOME/glib/-/merge_requests/1927.
+ * It should be replaced when GLib 2.68 becomes the stable branch.
+ *
+ * Returns: (nullable): a pointer to the newly-allocated copy of the memory,
+ *    or null if @mem is null.
+ */
+static inline void* _gjs_memdup2(const void* mem, size_t byte_size) {
+    if (!mem || byte_size == 0)
+        return nullptr;
+
+    void* new_mem = g_malloc(byte_size);
+    memcpy(new_mem, mem, byte_size);
+    return new_mem;
+}
+
 #endif  // UTIL_MISC_H_


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]