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

Side by Side Diff: third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp

Issue 1414553002: Fix out-of-memory crashes related to ArrayBuffer allocation Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: applied review comments Created 5 years, 2 months 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) 2004, 2006, 2007 Apple Inc. All rights reserved. 2 * Copyright (C) 2004, 2006, 2007 Apple Inc. All rights reserved.
3 * Copyright (C) 2007 Alp Toker <alp@atoker.com> 3 * Copyright (C) 2007 Alp Toker <alp@atoker.com>
4 * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved. 4 * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
(...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after
480 480
481 // FIXME: Make isSupportedImageMIMETypeForEncoding threadsafe (to allow this method to be used on a worker thread). 481 // FIXME: Make isSupportedImageMIMETypeForEncoding threadsafe (to allow this method to be used on a worker thread).
482 if (mimeType.isNull() || !MIMETypeRegistry::isSupportedImageMIMETypeForEncod ing(lowercaseMimeType)) 482 if (mimeType.isNull() || !MIMETypeRegistry::isSupportedImageMIMETypeForEncod ing(lowercaseMimeType))
483 lowercaseMimeType = "image/png"; 483 lowercaseMimeType = "image/png";
484 484
485 return lowercaseMimeType; 485 return lowercaseMimeType;
486 } 486 }
487 487
488 const AtomicString HTMLCanvasElement::imageSourceURL() const 488 const AtomicString HTMLCanvasElement::imageSourceURL() const
489 { 489 {
490 return AtomicString(toDataURLInternal("image/png", 0, FrontBuffer)); 490 NonThrowableExceptionState exceptionState;
491 AtomicString dataURL(toDataURLInternal("image/png", 0, FrontBuffer, exceptio nState));
492 if (exceptionState.hadException())
493 return AtomicString("data:,");
494 return dataURL;
491 } 495 }
492 496
493 void HTMLCanvasElement::prepareSurfaceForPaintingIfNeeded() const 497 void HTMLCanvasElement::prepareSurfaceForPaintingIfNeeded() const
494 { 498 {
495 ASSERT(m_context && m_context->is2d()); // This function is called by the 2d context 499 ASSERT(m_context && m_context->is2d()); // This function is called by the 2d context
496 if (buffer()) 500 if (buffer())
497 m_imageBuffer->prepareSurfaceForPaintingIfNeeded(); 501 m_imageBuffer->prepareSurfaceForPaintingIfNeeded();
498 } 502 }
499 503
500 ImageData* HTMLCanvasElement::toImageData(SourceDrawingBuffer sourceBuffer) cons t 504 ImageData* HTMLCanvasElement::toImageData(SourceDrawingBuffer sourceBuffer, Exce ptionState& exceptionState) const
501 { 505 {
502 ImageData* imageData; 506 ImageData* imageData;
503 if (is3D()) { 507 if (is3D()) {
504 // Get non-premultiplied data because of inaccurate premultiplied alpha conversion of buffer()->toDataURL(). 508 // Get non-premultiplied data because of inaccurate premultiplied alpha conversion of buffer()->toDataURL().
505 imageData = m_context->paintRenderingResultsToImageData(sourceBuffer); 509 imageData = m_context->paintRenderingResultsToImageData(sourceBuffer);
506 if (imageData) 510 if (imageData)
507 return imageData; 511 return imageData;
508 512
509 m_context->paintRenderingResultsToCanvas(sourceBuffer); 513 m_context->paintRenderingResultsToCanvas(sourceBuffer);
510 imageData = ImageData::create(m_size); 514 imageData = ImageData::create(m_size, exceptionState);
515 if (exceptionState.hadException())
516 return nullptr;
511 RefPtr<SkImage> snapshot = buffer()->newSkImageSnapshot(PreferNoAccelera tion); 517 RefPtr<SkImage> snapshot = buffer()->newSkImageSnapshot(PreferNoAccelera tion);
512 if (snapshot) { 518 if (snapshot) {
513 SkImageInfo imageInfo = SkImageInfo::Make(width(), height(), kRGBA_8 888_SkColorType, kUnpremul_SkAlphaType); 519 SkImageInfo imageInfo = SkImageInfo::Make(width(), height(), kRGBA_8 888_SkColorType, kUnpremul_SkAlphaType);
514 snapshot->readPixels(imageInfo, imageData->data()->data(), imageInfo .minRowBytes(), 0, 0); 520 snapshot->readPixels(imageInfo, imageData->data()->data(), imageInfo .minRowBytes(), 0, 0);
515 } 521 }
516 return imageData; 522 return imageData;
517 } 523 }
518 524
519 imageData = ImageData::create(m_size); 525 imageData = ImageData::create(m_size, exceptionState);
526 if (exceptionState.hadException())
527 return nullptr;
520 528
521 if (!m_context) 529 if (!m_context)
522 return imageData; 530 return imageData;
523 531
524 ASSERT(m_context->is2d()); 532 ASSERT(m_context->is2d());
525 RefPtr<SkImage> snapshot = buffer()->newSkImageSnapshot(PreferNoAcceleration ); 533 RefPtr<SkImage> snapshot = buffer()->newSkImageSnapshot(PreferNoAcceleration );
526 if (snapshot) { 534 if (snapshot) {
527 SkImageInfo imageInfo = SkImageInfo::Make(width(), height(), kRGBA_8888_ SkColorType, kUnpremul_SkAlphaType); 535 SkImageInfo imageInfo = SkImageInfo::Make(width(), height(), kRGBA_8888_ SkColorType, kUnpremul_SkAlphaType);
528 snapshot->readPixels(imageInfo, imageData->data()->data(), imageInfo.min RowBytes(), 0, 0); 536 snapshot->readPixels(imageInfo, imageData->data()->data(), imageInfo.min RowBytes(), 0, 0);
529 } 537 }
530 538
531 return imageData; 539 return imageData;
532 } 540 }
533 541
534 String HTMLCanvasElement::toDataURLInternal(const String& mimeType, const double & quality, SourceDrawingBuffer sourceBuffer) const 542 String HTMLCanvasElement::toDataURLInternal(const String& mimeType, const double & quality, SourceDrawingBuffer sourceBuffer, ExceptionState& exceptionState) con st
535 { 543 {
536 if (!isPaintable()) 544 if (!isPaintable())
537 return String("data:,"); 545 return String("data:,");
538 546
539 String encodingMimeType = toEncodingMimeType(mimeType); 547 String encodingMimeType = toEncodingMimeType(mimeType);
540 548
541 ImageData* imageData = toImageData(sourceBuffer); 549 ImageData* imageData = toImageData(sourceBuffer, exceptionState);
550 if (exceptionState.hadException())
551 return String();
552
542 ScopedDisposal<ImageData> disposer(imageData); 553 ScopedDisposal<ImageData> disposer(imageData);
543 554
544 return ImageDataBuffer(imageData->size(), imageData->data()->data()).toDataU RL(encodingMimeType, quality); 555 return ImageDataBuffer(imageData->size(), imageData->data()->data()).toDataU RL(encodingMimeType, quality);
545 } 556 }
546 557
547 String HTMLCanvasElement::toDataURL(const String& mimeType, const ScriptValue& q ualityArgument, ExceptionState& exceptionState) const 558 String HTMLCanvasElement::toDataURL(const String& mimeType, const ScriptValue& q ualityArgument, ExceptionState& exceptionState) const
548 { 559 {
549 if (!originClean()) { 560 if (!originClean()) {
550 exceptionState.throwSecurityError("Tainted canvases may not be exported. "); 561 exceptionState.throwSecurityError("Tainted canvases may not be exported. ");
551 return String(); 562 return String();
552 } 563 }
553 double quality = UndefinedQualityValue; 564 double quality = UndefinedQualityValue;
554 if (!qualityArgument.isEmpty()) { 565 if (!qualityArgument.isEmpty()) {
555 v8::Local<v8::Value> v8Value = qualityArgument.v8Value(); 566 v8::Local<v8::Value> v8Value = qualityArgument.v8Value();
556 if (v8Value->IsNumber()) { 567 if (v8Value->IsNumber()) {
557 quality = v8Value.As<v8::Number>()->Value(); 568 quality = v8Value.As<v8::Number>()->Value();
558 } 569 }
559 } 570 }
560 return toDataURLInternal(mimeType, quality, BackBuffer); 571 return toDataURLInternal(mimeType, quality, BackBuffer, exceptionState);
561 } 572 }
562 573
563 void HTMLCanvasElement::encodeImageAsync(DOMUint8ClampedArray* imageData, IntSiz e imageSize, FileCallback* callback, const String& mimeType, double quality) 574 void HTMLCanvasElement::encodeImageAsync(DOMUint8ClampedArray* imageData, IntSiz e imageSize, FileCallback* callback, const String& mimeType, double quality)
564 { 575 {
565 OwnPtr<Vector<char>> encodedImage(adoptPtr(new Vector<char>())); 576 OwnPtr<Vector<char>> encodedImage(adoptPtr(new Vector<char>()));
566 577
567 if (!ImageDataBuffer(imageSize, imageData->data()).encodeImage(mimeType, qua lity, encodedImage.get())) { 578 if (!ImageDataBuffer(imageSize, imageData->data()).encodeImage(mimeType, qua lity, encodedImage.get())) {
568 Platform::current()->mainThread()->taskRunner()->postTask(FROM_HERE, bin d(&FileCallback::handleEvent, callback, nullptr)); 579 Platform::current()->mainThread()->taskRunner()->postTask(FROM_HERE, bin d(&FileCallback::handleEvent, callback, nullptr));
569 } else { 580 } else {
570 Platform::current()->mainThread()->taskRunner()->postTask(FROM_HERE, thr eadSafeBind(&HTMLCanvasElement::createBlobAndCall, encodedImage.release(), mimeT ype, AllowCrossThreadAccess(callback))); 581 Platform::current()->mainThread()->taskRunner()->postTask(FROM_HERE, thr eadSafeBind(&HTMLCanvasElement::createBlobAndCall, encodedImage.release(), mimeT ype, AllowCrossThreadAccess(callback)));
(...skipping 25 matching lines...) Expand all
596 double quality = UndefinedQualityValue; 607 double quality = UndefinedQualityValue;
597 if (!qualityArgument.isEmpty()) { 608 if (!qualityArgument.isEmpty()) {
598 v8::Local<v8::Value> v8Value = qualityArgument.v8Value(); 609 v8::Local<v8::Value> v8Value = qualityArgument.v8Value();
599 if (v8Value->IsNumber()) { 610 if (v8Value->IsNumber()) {
600 quality = v8Value.As<v8::Number>()->Value(); 611 quality = v8Value.As<v8::Number>()->Value();
601 } 612 }
602 } 613 }
603 614
604 String encodingMimeType = toEncodingMimeType(mimeType); 615 String encodingMimeType = toEncodingMimeType(mimeType);
605 616
606 ImageData* imageData = toImageData(BackBuffer); 617 ImageData* imageData = toImageData(BackBuffer, exceptionState);
607 // imageData unref its data, which we still keep alive for the async toBlob thread 618 if (exceptionState.hadException())
619 return;
620
621 // ImageData unrefs its data, which we still keep alive for the async toBlob thread
608 ScopedDisposal<ImageData> disposer(imageData); 622 ScopedDisposal<ImageData> disposer(imageData);
609 623
610 // Add a ref to keep image data alive until completion of encoding 624 // Add a ref to keep image data alive until completion of encoding
611 RefPtr<DOMUint8ClampedArray> imageDataRef(imageData->data()); 625 RefPtr<DOMUint8ClampedArray> imageDataRef(imageData->data());
612 626
613 getToBlobThreadInstance()->taskRunner()->postTask(FROM_HERE, new Task(thread SafeBind(&HTMLCanvasElement::encodeImageAsync, AllowCrossThreadAccess(imageDataR ef.release().leakRef()), imageData->size(), AllowCrossThreadAccess(callback), en codingMimeType, quality))); 627 getToBlobThreadInstance()->taskRunner()->postTask(FROM_HERE, new Task(thread SafeBind(&HTMLCanvasElement::encodeImageAsync, AllowCrossThreadAccess(imageDataR ef.release().leakRef()), imageData->size(), AllowCrossThreadAccess(callback), en codingMimeType, quality)));
614 } 628 }
615 629
616 SecurityOrigin* HTMLCanvasElement::securityOrigin() const 630 SecurityOrigin* HTMLCanvasElement::securityOrigin() const
617 { 631 {
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after
979 { 993 {
980 return FloatSize(width(), height()); 994 return FloatSize(width(), height());
981 } 995 }
982 996
983 bool HTMLCanvasElement::isOpaque() const 997 bool HTMLCanvasElement::isOpaque() const
984 { 998 {
985 return m_context && !m_context->hasAlpha(); 999 return m_context && !m_context->hasAlpha();
986 } 1000 }
987 1001
988 } // blink 1002 } // blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698