Commit 239499fd authored by oliver@apple.com's avatar oliver@apple.com

Add more type validation to debug builds

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

Reviewed by Mark Hahnenberg.

Source/WebCore:

Add a bunch more type checks to the JS DOM bindings.

* Modules/mediastream/MediaStream.idl:
* Modules/webaudio/AudioDestinationNode.idl:
* WebCore.xcodeproj/project.pbxproj:
* bindings/js/JSDOMBinding.h:
(WebCore::getExistingWrapper):
(WebCore):
(WebCore::createNewWrapper):
* bindings/scripts/CodeGeneratorJS.pm:
(GetNativeTypeForConversions):
(GetGnuVTableRefForInterface):
(GetGnuVTableNameForInterface):
(GetGnuMangledNameForInterface):
(GetGnuVTableOffsetForType):
(GetWinVTableRefForInterface):
(GetWinVTableNameForInterface):
(GetWinMangledNameForInterface):
(GetNamespaceForInterface):
(GetImplementationLacksVTableForInterface):
(GetSkipVTableValidationForInterface):
(GenerateImplementation):
* bindings/scripts/IDLAttributes.txt:
* css/CSSRuleList.idl:
* css/CSSStyleDeclaration.idl:
* dom/Clipboard.idl:
* dom/DOMStringMap.idl:
* dom/MutationRecord.idl:
* dom/NodeList.idl:
* html/DOMTokenList.idl:
* html/track/TextTrack.idl:
* inspector/ScriptProfileNode.idl:
* storage/Storage.idl:
* xml/XPathNSResolver.idl:

Source/WTF:

Add BINDING_VALIDATION flag and make RELEASE_ASSERT use UNLIKELY.

* wtf/Assertions.h:
* wtf/Platform.h:

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@148257 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent fbdf3b6d
2013-04-11 Oliver Hunt <oliver@apple.com>
Add more type validation to debug builds
https://bugs.webkit.org/show_bug.cgi?id=114478
Reviewed by Mark Hahnenberg.
Add BINDING_VALIDATION flag and make RELEASE_ASSERT use UNLIKELY.
* wtf/Assertions.h:
* wtf/Platform.h:
2013-04-10 Thiago Marcos P. Santos <thiago.santos@intel.com>
[WTF] Get rid of truncated thread name warnings for non-Windows platforms
......
......@@ -416,7 +416,7 @@ static inline void UNREACHABLE_FOR_PLATFORM()
#endif
#if ASSERT_DISABLED
#define RELEASE_ASSERT(assertion) (!(assertion) ? (CRASH()) : (void)0)
#define RELEASE_ASSERT(assertion) (UNLIKELY(!(assertion)) ? (CRASH()) : (void)0)
#define RELEASE_ASSERT_WITH_MESSAGE(assertion, ...) RELEASE_ASSERT(assertion)
#define RELEASE_ASSERT_NOT_REACHED() CRASH()
#else
......
......@@ -965,6 +965,10 @@
#define ENABLE_GC_VALIDATION 1
#endif
#if !defined(ENABLE_BINDING_INTEGRITY)
#define ENABLE_BINDING_INTEGRITY 1
#endif
#if PLATFORM(MAC) && !PLATFORM(IOS) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
#define WTF_USE_AVFOUNDATION 1
#endif
......
2013-04-11 Oliver Hunt <oliver@apple.com>
Add more type validation to debug builds
https://bugs.webkit.org/show_bug.cgi?id=114478
Reviewed by Mark Hahnenberg.
Add a bunch more type checks to the JS DOM bindings.
* Modules/mediastream/MediaStream.idl:
* Modules/webaudio/AudioDestinationNode.idl:
* WebCore.xcodeproj/project.pbxproj:
* bindings/js/JSDOMBinding.h:
(WebCore::getExistingWrapper):
(WebCore):
(WebCore::createNewWrapper):
* bindings/scripts/CodeGeneratorJS.pm:
(GetNativeTypeForConversions):
(GetGnuVTableRefForInterface):
(GetGnuVTableNameForInterface):
(GetGnuMangledNameForInterface):
(GetGnuVTableOffsetForType):
(GetWinVTableRefForInterface):
(GetWinVTableNameForInterface):
(GetWinMangledNameForInterface):
(GetNamespaceForInterface):
(GetImplementationLacksVTableForInterface):
(GetSkipVTableValidationForInterface):
(GenerateImplementation):
* bindings/scripts/IDLAttributes.txt:
* css/CSSRuleList.idl:
* css/CSSStyleDeclaration.idl:
* dom/Clipboard.idl:
* dom/DOMStringMap.idl:
* dom/MutationRecord.idl:
* dom/NodeList.idl:
* html/DOMTokenList.idl:
* html/track/TextTrack.idl:
* inspector/ScriptProfileNode.idl:
* storage/Storage.idl:
* xml/XPathNSResolver.idl:
2013-04-11 Ryosuke Niwa <rniwa@webkit.org>
Remove ResourceLoadInfo
......@@ -30,7 +30,7 @@
Constructor(in MediaStreamTrack[] tracks),
ConstructorParameters=0,
CallWith=ScriptExecutionContext,
V8SkipVTableValidation
SkipVTableValidation
] interface MediaStream {
// DEPRECATED
readonly attribute DOMString label;
......
......@@ -25,7 +25,7 @@
[
Conditional=WEB_AUDIO,
JSGenerateToJSObject,
V8SkipVTableValidation
SkipVTableValidation
] interface AudioDestinationNode : AudioNode {
readonly attribute unsigned long maxChannelCount;
};
......@@ -9984,6 +9984,14 @@
A7DB418114CE1F0A00A2E316 /* ShadowRoot.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ShadowRoot.idl; sourceTree = "<group>"; };
A7DBF8DB1276919C006B6008 /* TextCheckingHelper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TextCheckingHelper.cpp; sourceTree = "<group>"; };
A7DBF8DC1276919C006B6008 /* TextCheckingHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextCheckingHelper.h; sourceTree = "<group>"; };
A7F1F4BA17148BDB00CD4852 /* DOMWindowQuota.idl */ = {isa = PBXFileReference; lastKnownFileType = text; name = DOMWindowQuota.idl; path = Modules/quota/DOMWindowQuota.idl; sourceTree = SOURCE_ROOT; };
A7F1F4BB17148BDB00CD4852 /* NavigatorStorageQuota.idl */ = {isa = PBXFileReference; lastKnownFileType = text; name = NavigatorStorageQuota.idl; path = Modules/quota/NavigatorStorageQuota.idl; sourceTree = SOURCE_ROOT; };
A7F1F4BC17148BDB00CD4852 /* StorageErrorCallback.idl */ = {isa = PBXFileReference; lastKnownFileType = text; name = StorageErrorCallback.idl; path = Modules/quota/StorageErrorCallback.idl; sourceTree = SOURCE_ROOT; };
A7F1F4BD17148BDB00CD4852 /* StorageInfo.idl */ = {isa = PBXFileReference; lastKnownFileType = text; name = StorageInfo.idl; path = Modules/quota/StorageInfo.idl; sourceTree = SOURCE_ROOT; };
A7F1F4BE17148BDB00CD4852 /* StorageQuota.idl */ = {isa = PBXFileReference; lastKnownFileType = text; name = StorageQuota.idl; path = Modules/quota/StorageQuota.idl; sourceTree = SOURCE_ROOT; };
A7F1F4BF17148BDB00CD4852 /* StorageQuotaCallback.idl */ = {isa = PBXFileReference; lastKnownFileType = text; name = StorageQuotaCallback.idl; path = Modules/quota/StorageQuotaCallback.idl; sourceTree = SOURCE_ROOT; };
A7F1F4C017148BDB00CD4852 /* StorageUsageCallback.idl */ = {isa = PBXFileReference; lastKnownFileType = text; name = StorageUsageCallback.idl; path = Modules/quota/StorageUsageCallback.idl; sourceTree = SOURCE_ROOT; };
A7F1F4C117148BDB00CD4852 /* WorkerNavigatorStorageQuota.idl */ = {isa = PBXFileReference; lastKnownFileType = text; name = WorkerNavigatorStorageQuota.idl; path = Modules/quota/WorkerNavigatorStorageQuota.idl; sourceTree = SOURCE_ROOT; };
A7F5D94D1384F02D00A29A87 /* NodeRenderingContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NodeRenderingContext.cpp; sourceTree = "<group>"; };
A7F5D94E1384F02D00A29A87 /* NodeRenderingContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NodeRenderingContext.h; sourceTree = "<group>"; };
A7F73ED9169AD7AA00CBAA4B /* DOMShadowRoot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMShadowRoot.h; sourceTree = "<group>"; };
......@@ -15470,6 +15478,14 @@
89F60B17157F6A020075E157 /* Quota */ = {
isa = PBXGroup;
children = (
A7F1F4BA17148BDB00CD4852 /* DOMWindowQuota.idl */,
A7F1F4BB17148BDB00CD4852 /* NavigatorStorageQuota.idl */,
A7F1F4BC17148BDB00CD4852 /* StorageErrorCallback.idl */,
A7F1F4BD17148BDB00CD4852 /* StorageInfo.idl */,
A7F1F4BE17148BDB00CD4852 /* StorageQuota.idl */,
A7F1F4BF17148BDB00CD4852 /* StorageQuotaCallback.idl */,
A7F1F4C017148BDB00CD4852 /* StorageUsageCallback.idl */,
A7F1F4C117148BDB00CD4852 /* WorkerNavigatorStorageQuota.idl */,
892ABE5F16EEE2E5009F3587 /* JSDOMWindowQuota.h */,
892ABE5C16EEE2AA009F3587 /* JSNavigatorStorageQuota.cpp */,
892ABE5D16EEE2AA009F3587 /* JSNavigatorStorageQuota.h */,
......@@ -200,6 +200,19 @@ class DOMStringList;
return createWrapper<WrapperClass>(exec, globalObject, domObject);
}
template<class WrapperClass, class DOMClass> inline JSC::JSValue getExistingWrapper(JSC::ExecState* exec, DOMClass* domObject)
{
ASSERT(domObject);
return getCachedWrapper(currentWorld(exec), domObject);
}
template<class WrapperClass, class DOMClass> inline JSC::JSValue createNewWrapper(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, DOMClass* domObject)
{
ASSERT(domObject);
ASSERT(!getCachedWrapper(currentWorld(exec), domObject));
return createWrapper<WrapperClass>(exec, globalObject, domObject);
}
inline JSC::JSValue argumentOrNull(JSC::ExecState* exec, unsigned index)
{
return index >= exec->argumentCount() ? JSC::JSValue() : exec->argument(index);
......
......@@ -9,6 +9,7 @@
# Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
# Copyright (C) 2011 Patrick Gansterer <paroga@webkit.org>
# Copyright (C) 2012 Ericsson AB. All rights reserved.
# Copyright (C) 2007, 2008, 2009, 2012 Google Inc.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Library General Public
......@@ -1395,6 +1396,128 @@ END
END
}
sub GetNativeTypeForConversions
{
my $interface = shift;
my $interfaceName = $interface->name;
$interfaceName = $codeGenerator->GetSVGTypeNeedingTearOff($interfaceName) if $codeGenerator->IsSVGTypeNeedingTearOff($interfaceName);
return $interfaceName;
}
# See http://refspecs.linux-foundation.org/cxxabi-1.83.html.
sub GetGnuVTableRefForInterface
{
my $interface = shift;
my $vtableName = GetGnuVTableNameForInterface($interface);
if (!$vtableName) {
return "0";
}
my $typename = GetNativeTypeForConversions($interface);
my $offset = GetGnuVTableOffsetForType($typename);
return "&" . $vtableName . "[" . $offset . "]";
}
sub GetGnuVTableNameForInterface
{
my $interface = shift;
my $typename = GetNativeTypeForConversions($interface);
my $templatePosition = index($typename, "<");
return "" if $templatePosition != -1;
return "" if GetImplementationLacksVTableForInterface($interface);
return "" if GetSkipVTableValidationForInterface($interface);
return "_ZTV" . GetGnuMangledNameForInterface($interface);
}
sub GetGnuMangledNameForInterface
{
my $interface = shift;
my $typename = GetNativeTypeForConversions($interface);
my $templatePosition = index($typename, "<");
if ($templatePosition != -1) {
return "";
}
my $mangledType = length($typename) . $typename;
my $namespace = GetNamespaceForInterface($interface);
my $mangledNamespace = "N" . length($namespace) . $namespace;
return $mangledNamespace . $mangledType . "E";
}
sub GetGnuVTableOffsetForType
{
my $typename = shift;
if ($typename eq "SVGAElement"
|| $typename eq "SVGCircleElement"
|| $typename eq "SVGClipPathElement"
|| $typename eq "SVGDefsElement"
|| $typename eq "SVGEllipseElement"
|| $typename eq "SVGForeignObjectElement"
|| $typename eq "SVGGElement"
|| $typename eq "SVGImageElement"
|| $typename eq "SVGLineElement"
|| $typename eq "SVGPathElement"
|| $typename eq "SVGPolyElement"
|| $typename eq "SVGPolygonElement"
|| $typename eq "SVGPolylineElement"
|| $typename eq "SVGRectElement"
|| $typename eq "SVGSVGElement"
|| $typename eq "SVGStyledLocatableElement"
|| $typename eq "SVGStyledTransformableElement"
|| $typename eq "SVGSwitchElement"
|| $typename eq "SVGTextElement"
|| $typename eq "SVGTransformable"
|| $typename eq "SVGUseElement") {
return "3";
}
return "2";
}
# See http://en.wikipedia.org/wiki/Microsoft_Visual_C%2B%2B_Name_Mangling.
sub GetWinVTableRefForInterface
{
my $interface = shift;
my $vtableName = GetWinVTableNameForInterface($interface);
return 0 if !$vtableName;
return "__identifier(\"" . $vtableName . "\")";
}
sub GetWinVTableNameForInterface
{
my $interface = shift;
my $typename = GetNativeTypeForConversions($interface);
my $templatePosition = index($typename, "<");
return "" if $templatePosition != -1;
return "" if GetImplementationLacksVTableForInterface($interface);
return "" if GetSkipVTableValidationForInterface($interface);
return "??_7" . GetWinMangledNameForInterface($interface) . "6B@";
}
sub GetWinMangledNameForInterface
{
my $interface = shift;
my $typename = GetNativeTypeForConversions($interface);
my $namespace = GetNamespaceForInterface($interface);
return $typename . "@" . $namespace . "@@";
}
sub GetNamespaceForInterface
{
my $interface = shift;
return $interface->extendedAttributes->{"ImplementationNamespace"} || "WebCore";
}
sub GetImplementationLacksVTableForInterface
{
my $interface = shift;
return $interface->extendedAttributes->{"ImplementationLacksVTable"};
}
sub GetSkipVTableValidationForInterface
{
my $interface = shift;
return $interface->extendedAttributes->{"SkipVTableValidation"};
}
sub GenerateImplementation
{
my ($object, $interface) = @_;
......@@ -1922,7 +2045,6 @@ sub GenerateImplementation
}
unshift(@arguments, @callWithArgs);
my $jsType = NativeToJSValue($attribute->signature, 0, $interfaceName, "${functionName}(" . join(", ", @arguments) . ")", "castedThis");
push(@implContent, " $interfaceName* impl = static_cast<$interfaceName*>(castedThis->impl());\n") if !$attribute->isStatic;
if ($codeGenerator->IsSVGAnimatedType($type)) {
......@@ -2578,13 +2700,59 @@ sub GenerateImplementation
}
if (ShouldGenerateToJSImplementation($hasParent, $interface)) {
my $vtableNameGnu = GetGnuVTableNameForInterface($interface);
my $vtableRefGnu = GetGnuVTableRefForInterface($interface);
my $vtableRefWin = GetWinVTableRefForInterface($interface);
push(@implContent, <<END) if $vtableNameGnu;
#if ENABLE(BINDING_INTEGRITY)
#if defined(OS_WIN)
#pragma warning(disable: 4483)
extern "C" { extern void (*const ${vtableRefWin}[])(); }
#else
extern "C" { extern void* ${vtableNameGnu}[]; }
#endif
#endif
END
push(@implContent, "JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, $implType* impl)\n");
push(@implContent, "{\n");
push(@implContent, <<END);
if (!impl)
return jsNull();
END
if ($svgPropertyType) {
push(@implContent, " return wrap<$className, $implType>(exec, globalObject, impl);\n");
push(@implContent, " if (JSValue result = getExistingWrapper<$className, $implType>(exec, impl)) return result;\n");
} else {
push(@implContent, " return wrap<$className>(exec, globalObject, impl);\n");
push(@implContent, " if (JSValue result = getExistingWrapper<$className>(exec, impl)) return result;\n");
}
push(@implContent, <<END) if $vtableNameGnu;
#if ENABLE(BINDING_INTEGRITY)
void* actualVTablePointer = *(reinterpret_cast<void**>(impl));
#if defined(OS_WIN)
void* expectedVTablePointer = reinterpret_cast<void*>(${vtableRefWin});
#else
void* expectedVTablePointer = ${vtableRefGnu};
#if COMPILER(CLANG)
COMPILE_ASSERT(__is_polymorphic($implType), ${implType}_is_not_polymorphic);
#endif
#endif
RELEASE_ASSERT(actualVTablePointer == expectedVTablePointer);
#endif
END
push(@implContent, <<END) if $interface->extendedAttributes->{"ImplementationLacksVTable"} && $vtableNameGnu;
#if COMPILER(CLANG)
COMPILE_ASSERT(!__is_polymorphic($implType), ${implType}_is_polymorphic_but_idl_claims_not_to_be);
#endif
END
if ($svgPropertyType) {
push(@implContent, " return createNewWrapper<$className, $implType>(exec, globalObject, impl);\n");
} else {
push(@implContent, " return createNewWrapper<$className>(exec, globalObject, impl);\n");
}
push(@implContent, "}\n\n");
}
......
......@@ -104,6 +104,7 @@ Reflect=*
Replaceable
ReplaceableConstructor
ReturnNewObject
SkipVTableValidation
StrictTypeChecking
Supplemental=*
SuppressToJSObject
......@@ -130,7 +131,6 @@ V8NoWrapperCache
V8MeasureAs=*
V8PerWorldBindings
V8ReadOnly
V8SkipVTableValidation
V8Unforgeable
V8WrapAsFunction
V8DeliverCustomElementCallbacks
......@@ -27,6 +27,7 @@
[
JSCustomIsReachable,
IndexedGetter,
SkipVTableValidation
] interface CSSRuleList {
readonly attribute unsigned long length;
CSSRule item(in [Optional=DefaultIsUndefined] unsigned long index);
......
......@@ -27,6 +27,7 @@
CustomNamedSetter,
IndexedGetter,
CustomEnumerateProperty,
SkipVTableValidation
] interface CSSStyleDeclaration {
[TreatReturnedNullStringAs=Null, TreatNullAs=NullString] attribute DOMString cssText
setter raises(DOMException);
......
......@@ -25,8 +25,9 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
interface Clipboard {
[
SkipVTableValidation
] interface Clipboard {
[TreatReturnedNullStringAs=Undefined] attribute DOMString dropEffect;
[TreatReturnedNullStringAs=Undefined] attribute DOMString effectAllowed;
[CustomGetter] readonly attribute Array types;
......
......@@ -29,6 +29,7 @@
CustomDeleteProperty,
CustomEnumerateProperty,
CustomNamedSetter,
SkipVTableValidation
] interface DOMStringMap {
};
......@@ -28,7 +28,9 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
interface MutationRecord {
[
SkipVTableValidation
] interface MutationRecord {
readonly attribute DOMString type;
readonly attribute Node target;
......
......@@ -22,6 +22,7 @@
CustomIsReachable,
IndexedGetter,
NamedGetter,
SkipVTableValidation
] interface NodeList {
Node item(in [IsIndex,Optional=DefaultIsUndefined] unsigned long index);
......
......@@ -25,6 +25,7 @@
[
GenerateIsReachable=ImplElementRoot,
IndexedGetter,
SkipVTableValidation
] interface DOMTokenList {
readonly attribute unsigned long length;
[TreatReturnedNullStringAs=Null] DOMString item(in unsigned long index);
......
......@@ -28,6 +28,7 @@
EventTarget,
JSCustomMarkFunction,
JSCustomIsReachable,
SkipVTableValidation
] interface TextTrack {
readonly attribute DOMString kind;
readonly attribute DOMString label;
......
......@@ -26,7 +26,8 @@
[
Conditional=JAVASCRIPT_DEBUGGER,
OmitConstructor
OmitConstructor,
ImplementationLacksVTable
] interface ScriptProfileNode {
readonly attribute DOMString functionName;
readonly attribute DOMString url;
......
......@@ -30,6 +30,7 @@
CustomEnumerateProperty,
V8CustomIndexedGetter,
CustomNamedSetter,
SkipVTableValidation
] interface Storage {
[NotEnumerable] readonly attribute unsigned long length getter raises(DOMException);
[NotEnumerable, TreatReturnedNullStringAs=Null] DOMString key(in unsigned long index)
......
......@@ -21,7 +21,7 @@
[
ObjCProtocol,
OmitConstructor,
V8SkipVTableValidation
SkipVTableValidation
] interface XPathNSResolver {
[TreatReturnedNullStringAs=Null] DOMString lookupNamespaceURI(in [Optional=DefaultIsUndefined] DOMString prefix);
};
......
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