[gjs: 2/5] jsapi-util: Add a function to check if a BigInt is out of range
- From: Philip Chimento <pchimento src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs: 2/5] jsapi-util: Add a function to check if a BigInt is out of range
- Date: Fri, 4 Feb 2022 06:17:19 +0000 (UTC)
commit 9454bc99a7b5aab0c2590ac3c22224602c8fe61e
Author: Marco Trevisan (TreviƱo) <mail 3v1n0 net>
Date: Tue Nov 3 21:34:41 2020 +0100
jsapi-util: Add a function to check if a BigInt is out of range
BigInts can contain (u)int64_t but they also can hold values that are way
bigger or smaller than their limits, so in order to ensure that we can do
runtime checks of the C-representability of a BigInt we need to verify
that it stays within the type boundaries we care about.
Since version 91 mozjs provides a C++ API for this, JS::BigIntFits(). We
use this function instead of calling JS::BigIntFits() directly, so that we
can additionally clamp the number to the type's limits if it doesn't fit.
See: #271
gjs/jsapi-util.h | 37 +++++++++++++++++++++++++++++++++++++
1 file changed, 37 insertions(+)
---
diff --git a/gjs/jsapi-util.h b/gjs/jsapi-util.h
index 9a8ff1084..616038b23 100644
--- a/gjs/jsapi-util.h
+++ b/gjs/jsapi-util.h
@@ -12,6 +12,7 @@
#include <stdlib.h> // for free
#include <sys/types.h> // for ssize_t
+#include <limits>
#include <string> // for string, u16string
#include <type_traits> // for enable_if_t, add_pointer_t, add_const_t
#include <utility> // IWYU pragma: keep
@@ -21,6 +22,7 @@
#include <glib-object.h>
#include <glib.h>
+#include <js/BigInt.h>
#include <js/GCAPI.h>
#include <js/GCPolicyAPI.h> // for IgnoreGCPolicy
#include <js/Id.h>
@@ -29,6 +31,11 @@
#include <jspubtd.h> // for JSProtoKey
#include "gjs/macros.h"
+#include "util/log.h"
+
+#if GJS_VERBOSE_ENABLE_MARSHAL
+# include "gi/arg-types-inl.h" // for static_type_name
+#endif
class JSErrorReport;
namespace JS {
@@ -600,6 +607,36 @@ static constexpr size_t N_REASONS = 0 FOREACH_GC_REASON(COUNT_GC_REASON);
#undef COUNT_GC_REASON
};
+template <typename T>
+[[nodiscard]] bool bigint_is_out_of_range(JS::BigInt* bi, T* clamped) {
+ static_assert(sizeof(T) == 8, "64-bit types only");
+ g_assert(bi && "bigint cannot be null");
+ g_assert(clamped && "forgot out parameter");
+
+ gjs_debug_marshal(GJS_DEBUG_GFUNCTION,
+ "Checking if BigInt %s is out of range for type %s",
+ gjs_debug_bigint(bi).c_str(), Gjs::static_type_name<T>());
+
+ if (JS::BigIntFits(bi, clamped)) {
+ gjs_debug_marshal(
+ GJS_DEBUG_GFUNCTION, "BigInt %s is in the range of type %s",
+ std::to_string(*clamped).c_str(), Gjs::static_type_name<T>());
+ return false;
+ }
+
+ if (JS::BigIntIsNegative(bi)) {
+ *clamped = std::numeric_limits<T>::min();
+ } else {
+ *clamped = std::numeric_limits<T>::max();
+ }
+
+ gjs_debug_marshal(GJS_DEBUG_GFUNCTION,
+ "BigInt %s is not in the range of type %s, clamped to %s",
+ gjs_debug_bigint(bi).c_str(), Gjs::static_type_name<T>(),
+ std::to_string(*clamped).c_str());
+ return true;
+}
+
} // namespace Gjs
[[nodiscard]] const char* gjs_explain_gc_reason(JS::GCReason reason);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]