From 5c68dce7750a5525a5cfae29943716ce5c0d51b3 Mon Sep 17 00:00:00 2001 From: Mike Reed Date: Thu, 21 Dec 2017 21:54:32 -0500 Subject: add safemath version of readbuffer->skip Bug: skia: Change-Id: I6a5d24569cc1bd93bd190d81e3375993da9c56f0 Reviewed-on: https://skia-review.googlesource.com/88581 Commit-Queue: Mike Reed Reviewed-by: Herb Derby Reviewed-by: Mike Klein --- src/core/SkMath.cpp | 17 +++++++++++++++-- src/core/SkPicturePlayback.cpp | 38 ++++++++++++++++++++------------------ src/core/SkReadBuffer.cpp | 5 +++++ src/core/SkReadBuffer.h | 1 + src/core/SkSafeMath.h | 4 ++++ 5 files changed, 45 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/core/SkMath.cpp b/src/core/SkMath.cpp index 6eff790c85..58645dab8f 100644 --- a/src/core/SkMath.cpp +++ b/src/core/SkMath.cpp @@ -9,6 +9,7 @@ #include "SkFixed.h" #include "SkFloatBits.h" #include "SkFloatingPoint.h" +#include "SkSafeMath.h" #include "SkScalar.h" #define sub_shift(zeros, x, n) \ @@ -67,8 +68,6 @@ int32_t SkSqrtBits(int32_t x, int count) { return root; } -/////////////////////////////////////////////////////////////////////////////// - float SkScalarSinCos(float radians, float* cosValue) { float sinValue = sk_float_sin(radians); @@ -84,3 +83,17 @@ float SkScalarSinCos(float radians, float* cosValue) { } return sinValue; } + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +size_t SkSafeMath::Add(size_t x, size_t y) { + SkSafeMath tmp; + size_t sum = tmp.add(x, y); + return tmp.ok() ? sum : SK_MaxSizeT; +} + +size_t SkSafeMath::Mul(size_t x, size_t y) { + SkSafeMath tmp; + size_t prod = tmp.mul(x, y); + return tmp.ok() ? prod : SK_MaxSizeT; +} diff --git a/src/core/SkPicturePlayback.cpp b/src/core/SkPicturePlayback.cpp index a2260952d7..c5aebe3602 100644 --- a/src/core/SkPicturePlayback.cpp +++ b/src/core/SkPicturePlayback.cpp @@ -14,6 +14,7 @@ #include "SkPictureRecord.h" #include "SkReadBuffer.h" #include "SkRSXform.h" +#include "SkSafeMath.h" #include "SkTextBlob.h" #include "SkTDArray.h" #include "SkTypes.h" @@ -246,12 +247,12 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader, const SkImage* atlas = fPictureData->getImage(reader); const uint32_t flags = reader->readUInt(); const int count = reader->readUInt(); - const SkRSXform* xform = (const SkRSXform*)reader->skip(count * sizeof(SkRSXform)); - const SkRect* tex = (const SkRect*)reader->skip(count * sizeof(SkRect)); + const SkRSXform* xform = (const SkRSXform*)reader->skip(count, sizeof(SkRSXform)); + const SkRect* tex = (const SkRect*)reader->skip(count, sizeof(SkRect)); const SkColor* colors = nullptr; SkBlendMode mode = SkBlendMode::kDst; if (flags & DRAW_ATLAS_HAS_COLORS) { - colors = (const SkColor*)reader->skip(count * sizeof(SkColor)); + colors = (const SkColor*)reader->skip(count, sizeof(SkColor)); mode = (SkBlendMode)reader->readUInt(); } const SkRect* cull = nullptr; @@ -360,9 +361,9 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader, const SkImage* image = fPictureData->getImage(reader); SkCanvas::Lattice lattice; lattice.fXCount = reader->readInt(); - lattice.fXDivs = (const int*) reader->skip(lattice.fXCount * sizeof(int32_t)); + lattice.fXDivs = (const int*) reader->skip(lattice.fXCount, sizeof(int32_t)); lattice.fYCount = reader->readInt(); - lattice.fYDivs = (const int*) reader->skip(lattice.fYCount * sizeof(int32_t)); + lattice.fYDivs = (const int*) reader->skip(lattice.fYCount, sizeof(int32_t)); int flagCount = reader->readInt(); lattice.fRectTypes = (0 == flagCount) ? nullptr : (const SkCanvas::Lattice::RectType*) @@ -427,16 +428,16 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader, case DRAW_PATCH: { const SkPaint* paint = fPictureData->getPaint(reader); - const SkPoint* cubics = (const SkPoint*)reader->skip(SkPatchUtils::kNumCtrlPts * + const SkPoint* cubics = (const SkPoint*)reader->skip(SkPatchUtils::kNumCtrlPts, sizeof(SkPoint)); uint32_t flag = reader->readInt(); const SkColor* colors = nullptr; if (flag & DRAW_VERTICES_HAS_COLORS) { - colors = (const SkColor*)reader->skip(SkPatchUtils::kNumCorners * sizeof(SkColor)); + colors = (const SkColor*)reader->skip(SkPatchUtils::kNumCorners, sizeof(SkColor)); } const SkPoint* texCoords = nullptr; if (flag & DRAW_VERTICES_HAS_TEXS) { - texCoords = (const SkPoint*)reader->skip(SkPatchUtils::kNumCorners * + texCoords = (const SkPoint*)reader->skip(SkPatchUtils::kNumCorners, sizeof(SkPoint)); } SkBlendMode bmode = SkBlendMode::kModulate; @@ -480,7 +481,7 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader, const SkPaint* paint = fPictureData->getPaint(reader); SkCanvas::PointMode mode = (SkCanvas::PointMode)reader->readInt(); size_t count = reader->readInt(); - const SkPoint* pts = (const SkPoint*)reader->skip(sizeof(SkPoint)* count); + const SkPoint* pts = (const SkPoint*)reader->skip(count, sizeof(SkPoint)); BREAK_ON_READ_ERROR(reader); if (paint) { @@ -492,7 +493,7 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader, TextContainer text(reader, paint); size_t points = reader->readInt(); reader->validate(points == text.count()); - const SkPoint* pos = (const SkPoint*)reader->skip(points * sizeof(SkPoint)); + const SkPoint* pos = (const SkPoint*)reader->skip(points, sizeof(SkPoint)); BREAK_ON_READ_ERROR(reader); if (paint && text.text()) { @@ -504,7 +505,7 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader, TextContainer text(reader, paint); size_t points = reader->readInt(); reader->validate(points == text.count()); - const SkPoint* pos = (const SkPoint*)reader->skip(points * sizeof(SkPoint)); + const SkPoint* pos = (const SkPoint*)reader->skip(points, sizeof(SkPoint)); const SkScalar top = reader->readScalar(); const SkScalar bottom = reader->readScalar(); SkDebugf("postexth count %zu pos %p\n", points, pos); @@ -521,7 +522,7 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader, size_t xCount = reader->readInt(); reader->validate(xCount == text.count()); const SkScalar constY = reader->readScalar(); - const SkScalar* xpos = (const SkScalar*)reader->skip(xCount * sizeof(SkScalar)); + const SkScalar* xpos = (const SkScalar*)reader->skip(xCount, sizeof(SkScalar)); BREAK_ON_READ_ERROR(reader); if (paint && text.text()) { @@ -533,7 +534,8 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader, TextContainer text(reader, paint); size_t xCount = reader->readInt(); reader->validate(xCount == text.count()); - const SkScalar* xpos = (const SkScalar*)reader->skip((3 + xCount) * sizeof(SkScalar)); + const SkScalar* xpos = (const SkScalar*)reader->skip(SkSafeMath::Add(3, xCount), + sizeof(SkScalar)); BREAK_ON_READ_ERROR(reader); const SkScalar top = *xpos++; @@ -651,7 +653,7 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader, int count = reader->readInt(); uint32_t flags = reader->read32(); TextContainer text(reader, paint); - const SkRSXform* xform = (const SkRSXform*)reader->skip(count * sizeof(SkRSXform)); + const SkRSXform* xform = (const SkRSXform*)reader->skip(count, sizeof(SkRSXform)); const SkRect* cull = nullptr; if (flags & DRAW_TEXT_RSXFORM_HAS_CULL) { cull = (const SkRect*)reader->skip(sizeof(SkRect)); @@ -667,20 +669,20 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader, DrawVertexFlags flags = (DrawVertexFlags)reader->readInt(); SkVertices::VertexMode vmode = (SkVertices::VertexMode)reader->readInt(); int vCount = reader->readInt(); - const SkPoint* verts = (const SkPoint*)reader->skip(vCount * sizeof(SkPoint)); + const SkPoint* verts = (const SkPoint*)reader->skip(vCount, sizeof(SkPoint)); const SkPoint* texs = nullptr; const SkColor* colors = nullptr; const uint16_t* indices = nullptr; int iCount = 0; if (flags & DRAW_VERTICES_HAS_TEXS) { - texs = (const SkPoint*)reader->skip(vCount * sizeof(SkPoint)); + texs = (const SkPoint*)reader->skip(vCount, sizeof(SkPoint)); } if (flags & DRAW_VERTICES_HAS_COLORS) { - colors = (const SkColor*)reader->skip(vCount * sizeof(SkColor)); + colors = (const SkColor*)reader->skip(vCount, sizeof(SkColor)); } if (flags & DRAW_VERTICES_HAS_INDICES) { iCount = reader->readInt(); - indices = (const uint16_t*)reader->skip(iCount * sizeof(uint16_t)); + indices = (const uint16_t*)reader->skip(iCount, sizeof(uint16_t)); } SkBlendMode bmode = SkBlendMode::kModulate; if (flags & DRAW_VERTICES_HAS_XFER) { diff --git a/src/core/SkReadBuffer.cpp b/src/core/SkReadBuffer.cpp index 9d15c1f40e..c4ca315f66 100644 --- a/src/core/SkReadBuffer.cpp +++ b/src/core/SkReadBuffer.cpp @@ -13,6 +13,7 @@ #include "SkMathPriv.h" #include "SkMatrixPriv.h" #include "SkReadBuffer.h" +#include "SkSafeMath.h" #include "SkStream.h" #include "SkTypeface.h" @@ -106,6 +107,10 @@ const void* SkReadBuffer::skip(size_t size) { return addr; } +const void* SkReadBuffer::skip(size_t count, size_t size) { + return this->skip(SkSafeMath::Mul(count, size)); +} + void SkReadBuffer::setDeserialProcs(const SkDeserialProcs& procs) { fProcs = procs; } diff --git a/src/core/SkReadBuffer.h b/src/core/SkReadBuffer.h index 9c62a33770..665f4080e3 100644 --- a/src/core/SkReadBuffer.h +++ b/src/core/SkReadBuffer.h @@ -115,6 +115,7 @@ public: size_t offset() { return fReader.offset(); } bool eof() { return fReader.eof(); } const void* skip(size_t size); + const void* skip(size_t count, size_t size); // does safe multiply // primitives bool readBool(); diff --git a/src/core/SkSafeMath.h b/src/core/SkSafeMath.h index 1005d069a8..7afd482579 100644 --- a/src/core/SkSafeMath.h +++ b/src/core/SkSafeMath.h @@ -48,6 +48,10 @@ public: return add(x, alignment - 1) & ~(alignment - 1); } + // These saturate to their results + static size_t Add(size_t x, size_t y); + static size_t Mul(size_t x, size_t y); + private: uint32_t mul32(uint32_t x, uint32_t y) { uint64_t bx = x; -- cgit v1.2.3