Changeset 209020 in webkit


Ignore:
Timestamp:
Nov 28, 2016 2:29:39 PM (7 years ago)
Author:
mark.lam@apple.com
Message:

Fix exception scope verification failures in ObjectConstructor.cpp and ObjectPrototype.cpp.
https://bugs.webkit.org/show_bug.cgi?id=165051

Reviewed by Saam Barati.

Source/JavaScriptCore:

Also,

  1. Replaced returning JSValue() with returning { }.
  2. Replaced uses of exec->propertyNames() with vm.propertyNames.
  • runtime/ObjectConstructor.cpp:

(JSC::constructObject):
(JSC::objectConstructorGetPrototypeOf):
(JSC::objectConstructorGetOwnPropertyDescriptor):
(JSC::objectConstructorGetOwnPropertyDescriptors):
(JSC::objectConstructorGetOwnPropertyNames):
(JSC::objectConstructorGetOwnPropertySymbols):
(JSC::objectConstructorKeys):
(JSC::ownEnumerablePropertyKeys):
(JSC::toPropertyDescriptor):
(JSC::defineProperties):
(JSC::objectConstructorDefineProperties):
(JSC::objectConstructorCreate):
(JSC::setIntegrityLevel):
(JSC::objectConstructorSeal):
(JSC::objectConstructorPreventExtensions):
(JSC::objectConstructorIsSealed):
(JSC::objectConstructorIsFrozen):
(JSC::ownPropertyKeys):

  • runtime/ObjectPrototype.cpp:

(JSC::objectProtoFuncValueOf):
(JSC::objectProtoFuncHasOwnProperty):
(JSC::objectProtoFuncIsPrototypeOf):
(JSC::objectProtoFuncDefineGetter):
(JSC::objectProtoFuncDefineSetter):
(JSC::objectProtoFuncLookupGetter):
(JSC::objectProtoFuncLookupSetter):
(JSC::objectProtoFuncToLocaleString):
(JSC::objectProtoFuncToString):

Source/WebCore:

No new tests because this is covered by the existing test
http/tests/security/cross-frame-access-object-prototype.html with the help of a
new ASSERT in ObjectPrototype.cpp.

Fixed jsDOMWindowGetOwnPropertySlotRestrictedAccess() to return false when it
throws an exception.

  • bindings/js/JSDOMWindowCustom.cpp:

(WebCore::jsDOMWindowGetOwnPropertySlotRestrictedAccess):

Location:
trunk/Source
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r209018 r209020  
     12016-11-28  Mark Lam  <mark.lam@apple.com>
     2
     3        Fix exception scope verification failures in ObjectConstructor.cpp and ObjectPrototype.cpp.
     4        https://bugs.webkit.org/show_bug.cgi?id=165051
     5
     6        Reviewed by Saam Barati.
     7
     8        Also,
     9        1. Replaced returning JSValue() with returning { }.
     10        2. Replaced uses of exec->propertyNames() with vm.propertyNames.
     11
     12        * runtime/ObjectConstructor.cpp:
     13        (JSC::constructObject):
     14        (JSC::objectConstructorGetPrototypeOf):
     15        (JSC::objectConstructorGetOwnPropertyDescriptor):
     16        (JSC::objectConstructorGetOwnPropertyDescriptors):
     17        (JSC::objectConstructorGetOwnPropertyNames):
     18        (JSC::objectConstructorGetOwnPropertySymbols):
     19        (JSC::objectConstructorKeys):
     20        (JSC::ownEnumerablePropertyKeys):
     21        (JSC::toPropertyDescriptor):
     22        (JSC::defineProperties):
     23        (JSC::objectConstructorDefineProperties):
     24        (JSC::objectConstructorCreate):
     25        (JSC::setIntegrityLevel):
     26        (JSC::objectConstructorSeal):
     27        (JSC::objectConstructorPreventExtensions):
     28        (JSC::objectConstructorIsSealed):
     29        (JSC::objectConstructorIsFrozen):
     30        (JSC::ownPropertyKeys):
     31        * runtime/ObjectPrototype.cpp:
     32        (JSC::objectProtoFuncValueOf):
     33        (JSC::objectProtoFuncHasOwnProperty):
     34        (JSC::objectProtoFuncIsPrototypeOf):
     35        (JSC::objectProtoFuncDefineGetter):
     36        (JSC::objectProtoFuncDefineSetter):
     37        (JSC::objectProtoFuncLookupGetter):
     38        (JSC::objectProtoFuncLookupSetter):
     39        (JSC::objectProtoFuncToLocaleString):
     40        (JSC::objectProtoFuncToString):
     41
    1422016-11-26  Mark Lam  <mark.lam@apple.com>
    243
  • trunk/Source/JavaScriptCore/runtime/ObjectConstructor.cpp

    r206948 r209020  
    134134
    135135    // 3. Return ToObject(value).
     136    scope.release();
    136137    return arg.toObject(exec, globalObject);
    137138}
     
    165166    JSObject* object = exec->argument(0).toObject(exec);
    166167    RETURN_IF_EXCEPTION(scope, encodedJSValue());
    167     return JSValue::encode(object->getPrototype(exec->vm(), exec));
     168    scope.release();
     169    return JSValue::encode(object->getPrototype(vm, exec));
    168170}
    169171
     
    195197    auto scope = DECLARE_THROW_SCOPE(vm);
    196198    PropertyDescriptor descriptor;
    197     if (!object->getOwnPropertyDescriptor(exec, propertyName, descriptor))
     199    if (!object->getOwnPropertyDescriptor(exec, propertyName, descriptor)) {
     200        scope.release();
    198201        return jsUndefined();
    199     RETURN_IF_EXCEPTION(scope, JSValue());
     202    }
     203    RETURN_IF_EXCEPTION(scope, { });
    200204
    201205    JSObject* result = constructObjectFromPropertyDescriptor(exec, descriptor);
     206    ASSERT(!!scope.exception() == !result);
    202207    if (!result)
    203208        return jsUndefined();
     
    211216    PropertyNameArray properties(exec, PropertyNameMode::StringsAndSymbols);
    212217    object->methodTable(vm)->getOwnPropertyNames(object, exec, properties, EnumerationMode(DontEnumPropertiesMode::Include));
    213     RETURN_IF_EXCEPTION(scope, JSValue());
     218    RETURN_IF_EXCEPTION(scope, { });
    214219
    215220    JSObject* descriptors = constructEmptyObject(exec);
    216     RETURN_IF_EXCEPTION(scope, JSValue());
     221    RETURN_IF_EXCEPTION(scope, { });
    217222
    218223    for (auto& propertyName : properties) {
    219224        PropertyDescriptor descriptor;
    220225        bool didGetDescriptor = object->getOwnPropertyDescriptor(exec, propertyName, descriptor);
    221         RETURN_IF_EXCEPTION(scope, JSValue());
     226        RETURN_IF_EXCEPTION(scope, { });
    222227
    223228        if (!didGetDescriptor)
     
    225230
    226231        JSObject* fromDescriptor = constructObjectFromPropertyDescriptor(exec, descriptor);
     232        ASSERT(!!scope.exception() == !fromDescriptor);
    227233        if (!fromDescriptor)
    228234            return jsUndefined();
     
    244250    auto propertyName = exec->argument(1).toPropertyKey(exec);
    245251    RETURN_IF_EXCEPTION(scope, encodedJSValue());
     252    scope.release();
    246253    return JSValue::encode(objectConstructorGetOwnPropertyDescriptor(exec, object, propertyName));
    247254}
     
    253260    JSObject* object = exec->argument(0).toObject(exec);
    254261    RETURN_IF_EXCEPTION(scope, encodedJSValue());
     262    scope.release();
    255263    return JSValue::encode(objectConstructorGetOwnPropertyDescriptors(exec, object));
    256264}
     
    263271    JSObject* object = exec->argument(0).toObject(exec);
    264272    RETURN_IF_EXCEPTION(scope, encodedJSValue());
     273    scope.release();
    265274    return JSValue::encode(ownPropertyKeys(exec, object, PropertyNameMode::Strings, DontEnumPropertiesMode::Include));
    266275}
     
    273282    JSObject* object = exec->argument(0).toObject(exec);
    274283    RETURN_IF_EXCEPTION(scope, encodedJSValue());
     284    scope.release();
    275285    return JSValue::encode(ownPropertyKeys(exec, object, PropertyNameMode::Symbols, DontEnumPropertiesMode::Include));
    276286}
     
    283293    JSObject* object = exec->argument(0).toObject(exec);
    284294    RETURN_IF_EXCEPTION(scope, encodedJSValue());
     295    scope.release();
    285296    return JSValue::encode(ownPropertyKeys(exec, object, PropertyNameMode::Strings, DontEnumPropertiesMode::Exclude));
    286297}
     
    292303    JSObject* object = exec->argument(0).toObject(exec);
    293304    RETURN_IF_EXCEPTION(scope, encodedJSValue());
     305    scope.release();
    294306    return JSValue::encode(ownPropertyKeys(exec, object, PropertyNameMode::StringsAndSymbols, DontEnumPropertiesMode::Exclude));
    295307}
     
    308320    JSObject* description = asObject(in);
    309321
    310     if (description->hasProperty(exec, exec->propertyNames().enumerable)) {
    311         JSValue value = description->get(exec, exec->propertyNames().enumerable);
     322    bool hasProperty = description->hasProperty(exec, vm.propertyNames->enumerable);
     323    ASSERT(!scope.exception() || !hasProperty);
     324    if (hasProperty) {
     325        JSValue value = description->get(exec, vm.propertyNames->enumerable);
    312326        RETURN_IF_EXCEPTION(scope, false);
    313327        desc.setEnumerable(value.toBoolean(exec));
     
    315329        RETURN_IF_EXCEPTION(scope, false);
    316330
    317     if (description->hasProperty(exec, exec->propertyNames().configurable)) {
    318         JSValue value = description->get(exec, exec->propertyNames().configurable);
     331    hasProperty = description->hasProperty(exec, vm.propertyNames->configurable);
     332    ASSERT(!scope.exception() || !hasProperty);
     333    if (hasProperty) {
     334        JSValue value = description->get(exec, vm.propertyNames->configurable);
    319335        RETURN_IF_EXCEPTION(scope, false);
    320336        desc.setConfigurable(value.toBoolean(exec));
     
    323339
    324340    JSValue value;
    325     if (description->hasProperty(exec, exec->propertyNames().value)) {
    326         JSValue value = description->get(exec, exec->propertyNames().value);
     341    hasProperty = description->hasProperty(exec, vm.propertyNames->value);
     342    ASSERT(!scope.exception() || !hasProperty);
     343    if (hasProperty) {
     344        JSValue value = description->get(exec, vm.propertyNames->value);
    327345        RETURN_IF_EXCEPTION(scope, false);
    328346        desc.setValue(value);
     
    330348        RETURN_IF_EXCEPTION(scope, false);
    331349
    332     if (description->hasProperty(exec, exec->propertyNames().writable)) {
    333         JSValue value = description->get(exec, exec->propertyNames().writable);
     350    hasProperty = description->hasProperty(exec, vm.propertyNames->writable);
     351    ASSERT(!scope.exception() || !hasProperty);
     352    if (hasProperty) {
     353        JSValue value = description->get(exec, vm.propertyNames->writable);
    334354        RETURN_IF_EXCEPTION(scope, false);
    335355        desc.setWritable(value.toBoolean(exec));
     
    337357        RETURN_IF_EXCEPTION(scope, false);
    338358
    339     if (description->hasProperty(exec, exec->propertyNames().get)) {
    340         JSValue get = description->get(exec, exec->propertyNames().get);
     359    hasProperty = description->hasProperty(exec, vm.propertyNames->get);
     360    ASSERT(!scope.exception() || !hasProperty);
     361    if (hasProperty) {
     362        JSValue get = description->get(exec, vm.propertyNames->get);
    341363        RETURN_IF_EXCEPTION(scope, false);
    342364        if (!get.isUndefined()) {
     
    351373        RETURN_IF_EXCEPTION(scope, false);
    352374
    353     if (description->hasProperty(exec, exec->propertyNames().set)) {
    354         JSValue set = description->get(exec, exec->propertyNames().set);
     375    hasProperty = description->hasProperty(exec, vm.propertyNames->set);
     376    ASSERT(!scope.exception() || !hasProperty);
     377    if (hasProperty) {
     378        JSValue set = description->get(exec, vm.propertyNames->set);
    355379        RETURN_IF_EXCEPTION(scope, false);
    356380        if (!set.isUndefined()) {
     
    409433    PropertyNameArray propertyNames(exec, PropertyNameMode::StringsAndSymbols);
    410434    asObject(properties)->methodTable(vm)->getOwnPropertyNames(asObject(properties), exec, propertyNames, EnumerationMode(DontEnumPropertiesMode::Exclude));
    411     RETURN_IF_EXCEPTION(scope, JSValue());
     435    RETURN_IF_EXCEPTION(scope, { });
    412436    size_t numProperties = propertyNames.size();
    413437    Vector<PropertyDescriptor> descriptors;
     
    415439    for (size_t i = 0; i < numProperties; i++) {
    416440        JSValue prop = properties->get(exec, propertyNames[i]);
    417         RETURN_IF_EXCEPTION(scope, JSValue());
     441        RETURN_IF_EXCEPTION(scope, { });
    418442        PropertyDescriptor descriptor;
    419         if (!toPropertyDescriptor(exec, prop, descriptor))
     443        bool success = toPropertyDescriptor(exec, prop, descriptor);
     444        ASSERT(!scope.exception() || !success);
     445        if (UNLIKELY(!success))
    420446            return jsNull();
    421447        descriptors.append(descriptor);
     
    432458    for (size_t i = 0; i < numProperties; i++) {
    433459        Identifier propertyName = propertyNames[i];
    434         if (exec->propertyNames().isPrivateName(propertyName))
     460        if (vm.propertyNames->isPrivateName(propertyName))
    435461            continue;
    436462        object->methodTable(vm)->defineOwnProperty(object, exec, propertyName, descriptors[i], true);
    437         RETURN_IF_EXCEPTION(scope, JSValue());
     463        RETURN_IF_EXCEPTION(scope, { });
    438464    }
    439465    return object;
     
    449475    JSObject* targetObj = asObject(exec->argument(0));
    450476    JSObject* props = exec->argument(1).toObject(exec);
    451     if (!props)
    452         return JSValue::encode(JSValue());
     477    ASSERT(!!scope.exception() == !props);
     478    if (UNLIKELY(!props))
     479        return encodedJSValue();
     480    scope.release();
    453481    return JSValue::encode(defineProperties(exec, targetObj, props));
    454482}
     
    469497    if (!exec->argument(1).isObject())
    470498        return throwVMTypeError(exec, scope, ASCIILiteral("Property descriptor list must be an Object."));
     499    scope.release();
    471500    return JSValue::encode(defineProperties(exec, newObject, asObject(exec->argument(1))));
    472501}
     
    502531            desc.setConfigurable(false);
    503532        else {
    504             if (!object->getOwnPropertyDescriptor(exec, propertyName, desc))
     533            bool hasPropertyDescriptor = object->getOwnPropertyDescriptor(exec, propertyName, desc);
     534            RETURN_IF_EXCEPTION(scope, false);
     535            if (!hasPropertyDescriptor)
    505536                continue;
    506537
     
    535566    bool success = setIntegrityLevel<IntegrityLevel::Sealed>(exec, vm, object);
    536567    RETURN_IF_EXCEPTION(scope, encodedJSValue());
    537     if (!success) {
     568    if (UNLIKELY(!success)) {
    538569        throwTypeError(exec, scope, ASCIILiteral("Unable to prevent extension in Object.seal"));
    539570        return encodedJSValue();
     
    575606EncodedJSValue JSC_HOST_CALL objectConstructorPreventExtensions(ExecState* exec)
    576607{
     608    VM& vm = exec->vm();
    577609    JSValue argument = exec->argument(0);
    578610    if (!argument.isObject())
    579611        return JSValue::encode(argument);
    580612    JSObject* object = asObject(argument);
    581     object->methodTable(exec->vm())->preventExtensions(object, exec);
     613    object->methodTable(vm)->preventExtensions(object, exec);
    582614    return JSValue::encode(object);
    583615}
     
    604636    for (PropertyNameArray::const_iterator iter = properties.begin(); iter != end; ++iter) {
    605637        Identifier propertyName = *iter;
    606         if (exec->propertyNames().isPrivateName(propertyName))
     638        if (vm.propertyNames->isPrivateName(propertyName))
    607639            continue;
    608640        // a. Let desc be the result of calling the [[GetOwnProperty]] internal method of O with P.
     
    643675    for (PropertyNameArray::const_iterator iter = properties.begin(); iter != end; ++iter) {
    644676        Identifier propertyName = *iter;
    645         if (exec->propertyNames().isPrivateName(propertyName))
     677        if (vm.propertyNames->isPrivateName(propertyName))
    646678            continue;
    647679        // a. Let desc be the result of calling the [[GetOwnProperty]] internal method of O with P.
     
    699731            ASSERT(!identifier.isSymbol());
    700732            keys->push(exec, jsOwnedString(exec, identifier.string()));
     733            RETURN_IF_EXCEPTION(scope, nullptr);
    701734        }
    702735        break;
     
    708741            const auto& identifier = properties[i];
    709742            ASSERT(identifier.isSymbol());
    710             if (!exec->propertyNames().isPrivateName(identifier))
     743            if (!vm.propertyNames->isPrivateName(identifier)) {
    711744                keys->push(exec, Symbol::create(vm, static_cast<SymbolImpl&>(*identifier.impl())));
     745                RETURN_IF_EXCEPTION(scope, nullptr);
     746            }
    712747        }
    713748        break;
     
    720755            const auto& identifier = properties[i];
    721756            if (identifier.isSymbol()) {
    722                 if (!exec->propertyNames().isPrivateName(identifier))
     757                if (!vm.propertyNames->isPrivateName(identifier))
    723758                    propertySymbols.append(identifier);
    724             } else
     759            } else {
    725760                keys->push(exec, jsOwnedString(exec, identifier.string()));
     761                RETURN_IF_EXCEPTION(scope, nullptr);
     762            }
    726763        }
    727764
    728765        // To ensure the order defined in the spec (9.1.12), we append symbols at the last elements of keys.
    729         for (const auto& identifier : propertySymbols)
     766        for (const auto& identifier : propertySymbols) {
    730767            keys->push(exec, Symbol::create(vm, static_cast<SymbolImpl&>(*identifier.impl())));
     768            RETURN_IF_EXCEPTION(scope, nullptr);
     769        }
    731770
    732771        break;
  • trunk/Source/JavaScriptCore/runtime/ObjectPrototype.cpp

    r208985 r209020  
    8484    JSValue thisValue = exec->thisValue().toThis(exec, StrictMode);
    8585    JSObject* valueObj = thisValue.toObject(exec);
    86     if (!valueObj)
    87         return JSValue::encode(JSValue());
     86    if (UNLIKELY(!valueObj))
     87        return encodedJSValue();
    8888    return JSValue::encode(valueObj);
    8989}
     
    9898    RETURN_IF_EXCEPTION(scope, encodedJSValue());
    9999    JSObject* thisObject = thisValue.toObject(exec);
     100    ASSERT(!!scope.exception() == !thisObject);
    100101    if (UNLIKELY(!thisObject))
    101         return JSValue::encode(JSValue());
     102        return encodedJSValue();
    102103
    103104    Structure* structure = thisObject->structure(vm);
     
    124125    JSValue thisValue = exec->thisValue().toThis(exec, StrictMode);
    125126    JSObject* thisObj = thisValue.toObject(exec);
    126     if (!thisObj)
    127         return JSValue::encode(JSValue());
     127    ASSERT(!!scope.exception() == !thisObj);
     128    if (UNLIKELY(!thisObj))
     129        return encodedJSValue();
    128130
    129131    if (!exec->argument(0).isObject())
     
    165167
    166168    bool shouldThrow = true;
     169    scope.release();
    167170    thisObject->methodTable(vm)->defineOwnProperty(thisObject, exec, propertyName, descriptor, shouldThrow);
    168171
     
    192195
    193196    bool shouldThrow = true;
     197    scope.release();
    194198    thisObject->methodTable(vm)->defineOwnProperty(thisObject, exec, propertyName, descriptor, shouldThrow);
    195199
     
    209213
    210214    PropertySlot slot(thisObject, PropertySlot::InternalMethodType::GetOwnProperty);
    211     if (thisObject->getPropertySlot(exec, propertyName, slot)) {
     215    bool hasProperty = thisObject->getPropertySlot(exec, propertyName, slot);
     216    ASSERT(!scope.exception() || !hasProperty);
     217    if (hasProperty) {
    212218        if (slot.isAccessor()) {
    213219            GetterSetter* getterSetter = slot.getterSetter();
     
    237243
    238244    PropertySlot slot(thisObject, PropertySlot::InternalMethodType::GetOwnProperty);
    239     if (thisObject->getPropertySlot(exec, propertyName, slot)) {
     245    bool hasProperty = thisObject->getPropertySlot(exec, propertyName, slot);
     246    ASSERT(!scope.exception() || !hasProperty);
     247    if (hasProperty) {
    240248        if (slot.isAccessor()) {
    241249            GetterSetter* getterSetter = slot.getterSetter();
     
    279287
    280288    // 2. Let toString be the result of calling the [[Get]] internal method of O passing "toString" as the argument.
    281     JSValue toString = object->get(exec, exec->propertyNames().toString);
     289    JSValue toString = object->get(exec, vm.propertyNames->toString);
     290    RETURN_IF_EXCEPTION(scope, encodedJSValue());
    282291
    283292    // 3. If IsCallable(toString) is false, throw a TypeError exception.
     
    288297
    289298    // 4. Return the result of calling the [[Call]] internal method of toString passing O as the this value and no arguments.
     299    scope.release();
    290300    return JSValue::encode(call(exec, toString, callType, callData, object, exec->emptyList()));
    291301}
     
    300310        return JSValue::encode(thisValue.isUndefined() ? vm.smallStrings.undefinedObjectString() : vm.smallStrings.nullObjectString());
    301311    JSObject* thisObject = thisValue.toObject(exec);
     312    ASSERT(!!scope.exception() == !thisObject);
    302313    if (!thisObject)
    303314        return JSValue::encode(jsUndefined());
     
    307318        return JSValue::encode(result);
    308319
    309     PropertyName toStringTagSymbol = exec->propertyNames().toStringTagSymbol;
     320    PropertyName toStringTagSymbol = vm.propertyNames->toStringTagSymbol;
     321    scope.release();
    310322    return JSValue::encode(thisObject->getPropertySlot(exec, toStringTagSymbol, [&] (bool found, PropertySlot& toStringTagSlot) -> JSValue {
    311323        if (found) {
    312324            JSValue stringTag = toStringTagSlot.getValue(exec, toStringTagSymbol);
    313             RETURN_IF_EXCEPTION(scope, JSValue());
     325            RETURN_IF_EXCEPTION(scope, { });
    314326            if (stringTag.isString()) {
    315327                JSRopeString::RopeBuilder ropeBuilder(vm);
     
    324336        }
    325337
    326         String tag = thisObject->methodTable(exec->vm())->toStringName(thisObject, exec);
    327         RETURN_IF_EXCEPTION(scope, JSValue());
     338        String tag = thisObject->methodTable(vm)->toStringName(thisObject, exec);
     339        RETURN_IF_EXCEPTION(scope, { });
    328340        String newString = WTF::tryMakeString("[object ", WTFMove(tag), "]");
    329341        if (!newString)
  • trunk/Source/WebCore/ChangeLog

    r209019 r209020  
     12016-11-28  Mark Lam  <mark.lam@apple.com>
     2
     3        Fix exception scope verification failures in ObjectConstructor.cpp and ObjectPrototype.cpp.
     4        https://bugs.webkit.org/show_bug.cgi?id=165051
     5
     6        Reviewed by Saam Barati.
     7
     8        No new tests because this is covered by the existing test
     9        http/tests/security/cross-frame-access-object-prototype.html with the help of a
     10        new ASSERT in ObjectPrototype.cpp.
     11
     12        Fixed jsDOMWindowGetOwnPropertySlotRestrictedAccess() to return false when it
     13        throws an exception.
     14
     15        * bindings/js/JSDOMWindowCustom.cpp:
     16        (WebCore::jsDOMWindowGetOwnPropertySlotRestrictedAccess):
     17
    1182016-11-28  Tim Horton  <timothy_horton@apple.com>
    219
  • trunk/Source/WebCore/bindings/js/JSDOMWindowCustom.cpp

    r208985 r209020  
    135135        throwSecurityError(*exec, scope, errorMessage);
    136136        slot.setUndefined();
    137         return true;
     137        return false;
    138138    }
    139139
     
    149149    throwSecurityError(*exec, scope, errorMessage);
    150150    slot.setUndefined();
    151     return true;
     151    return false;
    152152}
    153153
Note: See TracChangeset for help on using the changeset viewer.