diff options
Diffstat (limited to 'chromium/third_party/WebKit/Source/modules/crypto/CryptoResultImpl.cpp')
-rw-r--r-- | chromium/third_party/WebKit/Source/modules/crypto/CryptoResultImpl.cpp | 145 |
1 files changed, 123 insertions, 22 deletions
diff --git a/chromium/third_party/WebKit/Source/modules/crypto/CryptoResultImpl.cpp b/chromium/third_party/WebKit/Source/modules/crypto/CryptoResultImpl.cpp index 557562c2c68..c2cd20c9fdf 100644 --- a/chromium/third_party/WebKit/Source/modules/crypto/CryptoResultImpl.cpp +++ b/chromium/third_party/WebKit/Source/modules/crypto/CryptoResultImpl.cpp @@ -31,9 +31,13 @@ #include "config.h" #include "modules/crypto/CryptoResultImpl.h" -#include "bindings/v8/ScriptPromiseResolver.h" +#include "bindings/v8/ScriptPromiseResolverWithContext.h" +#include "bindings/v8/ScriptState.h" +#include "core/dom/ContextLifecycleObserver.h" +#include "core/dom/DOMError.h" +#include "core/dom/DOMException.h" +#include "core/dom/ExecutionContext.h" #include "modules/crypto/Key.h" -#include "modules/crypto/KeyPair.h" #include "modules/crypto/NormalizeAlgorithm.h" #include "public/platform/Platform.h" #include "public/platform/WebArrayBuffer.h" @@ -42,54 +46,151 @@ namespace WebCore { +class CryptoResultImpl::WeakResolver : public ScriptPromiseResolverWithContext { +public: + static WeakPtr<ScriptPromiseResolverWithContext> create(ScriptState* scriptState, CryptoResultImpl* result) + { + RefPtr<WeakResolver> p = adoptRef(new WeakResolver(scriptState, result)); + p->suspendIfNeeded(); + p->keepAliveWhilePending(); + return p->m_weakPtrFactory.createWeakPtr(); + } + + virtual ~WeakResolver() + { + m_result->cancel(); + } + +private: + WeakResolver(ScriptState* scriptState, CryptoResultImpl* result) + : ScriptPromiseResolverWithContext(scriptState) + , m_weakPtrFactory(this) + , m_result(result) { } + WeakPtrFactory<ScriptPromiseResolverWithContext> m_weakPtrFactory; + RefPtr<CryptoResultImpl> m_result; +}; + +ExceptionCode webCryptoErrorToExceptionCode(blink::WebCryptoErrorType errorType) +{ + switch (errorType) { + case blink::WebCryptoErrorTypeNotSupported: + return NotSupportedError; + case blink::WebCryptoErrorTypeSyntax: + return SyntaxError; + case blink::WebCryptoErrorTypeInvalidState: + return InvalidStateError; + case blink::WebCryptoErrorTypeInvalidAccess: + return InvalidAccessError; + case blink::WebCryptoErrorTypeUnknown: + return UnknownError; + case blink::WebCryptoErrorTypeData: + return DataError; + case blink::WebCryptoErrorTypeOperation: + return OperationError; + case blink::WebCryptoErrorTypeType: + // FIXME: This should construct a TypeError instead. For now do + // something to facilitate refactor, but this will need to be + // revisited. + return DataError; + } + + ASSERT_NOT_REACHED(); + return 0; +} + CryptoResultImpl::~CryptoResultImpl() { - ASSERT(m_finished); } -PassRefPtr<CryptoResultImpl> CryptoResultImpl::create(ScriptPromise promise) +PassRefPtr<CryptoResultImpl> CryptoResultImpl::create(ScriptState* scriptState) { - return adoptRef(new CryptoResultImpl(promise)); + return adoptRef(new CryptoResultImpl(scriptState)); } -void CryptoResultImpl::completeWithError() +void CryptoResultImpl::completeWithError(blink::WebCryptoErrorType errorType, const blink::WebString& errorDetails) { - m_promiseResolver->reject(ScriptValue::createNull()); - finish(); + if (m_resolver) + m_resolver->reject(DOMException::create(webCryptoErrorToExceptionCode(errorType), errorDetails)); } void CryptoResultImpl::completeWithBuffer(const blink::WebArrayBuffer& buffer) { - m_promiseResolver->resolve(PassRefPtr<ArrayBuffer>(buffer)); - finish(); + if (m_resolver) + m_resolver->resolve(PassRefPtr<ArrayBuffer>(buffer)); +} + +void CryptoResultImpl::completeWithJson(const char* utf8Data, unsigned length) +{ + if (m_resolver) { + ScriptPromiseResolverWithContext* resolver = m_resolver.get(); + ScriptState* scriptState = resolver->scriptState(); + ScriptState::Scope scope(scriptState); + + v8::Handle<v8::String> jsonString = v8::String::NewFromUtf8(scriptState->isolate(), utf8Data, v8::String::kInternalizedString, length); + + v8::TryCatch exceptionCatcher; + v8::Handle<v8::Value> jsonDictionary = v8::JSON::Parse(jsonString); + if (exceptionCatcher.HasCaught() || jsonDictionary.IsEmpty()) { + ASSERT_NOT_REACHED(); + resolver->reject(DOMException::create(OperationError, "Failed inflating JWK JSON to object")); + } else { + resolver->resolve(jsonDictionary); + } + } } void CryptoResultImpl::completeWithBoolean(bool b) { - m_promiseResolver->resolve(ScriptValue::createBoolean(b)); - finish(); + if (m_resolver) + m_resolver->resolve(b); } void CryptoResultImpl::completeWithKey(const blink::WebCryptoKey& key) { - m_promiseResolver->resolve(Key::create(key)); - finish(); + if (m_resolver) + m_resolver->resolve(Key::create(key)); } void CryptoResultImpl::completeWithKeyPair(const blink::WebCryptoKey& publicKey, const blink::WebCryptoKey& privateKey) { - m_promiseResolver->resolve(KeyPair::create(publicKey, privateKey)); - finish(); + if (m_resolver) { + ScriptState* scriptState = m_resolver->scriptState(); + ScriptState::Scope scope(scriptState); + + // FIXME: Use Dictionary instead, to limit amount of direct v8 access used from WebCore. + v8::Handle<v8::Object> keyPair = v8::Object::New(scriptState->isolate()); + + v8::Handle<v8::Value> publicKeyValue = toV8NoInline(Key::create(publicKey), scriptState->context()->Global(), scriptState->isolate()); + v8::Handle<v8::Value> privateKeyValue = toV8NoInline(Key::create(privateKey), scriptState->context()->Global(), scriptState->isolate()); + + keyPair->Set(v8::String::NewFromUtf8(scriptState->isolate(), "publicKey"), publicKeyValue); + keyPair->Set(v8::String::NewFromUtf8(scriptState->isolate(), "privateKey"), privateKeyValue); + + m_resolver->resolve(v8::Handle<v8::Value>(keyPair)); + } +} + +bool CryptoResultImpl::cancelled() const +{ + return acquireLoad(&m_cancelled); +} + +void CryptoResultImpl::cancel() +{ + releaseStore(&m_cancelled, 1); } -CryptoResultImpl::CryptoResultImpl(ScriptPromise promise) - : m_promiseResolver(ScriptPromiseResolver::create(promise)) - , m_finished(false) { } +CryptoResultImpl::CryptoResultImpl(ScriptState* scriptState) + : m_cancelled(0) +{ + // Creating the WeakResolver may return nullptr if active dom objects have + // been stopped. And in the process set m_cancelled to 1. + m_resolver = WeakResolver::create(scriptState, this); +} -void CryptoResultImpl::finish() +ScriptPromise CryptoResultImpl::promise() { - ASSERT(!m_finished); - m_finished = true; + return m_resolver ? m_resolver->promise() : ScriptPromise(); } } // namespace WebCore |