From 6f0e8c0788192357b849b6a68f86a9c7cdfec10d Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Tue, 15 Jan 2013 15:01:09 +0100 Subject: [PATCH] Fix case in parseInt where qin64 would overflow. Change-Id: I2c9fbd3f7476d35ffef4abb408cac5ac89d85268 Reviewed-by: Simon Hausmann --- qmljs_objects.cpp | 28 ++++++++++++++++++++++++++-- tests/TestExpectations | 1 - 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/qmljs_objects.cpp b/qmljs_objects.cpp index eacf40b..f9b4df0 100644 --- a/qmljs_objects.cpp +++ b/qmljs_objects.cpp @@ -985,6 +985,9 @@ Value ParseIntFunction::call(ExecutionContext *context, Value thisObject, Value // 13: this is handled by the toInt function if (pos == end) // 12 return Value::fromDouble(nan("")); + bool overflow = false; + qint64 v_overflow; + unsigned overflow_digit_count = 0; int d = toInt(*pos++, R); if (d == -1) return Value::fromDouble(nan("")); @@ -993,10 +996,31 @@ Value ParseIntFunction::call(ExecutionContext *context, Value thisObject, Value d = toInt(*pos++, R); if (d == -1) break; - v = v * R + d; + if (overflow) { + if (overflow_digit_count == 0) { + v_overflow = v; + v = 0; + } + ++overflow_digit_count; + v = v * R + d; + } else { + qint64 vNew = v * R + d; + if (vNew < v) { + overflow = true; + --pos; + } else { + v = vNew; + } + } } - return Value::fromDouble(v * sign); // 15 + if (overflow) { + double result = (double) v_overflow * pow(R, overflow_digit_count); + result += v; + return Value::fromDouble(sign * result); + } else { + return Value::fromDouble(sign * (double) v); // 15 + } } // parseFloat [15.1.2.3] diff --git a/tests/TestExpectations b/tests/TestExpectations index 96c6b25..c8dedea 100644 --- a/tests/TestExpectations +++ b/tests/TestExpectations @@ -372,7 +372,6 @@ S12.7_A7 failing S12.8_A4_T1 failing S12.8_A4_T2 failing S12.8_A4_T3 failing -S15.1.2.2_A7.3_T3 failing S15.1.2.2_A9.1 failing S15.1.2.2_A9.2 failing S15.1.2.2_A9.3 failing -- 2.7.4