javascriptcore bindings do not check exception after calling valueToStringWithNullCheck

https://bugs.webkit.org/show_bug.cgi?id=113219

Patch by Arnaud Renevier <a.renevier@sisa.samsung.com> on 2013-03-27
Reviewed by Kentaro Hara.

Source/WebCore:

When converting JSValue to native value in attribute setter, store the
native value in a temporary variable. After this variable assignment,
always check if an exception has been raised.

Update binding tests.

Test: fast/dom/exception-in-binding.html

* bindings/scripts/CodeGeneratorJS.pm:
(GenerateImplementation):
(GetNativeType):
(JSValueToNative):
* bindings/scripts/test/JS/JSTestInterface.cpp:
(WebCore::setJSTestInterfaceConstructorSupplementalStaticAttr):
(WebCore::setJSTestInterfaceSupplementalStr2):
(WebCore::setJSTestInterfaceSupplementalNode):
* bindings/scripts/test/JS/JSTestObj.cpp:
(WebCore::setJSTestObjConstructorStaticStringAttr):
(WebCore::setJSTestObjEnumAttr):
(WebCore::setJSTestObjShortAttr):
(WebCore::setJSTestObjUnsignedShortAttr):
(WebCore::setJSTestObjLongAttr):
(WebCore::setJSTestObjLongLongAttr):
(WebCore::setJSTestObjUnsignedLongLongAttr):
(WebCore::setJSTestObjStringAttr):
(WebCore::setJSTestObjTestObjAttr):
(WebCore::setJSTestObjXMLObjAttr):
(WebCore::setJSTestObjCreate):
(WebCore::setJSTestObjReflectedStringAttr):
(WebCore::setJSTestObjReflectedIntegralAttr):
(WebCore::setJSTestObjReflectedUnsignedIntegralAttr):
(WebCore::setJSTestObjReflectedBooleanAttr):
(WebCore::setJSTestObjReflectedURLAttr):
(WebCore::setJSTestObjReflectedCustomIntegralAttr):
(WebCore::setJSTestObjReflectedCustomBooleanAttr):
(WebCore::setJSTestObjReflectedCustomURLAttr):
(WebCore::setJSTestObjTypedArrayAttr):
(WebCore::setJSTestObjAttrWithGetterException):
(WebCore::setJSTestObjAttrWithSetterException):
(WebCore::setJSTestObjStringAttrWithGetterException):
(WebCore::setJSTestObjStringAttrWithSetterException):
(WebCore::setJSTestObjWithScriptStateAttribute):
(WebCore::setJSTestObjWithScriptExecutionContextAttribute):
(WebCore::setJSTestObjWithScriptStateAttributeRaises):
(WebCore::setJSTestObjWithScriptExecutionContextAttributeRaises):
(WebCore::setJSTestObjWithScriptExecutionContextAndScriptStateAttribute):
(WebCore::setJSTestObjWithScriptExecutionContextAndScriptStateAttributeRaises):
(WebCore::setJSTestObjWithScriptExecutionContextAndScriptStateWithSpacesAttribute):
(WebCore::setJSTestObjWithScriptArgumentsAndCallStackAttribute):
(WebCore::setJSTestObjConditionalAttr1):
(WebCore::setJSTestObjConditionalAttr2):
(WebCore::setJSTestObjConditionalAttr3):
(WebCore::setJSTestObjAnyAttribute):
(WebCore::setJSTestObjMutablePoint):
(WebCore::setJSTestObjImmutablePoint):
(WebCore::setJSTestObjStrawberry):
(WebCore::setJSTestObjStrictFloat):
(WebCore::setJSTestObjId):
(WebCore::setJSTestObjNullableLongSettableAttribute):
(WebCore::setJSTestObjNullableStringValue):
* bindings/scripts/test/JS/JSTestSerializedScriptValueInterface.cpp:
(WebCore::setJSTestSerializedScriptValueInterfaceValue):
(WebCore::setJSTestSerializedScriptValueInterfaceCachedValue):
* bindings/scripts/test/JS/JSTestTypedefs.cpp:
(WebCore::setJSTestTypedefsUnsignedLongLongAttr):
(WebCore::setJSTestTypedefsImmutableSerializedScriptValue):
(WebCore::setJSTestTypedefsAttrWithGetterException):
(WebCore::setJSTestTypedefsAttrWithSetterException):
(WebCore::setJSTestTypedefsStringAttrWithGetterException):
(WebCore::setJSTestTypedefsStringAttrWithSetterException):

LayoutTests:

* fast/dom/exception-in-binding-expected.txt: Added.
* fast/dom/exception-in-binding.html: Added.
* platform/chromium/TestExpectations: new test fails for now

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@147038 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 05240e15
2013-03-27 Arnaud Renevier <a.renevier@sisa.samsung.com>
javascriptcore bindings do not check exception after calling valueToStringWithNullCheck
https://bugs.webkit.org/show_bug.cgi?id=113219
Reviewed by Kentaro Hara.
* fast/dom/exception-in-binding-expected.txt: Added.
* fast/dom/exception-in-binding.html: Added.
* platform/chromium/TestExpectations: new test fails for now
2013-03-27 Claudio Saavedra <csaavedra@igalia.com>
Explicitly set editingBehavior in some tests.
Tests to ensure that attributes are not set when an exceptions is raised while converting argument to JSValue.
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
PASS select.name is "select"
PASS select.selectedIndex is 1
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="../js/resources/js-test-pre.js"></script>
<script>
description("Tests to ensure that attributes are not set when an exceptions is raised while converting argument to JSValue.");
function setName(select) {
var stringLike = {
toString: function() {
throw new Error("error");
}
};
select.name = stringLike;;
}
function setSelectedIndex(select) {
var integerLike = {
valueOf: function() {
throw new Error("error");
}
};
select.selectedIndex = integerLike;;
}
function runTest() {
var select = document.getElementById("select");
try {
setName(select);
} catch(e) {
}
shouldBe('select.name', '"select"');
try {
setSelectedIndex(select);
} catch(e) {
}
shouldBe('select.selectedIndex', '1');
}
</script>
</head>
<body onload="runTest()">
<select id="select" name="select">
<option value="value1">Value 1</option>
<option value="value2" selected>Value 2</option>
<option value="value3">Value 3</option>
</select>
<p id="description"></p>
<script src="../js/resources/js-test-pre.js"></script>
</body>
</html>
......@@ -3798,3 +3798,5 @@ crbug.com/223329 [ MountainLion ] fast/writing-mode/text-orientation-basic.html
crbug.com/223332 svg/css/root-shadow-offscreen.svg [ ImageOnlyFailure ]
webkit.org/b/113114 media/video-controls-captions.html [ Timeout ]
webkit.org/b/113219 fast/dom/exception-in-binding.html [ Failure ]
2013-03-27 Arnaud Renevier <a.renevier@sisa.samsung.com>
javascriptcore bindings do not check exception after calling valueToStringWithNullCheck
https://bugs.webkit.org/show_bug.cgi?id=113219
Reviewed by Kentaro Hara.
When converting JSValue to native value in attribute setter, store the
native value in a temporary variable. After this variable assignment,
always check if an exception has been raised.
Update binding tests.
Test: fast/dom/exception-in-binding.html
* bindings/scripts/CodeGeneratorJS.pm:
(GenerateImplementation):
(GetNativeType):
(JSValueToNative):
* bindings/scripts/test/JS/JSTestInterface.cpp:
(WebCore::setJSTestInterfaceConstructorSupplementalStaticAttr):
(WebCore::setJSTestInterfaceSupplementalStr2):
(WebCore::setJSTestInterfaceSupplementalNode):
* bindings/scripts/test/JS/JSTestObj.cpp:
(WebCore::setJSTestObjConstructorStaticStringAttr):
(WebCore::setJSTestObjEnumAttr):
(WebCore::setJSTestObjShortAttr):
(WebCore::setJSTestObjUnsignedShortAttr):
(WebCore::setJSTestObjLongAttr):
(WebCore::setJSTestObjLongLongAttr):
(WebCore::setJSTestObjUnsignedLongLongAttr):
(WebCore::setJSTestObjStringAttr):
(WebCore::setJSTestObjTestObjAttr):
(WebCore::setJSTestObjXMLObjAttr):
(WebCore::setJSTestObjCreate):
(WebCore::setJSTestObjReflectedStringAttr):
(WebCore::setJSTestObjReflectedIntegralAttr):
(WebCore::setJSTestObjReflectedUnsignedIntegralAttr):
(WebCore::setJSTestObjReflectedBooleanAttr):
(WebCore::setJSTestObjReflectedURLAttr):
(WebCore::setJSTestObjReflectedCustomIntegralAttr):
(WebCore::setJSTestObjReflectedCustomBooleanAttr):
(WebCore::setJSTestObjReflectedCustomURLAttr):
(WebCore::setJSTestObjTypedArrayAttr):
(WebCore::setJSTestObjAttrWithGetterException):
(WebCore::setJSTestObjAttrWithSetterException):
(WebCore::setJSTestObjStringAttrWithGetterException):
(WebCore::setJSTestObjStringAttrWithSetterException):
(WebCore::setJSTestObjWithScriptStateAttribute):
(WebCore::setJSTestObjWithScriptExecutionContextAttribute):
(WebCore::setJSTestObjWithScriptStateAttributeRaises):
(WebCore::setJSTestObjWithScriptExecutionContextAttributeRaises):
(WebCore::setJSTestObjWithScriptExecutionContextAndScriptStateAttribute):
(WebCore::setJSTestObjWithScriptExecutionContextAndScriptStateAttributeRaises):
(WebCore::setJSTestObjWithScriptExecutionContextAndScriptStateWithSpacesAttribute):
(WebCore::setJSTestObjWithScriptArgumentsAndCallStackAttribute):
(WebCore::setJSTestObjConditionalAttr1):
(WebCore::setJSTestObjConditionalAttr2):
(WebCore::setJSTestObjConditionalAttr3):
(WebCore::setJSTestObjAnyAttribute):
(WebCore::setJSTestObjMutablePoint):
(WebCore::setJSTestObjImmutablePoint):
(WebCore::setJSTestObjStrawberry):
(WebCore::setJSTestObjStrictFloat):
(WebCore::setJSTestObjId):
(WebCore::setJSTestObjNullableLongSettableAttribute):
(WebCore::setJSTestObjNullableStringValue):
* bindings/scripts/test/JS/JSTestSerializedScriptValueInterface.cpp:
(WebCore::setJSTestSerializedScriptValueInterfaceValue):
(WebCore::setJSTestSerializedScriptValueInterfaceCachedValue):
* bindings/scripts/test/JS/JSTestTypedefs.cpp:
(WebCore::setJSTestTypedefsUnsignedLongLongAttr):
(WebCore::setJSTestTypedefsImmutableSerializedScriptValue):
(WebCore::setJSTestTypedefsAttrWithGetterException):
(WebCore::setJSTestTypedefsAttrWithSetterException):
(WebCore::setJSTestTypedefsStringAttrWithGetterException):
(WebCore::setJSTestTypedefsStringAttrWithSetterException):
2013-03-27 Arnaud Renevier <a.renevier@sisa.samsung.com>
cache parsed interfaces in CodeGenerator.pm
......@@ -2142,21 +2142,18 @@ sub GenerateImplementation
}
}
my $nativeValue;
push(@implContent, " " . GetNativeTypeFromSignature($attribute->signature) . " nativeValue(" . JSValueToNative($attribute->signature, "value") . ");\n");
push(@implContent, " if (exec->hadException())\n");
push(@implContent, " return;\n");
if ($codeGenerator->IsEnumType($type)) {
push(@implContent, " const String string = value.isEmpty() ? String() : value.toString(exec)->value(exec);\n");
push(@implContent, " if (exec->hadException())\n");
push(@implContent, " return;\n");
my @enumValues = $codeGenerator->ValidEnumValues($type);
my @enumChecks = ();
foreach my $enumValue (@enumValues) {
push(@enumChecks, "string != \"$enumValue\"");
push(@enumChecks, "nativeValue != \"$enumValue\"");
}
push (@implContent, " if (" . join(" && ", @enumChecks) . ")\n");
push (@implContent, " return;\n");
$nativeValue = "string";
} else {
$nativeValue = JSValueToNative($attribute->signature, "value");
}
if ($svgPropertyOrListPropertyType) {
......@@ -2169,9 +2166,9 @@ sub GenerateImplementation
}
push(@implContent, " $svgPropertyOrListPropertyType& podImpl = impl->propertyReference();\n");
if ($svgPropertyOrListPropertyType eq "float") { # Special case for JSSVGNumber
push(@implContent, " podImpl = $nativeValue;\n");
push(@implContent, " podImpl = nativeValue;\n");
} else {
push(@implContent, " podImpl.set$implSetterFunctionName($nativeValue");
push(@implContent, " podImpl.set$implSetterFunctionName(nativeValue");
push(@implContent, ", ec") if @{$attribute->setterExceptions};
push(@implContent, ");\n");
push(@implContent, " setDOMException(exec, ec);\n") if @{$attribute->setterExceptions};
......@@ -2186,7 +2183,7 @@ sub GenerateImplementation
}
} else {
my ($functionName, @arguments) = $codeGenerator->SetterExpression(\%implIncludes, $interfaceName, $attribute);
push(@arguments, $nativeValue);
push(@arguments, "nativeValue");
if ($attribute->signature->extendedAttributes->{"ImplementedBy"}) {
my $implementedBy = $attribute->signature->extendedAttributes->{"ImplementedBy"};
$implIncludes{"${implementedBy}.h"} = 1;
......@@ -3097,6 +3094,7 @@ my %nativeType = (
"DOMString" => "const String&",
"NodeFilter" => "RefPtr<NodeFilter>",
"SerializedScriptValue" => "RefPtr<SerializedScriptValue>",
"Date" => "double",
"Dictionary" => "Dictionary",
"any" => "ScriptValue",
"boolean" => "bool",
......@@ -3127,6 +3125,10 @@ sub GetNativeType
return "Vector<" . GetNativeVectorInnerType($arrayOrSequenceType) . ">" if $arrayOrSequenceType;
if ($codeGenerator->IsEnumType($type)) {
return "const String";
}
# For all other types, the native type is a pointer with same type name as the IDL type.
return "${type}*";
}
......@@ -3273,6 +3275,10 @@ sub JSValueToNative
return "toNativeArray<" . GetNativeVectorInnerType($arrayOrSequenceType) . ">(exec, $value)";
}
if ($codeGenerator->IsEnumType($type)) {
return "$value.isEmpty() ? String() : $value.toString(exec)->value(exec)";
}
# Default, assume autogenerated type conversion routines
AddToImplIncludes("JS$type.h", $conditional);
return "to$type($value)";
......
......@@ -339,7 +339,10 @@ void JSTestInterface::putByIndex(JSCell* cell, ExecState* exec, unsigned index,
void setJSTestInterfaceConstructorSupplementalStaticAttr(ExecState* exec, JSObject*, JSValue value)
{
UNUSED_PARAM(exec);
TestSupplemental::setSupplementalStaticAttr(value.isEmpty() ? String() : value.toString(exec)->value(exec));
const String& nativeValue(value.isEmpty() ? String() : value.toString(exec)->value(exec));
if (exec->hadException())
return;
TestSupplemental::setSupplementalStaticAttr(nativeValue);
}
#endif
......@@ -350,7 +353,10 @@ void setJSTestInterfaceSupplementalStr2(ExecState* exec, JSObject* thisObject, J
UNUSED_PARAM(exec);
JSTestInterface* castedThis = jsCast<JSTestInterface*>(thisObject);
TestInterface* impl = static_cast<TestInterface*>(castedThis->impl());
TestSupplemental::setSupplementalStr2(impl, value.isEmpty() ? String() : value.toString(exec)->value(exec));
const String& nativeValue(value.isEmpty() ? String() : value.toString(exec)->value(exec));
if (exec->hadException())
return;
TestSupplemental::setSupplementalStr2(impl, nativeValue);
}
#endif
......@@ -370,7 +376,10 @@ void setJSTestInterfaceSupplementalNode(ExecState* exec, JSObject* thisObject, J
UNUSED_PARAM(exec);
JSTestInterface* castedThis = jsCast<JSTestInterface*>(thisObject);
TestInterface* impl = static_cast<TestInterface*>(castedThis->impl());
TestSupplemental::setSupplementalNode(impl, toNode(value));
Node* nativeValue(toNode(value));
if (exec->hadException())
return;
TestSupplemental::setSupplementalNode(impl, nativeValue);
}
#endif
......
......@@ -257,7 +257,10 @@ void setJSTestSerializedScriptValueInterfaceValue(ExecState* exec, JSObject* thi
UNUSED_PARAM(exec);
JSTestSerializedScriptValueInterface* castedThis = jsCast<JSTestSerializedScriptValueInterface*>(thisObject);
TestSerializedScriptValueInterface* impl = static_cast<TestSerializedScriptValueInterface*>(castedThis->impl());
impl->setValue(SerializedScriptValue::create(exec, value, 0, 0));
RefPtr<SerializedScriptValue> nativeValue(SerializedScriptValue::create(exec, value, 0, 0));
if (exec->hadException())
return;
impl->setValue(nativeValue);
}
......@@ -266,7 +269,10 @@ void setJSTestSerializedScriptValueInterfaceCachedValue(ExecState* exec, JSObjec
UNUSED_PARAM(exec);
JSTestSerializedScriptValueInterface* castedThis = jsCast<JSTestSerializedScriptValueInterface*>(thisObject);
TestSerializedScriptValueInterface* impl = static_cast<TestSerializedScriptValueInterface*>(castedThis->impl());
impl->setCachedValue(SerializedScriptValue::create(exec, value, 0, 0));
RefPtr<SerializedScriptValue> nativeValue(SerializedScriptValue::create(exec, value, 0, 0));
if (exec->hadException())
return;
impl->setCachedValue(nativeValue);
}
......
......@@ -280,7 +280,10 @@ void setJSTestTypedefsUnsignedLongLongAttr(ExecState* exec, JSObject* thisObject
UNUSED_PARAM(exec);
JSTestTypedefs* castedThis = jsCast<JSTestTypedefs*>(thisObject);
TestTypedefs* impl = static_cast<TestTypedefs*>(castedThis->impl());
impl->setUnsignedLongLongAttr(toUInt64(exec, value, NormalConversion));
unsigned long long nativeValue(toUInt64(exec, value, NormalConversion));
if (exec->hadException())
return;
impl->setUnsignedLongLongAttr(nativeValue);
}
......@@ -289,7 +292,10 @@ void setJSTestTypedefsImmutableSerializedScriptValue(ExecState* exec, JSObject*
UNUSED_PARAM(exec);
JSTestTypedefs* castedThis = jsCast<JSTestTypedefs*>(thisObject);
TestTypedefs* impl = static_cast<TestTypedefs*>(castedThis->impl());
impl->setImmutableSerializedScriptValue(SerializedScriptValue::create(exec, value, 0, 0));
RefPtr<SerializedScriptValue> nativeValue(SerializedScriptValue::create(exec, value, 0, 0));
if (exec->hadException())
return;
impl->setImmutableSerializedScriptValue(nativeValue);
}
......@@ -298,7 +304,10 @@ void setJSTestTypedefsAttrWithGetterException(ExecState* exec, JSObject* thisObj
UNUSED_PARAM(exec);
JSTestTypedefs* castedThis = jsCast<JSTestTypedefs*>(thisObject);
TestTypedefs* impl = static_cast<TestTypedefs*>(castedThis->impl());
impl->setAttrWithGetterException(toInt32(exec, value, NormalConversion));
int nativeValue(toInt32(exec, value, NormalConversion));
if (exec->hadException())
return;
impl->setAttrWithGetterException(nativeValue);
}
......@@ -308,7 +317,10 @@ void setJSTestTypedefsAttrWithSetterException(ExecState* exec, JSObject* thisObj
JSTestTypedefs* castedThis = jsCast<JSTestTypedefs*>(thisObject);
TestTypedefs* impl = static_cast<TestTypedefs*>(castedThis->impl());
ExceptionCode ec = 0;
impl->setAttrWithSetterException(toInt32(exec, value, NormalConversion), ec);
int nativeValue(toInt32(exec, value, NormalConversion));
if (exec->hadException())
return;
impl->setAttrWithSetterException(nativeValue, ec);
setDOMException(exec, ec);
}
......@@ -318,7 +330,10 @@ void setJSTestTypedefsStringAttrWithGetterException(ExecState* exec, JSObject* t
UNUSED_PARAM(exec);
JSTestTypedefs* castedThis = jsCast<JSTestTypedefs*>(thisObject);
TestTypedefs* impl = static_cast<TestTypedefs*>(castedThis->impl());
impl->setStringAttrWithGetterException(value.isEmpty() ? String() : value.toString(exec)->value(exec));
const String& nativeValue(value.isEmpty() ? String() : value.toString(exec)->value(exec));
if (exec->hadException())
return;
impl->setStringAttrWithGetterException(nativeValue);
}
......@@ -328,7 +343,10 @@ void setJSTestTypedefsStringAttrWithSetterException(ExecState* exec, JSObject* t
JSTestTypedefs* castedThis = jsCast<JSTestTypedefs*>(thisObject);
TestTypedefs* impl = static_cast<TestTypedefs*>(castedThis->impl());
ExceptionCode ec = 0;
impl->setStringAttrWithSetterException(value.isEmpty() ? String() : value.toString(exec)->value(exec), ec);
const String& nativeValue(value.isEmpty() ? String() : value.toString(exec)->value(exec));
if (exec->hadException())
return;
impl->setStringAttrWithSetterException(nativeValue, ec);
setDOMException(exec, ec);
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment