summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Chimento <philip.chimento@gmail.com>2020-09-10 05:33:59 +0000
committerPhilip Chimento <philip.chimento@gmail.com>2020-09-10 05:33:59 +0000
commiteb2876afd845253f95029b84b697f18e44d1facb (patch)
treee0de23ff04766a5156a410e4d143899a81705370
parent8836e6ce41f8774cc571239f4a34f77d648f1f6f (diff)
parent4746f8ba0d37b7d59a0de9da50c57782dfa8c348 (diff)
downloadgjs-eb2876afd845253f95029b84b697f18e44d1facb.tar.gz
Merge branch 'safe-integers-check' into 'master'
arg: Fix MIN/MAX safe big integer limits See merge request GNOME/gjs!492
-rw-r--r--gi/arg-inl.h4
-rw-r--r--test/gjs-tests.cpp32
2 files changed, 34 insertions, 2 deletions
diff --git a/gi/arg-inl.h b/gi/arg-inl.h
index 852bf904..6d45e682 100644
--- a/gi/arg-inl.h
+++ b/gi/arg-inl.h
@@ -176,13 +176,13 @@ template <typename T, GITypeTag TAG = GI_TYPE_TAG_VOID>
template <typename BigT>
[[nodiscard]] inline constexpr BigT max_safe_big_number() {
- return BigT(1) << std::numeric_limits<double>::digits;
+ return (BigT(1) << std::numeric_limits<double>::digits) - 1;
}
template <typename BigT>
[[nodiscard]] inline constexpr BigT min_safe_big_number() {
if constexpr (std::is_signed_v<BigT>)
- return -(max_safe_big_number<BigT>()) + 1;
+ return -(max_safe_big_number<BigT>());
return std::numeric_limits<BigT>::lowest();
}
diff --git a/test/gjs-tests.cpp b/test/gjs-tests.cpp
index 60f1b493..2e4b10e9 100644
--- a/test/gjs-tests.cpp
+++ b/test/gjs-tests.cpp
@@ -23,6 +23,7 @@
#include <config.h>
+#include <stdint.h>
#include <string.h> // for size_t, strlen
#include <string> // for u16string, u32string
@@ -39,7 +40,9 @@
#include <js/Value.h>
#include <js/ValueArray.h>
#include <jsapi.h>
+#include <jspubtd.h> // for JSProto_Number
+#include "gi/arg-inl.h"
#include "gjs/context.h"
#include "gjs/error-types.h"
#include "gjs/jsapi-util.h"
@@ -398,6 +401,30 @@ gjstest_test_profiler_start_stop(void)
g_message("Temp profiler file not deleted");
}
+static void gjstest_test_safe_integer_max(GjsUnitTestFixture* fx, const void*) {
+ JS::RootedObject number_class_object(fx->cx);
+ JS::RootedValue safe_value(fx->cx);
+
+ g_assert_true(
+ JS_GetClassObject(fx->cx, JSProto_Number, &number_class_object));
+ g_assert_true(JS_GetProperty(fx->cx, number_class_object,
+ "MAX_SAFE_INTEGER", &safe_value));
+
+ g_assert_cmpint(safe_value.toNumber(), ==, max_safe_big_number<int64_t>());
+}
+
+static void gjstest_test_safe_integer_min(GjsUnitTestFixture* fx, const void*) {
+ JS::RootedObject number_class_object(fx->cx);
+ JS::RootedValue safe_value(fx->cx);
+
+ g_assert_true(
+ JS_GetClassObject(fx->cx, JSProto_Number, &number_class_object));
+ g_assert_true(JS_GetProperty(fx->cx, number_class_object,
+ "MIN_SAFE_INTEGER", &safe_value));
+
+ g_assert_cmpint(safe_value.toNumber(), ==, min_safe_big_number<int64_t>());
+}
+
int
main(int argc,
char **argv)
@@ -444,6 +471,11 @@ main(int argc,
ADD_JSAPI_UTIL_TEST("debug_string/object-with-complicated-to-string",
test_jsapi_util_debug_string_object_with_complicated_to_string);
+ ADD_JSAPI_UTIL_TEST("gi/args/safe-integer/max",
+ gjstest_test_safe_integer_max);
+ ADD_JSAPI_UTIL_TEST("gi/args/safe-integer/min",
+ gjstest_test_safe_integer_min);
+
#undef ADD_JSAPI_UTIL_TEST
gjs_test_add_tests_for_coverage ();