[gjs/gnome-3-34] arg: Allow empty flat arrays of structs
- From: Philip Chimento <pchimento src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs/gnome-3-34] arg: Allow empty flat arrays of structs
- Date: Mon, 25 Nov 2019 18:07:08 +0000 (UTC)
commit 3b56f18af68ad176bd2a30d25b5ca89a569beeda
Author: Philip Chimento <philip chimento gmail com>
Date: Mon Nov 25 09:53:20 2019 -0800
arg: Allow empty flat arrays of structs
We should be able to pass null or [] to a parameter expecting a flat
array of structs even if passing anything else would crash. This case
was inadvertently broken when we prevented the crash as part of #44.
Closes: #289
gi/arg.cpp | 43 +++++++++++++++++++++++++--------
installed-tests/js/testIntrospection.js | 19 +++++++++++++++
2 files changed, 52 insertions(+), 10 deletions(-)
---
diff --git a/gi/arg.cpp b/gi/arg.cpp
index 3e6aae5c..f1bb87b4 100644
--- a/gi/arg.cpp
+++ b/gi/arg.cpp
@@ -1052,14 +1052,32 @@ is_gvalue_flat_array(GITypeInfo *param_info,
}
GJS_JSAPI_RETURN_CONVENTION
-static bool
-gjs_array_to_array(JSContext *context,
- JS::Value array_value,
- gsize length,
- GITransfer transfer,
- GITypeInfo *param_info,
- void **arr_p)
-{
+static bool is_empty(JSContext* cx, JS::HandleValue array_value, bool* empty) {
+ if (array_value.isNull()) {
+ *empty = true;
+ return true;
+ }
+
+ bool is_array;
+ if (!JS_IsArrayObject(cx, array_value, &is_array))
+ return false;
+ if (!is_array) {
+ *empty = false;
+ return true;
+ }
+
+ JS::RootedObject array_object(cx, &array_value.toObject());
+ uint32_t length;
+ if (!JS_GetArrayLength(cx, array_object, &length))
+ return false;
+ *empty = (length == 0);
+ return true;
+}
+
+GJS_JSAPI_RETURN_CONVENTION
+static bool gjs_array_to_array(JSContext* context, JS::HandleValue array_value,
+ size_t length, GITransfer transfer,
+ GITypeInfo* param_info, void** arr_p) {
enum { UNSIGNED=false, SIGNED=true };
GITypeTag element_type;
@@ -1127,8 +1145,13 @@ gjs_array_to_array(JSContext *context,
GjsAutoBaseInfo interface_info =
g_type_info_get_interface(param_info);
GIInfoType info_type = g_base_info_get_type(interface_info);
- if (info_type == GI_INFO_TYPE_STRUCT ||
- info_type == GI_INFO_TYPE_UNION) {
+
+ bool array_is_empty;
+ if (!is_empty(context, array_value, &array_is_empty))
+ return false;
+
+ if (!array_is_empty && (info_type == GI_INFO_TYPE_STRUCT ||
+ info_type == GI_INFO_TYPE_UNION)) {
gjs_throw(context,
"Flat array of type %s is not currently supported",
interface_info.name());
diff --git a/installed-tests/js/testIntrospection.js b/installed-tests/js/testIntrospection.js
index 814beb27..f81751b0 100644
--- a/installed-tests/js/testIntrospection.js
+++ b/installed-tests/js/testIntrospection.js
@@ -28,6 +28,25 @@ describe('Unsafe integer marshalling', function () {
});
});
+describe('Marshalling empty flat arrays of structs', function () {
+ let widget;
+ beforeAll(function () {
+ Gtk.init(null);
+ });
+
+ beforeEach(function () {
+ widget = new Gtk.Label();
+ });
+
+ it('accepts null', function () {
+ widget.drag_dest_set(0, null, Gdk.DragAction.COPY);
+ });
+
+ it('accepts an empty array', function () {
+ widget.drag_dest_set(0, [], Gdk.DragAction.COPY);
+ });
+});
+
describe('Constructor', function () {
it('throws when constructor called without new', function () {
expect(() => Gio.AppLaunchContext())
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]