mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-21 09:15:35 +00:00
Bug 1487463 - implement StructuredCloneTester to be used in testing r=baku
StructuredCloneTester objects can configured to be serializable (or not) and deserializable (or not) by the structured clone algorithm. They can be used to test, for example, onmessageerror event handlers, where the messageerror event is fired when a message fails to be deserialized (but was successfully serialized). The class is pref'ed with "dom.testing.structuredclonetester.enabled". Differential Revision: https://phabricator.services.mozilla.com/D5207 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
71b9be5097
commit
b61092a88e
@ -20,6 +20,7 @@ DOM_WEBIDL_PREF(dom_webnotifications_serviceworker_enabled)
|
||||
DOM_WEBIDL_PREF(dom_webnotifications_requireinteraction_enabled)
|
||||
DOM_WEBIDL_PREF(dom_serviceWorkers_enabled)
|
||||
DOM_WEBIDL_PREF(dom_storageManager_enabled)
|
||||
DOM_WEBIDL_PREF(dom_testing_structuredclonetester_enabled)
|
||||
DOM_WEBIDL_PREF(dom_promise_rejection_events_enabled)
|
||||
DOM_WEBIDL_PREF(dom_push_enabled)
|
||||
DOM_WEBIDL_PREF(gfx_offscreencanvas_enabled)
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "mozilla/dom/StructuredCloneBlob.h"
|
||||
#include "mozilla/dom/Directory.h"
|
||||
#include "mozilla/dom/DirectoryBinding.h"
|
||||
#include "mozilla/dom/DOMPrefs.h"
|
||||
#include "mozilla/dom/File.h"
|
||||
#include "mozilla/dom/FileList.h"
|
||||
#include "mozilla/dom/FileListBinding.h"
|
||||
@ -28,6 +29,8 @@
|
||||
#include "mozilla/dom/OffscreenCanvasBinding.h"
|
||||
#include "mozilla/dom/PMessagePort.h"
|
||||
#include "mozilla/dom/StructuredCloneTags.h"
|
||||
#include "mozilla/dom/StructuredCloneTester.h"
|
||||
#include "mozilla/dom/StructuredCloneTesterBinding.h"
|
||||
#include "mozilla/dom/SubtleCryptoBinding.h"
|
||||
#include "mozilla/dom/ToJSValue.h"
|
||||
#include "mozilla/dom/URLSearchParams.h"
|
||||
@ -455,6 +458,10 @@ StructuredCloneHolder::ReadFullySerializableObjects(JSContext* aCx,
|
||||
}
|
||||
#endif
|
||||
|
||||
if (aTag == SCTAG_DOM_STRUCTURED_CLONE_TESTER) {
|
||||
return StructuredCloneTester::ReadStructuredClone(aCx, aReader);
|
||||
}
|
||||
|
||||
// Don't know what this is. Bail.
|
||||
xpc::Throw(aCx, NS_ERROR_DOM_DATA_CLONE_ERR);
|
||||
return nullptr;
|
||||
@ -505,6 +512,22 @@ StructuredCloneHolder::WriteFullySerializableObjects(JSContext* aCx,
|
||||
}
|
||||
#endif
|
||||
|
||||
// StructuredCloneTester - testing only
|
||||
{
|
||||
StructuredCloneTester* sct = nullptr;
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(StructuredCloneTester, &obj, sct))) {
|
||||
MOZ_ASSERT(StaticPrefs::dom_testing_structuredclonetester_enabled());
|
||||
|
||||
// "Fail" serialization
|
||||
if (!sct->Serializable()) {
|
||||
xpc::Throw(aCx, NS_ERROR_DOM_DATA_CLONE_ERR);
|
||||
return false;
|
||||
}
|
||||
|
||||
return sct->WriteStructuredClone(aWriter);
|
||||
}
|
||||
}
|
||||
|
||||
if (NS_IsMainThread() && xpc::IsReflector(obj)) {
|
||||
nsCOMPtr<nsISupports> base = xpc::UnwrapReflectorToISupports(obj);
|
||||
nsCOMPtr<nsIPrincipal> principal = do_QueryInterface(base);
|
||||
|
@ -70,7 +70,9 @@ enum StructuredCloneTags {
|
||||
// Adding to the end of the list would make removing of other tags harder in
|
||||
// future.
|
||||
|
||||
SCTAG_DOM_MAX
|
||||
SCTAG_DOM_MAX,
|
||||
|
||||
SCTAG_DOM_STRUCTURED_CLONE_TESTER
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
121
dom/base/StructuredCloneTester.cpp
Normal file
121
dom/base/StructuredCloneTester.cpp
Normal file
@ -0,0 +1,121 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "StructuredCloneTester.h"
|
||||
|
||||
#include "js/StructuredClone.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/dom/StructuredCloneTags.h"
|
||||
#include "mozilla/dom/StructuredCloneTesterBinding.h"
|
||||
#include "xpcpublic.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class ErrorResult;
|
||||
|
||||
namespace dom {
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(StructuredCloneTester)
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(StructuredCloneTester)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(StructuredCloneTester)
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(StructuredCloneTester)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
StructuredCloneTester::StructuredCloneTester(nsISupports* aParent,
|
||||
const bool aSerializable,
|
||||
const bool aDeserializable)
|
||||
: mParent(aParent),
|
||||
mSerializable(aSerializable),
|
||||
mDeserializable(aDeserializable)
|
||||
{
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<StructuredCloneTester>
|
||||
StructuredCloneTester::Constructor(const GlobalObject& aGlobal,
|
||||
const bool aSerializable,
|
||||
const bool aDeserializable,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
RefPtr<StructuredCloneTester> sct = new StructuredCloneTester(aGlobal.GetAsSupports(),
|
||||
aSerializable,
|
||||
aDeserializable);
|
||||
return sct.forget();
|
||||
}
|
||||
|
||||
bool
|
||||
StructuredCloneTester::Serializable() const
|
||||
{
|
||||
return mSerializable;
|
||||
}
|
||||
|
||||
bool
|
||||
StructuredCloneTester::Deserializable() const
|
||||
{
|
||||
return mDeserializable;
|
||||
}
|
||||
|
||||
/* static */ JSObject*
|
||||
StructuredCloneTester::ReadStructuredClone(JSContext* aCx,
|
||||
JSStructuredCloneReader* aReader)
|
||||
{
|
||||
uint32_t serializable = 0;
|
||||
uint32_t deserializable = 0;
|
||||
|
||||
if (!JS_ReadUint32Pair(aReader, &serializable, &deserializable)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsIGlobalObject* global = xpc::CurrentNativeGlobal(aCx);
|
||||
|
||||
if (NS_WARN_IF(!global)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Prevent the return value from being trashed by a GC during ~nsRefPtr
|
||||
JS::RootedObject result(aCx);
|
||||
|
||||
RefPtr<StructuredCloneTester> sct = new StructuredCloneTester(
|
||||
global,
|
||||
static_cast<bool>(serializable),
|
||||
static_cast<bool>(deserializable)
|
||||
);
|
||||
|
||||
// "Fail" deserialization
|
||||
if (!sct->Deserializable()) {
|
||||
xpc::Throw(aCx, NS_ERROR_DOM_DATA_CLONE_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
result = sct->WrapObject(aCx, nullptr);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool
|
||||
StructuredCloneTester::WriteStructuredClone(JSStructuredCloneWriter* aWriter) const
|
||||
{
|
||||
return JS_WriteUint32Pair(aWriter, SCTAG_DOM_STRUCTURED_CLONE_TESTER, 0) &&
|
||||
JS_WriteUint32Pair(aWriter, static_cast<uint32_t>(Serializable()),
|
||||
static_cast<uint32_t>(Deserializable()));
|
||||
}
|
||||
|
||||
nsISupports*
|
||||
StructuredCloneTester::GetParentObject() const
|
||||
{
|
||||
return mParent;
|
||||
}
|
||||
|
||||
JSObject*
|
||||
StructuredCloneTester::WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto)
|
||||
{
|
||||
return StructuredCloneTester_Binding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
70
dom/base/StructuredCloneTester.h
Normal file
70
dom/base/StructuredCloneTester.h
Normal file
@ -0,0 +1,70 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_dom_StructuredCloneTester_h
|
||||
#define mozilla_dom_StructuredCloneTester_h
|
||||
|
||||
#include "mozilla/AlreadyAddRefed.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsISupports.h"
|
||||
#include "nsWrapperCache.h"
|
||||
|
||||
struct JSStructuredCloneReader;
|
||||
struct JSStructuredCloneWriter;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class ErrorResult;
|
||||
|
||||
namespace dom {
|
||||
|
||||
class GlobalObject;
|
||||
|
||||
class StructuredCloneTester final : public nsISupports
|
||||
, public nsWrapperCache
|
||||
{
|
||||
public:
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(StructuredCloneTester)
|
||||
|
||||
static already_AddRefed<StructuredCloneTester>
|
||||
Constructor(const GlobalObject& aGlobal, const bool aSerializable,
|
||||
const bool aDeserializable, ErrorResult& aRv);
|
||||
|
||||
bool
|
||||
Serializable() const;
|
||||
|
||||
bool
|
||||
Deserializable() const;
|
||||
|
||||
static JSObject*
|
||||
ReadStructuredClone(JSContext* aCx, JSStructuredCloneReader* aReader);
|
||||
|
||||
bool
|
||||
WriteStructuredClone(JSStructuredCloneWriter* aWriter) const;
|
||||
|
||||
nsISupports*
|
||||
GetParentObject() const;
|
||||
|
||||
// nsWrapperCache interface
|
||||
JSObject*
|
||||
WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
private:
|
||||
StructuredCloneTester(nsISupports* aParent,
|
||||
const bool aSerializable,
|
||||
const bool aDeserializable);
|
||||
~StructuredCloneTester() = default;
|
||||
|
||||
nsCOMPtr<nsISupports> mParent;
|
||||
bool mSerializable;
|
||||
bool mDeserializable;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_StructuredCloneTester_h
|
@ -219,6 +219,7 @@ EXPORTS.mozilla.dom += [
|
||||
'StructuredCloneBlob.h',
|
||||
'StructuredCloneHolder.h',
|
||||
'StructuredCloneTags.h',
|
||||
'StructuredCloneTester.h',
|
||||
'StyleSheetList.h',
|
||||
'SubtleCrypto.h',
|
||||
'SyncMessageSender.h',
|
||||
@ -374,6 +375,7 @@ UNIFIED_SOURCES += [
|
||||
'ShadowRoot.cpp',
|
||||
'StructuredCloneBlob.cpp',
|
||||
'StructuredCloneHolder.cpp',
|
||||
'StructuredCloneTester.cpp',
|
||||
'StyleSheetList.cpp',
|
||||
'SubtleCrypto.cpp',
|
||||
'TabGroup.cpp',
|
||||
|
15
dom/webidl/StructuredCloneTester.webidl
Normal file
15
dom/webidl/StructuredCloneTester.webidl
Normal file
@ -0,0 +1,15 @@
|
||||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
// The WebIDL compiler does not accept a Pref-ed interface exposed to any scopes
|
||||
// other than *only* `Window`, so the Func is Pref-ed instead.
|
||||
[Constructor(boolean serializable, boolean deserializable),
|
||||
Exposed=(Window,Worker),
|
||||
Func="mozilla::dom::DOMPrefs::dom_structuredclonetester_enabled"]
|
||||
interface StructuredCloneTester {
|
||||
readonly attribute boolean serializable;
|
||||
readonly attribute boolean deserializable;
|
||||
};
|
@ -773,6 +773,7 @@ WEBIDL_FILES = [
|
||||
'StorageType.webidl',
|
||||
'StreamFilter.webidl',
|
||||
'StreamFilterDataEvent.webidl',
|
||||
'StructuredCloneTester.webidl',
|
||||
'StyleSheet.webidl',
|
||||
'StyleSheetList.webidl',
|
||||
'SubtleCrypto.webidl',
|
||||
|
@ -286,6 +286,12 @@ VARCACHE_PREF(
|
||||
RelaxedAtomicBool, false
|
||||
)
|
||||
|
||||
VARCACHE_PREF(
|
||||
"dom.testing.structuredclonetester.enabled",
|
||||
dom_testing_structuredclonetester_enabled,
|
||||
RelaxedAtomicBool, false
|
||||
)
|
||||
|
||||
// Enable Storage API for all platforms except Android.
|
||||
#if !defined(MOZ_WIDGET_ANDROID)
|
||||
# define PREF_VALUE true
|
||||
|
Loading…
Reference in New Issue
Block a user