Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(331)

Side by Side Diff: Source/bindings/v8/SerializedScriptValue.cpp

Issue 114363002: Structured cloning: improve DataCloneError reporting. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2010 Google Inc. All rights reserved. 2 * Copyright (C) 2010 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 670 matching lines...) Expand 10 before | Expand all | Expand 10 after
681 return wrapper.As<v8::ArrayBuffer>(); 681 return wrapper.As<v8::ArrayBuffer>();
682 } 682 }
683 683
684 class Serializer { 684 class Serializer {
685 class StateBase; 685 class StateBase;
686 public: 686 public:
687 enum Status { 687 enum Status {
688 Success, 688 Success,
689 InputError, 689 InputError,
690 DataCloneError, 690 DataCloneError,
691 InvalidStateError,
692 JSException, 691 JSException,
693 JSFailure 692 JSFailure
694 }; 693 };
695 694
696 Serializer(Writer& writer, MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers, BlobDataHandleMap& blobDataHandles, v8::TryCatch& tryCatch, v8::I solate* isolate) 695 Serializer(Writer& writer, MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers, BlobDataHandleMap& blobDataHandles, v8::TryCatch& tryCatch, v8::I solate* isolate)
697 : m_writer(writer) 696 : m_writer(writer)
698 , m_tryCatch(tryCatch) 697 , m_tryCatch(tryCatch)
699 , m_depth(0) 698 , m_depth(0)
700 , m_status(Success) 699 , m_status(Success)
701 , m_nextObjectReference(0) 700 , m_nextObjectReference(0)
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after
1124 greyObject(object); 1123 greyObject(object);
1125 return 0; 1124 return 0;
1126 } 1125 }
1127 1126
1128 StateBase* writeArrayBuffer(v8::Handle<v8::Value> value, StateBase* next) 1127 StateBase* writeArrayBuffer(v8::Handle<v8::Value> value, StateBase* next)
1129 { 1128 {
1130 ArrayBuffer* arrayBuffer = V8ArrayBuffer::toNative(value.As<v8::Object>( )); 1129 ArrayBuffer* arrayBuffer = V8ArrayBuffer::toNative(value.As<v8::Object>( ));
1131 if (!arrayBuffer) 1130 if (!arrayBuffer)
1132 return 0; 1131 return 0;
1133 if (arrayBuffer->isNeutered()) 1132 if (arrayBuffer->isNeutered())
1134 return handleError(InvalidStateError, next); 1133 return handleError(DataCloneError, next);
1135 ASSERT(!m_transferredArrayBuffers.contains(value.As<v8::Object>())); 1134 ASSERT(!m_transferredArrayBuffers.contains(value.As<v8::Object>()));
1136 m_writer.writeArrayBuffer(*arrayBuffer); 1135 m_writer.writeArrayBuffer(*arrayBuffer);
1137 return 0; 1136 return 0;
1138 } 1137 }
1139 1138
1140 StateBase* writeTransferredArrayBuffer(v8::Handle<v8::Value> value, uint32_t index, StateBase* next) 1139 StateBase* writeTransferredArrayBuffer(v8::Handle<v8::Value> value, uint32_t index, StateBase* next)
1141 { 1140 {
1142 ArrayBuffer* arrayBuffer = V8ArrayBuffer::toNative(value.As<v8::Object>( )); 1141 ArrayBuffer* arrayBuffer = V8ArrayBuffer::toNative(value.As<v8::Object>( ));
1143 if (!arrayBuffer) 1142 if (!arrayBuffer)
1144 return 0; 1143 return 0;
(...skipping 1069 matching lines...) Expand 10 before | Expand all | Expand 10 after
2214 Vector<v8::Handle<v8::Value> > m_objectPool; 2213 Vector<v8::Handle<v8::Value> > m_objectPool;
2215 Vector<uint32_t> m_openCompositeReferenceStack; 2214 Vector<uint32_t> m_openCompositeReferenceStack;
2216 MessagePortArray* m_transferredMessagePorts; 2215 MessagePortArray* m_transferredMessagePorts;
2217 ArrayBufferContentsArray* m_arrayBufferContents; 2216 ArrayBufferContentsArray* m_arrayBufferContents;
2218 Vector<v8::Handle<v8::Object> > m_arrayBuffers; 2217 Vector<v8::Handle<v8::Object> > m_arrayBuffers;
2219 uint32_t m_version; 2218 uint32_t m_version;
2220 }; 2219 };
2221 2220
2222 } // namespace 2221 } // namespace
2223 2222
2223 PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(v8::Handle<v8::V alue> value, MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers, Exc eptionState& exceptionState, v8::Isolate* isolate)
2224 {
2225 bool didThrow;
2226 return adoptRef(new SerializedScriptValue(value, messagePorts, arrayBuffers, didThrow, &exceptionState, isolate));
2227 }
2228
2224 PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(v8::Handle<v8::V alue> value, MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers, boo l& didThrow, v8::Isolate* isolate) 2229 PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(v8::Handle<v8::V alue> value, MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers, boo l& didThrow, v8::Isolate* isolate)
2225 { 2230 {
2226 return adoptRef(new SerializedScriptValue(value, messagePorts, arrayBuffers, didThrow, isolate)); 2231 return adoptRef(new SerializedScriptValue(value, messagePorts, arrayBuffers, didThrow, 0, isolate));
2227 } 2232 }
2228 2233
2229 PassRefPtr<SerializedScriptValue> SerializedScriptValue::createAndSwallowExcepti ons(v8::Handle<v8::Value> value, v8::Isolate* isolate) 2234 PassRefPtr<SerializedScriptValue> SerializedScriptValue::createAndSwallowExcepti ons(v8::Handle<v8::Value> value, v8::Isolate* isolate)
2230 { 2235 {
2231 bool didThrow; 2236 bool didThrow;
2232 return adoptRef(new SerializedScriptValue(value, 0, 0, didThrow, isolate, Do NotThrowExceptions)); 2237 return adoptRef(new SerializedScriptValue(value, 0, 0, didThrow, 0, isolate, DoNotThrowExceptions));
2233 } 2238 }
2234 2239
2235 PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(const ScriptValu e& value, bool& didThrow, ScriptState* state) 2240 PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(const ScriptValu e& value, bool& didThrow, ScriptState* state)
2236 { 2241 {
2237 ScriptScope scope(state); 2242 ScriptScope scope(state);
2238 return adoptRef(new SerializedScriptValue(value.v8Value(), 0, 0, didThrow, s tate->isolate())); 2243 return adoptRef(new SerializedScriptValue(value.v8Value(), 0, 0, didThrow, 0 , state->isolate()));
2239 } 2244 }
2240 2245
2241 PassRefPtr<SerializedScriptValue> SerializedScriptValue::createFromWire(const St ring& data) 2246 PassRefPtr<SerializedScriptValue> SerializedScriptValue::createFromWire(const St ring& data)
2242 { 2247 {
2243 return adoptRef(new SerializedScriptValue(data)); 2248 return adoptRef(new SerializedScriptValue(data));
2244 } 2249 }
2245 2250
2246 PassRefPtr<SerializedScriptValue> SerializedScriptValue::createFromWireBytes(con st Vector<uint8_t>& data) 2251 PassRefPtr<SerializedScriptValue> SerializedScriptValue::createFromWireBytes(con st Vector<uint8_t>& data)
2247 { 2252 {
2248 // Decode wire data from big endian to host byte order. 2253 // Decode wire data from big endian to host byte order.
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
2329 { 2334 {
2330 v8::Isolate* isolate = v8::Isolate::GetCurrent(); 2335 v8::Isolate* isolate = v8::Isolate::GetCurrent();
2331 Vector<DOMDataStore*>& allStores = V8PerIsolateData::from(isolate)->allStore s(); 2336 Vector<DOMDataStore*>& allStores = V8PerIsolateData::from(isolate)->allStore s();
2332 for (size_t i = 0; i < allStores.size(); i++) { 2337 for (size_t i = 0; i < allStores.size(); i++) {
2333 v8::Handle<v8::Object> wrapper = allStores[i]->get<V8ArrayBufferView>(ob ject, isolate); 2338 v8::Handle<v8::Object> wrapper = allStores[i]->get<V8ArrayBufferView>(ob ject, isolate);
2334 if (!wrapper.IsEmpty()) 2339 if (!wrapper.IsEmpty())
2335 wrapper->SetIndexedPropertiesToExternalArrayData(0, v8::kExternalByt eArray, 0); 2340 wrapper->SetIndexedPropertiesToExternalArrayData(0, v8::kExternalByt eArray, 0);
2336 } 2341 }
2337 } 2342 }
2338 2343
2339 PassOwnPtr<SerializedScriptValue::ArrayBufferContentsArray> SerializedScriptValu e::transferArrayBuffers(ArrayBufferArray& arrayBuffers, bool& didThrow, v8::Isol ate* isolate) 2344 PassOwnPtr<SerializedScriptValue::ArrayBufferContentsArray> SerializedScriptValu e::transferArrayBuffers(ArrayBufferArray& arrayBuffers, bool& didThrow, Exceptio nState* exceptionState, v8::Isolate* isolate)
2340 { 2345 {
2341 ASSERT(arrayBuffers.size()); 2346 ASSERT(arrayBuffers.size());
2342 2347
2343 for (size_t i = 0; i < arrayBuffers.size(); i++) { 2348 for (size_t i = 0; i < arrayBuffers.size(); i++) {
2344 if (arrayBuffers[i]->isNeutered()) { 2349 if (arrayBuffers[i]->isNeutered()) {
2345 setDOMException(InvalidStateError, isolate); 2350 if (exceptionState)
2351 exceptionState->throwDOMException(DataCloneError, "ArrayBuffer a t index " + String::number(i) + " is already neutered.");
2352 else
2353 setDOMException(DataCloneError, isolate);
2346 didThrow = true; 2354 didThrow = true;
2347 return nullptr; 2355 return nullptr;
2348 } 2356 }
2349 } 2357 }
2350 2358
2351 OwnPtr<ArrayBufferContentsArray> contents = adoptPtr(new ArrayBufferContents Array(arrayBuffers.size())); 2359 OwnPtr<ArrayBufferContentsArray> contents = adoptPtr(new ArrayBufferContents Array(arrayBuffers.size()));
2352 2360
2353 HashSet<ArrayBuffer*> visited; 2361 HashSet<ArrayBuffer*> visited;
2354 for (size_t i = 0; i < arrayBuffers.size(); i++) { 2362 for (size_t i = 0; i < arrayBuffers.size(); i++) {
2355 Vector<RefPtr<ArrayBufferView> > neuteredViews; 2363 Vector<RefPtr<ArrayBufferView> > neuteredViews;
2356 2364
2357 if (visited.contains(arrayBuffers[i].get())) 2365 if (visited.contains(arrayBuffers[i].get()))
2358 continue; 2366 continue;
2359 visited.add(arrayBuffers[i].get()); 2367 visited.add(arrayBuffers[i].get());
2360 2368
2361 bool result = arrayBuffers[i]->transfer(contents->at(i), neuteredViews); 2369 bool result = arrayBuffers[i]->transfer(contents->at(i), neuteredViews);
2362 if (!result) { 2370 if (!result) {
2363 setDOMException(InvalidStateError, isolate); 2371 if (exceptionState)
2372 exceptionState->throwDOMException(DataCloneError, "ArrayBuffer a t index " + String::number(i) + " could not be transferred.");
2373 else
2374 setDOMException(DataCloneError, isolate);
2364 didThrow = true; 2375 didThrow = true;
2365 return nullptr; 2376 return nullptr;
2366 } 2377 }
2367 2378
2368 neuterBinding(arrayBuffers[i].get()); 2379 neuterBinding(arrayBuffers[i].get());
2369 for (size_t j = 0; j < neuteredViews.size(); j++) 2380 for (size_t j = 0; j < neuteredViews.size(); j++)
2370 neuterBinding(neuteredViews[j].get()); 2381 neuterBinding(neuteredViews[j].get());
2371 } 2382 }
2372 return contents.release(); 2383 return contents.release();
2373 } 2384 }
2374 2385
2375 SerializedScriptValue::SerializedScriptValue(v8::Handle<v8::Value> value, Messag ePortArray* messagePorts, ArrayBufferArray* arrayBuffers, bool& didThrow, v8::Is olate* isolate, ExceptionPolicy policy) 2386 SerializedScriptValue::SerializedScriptValue(v8::Handle<v8::Value> value, Messag ePortArray* messagePorts, ArrayBufferArray* arrayBuffers, bool& didThrow, Except ionState* exceptionState, v8::Isolate* isolate, ExceptionPolicy policy)
2376 : m_externallyAllocatedMemory(0) 2387 : m_externallyAllocatedMemory(0)
2377 { 2388 {
2378 didThrow = false; 2389 didThrow = false;
2379 Writer writer(isolate); 2390 Writer writer(isolate);
2380 Serializer::Status status; 2391 Serializer::Status status;
2381 { 2392 {
2382 v8::TryCatch tryCatch; 2393 v8::TryCatch tryCatch;
2383 Serializer serializer(writer, messagePorts, arrayBuffers, m_blobDataHand les, tryCatch, isolate); 2394 Serializer serializer(writer, messagePorts, arrayBuffers, m_blobDataHand les, tryCatch, isolate);
2384 status = serializer.serialize(value); 2395 status = serializer.serialize(value);
2385 if (status == Serializer::JSException) { 2396 if (status == Serializer::JSException) {
2386 didThrow = true; 2397 didThrow = true;
2387 // If there was a JS exception thrown, re-throw it. 2398 // If there was a JS exception thrown, re-throw it.
2388 if (policy == ThrowExceptions) 2399 if (policy == ThrowExceptions) {
2389 tryCatch.ReThrow(); 2400 if (exceptionState)
2401 exceptionState->setException(tryCatch.Exception());
2402 else
2403 tryCatch.ReThrow();
2404 }
2390 return; 2405 return;
2391 } 2406 }
2392 } 2407 }
2393 switch (status) { 2408 switch (status) {
2394 case Serializer::InputError: 2409 case Serializer::InputError:
2395 case Serializer::DataCloneError: 2410 case Serializer::DataCloneError:
2396 // If there was an input error, throw a new exception outside 2411 // If there was an input error, throw a new exception outside
2397 // of the TryCatch scope. 2412 // of the TryCatch scope.
2398 didThrow = true; 2413 didThrow = true;
2399 if (policy == ThrowExceptions) 2414 if (policy == ThrowExceptions) {
2400 setDOMException(DataCloneError, isolate); 2415 if (exceptionState) {
2401 return; 2416 // FIXME possible to generate a better error messsage than this?
2402 case Serializer::InvalidStateError: 2417 exceptionState->throwDOMException(DataCloneError, "An object cou ld not be cloned.");
2403 didThrow = true; 2418 } else {
2404 if (policy == ThrowExceptions) 2419 setDOMException(DataCloneError, isolate);
2405 setDOMException(InvalidStateError, isolate); 2420 }
2421 }
2406 return; 2422 return;
2407 case Serializer::JSFailure: 2423 case Serializer::JSFailure:
2408 // If there was a JS failure (but no exception), there's not 2424 // If there was a JS failure (but no exception), there's not
2409 // much we can do except for unwinding the C++ stack by 2425 // much we can do except for unwinding the C++ stack by
2410 // pretending there was a JS exception. 2426 // pretending there was a JS exception.
2411 didThrow = true; 2427 didThrow = true;
2412 return; 2428 return;
2413 case Serializer::Success: 2429 case Serializer::Success:
2414 m_data = writer.takeWireString(); 2430 m_data = writer.takeWireString();
2415 ASSERT(m_data.impl()->hasOneRef()); 2431 ASSERT(m_data.impl()->hasOneRef());
2416 if (arrayBuffers && arrayBuffers->size()) 2432 if (arrayBuffers && arrayBuffers->size())
2417 m_arrayBufferContentsArray = transferArrayBuffers(*arrayBuffers, did Throw, isolate); 2433 m_arrayBufferContentsArray = transferArrayBuffers(*arrayBuffers, did Throw, exceptionState, isolate);
2418 return; 2434 return;
2419 case Serializer::JSException: 2435 case Serializer::JSException:
2420 // We should never get here because this case was handled above. 2436 // We should never get here because this case was handled above.
2421 break; 2437 break;
2422 } 2438 }
2423 ASSERT_NOT_REACHED(); 2439 ASSERT_NOT_REACHED();
2424 } 2440 }
2425 2441
2426 SerializedScriptValue::SerializedScriptValue(const String& wireData) 2442 SerializedScriptValue::SerializedScriptValue(const String& wireData)
2427 : m_externallyAllocatedMemory(0) 2443 : m_externallyAllocatedMemory(0)
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
2466 // If the allocated memory was not registered before, then this class is lik ely 2482 // If the allocated memory was not registered before, then this class is lik ely
2467 // used in a context other then Worker's onmessage environment and the prese nce of 2483 // used in a context other then Worker's onmessage environment and the prese nce of
2468 // current v8 context is not guaranteed. Avoid calling v8 then. 2484 // current v8 context is not guaranteed. Avoid calling v8 then.
2469 if (m_externallyAllocatedMemory) { 2485 if (m_externallyAllocatedMemory) {
2470 ASSERT(v8::Isolate::GetCurrent()); 2486 ASSERT(v8::Isolate::GetCurrent());
2471 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(-m_exte rnallyAllocatedMemory); 2487 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(-m_exte rnallyAllocatedMemory);
2472 } 2488 }
2473 } 2489 }
2474 2490
2475 } // namespace WebCore 2491 } // namespace WebCore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698