[gjs: 4/16] js: Fix missing error checks



commit 5aa46c2ef4e8c26864d33b4a042cf9c021a7099a
Author: Philip Chimento <philip chimento gmail com>
Date:   Sun Oct 28 15:57:31 2018 -0400

    js: Fix missing error checks
    
    These fixes were caught by the compiler warnings added in the subsequent
    annotations commit. They are placed here in a separate commit for ease
    of review.

 gi/arg.cpp                 | 14 +++++---------
 gi/boxed.cpp               | 26 ++++++++++++++++----------
 gi/enumeration.cpp         | 17 +++++++++--------
 gi/function.cpp            | 16 +++++++---------
 gi/fundamental.cpp         |  8 ++++++--
 gi/gerror.cpp              | 26 ++++++++++----------------
 gi/interface.cpp           | 26 +++++++++++++++-----------
 gi/object.cpp              |  7 ++++++-
 gi/private.cpp             | 10 ++++++----
 gi/repo.cpp                |  8 ++++----
 gi/union.cpp               | 18 ++++++++++--------
 gjs/context.cpp            | 12 ++++++++++--
 gjs/jsapi-class.h          |  4 ++--
 test/gjs-test-coverage.cpp |  7 +++----
 test/gjs-tests.cpp         |  3 ++-
 15 files changed, 111 insertions(+), 91 deletions(-)
---
diff --git a/gi/arg.cpp b/gi/arg.cpp
index be1237d0..cb282ff5 100644
--- a/gi/arg.cpp
+++ b/gi/arg.cpp
@@ -3445,11 +3445,9 @@ gjs_g_arg_release_internal(JSContext  *context,
                         GArgument arg_iter;
 
                         arg_iter.v_pointer = g_array_index (array, gpointer, i);
-                        gjs_g_arg_release_internal(context,
-                                                   transfer,
-                                                   param_info,
-                                                   element_type,
-                                                   &arg_iter);
+                        failed = !gjs_g_arg_release_internal(
+                            context, transfer, param_info, element_type,
+                            &arg_iter);
                     }
 
                     g_array_free (array, true);
@@ -3482,10 +3480,8 @@ gjs_g_arg_release_internal(JSContext  *context,
                     GArgument arg_iter;
 
                     arg_iter.v_pointer = g_ptr_array_index (array, i);
-                    gjs_g_argument_release(context,
-                                           transfer,
-                                           param_info,
-                                           &arg_iter);
+                    failed = !gjs_g_argument_release(context, transfer,
+                                                     param_info, &arg_iter);
                 }
             }
 
diff --git a/gi/boxed.cpp b/gi/boxed.cpp
index c430c877..30851291 100644
--- a/gi/boxed.cpp
+++ b/gi/boxed.cpp
@@ -89,10 +89,9 @@ gjs_define_static_methods(JSContext       *context,
     n_methods = g_struct_info_get_n_methods(boxed_info);
 
     for (i = 0; i < n_methods; i++) {
-        GIFunctionInfo *meth_info;
         GIFunctionInfoFlags flags;
 
-        meth_info = g_struct_info_get_method (boxed_info, i);
+        GjsAutoFunctionInfo meth_info = g_struct_info_get_method(boxed_info, i);
         flags = g_function_info_get_flags (meth_info);
 
         /* Anything that isn't a method we put on the prototype of the
@@ -103,11 +102,9 @@ gjs_define_static_methods(JSContext       *context,
          * like in the near future.
          */
         if (!(flags & GI_FUNCTION_IS_METHOD)) {
-            gjs_define_function(context, constructor, gtype,
-                                (GICallableInfo *)meth_info);
+            if (!gjs_define_function(context, constructor, gtype, meth_info))
+                return false;
         }
-
-        g_base_info_unref((GIBaseInfo*) meth_info);
     }
     return true;
 }
@@ -562,6 +559,8 @@ get_nested_interface_object(JSContext             *context,
     JS::RootedObject proto(context,
                            gjs_lookup_generic_prototype(context,
                                                         (GIBoxedInfo*) interface_info));
+    if (!proto)
+        return false;
     proto_priv = priv_from_js(context, proto);
 
     offset = g_field_info_get_offset (field_info);
@@ -682,6 +681,8 @@ set_nested_interface_object (JSContext      *context,
     JS::RootedObject proto(context,
                            gjs_lookup_generic_prototype(context,
                                                         (GIBoxedInfo*) interface_info));
+    if (!proto)
+        return false;
     proto_priv = priv_from_js(context, proto);
 
     /* If we can't directly copy from the source object we need
@@ -762,10 +763,13 @@ boxed_set_field_from_value(JSContext      *context,
     success = true;
 
 out:
-    if (need_release)
-        gjs_g_argument_release (context, GI_TRANSFER_NOTHING,
-                                type_info,
-                                &arg);
+    if (need_release) {
+        JS::AutoSaveExceptionState saved_exc(context);
+        if (!gjs_g_argument_release(context, GI_TRANSFER_NOTHING, type_info,
+                                    &arg))
+            gjs_log_exception(context);
+        saved_exc.restore();
+    }
 
     g_base_info_unref ((GIBaseInfo *)type_info);
 
@@ -1173,6 +1177,8 @@ gjs_boxed_from_c_struct(JSContext             *context,
                       g_base_info_get_name((GIBaseInfo *)info), gboxed);
 
     JS::RootedObject proto(context, gjs_lookup_generic_prototype(context, info));
+    if (!proto)
+        return nullptr;
     proto_priv = priv_from_js(context, proto);
 
     obj = JS_NewObjectWithGivenProto(context, JS_GetClass(proto), proto);
diff --git a/gi/enumeration.cpp b/gi/enumeration.cpp
index 9f6c91f9..ade2295b 100644
--- a/gi/enumeration.cpp
+++ b/gi/enumeration.cpp
@@ -106,6 +106,9 @@ gjs_define_enum_values(JSContext       *context,
     gtype = g_registered_type_info_get_g_type((GIRegisteredTypeInfo*)info);
     JS::RootedObject gtype_obj(context,
         gjs_gtype_create_gtype_wrapper(context, gtype));
+    if (!gtype_obj)
+        return false;
+
     JS_DefineProperty(context, in_object, "$gtype", gtype_obj, JSPROP_PERMANENT);
 
     return true;
@@ -121,10 +124,9 @@ gjs_define_enum_static_methods(JSContext       *context,
     n_methods = g_enum_info_get_n_methods(enum_info);
 
     for (i = 0; i < n_methods; i++) {
-        GIFunctionInfo *meth_info;
         GIFunctionInfoFlags flags;
 
-        meth_info = g_enum_info_get_method(enum_info, i);
+        GjsAutoFunctionInfo meth_info = g_enum_info_get_method(enum_info, i);
         flags = g_function_info_get_flags(meth_info);
 
         g_warn_if_fail(!(flags & GI_FUNCTION_IS_METHOD));
@@ -136,11 +138,10 @@ gjs_define_enum_static_methods(JSContext       *context,
          * like in the near future.
          */
         if (!(flags & GI_FUNCTION_IS_METHOD)) {
-            gjs_define_function(context, constructor, G_TYPE_NONE,
-                                (GICallableInfo *)meth_info);
+            if (!gjs_define_function(context, constructor, G_TYPE_NONE,
+                                     meth_info))
+                return false;
         }
-
-        g_base_info_unref((GIBaseInfo*) meth_info);
     }
 
     return true;
@@ -171,9 +172,9 @@ gjs_define_enumeration(JSContext       *context,
                 enum_name);
     }
 
-    if (!gjs_define_enum_values(context, enum_obj, info))
+    if (!gjs_define_enum_values(context, enum_obj, info) ||
+        !gjs_define_enum_static_methods(context, enum_obj, info))
         return false;
-    gjs_define_enum_static_methods (context, enum_obj, info);
 
     gjs_debug(GJS_DEBUG_GENUM,
               "Defining %s.%s as %p",
diff --git a/gi/function.cpp b/gi/function.cpp
index 0491187b..49f14eef 100644
--- a/gi/function.cpp
+++ b/gi/function.cpp
@@ -1303,16 +1303,14 @@ release:
             transfer = g_arg_info_get_ownership_transfer(&arg_info);
             if (!arg_failed) {
                 if (array_length_pos >= 0) {
-                    gjs_g_argument_release_out_array(context,
-                                                     transfer,
-                                                     &arg_type_info,
-                                                     array_length.toInt32(),
-                                                     arg);
+                    if (!gjs_g_argument_release_out_array(
+                            context, transfer, &arg_type_info,
+                            array_length.toInt32(), arg))
+                        postinvoke_release_failed = true;
                 } else {
-                    gjs_g_argument_release(context,
-                                           transfer,
-                                           &arg_type_info,
-                                           arg);
+                    if (!gjs_g_argument_release(context, transfer,
+                                                &arg_type_info, arg))
+                        postinvoke_release_failed = true;
                 }
             }
 
diff --git a/gi/fundamental.cpp b/gi/fundamental.cpp
index 6769b188..c661d0d0 100644
--- a/gi/fundamental.cpp
+++ b/gi/fundamental.cpp
@@ -573,8 +573,9 @@ gjs_lookup_fundamental_prototype(JSContext    *context,
            we need to define it first.
         */
         JS::RootedObject ignored(context);
-        gjs_define_fundamental_class(context, in_object, info, &constructor,
-                                     &ignored);
+        if (!gjs_define_fundamental_class(context, in_object, info,
+                                          &constructor, &ignored))
+            return nullptr;
     } else {
         if (G_UNLIKELY (!value.isObject()))
             return NULL;
@@ -701,6 +702,9 @@ gjs_define_fundamental_class(JSContext              *context,
 
     JS::RootedObject gtype_obj(context,
         gjs_gtype_create_gtype_wrapper(context, gtype));
+    if (!gtype_obj)
+        return false;
+
     return JS_DefineProperty(context, constructor, "$gtype", gtype_obj,
                              JSPROP_PERMANENT);
 }
diff --git a/gi/gerror.cpp b/gi/gerror.cpp
index 28ac547f..5fadd83c 100644
--- a/gi/gerror.cpp
+++ b/gi/gerror.cpp
@@ -325,22 +325,16 @@ gjs_define_error_class(JSContext       *context,
         gjs_lookup_generic_prototype(context, glib_error_info));
     g_base_info_unref((GIBaseInfo*)glib_error_info);
 
-    if (!gjs_init_class_dynamic(context, in_object,
-                                parent_proto,
-                                g_base_info_get_namespace( (GIBaseInfo*) info),
-                                constructor_name,
-                                &gjs_error_class,
-                                gjs_error_constructor, 1,
-                                /* props of prototype */
-                                &gjs_error_proto_props[0],
-                                /* funcs of prototype */
-                                &gjs_error_proto_funcs[0],
-                                /* props of constructor, MyConstructor.myprop */
-                                NULL,
-                                /* funcs of constructor, MyConstructor.myfunc() */
-                                &gjs_error_constructor_funcs[0],
-                                &prototype,
-                                &constructor)) {
+    if (!parent_proto ||
+        !gjs_init_class_dynamic(
+            context, in_object, parent_proto, g_base_info_get_namespace(info),
+            constructor_name, &gjs_error_class, gjs_error_constructor, 1,
+            gjs_error_proto_props,  // props of prototype
+            gjs_error_proto_funcs,  // funcs of prototype
+            nullptr,  // props of constructor, MyConstructor.myprop
+            gjs_error_constructor_funcs,  // funcs of constructor,
+                                          // MyConstructor.myfunc()
+            &prototype, &constructor)) {
         gjs_log_exception(context);
         g_error("Can't init class %s", constructor_name);
     }
diff --git a/gi/interface.cpp b/gi/interface.cpp
index ac7467da..266689bf 100644
--- a/gi/interface.cpp
+++ b/gi/interface.cpp
@@ -83,10 +83,9 @@ gjs_define_static_methods(JSContext       *context,
     n_methods = g_interface_info_get_n_methods(info);
 
     for (i = 0; i < n_methods; i++) {
-        GIFunctionInfo *meth_info;
         GIFunctionInfoFlags flags;
 
-        meth_info = g_interface_info_get_method (info, i);
+        GjsAutoFunctionInfo meth_info = g_interface_info_get_method(info, i);
         flags = g_function_info_get_flags (meth_info);
 
         /* Anything that isn't a method we put on the prototype of the
@@ -97,11 +96,9 @@ gjs_define_static_methods(JSContext       *context,
          * like in the near future.
          */
         if (!(flags & GI_FUNCTION_IS_METHOD)) {
-            gjs_define_function(context, constructor, gtype,
-                                (GICallableInfo *)meth_info);
+            if (!gjs_define_function(context, constructor, gtype, meth_info))
+                return false;
         }
-
-        g_base_info_unref((GIBaseInfo*) meth_info);
     }
     return true;
 }
@@ -162,9 +159,10 @@ interface_has_instance_func(JSContext *cx,
     g_assert(interface.isObject());
     JS::RootedObject interface_constructor(cx, &interface.toObject());
     JS::RootedObject interface_proto(cx);
-    gjs_object_require_property(cx, interface_constructor,
-                                "interface constructor",
-                                GJS_STRING_PROTOTYPE, &interface_proto);
+    if (!gjs_object_require_property(cx, interface_constructor,
+                                     "interface constructor",
+                                     GJS_STRING_PROTOTYPE, &interface_proto))
+        return false;
 
     Interface *priv;
     if (!priv_from_js_with_typecheck(cx, interface_proto, &priv))
@@ -247,11 +245,17 @@ gjs_define_interface_class(JSContext              *context,
 
     /* If we have no GIRepository information, then this interface was defined
      * from within GJS and therefore has no C static methods to be defined. */
-    if (priv->info)
-        gjs_define_static_methods(context, constructor, priv->gtype, priv->info);
+    if (priv->info) {
+        if (!gjs_define_static_methods(context, constructor, priv->gtype,
+                                       priv->info))
+            return false;
+    }
 
     JS::RootedObject gtype_obj(context,
         gjs_gtype_create_gtype_wrapper(context, priv->gtype));
+    if (!gtype_obj)
+        return false;
+
     JS_DefineProperty(context, constructor, "$gtype", gtype_obj, JSPROP_PERMANENT);
 
     return true;
diff --git a/gi/object.cpp b/gi/object.cpp
index 8265cd2e..530561d5 100644
--- a/gi/object.cpp
+++ b/gi/object.cpp
@@ -875,7 +875,9 @@ bool ObjectPrototype::resolve_impl(JSContext* context, JS::HandleObject obj,
                 return true;
             }
 
-            gjs_define_function(context, obj, m_gtype, vfunc);
+            if (!gjs_define_function(context, obj, m_gtype, vfunc))
+                return false;
+
             *resolved = true;
             return true;
         }
@@ -2240,6 +2242,9 @@ gjs_define_object_class(JSContext              *context,
 
     JS::RootedObject gtype_obj(context,
         gjs_gtype_create_gtype_wrapper(context, gtype));
+    if (!gtype_obj)
+        return false;
+
     return JS_DefineProperty(context, constructor, "$gtype", gtype_obj,
                              JSPROP_PERMANENT);
 }
diff --git a/gi/private.cpp b/gi/private.cpp
index 097b8a6f..64bacbf5 100644
--- a/gi/private.cpp
+++ b/gi/private.cpp
@@ -220,8 +220,9 @@ static bool gjs_register_interface(JSContext* cx, unsigned argc,
         return false;  // error will have been thrown already
 
     JS::RootedObject constructor(cx);
-    gjs_define_interface_class(cx, module, nullptr, interface_type,
-                               &constructor);
+    if (!gjs_define_interface_class(cx, module, nullptr, interface_type,
+                                    &constructor))
+        return false;
 
     args.rval().setObject(*constructor);
     return true;
@@ -302,8 +303,9 @@ static bool gjs_register_type(JSContext* cx, unsigned argc, JS::Value* vp) {
     /* create a custom JSClass */
     JS::RootedObject module(cx, gjs_lookup_private_namespace(cx));
     JS::RootedObject constructor(cx), prototype(cx);
-    gjs_define_object_class(cx, module, nullptr, instance_type, &constructor,
-                            &prototype);
+    if (!gjs_define_object_class(cx, module, nullptr, instance_type,
+                                 &constructor, &prototype))
+        return false;
 
     auto* priv = ObjectPrototype::for_js(cx, prototype);
     priv->set_type_qdata();
diff --git a/gi/repo.cpp b/gi/repo.cpp
index 495c327c..2a3d110a 100644
--- a/gi/repo.cpp
+++ b/gi/repo.cpp
@@ -479,10 +479,10 @@ gjs_define_info(JSContext       *context,
     case GI_INFO_TYPE_INTERFACE:
         {
             JS::RootedObject ignored(context);
-            gjs_define_interface_class(context, in_object,
-                                       (GIInterfaceInfo *) info,
-                                       g_registered_type_info_get_g_type((GIRegisteredTypeInfo *) info),
-                                       &ignored);
+            if (!gjs_define_interface_class(
+                    context, in_object, info,
+                    g_registered_type_info_get_g_type(info), &ignored))
+                return false;
         }
         break;
     case GI_INFO_TYPE_INVALID:
diff --git a/gi/union.cpp b/gi/union.cpp
index 853c908a..13f1a80e 100644
--- a/gi/union.cpp
+++ b/gi/union.cpp
@@ -130,10 +130,9 @@ union_new(JSContext       *context,
     n_methods = g_union_info_get_n_methods(info);
 
     for (i = 0; i < n_methods; ++i) {
-        GIFunctionInfo *func_info;
         GIFunctionInfoFlags flags;
 
-        func_info = g_union_info_get_method(info, i);
+        GjsAutoFunctionInfo func_info = g_union_info_get_method(info, i);
 
         flags = g_function_info_get_flags(func_info);
         if ((flags & GI_FUNCTION_IS_CONSTRUCTOR) != 0 &&
@@ -141,10 +140,10 @@ union_new(JSContext       *context,
 
             JS::RootedValue rval(context, JS::NullValue());
 
-            gjs_invoke_c_function_uncached(context, func_info, obj,
-                                           JS::HandleValueArray::empty(), &rval);
-
-            g_base_info_unref((GIBaseInfo*) func_info);
+            if (!gjs_invoke_c_function_uncached(context, func_info, obj,
+                                                JS::HandleValueArray::empty(),
+                                                &rval))
+                return nullptr;
 
             /* We are somewhat wasteful here; invoke_c_function() above
              * creates a JSObject wrapper for the union that we immediately
@@ -157,8 +156,6 @@ union_new(JSContext       *context,
                 return gjs_c_union_from_union(context, rval_obj);
             }
         }
-
-        g_base_info_unref((GIBaseInfo*) func_info);
     }
 
     gjs_throw(context, "Unable to construct union type %s since it has no zero-args <constructor>, can only 
wrap an existing one",
@@ -355,6 +352,9 @@ gjs_define_union_class(JSContext       *context,
 
     JS::RootedObject gtype_obj(context,
         gjs_gtype_create_gtype_wrapper(context, gtype));
+    if (!gtype_obj)
+        return false;
+
     JS_DefineProperty(context, constructor, "$gtype", gtype_obj, JSPROP_PERMANENT);
 
     return true;
@@ -387,6 +387,8 @@ gjs_union_from_c_union(JSContext    *context,
 
     JS::RootedObject proto(context,
         gjs_lookup_generic_prototype(context, (GIUnionInfo*) info));
+    if (!proto)
+        return nullptr;
 
     obj = JS_NewObjectWithGivenProto(context, JS_GetClass(proto), proto);
 
diff --git a/gjs/context.cpp b/gjs/context.cpp
index 1af42788..df6c487e 100644
--- a/gjs/context.cpp
+++ b/gjs/context.cpp
@@ -702,7 +702,11 @@ static gboolean
 drain_job_queue_idle_handler(void *data)
 {
     auto gjs_context = static_cast<GjsContext *>(data);
-    _gjs_context_run_jobs(gjs_context);
+    if (!_gjs_context_run_jobs(gjs_context)) {
+        auto* cx = static_cast<JSContext*>(
+            gjs_context_get_native_context(gjs_context));
+        gjs_log_exception(cx);
+    }
     /* Uncatchable exceptions are swallowed here - no way to get a handle on
      * the main loop to exit it from this idle handler */
     g_assert(((void) "_gjs_context_run_jobs() should have emptied queue",
@@ -720,8 +724,12 @@ _gjs_context_enqueue_job(GjsContext      *gjs_context,
     else
         g_assert(gjs_context->job_queue->length() == 0);
 
-    if (!gjs_context->job_queue->append(job))
+    if (!gjs_context->job_queue->append(job)) {
+        auto* cx = static_cast<JSContext*>(
+            gjs_context_get_native_context(gjs_context));
+        JS_ReportOutOfMemory(cx);
         return false;
+    }
     if (!gjs_context->idle_drain_handler)
         gjs_context->idle_drain_handler =
             g_idle_add_full(G_PRIORITY_DEFAULT, drain_job_queue_idle_handler,
diff --git a/gjs/jsapi-class.h b/gjs/jsapi-class.h
index 0473e12b..32f8d315 100644
--- a/gjs/jsapi-class.h
+++ b/gjs/jsapi-class.h
@@ -279,8 +279,8 @@ gjs_##cname##_define_proto(JSContext              *cx,                       \
     if (gtype != G_TYPE_NONE) {                                              \
         JS::RootedObject gtype_obj(cx,                                       \
             gjs_gtype_create_gtype_wrapper(cx, gtype));                      \
-        if (!JS_DefineProperty(cx, ctor_obj, "$gtype", gtype_obj,            \
-                               JSPROP_PERMANENT))                            \
+        if (!gtype_obj || !JS_DefineProperty(cx, ctor_obj, "$gtype",         \
+                                             gtype_obj,  JSPROP_PERMANENT))  \
             return false;                                                    \
     }                                                                        \
     gjs_debug(GJS_DEBUG_CONTEXT, "Initialized class %s prototype %p",        \
diff --git a/test/gjs-test-coverage.cpp b/test/gjs-test-coverage.cpp
index 7d3cbcdb..996bcb94 100644
--- a/test/gjs-test-coverage.cpp
+++ b/test/gjs-test-coverage.cpp
@@ -305,10 +305,9 @@ test_covered_file_is_duplicated_into_output_if_resource(gpointer      fixture_da
     fixture->coverage = gjs_coverage_new(coverage_scripts, fixture->context,
                                          fixture->lcov_output_dir);
 
-    gjs_context_eval_file(fixture->context,
-                          mock_resource_filename,
-                          NULL,
-                          NULL);
+    bool ok = gjs_context_eval_file(fixture->context, mock_resource_filename,
+                                    nullptr, nullptr);
+    g_assert_true(ok);
 
     gjs_coverage_write_statistics(fixture->coverage);
 
diff --git a/test/gjs-tests.cpp b/test/gjs-tests.cpp
index 328c61c2..309270c6 100644
--- a/test/gjs-tests.cpp
+++ b/test/gjs-tests.cpp
@@ -149,7 +149,8 @@ gjstest_test_func_gjs_jsapi_util_error_throw(GjsUnitTestFixture *fx,
     g_assert(value.isString());
 
     JS::UniqueChars s;
-    gjs_string_to_utf8(fx->cx, value, &s);
+    bool ok = gjs_string_to_utf8(fx->cx, value, &s);
+    g_assert_true(ok);
     g_assert_nonnull(s);
     g_assert_cmpstr(s.get(), ==, "This is an exception 42");
 


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