From b622fa663ea754212470d53c5d13b21e19cd2539 Mon Sep 17 00:00:00 2001 From: Sami Vaarala Date: Sat, 26 Nov 2016 19:25:39 +0200 Subject: [PATCH 1/2] Add an fmod() self test --- src-input/duk_selftest.c | 44 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/src-input/duk_selftest.c b/src-input/duk_selftest.c index 7681af00..0fccd396 100644 --- a/src-input/duk_selftest.c +++ b/src-input/duk_selftest.c @@ -18,7 +18,7 @@ typedef union { /* Self test failed. Expects a local variable 'error_count' to exist. */ #define DUK__FAILED(msg) do { \ - DUK_D(DUK_DPRINT("self test failed: " #msg)); \ + DUK_D(DUK_DPRINT("self test failed: " #msg " at " DUK_FILE_MACRO ":" DUK_MACRO_STRINGIFY(DUK_LINE_MACRO))); \ error_count++; \ } while (0) @@ -375,6 +375,47 @@ DUK_LOCAL duk_uint_t duk__selftest_double_rounding(void) { return error_count; } +/* + * fmod(): often a portability issue in embedded or bare platform targets. + * Check for at least minimally correct behavior. Unlike some other math + * functions (like cos()) Duktape relies on fmod() internally too. + */ + +DUK_LOCAL duk_uint_t duk__selftest_fmod(void) { + duk_uint_t error_count = 0; + duk__test_double_union u1, u2; + + /* fmod() with integer argument and exponent 2^32 is used by e.g. + * ToUint32() and some Duktape internals. + */ + u1.d = DUK_FMOD(10.0, 4294967296.0); + u2.d = 10.0; + DUK__DBLUNION_CMP_TRUE(&u1, &u2); + + u1.d = DUK_FMOD(4294967306.0, 4294967296.0); + u2.d = 10.0; + DUK__DBLUNION_CMP_TRUE(&u1, &u2); + + u1.d = DUK_FMOD(73014444042.0, 4294967296.0); + u2.d = 10.0; + DUK__DBLUNION_CMP_TRUE(&u1, &u2); + + /* C99 behavior is for fmod() result sign to mathc argument sign. */ + u1.d = DUK_FMOD(-10.0, 4294967296.0); + u2.d = -10.0; + DUK__DBLUNION_CMP_TRUE(&u1, &u2); + + u1.d = DUK_FMOD(-4294967306.0, 4294967296.0); + u2.d = -10.0; + DUK__DBLUNION_CMP_TRUE(&u1, &u2); + + u1.d = DUK_FMOD(-73014444042.0, 4294967296.0); + u2.d = -10.0; + DUK__DBLUNION_CMP_TRUE(&u1, &u2); + + return error_count; +} + /* * Struct size/alignment if platform requires it * @@ -563,6 +604,7 @@ DUK_INTERNAL duk_uint_t duk_selftest_run_tests(duk_alloc_function alloc_func, error_count += duk__selftest_double_aliasing(); error_count += duk__selftest_double_zero_sign(); error_count += duk__selftest_double_rounding(); + error_count += duk__selftest_fmod(); error_count += duk__selftest_struct_align(); error_count += duk__selftest_64bit_arithmetic(); error_count += duk__selftest_cast_double_to_small_uint(); From 2c70151cc9abc827f1950f27adcfba6f8c966e67 Mon Sep 17 00:00:00 2001 From: Sami Vaarala Date: Sat, 26 Nov 2016 20:57:09 +0200 Subject: [PATCH 2/2] Releases: fmod() self test --- RELEASES.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/RELEASES.rst b/RELEASES.rst index 1f3f7b0d..a29f8f3d 100644 --- a/RELEASES.rst +++ b/RELEASES.rst @@ -1970,6 +1970,8 @@ Planned opcode (fastint downgrade check is intended to be applied to unary plus only) (GH-903) +* Add an fmod() self test (GH-1108) + * Fix a few bugs in object property handling (delete property and Object.defineProperty()) where an object property table resize triggered by a finalizer of a previous value could cause memory unsafe behavior