Changeset 143441 in webkit


Ignore:
Timestamp:
Feb 20, 2013 1:58:37 AM (11 years ago)
Author:
commit-queue@webkit.org
Message:

[v8] ScriptValue has dangerous copy semantics
https://bugs.webkit.org/show_bug.cgi?id=110206

Patch by Dan Carney <dcarney@google.com> on 2013-02-20
Reviewed by Kentaro Hara.

Update ScriptValue to used a SharedPersistent,
making it impossible to return dead references.

No new tests. No change in functionality.

  • bindings/v8/ScriptValue.cpp:

(WebCore::ScriptValue::serialize):
(WebCore::ScriptValue::getString):
(WebCore::ScriptValue::toString):
(WebCore::ScriptValue::toInspectorValue):

  • bindings/v8/ScriptValue.h:

(WebCore::ScriptValue::ScriptValue):
(WebCore::ScriptValue::operator=):
(WebCore::ScriptValue::operator==):
(WebCore::ScriptValue::isEqual):
(WebCore::ScriptValue::isFunction):
(WebCore::ScriptValue::isNull):
(WebCore::ScriptValue::isUndefined):
(WebCore::ScriptValue::isObject):
(WebCore::ScriptValue::hasNoValue):
(WebCore::ScriptValue::clear):
(ScriptValue):
(WebCore::ScriptValue::v8Value):
(WebCore::ScriptValue::v8ValueRaw):

  • bindings/v8/SharedPersistent.h:
  • bindings/v8/custom/V8InjectedScriptHostCustom.cpp:

(WebCore::InjectedScriptHost::scriptValueAsNode):

  • bindings/v8/custom/V8MessageEventCustom.cpp:

(WebCore::V8MessageEvent::dataAttrGetterCustom):

Location:
trunk/Source/WebCore
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r143440 r143441  
     12013-02-20  Dan Carney  <dcarney@google.com>
     2
     3        [v8] ScriptValue has dangerous copy semantics
     4        https://bugs.webkit.org/show_bug.cgi?id=110206
     5
     6        Reviewed by Kentaro Hara.
     7
     8        Update ScriptValue to used a SharedPersistent,
     9        making it impossible to return dead references.
     10
     11        No new tests. No change in functionality.
     12
     13        * bindings/v8/ScriptValue.cpp:
     14        (WebCore::ScriptValue::serialize):
     15        (WebCore::ScriptValue::getString):
     16        (WebCore::ScriptValue::toString):
     17        (WebCore::ScriptValue::toInspectorValue):
     18        * bindings/v8/ScriptValue.h:
     19        (WebCore::ScriptValue::ScriptValue):
     20        (WebCore::ScriptValue::operator=):
     21        (WebCore::ScriptValue::operator==):
     22        (WebCore::ScriptValue::isEqual):
     23        (WebCore::ScriptValue::isFunction):
     24        (WebCore::ScriptValue::isNull):
     25        (WebCore::ScriptValue::isUndefined):
     26        (WebCore::ScriptValue::isObject):
     27        (WebCore::ScriptValue::hasNoValue):
     28        (WebCore::ScriptValue::clear):
     29        (ScriptValue):
     30        (WebCore::ScriptValue::v8Value):
     31        (WebCore::ScriptValue::v8ValueRaw):
     32        * bindings/v8/SharedPersistent.h:
     33        * bindings/v8/custom/V8InjectedScriptHostCustom.cpp:
     34        (WebCore::InjectedScriptHost::scriptValueAsNode):
     35        * bindings/v8/custom/V8MessageEventCustom.cpp:
     36        (WebCore::V8MessageEvent::dataAttrGetterCustom):
     37
    1382013-02-20  Andrey Lushnikov  <lushnikov@chromium.org>
    239
  • trunk/Source/WebCore/bindings/v8/ScriptValue.cpp

    r126564 r143441  
    4848{
    4949    ScriptScope scope(scriptState);
    50     return SerializedScriptValue::create(v8Value());
     50    return SerializedScriptValue::create(v8ValueRaw());
    5151}
    5252
     
    5454{
    5555    ScriptScope scope(scriptState);
    56     return SerializedScriptValue::create(v8Value(), messagePorts, arrayBuffers, didThrow);
     56    return SerializedScriptValue::create(v8ValueRaw(), messagePorts, arrayBuffers, didThrow);
    5757}
    5858
     
    6565bool ScriptValue::getString(String& result) const
    6666{
    67     if (m_value.isEmpty())
     67    if (hasNoValue())
    6868        return false;
    6969
    70     if (!m_value->IsString())
     70    if (!v8ValueRaw()->IsString())
    7171        return false;
    7272
    73     result = toWebCoreString(m_value.get());
     73    result = toWebCoreString(v8ValueRaw());
    7474    return true;
    7575}
     
    7878{
    7979    v8::TryCatch block;
    80     v8::Handle<v8::String> string = m_value->ToString();
     80    v8::Handle<v8::String> string = v8ValueRaw()->ToString();
    8181    if (block.HasCaught())
    8282        return String();
     
    143143    // v8::Object::GetPropertyNames() expects current context to be not null.
    144144    v8::Context::Scope contextScope(scriptState->context());
    145     return v8ToInspectorValue(m_value.get(), InspectorValue::maxDepth);
     145    return v8ToInspectorValue(v8ValueRaw(), InspectorValue::maxDepth);
    146146}
    147147#endif
  • trunk/Source/WebCore/bindings/v8/ScriptValue.h

    r126564 r143441  
    3232#define ScriptValue_h
    3333
    34 #include "ScopedPersistent.h"
    3534#include "ScriptState.h"
     35#include "SharedPersistent.h"
    3636#include <v8.h>
    3737#include <wtf/PassRefPtr.h>
     
    6161    virtual ~ScriptValue();
    6262
    63     ScriptValue(v8::Handle<v8::Value> value)
     63    ScriptValue(v8::Handle<v8::Value> value)
     64        : m_value(value.IsEmpty() ? 0 : SharedPersistent<v8::Value>::create(value))
    6465    {
    65         if (value.IsEmpty())
    66             return;
    67         m_value.set(value);
    6866    }
    6967
    70     ScriptValue(const ScriptValue& value)
     68    ScriptValue(const ScriptValue& value)
     69        : m_value(value.m_value)
    7170    {
    72         if (value.hasNoValue())
    73             return;
    74         m_value.set(value.m_value.get());
    7571    }
    7672
    7773    ScriptValue& operator=(const ScriptValue& value)
    7874    {
    79         if (this == &value)
    80             return *this;
    81 
    82         m_value.clear();
    83 
    84         if (value.hasNoValue())
    85             return *this;
    86 
    87         m_value.set(value.m_value.get());
     75        if (this != &value)
     76            m_value = value.m_value;
    8877        return *this;
    8978    }
     
    9180    bool operator==(const ScriptValue& value) const
    9281    {
    93         return m_value.get() == value.m_value.get();
     82        return v8ValueRaw() == value.v8ValueRaw();
    9483    }
    9584
    9685    bool isEqual(ScriptState*, const ScriptValue& value) const
    9786    {
    98         return m_value.get() == value.m_value.get();
     87        return operator==(value);
    9988    }
    10089
    10190    bool isFunction() const
    10291    {
    103         return m_value->IsFunction();
     92        ASSERT(!hasNoValue());
     93        return v8ValueRaw()->IsFunction();
    10494    }
    10595
     
    111101    bool isNull() const
    112102    {
    113         return m_value->IsNull();
     103        ASSERT(!hasNoValue());
     104        return v8ValueRaw()->IsNull();
    114105    }
    115106
    116107    bool isUndefined() const
    117108    {
    118         return m_value->IsUndefined();
     109        ASSERT(!hasNoValue());
     110        return v8ValueRaw()->IsUndefined();
    119111    }
    120112
    121113    bool isObject() const
    122114    {
    123         return m_value->IsObject();
     115        ASSERT(!hasNoValue());
     116        return v8ValueRaw()->IsObject();
    124117    }
    125118
    126119    bool hasNoValue() const
    127120    {
    128         return m_value.isEmpty();
     121        return !m_value.get() || m_value->get().IsEmpty();
    129122    }
    130123
     
    135128    void clear()
    136129    {
    137         m_value.clear();
     130        m_value = 0;
    138131    }
    139132
    140     v8::Handle<v8::Value> v8Value() const { return m_value.get(); }
     133    v8::Handle<v8::Value> v8Value() const
     134    {
     135        return v8::Local<v8::Value>::New(v8ValueRaw());
     136    }
     137
     138    // FIXME: This function should be private.
     139    v8::Handle<v8::Value> v8ValueRaw() const
     140    {
     141        return m_value.get() ? m_value->get() : v8::Handle<v8::Value>();
     142    }
    141143
    142144    bool getString(ScriptState*, String& result) const { return getString(result); }
     
    147149
    148150private:
    149     ScopedPersistent<v8::Value> m_value;
     151    RefPtr<SharedPersistent<v8::Value> > m_value;
    150152};
    151153
  • trunk/Source/WebCore/bindings/v8/SharedPersistent.h

    r128159 r143441  
    3939namespace WebCore {
    4040
    41     // FIXME: Remove this class.
    4241    template <typename T>
    4342    class SharedPersistent : public RefCounted<SharedPersistent<T> > {
  • trunk/Source/WebCore/bindings/v8/custom/V8InjectedScriptHostCustom.cpp

    r142849 r143441  
    6666    if (!value.isObject() || value.isNull())
    6767        return 0;
    68     return V8Node::toNative(v8::Handle<v8::Object>::Cast(value.v8Value()));
     68    return V8Node::toNative(v8::Handle<v8::Object>::Cast(value.v8ValueRaw()));
    6969}
    7070
  • trunk/Source/WebCore/bindings/v8/custom/V8MessageEventCustom.cpp

    r142849 r143441  
    5454            result = v8Null(info.GetIsolate());
    5555        else
    56             result = v8::Local<v8::Value>::New(scriptValue.v8Value());
     56            result = scriptValue.v8Value();
    5757        break;
    5858    }
Note: See TracChangeset for help on using the changeset viewer.