diff options
author | Android (Google) Code Review <android-gerrit@google.com> | 2009-09-07 04:40:06 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2009-09-07 04:40:06 -0700 |
commit | 9d9dbfe4e0be065094e561632b7a013dc111119f (patch) | |
tree | 6dea67ed94568f84aafb6bdbcd789143872f4409 /WebCore | |
parent | fb386a4cb13329c6a64fd29e134184610c2c3dbc (diff) | |
parent | 4bb414d51f2850c0da64c0832fb0dbb0378a5707 (diff) | |
download | external_webkit-9d9dbfe4e0be065094e561632b7a013dc111119f.zip external_webkit-9d9dbfe4e0be065094e561632b7a013dc111119f.tar.gz external_webkit-9d9dbfe4e0be065094e561632b7a013dc111119f.tar.bz2 |
Merge change 23972 into eclair
* changes:
Fixes Geolocation to correctly handle infinite values for PositionOptions properties.
Diffstat (limited to 'WebCore')
-rw-r--r-- | WebCore/bindings/js/JSGeolocationCustom.cpp | 22 | ||||
-rw-r--r-- | WebCore/bindings/v8/custom/V8GeolocationCustom.cpp | 43 | ||||
-rw-r--r-- | WebCore/page/PositionOptions.h | 12 |
3 files changed, 63 insertions, 14 deletions
diff --git a/WebCore/bindings/js/JSGeolocationCustom.cpp b/WebCore/bindings/js/JSGeolocationCustom.cpp index 6379a1c..8ef8601 100644 --- a/WebCore/bindings/js/JSGeolocationCustom.cpp +++ b/WebCore/bindings/js/JSGeolocationCustom.cpp @@ -101,20 +101,34 @@ static PassRefPtr<PositionOptions> createPositionOptions(ExecState* exec, JSValu if (exec->hadException()) return 0; if (!timeoutValue.isUndefined()) { - // Wrap to int32 and force non-negative to match behavior of window.setTimeout. - options->setTimeout(max(0, timeoutValue.toInt32(exec))); + double timeoutNumber = timeoutValue.toNumber(exec); if (exec->hadException()) return 0; + // If the value is infinity, there's nothing to do. + if (timeoutNumber != Inf) { + // Wrap to int32 and force non-negative to match behavior of window.setTimeout. + options->setTimeout(max(0, timeoutValue.toInt32(exec))); + if (exec->hadException()) + return 0; + } } JSValue maximumAgeValue = object->get(exec, Identifier(exec, "maximumAge")); if (exec->hadException()) return 0; if (!maximumAgeValue.isUndefined()) { - // Wrap to int32 and force non-negative to match behavior of window.setTimeout. - options->setMaximumAge(max(0, maximumAgeValue.toInt32(exec))); + double maximumAgeNumber = maximumAgeValue.toNumber(exec); if (exec->hadException()) return 0; + if (maximumAgeNumber == Inf) { + // If the value is infinity, clear maximumAge. + options->clearMaximumAge(); + } else { + // Wrap to int32 and force non-negative to match behavior of window.setTimeout. + options->setMaximumAge(max(0, maximumAgeValue.toInt32(exec))); + if (exec->hadException()) + return 0; + } } return options.release(); diff --git a/WebCore/bindings/v8/custom/V8GeolocationCustom.cpp b/WebCore/bindings/v8/custom/V8GeolocationCustom.cpp index 5373626..7bc687c 100644 --- a/WebCore/bindings/v8/custom/V8GeolocationCustom.cpp +++ b/WebCore/bindings/v8/custom/V8GeolocationCustom.cpp @@ -38,6 +38,7 @@ #include "V8Proxy.h" +using namespace std; using namespace WTF; namespace WebCore { @@ -123,13 +124,28 @@ static PassRefPtr<PositionOptions> createPositionOptions(v8::Local<v8::Value> va return 0; } if (!timeoutValue->IsUndefined()) { - v8::Local<v8::Int32> timeoutInt32 = timeoutValue->ToInt32(); - if (timeoutInt32.IsEmpty()) { + v8::Local<v8::Number> timeoutNumber = timeoutValue->ToNumber(); + if (timeoutNumber.IsEmpty()) { succeeded = false; return 0; } - // Wrap to int32 and force non-negative to match behavior of window.setTimeout. - options->setTimeout(max(0, timeoutInt32->Value())); + double timeoutDouble = timeoutNumber->Value(); + // V8 does not export a public symbol for infinity, so we must use a + // platform type. On Android, it seems that V8 uses 0xf70f000000000000, + // which is the standard way to represent infinity in a double. However, + // numeric_limits<double>::infinity uses the system HUGE_VAL, which is + // different. Therefore we test using isinf() and check that the value + // is positive, which seems to handle things correctly. + // If the value is infinity, there's nothing to do. + if (!(isinf(timeoutDouble) && timeoutDouble > 0)) { + v8::Local<v8::Int32> timeoutInt32 = timeoutValue->ToInt32(); + if (timeoutInt32.IsEmpty()) { + succeeded = false; + return 0; + } + // Wrap to int32 and force non-negative to match behavior of window.setTimeout. + options->setTimeout(max(0, timeoutInt32->Value())); + } } v8::Local<v8::Value> maximumAgeValue = object->Get(v8::String::New("maximumAge")); @@ -138,13 +154,24 @@ static PassRefPtr<PositionOptions> createPositionOptions(v8::Local<v8::Value> va return 0; } if (!maximumAgeValue->IsUndefined()) { - v8::Local<v8::Int32> maximumAgeInt32 = maximumAgeValue->ToInt32(); - if (maximumAgeInt32.IsEmpty()) { + v8::Local<v8::Number> maximumAgeNumber = maximumAgeValue->ToNumber(); + if (maximumAgeNumber.IsEmpty()) { succeeded = false; return 0; } - // Wrap to int32 and force non-negative to match behavior of window.setTimeout. - options->setMaximumAge(max(0, maximumAgeInt32->Value())); + double maximumAgeDouble = maximumAgeNumber->Value(); + if (isinf(maximumAgeDouble) && maximumAgeDouble > 0) { + // If the value is infinity, clear maximumAge. + options->clearMaximumAge(); + } else { + v8::Local<v8::Int32> maximumAgeInt32 = maximumAgeValue->ToInt32(); + if (maximumAgeInt32.IsEmpty()) { + succeeded = false; + return 0; + } + // Wrap to int32 and force non-negative to match behavior of window.setTimeout. + options->setMaximumAge(max(0, maximumAgeInt32->Value())); + } } return options.release(); diff --git a/WebCore/page/PositionOptions.h b/WebCore/page/PositionOptions.h index ee8530a..5900998 100644 --- a/WebCore/page/PositionOptions.h +++ b/WebCore/page/PositionOptions.h @@ -49,10 +49,17 @@ public: m_hasTimeout = true; m_timeout = timeout; } - int maximumAge() const { return m_maximumAge; } + bool hasMaximumAge() const { return m_hasMaximumAge; } + int maximumAge() const + { + ASSERT(hasMaximumAge()); + return m_maximumAge; + } + void clearMaximumAge() { m_hasMaximumAge = false; } void setMaximumAge(int age) { ASSERT(age >= 0); + m_hasMaximumAge = true; m_maximumAge = age; } @@ -60,13 +67,14 @@ private: PositionOptions() : m_highAccuracy(false) , m_hasTimeout(false) - , m_maximumAge(0) { + setMaximumAge(0); } bool m_highAccuracy; bool m_hasTimeout; int m_timeout; + bool m_hasMaximumAge; int m_maximumAge; }; |