Keep SkRasterPipelineSpriteBlitter's src/dst offset math in size_t
With big enough y and stride (e.g. 27 and ~20000000) the expression
- bpp*x - bpp*y*fSrcPtr.stride
can underflow, and cause mayhem.
Bug: chromium:797796
Change-Id: Ifc412230c4c7eadfcd36446113be9ac1753b5b1c
Reviewed-on: https://skia-review.googlesource.com/99343
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Mike Klein <mtklein@chromium.org>
diff --git a/src/core/SkBlitter_Sprite.cpp b/src/core/SkBlitter_Sprite.cpp
index 95259c6..8f0ebfa 100644
--- a/src/core/SkBlitter_Sprite.cpp
+++ b/src/core/SkBlitter_Sprite.cpp
@@ -142,11 +142,15 @@
}
void blitRect(int x, int y, int width, int height) override {
- int bpp = fSource.info().bytesPerPixel();
-
fSrcPtr.stride = fSource.rowBytesAsPixels();
- fSrcPtr.pixels = (char*)fSource.addr(x-fLeft, y-fTop) - bpp * x
- - bpp * y * fSrcPtr.stride;
+
+ // We really want fSrcPtr.pixels = fSource.addr(-fLeft, -fTop) here, but that asserts.
+ // Instead we ask for addr(-fLeft+x, -fTop+y), then back up (x,y) manually.
+ // Representing bpp as a size_t keeps all this math in size_t instead of int,
+ // which could wrap around with large enough fSrcPtr.stride and y.
+ size_t bpp = fSource.info().bytesPerPixel();
+ fSrcPtr.pixels = (char*)fSource.addr(-fLeft+x, -fTop+y) - bpp * x
+ - bpp * y * fSrcPtr.stride;
fBlitter->blitRect(x,y,width,height);
}