RESOLVED FIXED 141596
FEGaussianBlur::calculateUnscaledKernelSize does unspeakable things with signed and unsigned values
https://bugs.webkit.org/show_bug.cgi?id=141596
Summary FEGaussianBlur::calculateUnscaledKernelSize does unspeakable things with sign...
Brent Fulgham
Reported 2015-02-13 21:39:54 PST
The 'calculateUnscaledKernelSize' method improperly treats signed and unsigned values as interchangeable. This creates problems when we have extremely large stdDevication values (such as in the test case "css3/filters/huge-blur-value.html"). When the standard deviation supplied to the routine overflows a int value, we pass In this pathological case, the Std Deviation used for the blur is the float 2.14748365E+9. When this is cast as an unsigned, then assigned to a signed integer, we end up with -257759744. The minimum of -257759744 and 500 turns out to be -257759744. IntSize kernelSize; // Limit the kernel size to 500. A bigger radius won't make a big difference for the result image but // inflates the absolute paint rect too much. This is compatible with Firefox' behavior. if (stdDeviation.x()) { int size = std::max<unsigned>(2, static_cast<unsigned>(floorf(stdDeviation.x() * gaussianKernelFactor() + 0.5f))); kernelSize.setWidth(std::min(size, gMaxKernelSize)); } Later, this kernelSize is cast back to an unsigned, bypassing this ceiling, and subjecting other code to values far in excess of 500.
Attachments
Patch (2.53 KB, patch)
2015-02-13 21:54 PST, Brent Fulgham
no flags
Patch (2.52 KB, patch)
2015-02-14 09:25 PST, Brent Fulgham
no flags
Patch (2.93 KB, patch)
2015-02-14 09:49 PST, Brent Fulgham
zalan: review+
Radar WebKit Bug Importer
Comment 1 2015-02-13 21:40:49 PST
Brent Fulgham
Comment 2 2015-02-13 21:54:13 PST
zalan
Comment 3 2015-02-13 22:08:41 PST
Comment on attachment 246582 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=246582&action=review > Source/WebCore/platform/graphics/filters/FEGaussianBlur.cpp:479 > + kernelSize.setWidth(static_cast<int>(clampedSize)); I'd rather use clampTo and not static casting.
Brent Fulgham
Comment 4 2015-02-14 09:24:07 PST
Comment on attachment 246582 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=246582&action=review >> Source/WebCore/platform/graphics/filters/FEGaussianBlur.cpp:479 >> + kernelSize.setWidth(static_cast<int>(clampedSize)); > > I'd rather use clampTo and not static casting. OK!
Brent Fulgham
Comment 5 2015-02-14 09:25:13 PST
Brent Fulgham
Comment 6 2015-02-14 09:49:52 PST
zalan
Comment 7 2015-02-14 18:59:30 PST
Comment on attachment 246593 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=246593&action=review > Source/WebCore/platform/graphics/filters/FEGaussianBlur.cpp:469 > +static int clampedKernelSize(float value) clampedToKernelSize() might be a better name. > Source/WebCore/platform/graphics/filters/FEGaussianBlur.cpp:475 > + unsigned clampedSize = std::min(size, static_cast<unsigned>(gMaxKernelSize)); > + return clampTo<int>(clampedSize); the clampedSize variable is a bit redundant, i'd just go with clampTo<int>(std::min(size, static_cast<unsigned>(gMaxKernelSize)));
Brent Fulgham
Comment 8 2015-02-16 09:07:16 PST
Simon Fraser (smfr)
Comment 9 2015-02-16 13:18:00 PST
Comment on attachment 246593 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=246593&action=review > Source/WebCore/platform/graphics/filters/FEGaussianBlur.cpp:473 > + unsigned size = std::max<unsigned>(2, static_cast<unsigned>(floorf(value * gaussianKernelFactor() + 0.5f))); Why not just do this math as floats, then clamp to int directly without going via unsigned?
Note You need to log in before you can comment on or make changes to this bug.