diff options
author | Philip Chimento <philip.chimento@gmail.com> | 2020-09-10 05:33:59 +0000 |
---|---|---|
committer | Philip Chimento <philip.chimento@gmail.com> | 2020-09-10 05:33:59 +0000 |
commit | eb2876afd845253f95029b84b697f18e44d1facb (patch) | |
tree | e0de23ff04766a5156a410e4d143899a81705370 | |
parent | 8836e6ce41f8774cc571239f4a34f77d648f1f6f (diff) | |
parent | 4746f8ba0d37b7d59a0de9da50c57782dfa8c348 (diff) | |
download | gjs-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.h | 4 | ||||
-rw-r--r-- | test/gjs-tests.cpp | 32 |
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 (); |