OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 29 matching lines...) Expand all Loading... |
40 #include "modules/crypto/Key.h" | 40 #include "modules/crypto/Key.h" |
41 #include "modules/crypto/KeyPair.h" | 41 #include "modules/crypto/KeyPair.h" |
42 #include "modules/crypto/NormalizeAlgorithm.h" | 42 #include "modules/crypto/NormalizeAlgorithm.h" |
43 #include "public/platform/Platform.h" | 43 #include "public/platform/Platform.h" |
44 #include "public/platform/WebArrayBuffer.h" | 44 #include "public/platform/WebArrayBuffer.h" |
45 #include "public/platform/WebCryptoAlgorithm.h" | 45 #include "public/platform/WebCryptoAlgorithm.h" |
46 #include "wtf/ArrayBufferView.h" | 46 #include "wtf/ArrayBufferView.h" |
47 | 47 |
48 namespace WebCore { | 48 namespace WebCore { |
49 | 49 |
50 namespace { | |
51 | |
52 class WeakResolver : public ScriptPromiseResolverWithContext { | |
53 public: | |
54 static WeakPtr<ScriptPromiseResolverWithContext> create(ScriptState* scriptS
tate) | |
55 { | |
56 RefPtr<WeakResolver> p = adoptRef(new WeakResolver(scriptState)); | |
57 p->suspendIfNeeded(); | |
58 return p->m_weakPtrFactory.createWeakPtr(); | |
59 } | |
60 | |
61 private: | |
62 explicit WeakResolver(ScriptState* scriptState) | |
63 : ScriptPromiseResolverWithContext(scriptState, ScriptPromiseResolverWit
hContext::KeepAliveWhilePending) | |
64 , m_weakPtrFactory(this) { } | |
65 WeakPtrFactory<ScriptPromiseResolverWithContext> m_weakPtrFactory; | |
66 }; | |
67 | |
68 } // namespace | |
69 | |
70 ExceptionCode webCryptoErrorToExceptionCode(blink::WebCryptoErrorType errorType) | 50 ExceptionCode webCryptoErrorToExceptionCode(blink::WebCryptoErrorType errorType) |
71 { | 51 { |
72 switch (errorType) { | 52 switch (errorType) { |
73 case blink::WebCryptoErrorTypeNotSupported: | 53 case blink::WebCryptoErrorTypeNotSupported: |
74 return NotSupportedError; | 54 return NotSupportedError; |
75 case blink::WebCryptoErrorTypeSyntax: | 55 case blink::WebCryptoErrorTypeSyntax: |
76 return SyntaxError; | 56 return SyntaxError; |
77 case blink::WebCryptoErrorTypeInvalidState: | 57 case blink::WebCryptoErrorTypeInvalidState: |
78 return InvalidStateError; | 58 return InvalidStateError; |
79 case blink::WebCryptoErrorTypeInvalidAccess: | 59 case blink::WebCryptoErrorTypeInvalidAccess: |
80 return InvalidAccessError; | 60 return InvalidAccessError; |
81 case blink::WebCryptoErrorTypeUnknown: | 61 case blink::WebCryptoErrorTypeUnknown: |
82 return UnknownError; | 62 return UnknownError; |
83 case blink::WebCryptoErrorTypeData: | 63 case blink::WebCryptoErrorTypeData: |
84 return DataError; | 64 return DataError; |
85 case blink::WebCryptoErrorTypeOperation: | 65 case blink::WebCryptoErrorTypeOperation: |
86 return OperationError; | 66 return OperationError; |
87 case blink::WebCryptoErrorTypeType: | 67 case blink::WebCryptoErrorTypeType: |
88 // FIXME: This should construct a TypeError instead. For now do | 68 // FIXME: This should construct a TypeError instead. For now do |
89 // something to facilitate refactor, but this will need to be | 69 // something to facilitate refactor, but this will need to be |
90 // revisited. | 70 // revisited. |
91 return DataError; | 71 return DataError; |
92 } | 72 } |
93 | 73 |
94 ASSERT_NOT_REACHED(); | 74 ASSERT_NOT_REACHED(); |
95 return 0; | 75 return 0; |
96 } | 76 } |
97 | 77 |
98 CryptoResultImpl::~CryptoResultImpl() | 78 // The PromiseState class contains all the state which is tied to an |
99 { | 79 // ExecutionContext. Whereas CryptoResultImpl can be deleted from any thread, |
100 } | 80 // PromiseState is not thread safe and must only be accessed and deleted from |
| 81 // the blink thread. |
| 82 // |
| 83 // This is achieved by making CryptoResultImpl hold a WeakPtr to the PromiseStat
e. |
| 84 // The PromiseState deletes itself after being notified of completion. |
| 85 // Additionally the PromiseState is deleted when the ExecutionContext is |
| 86 // destroyed (necessary to avoid leaks when dealing with WebWorker threads, |
| 87 // which may die before the operation is completed). |
| 88 class CryptoResultImpl::PromiseState FINAL { |
| 89 public: |
| 90 static WeakPtr<PromiseState> create(ScriptState* scriptState) |
| 91 { |
| 92 PromiseState* promiseState = new PromiseState(scriptState); |
| 93 return promiseState->m_weakFactory.createWeakPtr(); |
| 94 } |
101 | 95 |
102 PassRefPtr<CryptoResultImpl> CryptoResultImpl::create(ScriptState* scriptState) | 96 void contextDestroyed() |
103 { | 97 { |
104 return adoptRef(new CryptoResultImpl(scriptState)); | 98 delete this; |
105 } | 99 } |
106 | 100 |
107 void CryptoResultImpl::completeWithError(blink::WebCryptoErrorType errorType, co
nst blink::WebString& errorDetails) | 101 ScriptPromise promise() |
108 { | 102 { |
109 if (m_resolver) | 103 return m_promiseResolver->promise(); |
110 m_resolver->reject(DOMException::create(webCryptoErrorToExceptionCode(er
rorType), errorDetails)); | 104 } |
111 } | |
112 | 105 |
113 void CryptoResultImpl::completeWithBuffer(const blink::WebArrayBuffer& buffer) | 106 void completeWithError(blink::WebCryptoErrorType errorType, const blink::Web
String& errorDetails) |
114 { | 107 { |
115 if (m_resolver) | 108 m_promiseResolver->reject(DOMException::create(webCryptoErrorToException
Code(errorType), errorDetails)); |
116 m_resolver->resolve(PassRefPtr<ArrayBuffer>(buffer)); | 109 delete this; |
117 } | 110 } |
118 | 111 |
119 void CryptoResultImpl::completeWithJson(const char* utf8Data, unsigned length) | 112 void completeWithBuffer(const blink::WebArrayBuffer& buffer) |
120 { | 113 { |
121 if (m_resolver) { | 114 m_promiseResolver->resolve(PassRefPtr<ArrayBuffer>(buffer)); |
122 ScriptPromiseResolverWithContext* resolver = m_resolver.get(); | 115 delete this; |
123 ScriptState* scriptState = resolver->scriptState(); | 116 } |
| 117 |
| 118 void completeWithJson(const char* utf8Data, unsigned length) |
| 119 { |
| 120 ScriptState* scriptState = m_promiseResolver->scriptState(); |
124 ScriptState::Scope scope(scriptState); | 121 ScriptState::Scope scope(scriptState); |
125 | 122 |
126 v8::Handle<v8::String> jsonString = v8::String::NewFromUtf8(scriptState-
>isolate(), utf8Data, v8::String::kInternalizedString, length); | 123 v8::Handle<v8::String> jsonString = v8::String::NewFromUtf8(scriptState-
>isolate(), utf8Data, v8::String::kInternalizedString, length); |
127 | 124 |
128 v8::TryCatch exceptionCatcher; | 125 v8::TryCatch exceptionCatcher; |
129 v8::Handle<v8::Value> jsonDictionary = v8::JSON::Parse(jsonString); | 126 v8::Handle<v8::Value> jsonDictionary = v8::JSON::Parse(jsonString); |
130 if (exceptionCatcher.HasCaught() || jsonDictionary.IsEmpty()) { | 127 if (exceptionCatcher.HasCaught() || jsonDictionary.IsEmpty()) { |
131 ASSERT_NOT_REACHED(); | 128 ASSERT_NOT_REACHED(); |
132 resolver->reject(DOMException::create(OperationError, "Failed inflat
ing JWK JSON to object")); | 129 m_promiseResolver->reject(DOMException::create(OperationError, "Fail
ed inflating JWK JSON to object")); |
133 } else { | 130 } else { |
134 resolver->resolve(jsonDictionary); | 131 m_promiseResolver->resolve(jsonDictionary); |
135 } | 132 } |
| 133 delete this; |
136 } | 134 } |
| 135 |
| 136 void completeWithBoolean(bool b) |
| 137 { |
| 138 m_promiseResolver->resolve(b); |
| 139 delete this; |
| 140 } |
| 141 |
| 142 void completeWithKey(const blink::WebCryptoKey& key) |
| 143 { |
| 144 m_promiseResolver->resolve(Key::create(key)); |
| 145 delete this; |
| 146 } |
| 147 |
| 148 void completeWithKeyPair(const blink::WebCryptoKey& publicKey, const blink::
WebCryptoKey& privateKey) |
| 149 { |
| 150 m_promiseResolver->resolve(KeyPair::create(publicKey, privateKey)); |
| 151 delete this; |
| 152 } |
| 153 |
| 154 private: |
| 155 // This subclass of ScriptPromiseResolverWithContext is to be notified |
| 156 // when the context was destroyed. |
| 157 class PromiseResolver FINAL : public ScriptPromiseResolverWithContext { |
| 158 public: |
| 159 static PassRefPtr<PromiseResolver> create(ScriptState* scriptState, Prom
iseState* promiseState) |
| 160 { |
| 161 RefPtr<PromiseResolver> resolver = adoptRef(new PromiseResolver(scri
ptState, promiseState)); |
| 162 resolver->suspendIfNeeded(); |
| 163 return resolver.release(); |
| 164 } |
| 165 |
| 166 virtual void contextDestroyed() OVERRIDE |
| 167 { |
| 168 ScriptPromiseResolverWithContext::contextDestroyed(); |
| 169 m_promiseState->contextDestroyed(); |
| 170 } |
| 171 |
| 172 private: |
| 173 explicit PromiseResolver(ScriptState* scriptState, PromiseState* promise
State) |
| 174 : ScriptPromiseResolverWithContext(scriptState) |
| 175 , m_promiseState(promiseState) |
| 176 { |
| 177 } |
| 178 |
| 179 PromiseState* m_promiseState; |
| 180 }; |
| 181 |
| 182 explicit PromiseState(ScriptState* scriptState) |
| 183 : m_weakFactory(this) |
| 184 , m_promiseResolver(PromiseResolver::create(scriptState, this)) |
| 185 { |
| 186 } |
| 187 |
| 188 WeakPtrFactory<PromiseState> m_weakFactory; |
| 189 RefPtr<PromiseResolver> m_promiseResolver; |
| 190 }; |
| 191 |
| 192 CryptoResultImpl::~CryptoResultImpl() |
| 193 { |
| 194 } |
| 195 |
| 196 PassRefPtr<CryptoResultImpl> CryptoResultImpl::create(ScriptState* scriptState) |
| 197 { |
| 198 return adoptRef(new CryptoResultImpl(scriptState)); |
| 199 } |
| 200 |
| 201 void CryptoResultImpl::completeWithError(blink::WebCryptoErrorType errorType, co
nst blink::WebString& errorDetails) |
| 202 { |
| 203 if (m_promiseState) |
| 204 m_promiseState->completeWithError(errorType, errorDetails); |
| 205 } |
| 206 |
| 207 void CryptoResultImpl::completeWithBuffer(const blink::WebArrayBuffer& buffer) |
| 208 { |
| 209 if (m_promiseState) |
| 210 m_promiseState->completeWithBuffer(buffer); |
| 211 } |
| 212 |
| 213 void CryptoResultImpl::completeWithJson(const char* utf8Data, unsigned length) |
| 214 { |
| 215 if (m_promiseState) |
| 216 m_promiseState->completeWithJson(utf8Data, length); |
137 } | 217 } |
138 | 218 |
139 void CryptoResultImpl::completeWithBoolean(bool b) | 219 void CryptoResultImpl::completeWithBoolean(bool b) |
140 { | 220 { |
141 if (m_resolver) | 221 if (m_promiseState) |
142 m_resolver->resolve(b); | 222 m_promiseState->completeWithBoolean(b); |
143 } | 223 } |
144 | 224 |
145 void CryptoResultImpl::completeWithKey(const blink::WebCryptoKey& key) | 225 void CryptoResultImpl::completeWithKey(const blink::WebCryptoKey& key) |
146 { | 226 { |
147 if (m_resolver) | 227 if (m_promiseState) |
148 m_resolver->resolve(Key::create(key)); | 228 m_promiseState->completeWithKey(key); |
149 } | 229 } |
150 | 230 |
151 void CryptoResultImpl::completeWithKeyPair(const blink::WebCryptoKey& publicKey,
const blink::WebCryptoKey& privateKey) | 231 void CryptoResultImpl::completeWithKeyPair(const blink::WebCryptoKey& publicKey,
const blink::WebCryptoKey& privateKey) |
152 { | 232 { |
153 if (m_resolver) | 233 if (m_promiseState) |
154 m_resolver->resolve(KeyPair::create(publicKey, privateKey)); | 234 m_promiseState->completeWithKeyPair(publicKey, privateKey); |
155 } | 235 } |
156 | 236 |
157 CryptoResultImpl::CryptoResultImpl(ScriptState* scriptState) | 237 CryptoResultImpl::CryptoResultImpl(ScriptState* scriptState) |
158 : m_resolver(WeakResolver::create(scriptState)) | 238 : m_promiseState(PromiseState::create(scriptState)) |
159 { | 239 { |
160 } | 240 } |
161 | 241 |
162 ScriptPromise CryptoResultImpl::promise() | 242 ScriptPromise CryptoResultImpl::promise() |
163 { | 243 { |
164 return m_resolver->promise(); | 244 return m_promiseState->promise(); |
165 } | 245 } |
166 | 246 |
167 } // namespace WebCore | 247 } // namespace WebCore |
OLD | NEW |