Commit f2107046 authored by Yi Xu's avatar Yi Xu Committed by Commit Bot

Checks for rect size on Canvas strokeRect

StrokeRect can get inflated, which may go to infinity. Generalize the
validation functions for double and float and validate rect during
strokeRect.


Bug: 1010586
Change-Id: Id2e057bf1f5789b334a8ad3155a1da0a1a91b8f6
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1869034
Commit-Queue: Yi Xu <yiyix@chromium.org>
Reviewed-by: default avatarFernando Serboncini <fserb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#710587}
parent 1a9d21c9
...@@ -598,30 +598,6 @@ void BaseRenderingContext2D::beginPath() { ...@@ -598,30 +598,6 @@ void BaseRenderingContext2D::beginPath() {
path_.Clear(); path_.Clear();
} }
static bool ValidateRectForCanvas(double& x,
double& y,
double& width,
double& height) {
if (!std::isfinite(x) || !std::isfinite(y) || !std::isfinite(width) ||
!std::isfinite(height))
return false;
if (!width && !height)
return false;
if (width < 0) {
width = -width;
x -= width;
}
if (height < 0) {
height = -height;
y -= height;
}
return true;
}
bool BaseRenderingContext2D::IsFullCanvasCompositeMode(SkBlendMode op) { bool BaseRenderingContext2D::IsFullCanvasCompositeMode(SkBlendMode op) {
// See 4.8.11.1.3 Compositing // See 4.8.11.1.3 Compositing
// CompositeSourceAtop and CompositeDestinationOut are not listed here as the // CompositeSourceAtop and CompositeDestinationOut are not listed here as the
...@@ -699,6 +675,7 @@ void BaseRenderingContext2D::fillRect(double x, ...@@ -699,6 +675,7 @@ void BaseRenderingContext2D::fillRect(double x,
return; return;
// clamp to float to avoid float cast overflow when used as SkScalar // clamp to float to avoid float cast overflow when used as SkScalar
AdjustRectForCanvas(x, y, width, height);
float fx = clampTo<float>(x); float fx = clampTo<float>(x);
float fy = clampTo<float>(y); float fy = clampTo<float>(y);
float fwidth = clampTo<float>(width); float fwidth = clampTo<float>(width);
...@@ -748,6 +725,7 @@ void BaseRenderingContext2D::strokeRect(double x, ...@@ -748,6 +725,7 @@ void BaseRenderingContext2D::strokeRect(double x,
return; return;
// clamp to float to avoid float cast overflow when used as SkScalar // clamp to float to avoid float cast overflow when used as SkScalar
AdjustRectForCanvas(x, y, width, height);
float fx = clampTo<float>(x); float fx = clampTo<float>(x);
float fy = clampTo<float>(y); float fy = clampTo<float>(y);
float fwidth = clampTo<float>(width); float fwidth = clampTo<float>(width);
...@@ -756,6 +734,11 @@ void BaseRenderingContext2D::strokeRect(double x, ...@@ -756,6 +734,11 @@ void BaseRenderingContext2D::strokeRect(double x,
SkRect rect = SkRect::MakeXYWH(fx, fy, fwidth, fheight); SkRect rect = SkRect::MakeXYWH(fx, fy, fwidth, fheight);
FloatRect bounds = rect; FloatRect bounds = rect;
InflateStrokeRect(bounds); InflateStrokeRect(bounds);
if (!ValidateRectForCanvas(bounds.X(), bounds.Y(), bounds.Width(),
bounds.Height()))
return;
Draw([&rect](cc::PaintCanvas* c, const PaintFlags* flags) // draw lambda Draw([&rect](cc::PaintCanvas* c, const PaintFlags* flags) // draw lambda
{ StrokeRectOnCanvas(rect, c, flags); }, { StrokeRectOnCanvas(rect, c, flags); },
[](const SkIRect& clip_bounds) // overdraw test lambda [](const SkIRect& clip_bounds) // overdraw test lambda
...@@ -884,6 +867,7 @@ void BaseRenderingContext2D::clearRect(double x, ...@@ -884,6 +867,7 @@ void BaseRenderingContext2D::clearRect(double x,
clear_flags.setStyle(PaintFlags::kFill_Style); clear_flags.setStyle(PaintFlags::kFill_Style);
// clamp to float to avoid float cast overflow when used as SkScalar // clamp to float to avoid float cast overflow when used as SkScalar
AdjustRectForCanvas(x, y, width, height);
float fx = clampTo<float>(x); float fx = clampTo<float>(x);
float fy = clampTo<float>(y); float fy = clampTo<float>(y);
float fwidth = clampTo<float>(width); float fwidth = clampTo<float>(width);
......
...@@ -409,6 +409,12 @@ class MODULES_EXPORT BaseRenderingContext2D : public GarbageCollectedMixin, ...@@ -409,6 +409,12 @@ class MODULES_EXPORT BaseRenderingContext2D : public GarbageCollectedMixin,
CanvasRenderingContext2DState::PaintType, CanvasRenderingContext2DState::PaintType,
CanvasRenderingContext2DState::ImageType); CanvasRenderingContext2DState::ImageType);
template <typename T>
bool ValidateRectForCanvas(T x, T y, T width, T height);
template <typename T>
void AdjustRectForCanvas(T& x, T& y, T& width, T& height);
void ClearCanvas(); void ClearCanvas();
bool RectContainsTransformedRect(const FloatRect&, const SkIRect&) const; bool RectContainsTransformedRect(const FloatRect&, const SkIRect&) const;
// Sets the origin to be tainted by the content of the canvas, such // Sets the origin to be tainted by the content of the canvas, such
...@@ -522,6 +528,31 @@ void BaseRenderingContext2D::CompositedDraw( ...@@ -522,6 +528,31 @@ void BaseRenderingContext2D::CompositedDraw(
c->setMatrix(ctm); c->setMatrix(ctm);
} }
template <typename T>
bool BaseRenderingContext2D::ValidateRectForCanvas(T x,
T y,
T width,
T height) {
return (std::isfinite(x) && std::isfinite(y) && std::isfinite(width) &&
std::isfinite(height) && (width || height));
}
template <typename T>
void BaseRenderingContext2D::AdjustRectForCanvas(T& x,
T& y,
T& width,
T& height) {
if (width < 0) {
width = -width;
x -= width;
}
if (height < 0) {
height = -height;
y -= height;
}
}
} // namespace blink } // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_CANVAS2D_BASE_RENDERING_CONTEXT_2D_H_ #endif // THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_CANVAS2D_BASE_RENDERING_CONTEXT_2D_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment