Changeset 193500 in webkit
- Timestamp:
- Dec 4, 2015 5:45:33 PM (8 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r193494 r193500 1 2015-12-04 Brent Fulgham <bfulgham@apple.com> 2 3 Place an upper bound on canvas pixel count 4 https://bugs.webkit.org/show_bug.cgi?id=151825 5 <rdar://problem/23324916> 6 7 Reviewed by Simon Fraser. 8 9 Malformed JavaScript can attempt to create lots of canvas contexts. Limit the amount of memory 10 we will use for this purpose to some percentage of system RAM. 11 12 * html/HTMLCanvasElement.cpp: 13 (WebCore::removeFromActivePixelMemory): Added helper function 14 (WebCore::HTMLCanvasElement::~HTMLCanvasElement): Call new 'releaseImageBufferAndContext' method 15 to ensure ImageBuffer and graphics context state are properly cleaned up. 16 (WebCore::maxActivePixels): Use one quarter of the system RAM, or 1 GB (whichever is more) as 17 an upper bound on active pixel memory. 18 (WebCore::HTMLCanvasElement::getContext): If we are attempting to create a context that will cause 19 us to exceed the allowed active pixel count, fail. 20 (WebCore::HTMLCanvasElement::releaseImageBufferAndContext): Added helper function 21 (WebCore::HTMLCanvasElement::setSurfaceSize): Use the new 'releaseImageBufferAndContext' method 22 to handle active pixel memory counts. 23 (WebCore::HTMLCanvasElement::createImageBuffer): Refuse to create a backing buffer if it will 24 exceed our available pixel memory. 25 1 26 2015-12-04 Brady Eidson <beidson@apple.com> 2 27 -
trunk/Source/WebCore/html/HTMLCanvasElement.cpp
r192140 r193500 48 48 #include "Settings.h" 49 49 #include <math.h> 50 #include <wtf/RAMSize.h> 50 51 51 52 #include <runtime/JSCInlines.h> … … 76 77 #endif 77 78 79 static size_t activePixelMemory = 0; 80 78 81 HTMLCanvasElement::HTMLCanvasElement(const QualifiedName& tagName, Document& document) 79 82 : HTMLElement(tagName, document) … … 98 101 } 99 102 103 static void removeFromActivePixelMemory(size_t pixelsReleased) 104 { 105 if (!pixelsReleased) 106 return; 107 108 if (pixelsReleased < activePixelMemory) 109 activePixelMemory -= pixelsReleased; 110 else 111 activePixelMemory = 0; 112 } 113 100 114 HTMLCanvasElement::~HTMLCanvasElement() 101 115 { … … 104 118 105 119 m_context = nullptr; // Ensure this goes away before the ImageBuffer. 120 121 releaseImageBufferAndContext(); 106 122 } 107 123 … … 179 195 } 180 196 #endif 197 198 static inline size_t maxActivePixelMemory() 199 { 200 static size_t maxPixelMemory; 201 static std::once_flag onceFlag; 202 std::call_once(onceFlag, [] { 203 maxPixelMemory = std::max(ramSize() / 4, 1024 * MB); 204 }); 205 return maxPixelMemory; 206 } 181 207 182 208 CanvasRenderingContext* HTMLCanvasElement::getContext(const String& type, CanvasContextAttributes* attrs) … … 199 225 usesDashbardCompatibilityMode = settings->usesDashboardBackwardCompatibilityMode(); 200 226 #endif 227 size_t requestedPixelMemory = 4 * width() * height(); 228 if (activePixelMemory + requestedPixelMemory > maxActivePixelMemory()) 229 return nullptr; 230 201 231 m_context = std::make_unique<CanvasRenderingContext2D>(this, document().inQuirksMode(), usesDashbardCompatibilityMode); 202 232 #if USE(IOSURFACE_CANVAS_BACKING_STORE) || ENABLE(ACCELERATED_2D_CANVAS) … … 427 457 } 428 458 459 void HTMLCanvasElement::releaseImageBufferAndContext() 460 { 461 m_contextStateSaver = nullptr; 462 setImageBuffer(nullptr); 463 } 464 429 465 void HTMLCanvasElement::setSurfaceSize(const IntSize& size) 430 466 { 431 467 m_size = size; 432 468 m_hasCreatedImageBuffer = false; 433 m_contextStateSaver = nullptr; 434 m_imageBuffer.reset(); 469 releaseImageBufferAndContext(); 435 470 clearCopiedImage(); 436 471 } … … 572 607 return; 573 608 } 609 610 // Make sure we don't use more pixel memory than the system can support. 611 size_t requestedPixelMemory = 4 * width() * height(); 612 if (activePixelMemory + requestedPixelMemory > maxActivePixelMemory()) { 613 StringBuilder stringBuilder; 614 stringBuilder.appendLiteral("Total canvas memory use exceeds the maximum limit ("); 615 stringBuilder.appendNumber(maxActivePixelMemory() / 1024 / 1024); 616 stringBuilder.appendLiteral(" MB)."); 617 document().addConsoleMessage(MessageSource::JS, MessageLevel::Warning, stringBuilder.toString()); 618 return; 619 } 574 620 575 621 IntSize bufferSize(deviceSize.width(), deviceSize.height()); … … 578 624 579 625 RenderingMode renderingMode = shouldAccelerate(bufferSize) ? Accelerated : Unaccelerated; 580 m_imageBuffer = ImageBuffer::create(size(), renderingMode); 626 627 setImageBuffer(ImageBuffer::create(size(), renderingMode)); 581 628 if (!m_imageBuffer) 582 629 return; … … 596 643 const_cast<HTMLCanvasElement*>(this)->setNeedsStyleRecalc(SyntheticStyleChange); 597 644 #endif 645 } 646 647 void HTMLCanvasElement::setImageBuffer(std::unique_ptr<ImageBuffer> buffer) const 648 { 649 removeFromActivePixelMemory(memoryCost()); 650 651 m_imageBuffer = WTF::move(buffer); 652 653 activePixelMemory += memoryCost(); 598 654 } 599 655 -
trunk/Source/WebCore/html/HTMLCanvasElement.h
r189144 r193500 153 153 154 154 void setSurfaceSize(const IntSize&); 155 void setImageBuffer(std::unique_ptr<ImageBuffer>) const; 156 void releaseImageBufferAndContext(); 155 157 156 158 bool paintsIntoCanvasBuffer() const;
Note: See TracChangeset
for help on using the changeset viewer.