aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu
diff options
context:
space:
mode:
authorGravatar Greg Daniel <egdaniel@google.com>2018-06-07 13:15:10 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-06-07 17:38:01 +0000
commitd5b4593024544c3405615066aa5b4f94352eb3cb (patch)
tree9e6b507ecf6674d2905caf3636eb43b8731d5285 /src/gpu
parent8345aa6302c7ca25a4b9c2df913e83ef79220ab7 (diff)
Add checks to make sure we don't overflow 32 bit int in GPU path renderers.
Bug: chromium:848716 Change-Id: I5b8fe036c666a1f379c4125115b2cec0295711b3 Reviewed-on: https://skia-review.googlesource.com/132268 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Greg Daniel <egdaniel@google.com>
Diffstat (limited to 'src/gpu')
-rw-r--r--src/gpu/GrTessellator.cpp20
-rw-r--r--src/gpu/ops/GrAAConvexPathRenderer.cpp22
-rw-r--r--src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp30
-rw-r--r--src/gpu/ops/GrSmallPathRenderer.cpp6
4 files changed, 52 insertions, 26 deletions
diff --git a/src/gpu/GrTessellator.cpp b/src/gpu/GrTessellator.cpp
index 79f5765ee4..9369d70c30 100644
--- a/src/gpu/GrTessellator.cpp
+++ b/src/gpu/GrTessellator.cpp
@@ -2116,8 +2116,8 @@ int get_contour_count(const SkPath& path, SkScalar tolerance) {
return contourCnt;
}
-int count_points(Poly* polys, SkPath::FillType fillType) {
- int count = 0;
+int64_t count_points(Poly* polys, SkPath::FillType fillType) {
+ int64_t count = 0;
for (Poly* poly = polys; poly; poly = poly->fNext) {
if (apply_fill_type(fillType, poly) && poly->fCount >= 3) {
count += (poly->fCount - 2) * (TESSELLATOR_WIREFRAME ? 6 : 3);
@@ -2126,8 +2126,8 @@ int count_points(Poly* polys, SkPath::FillType fillType) {
return count;
}
-int count_outer_mesh_points(const VertexList& outerMesh) {
- int count = 0;
+int64_t count_outer_mesh_points(const VertexList& outerMesh) {
+ int64_t count = 0;
for (Vertex* v = outerMesh.fHead; v; v = v->fNext) {
for (Edge* e = v->fFirstEdgeBelow; e; e = e->fNextEdgeBelow) {
count += TESSELLATOR_WIREFRAME ? 12 : 6;
@@ -2169,13 +2169,14 @@ int PathToTriangles(const SkPath& path, SkScalar tolerance, const SkRect& clipBo
Poly* polys = path_to_polys(path, tolerance, clipBounds, contourCnt, alloc, antialias,
isLinear, &outerMesh);
SkPath::FillType fillType = antialias ? SkPath::kWinding_FillType : path.getFillType();
- int count = count_points(polys, fillType);
+ int64_t count64 = count_points(polys, fillType);
if (antialias) {
- count += count_outer_mesh_points(outerMesh);
+ count64 += count_outer_mesh_points(outerMesh);
}
- if (0 == count) {
+ if (0 == count64 || count64 > SK_MaxS32) {
return 0;
}
+ int count = count64;
void* verts = vertexAllocator->lock(count);
if (!verts) {
@@ -2209,11 +2210,12 @@ int PathToVertices(const SkPath& path, SkScalar tolerance, const SkRect& clipBou
Poly* polys = path_to_polys(path, tolerance, clipBounds, contourCnt, alloc, false, &isLinear,
nullptr);
SkPath::FillType fillType = path.getFillType();
- int count = count_points(polys, fillType);
- if (0 == count) {
+ int64_t count64 = count_points(polys, fillType);
+ if (0 == count64 || count64 > SK_MaxS32) {
*verts = nullptr;
return 0;
}
+ int count = count64;
*verts = new GrTessellator::WindingVertex[count];
GrTessellator::WindingVertex* vertsEnd = *verts;
diff --git a/src/gpu/ops/GrAAConvexPathRenderer.cpp b/src/gpu/ops/GrAAConvexPathRenderer.cpp
index a1d7392de0..d1fbbc4e7b 100644
--- a/src/gpu/ops/GrAAConvexPathRenderer.cpp
+++ b/src/gpu/ops/GrAAConvexPathRenderer.cpp
@@ -22,6 +22,7 @@
#include "SkPointPriv.h"
#include "SkString.h"
#include "SkTraceEvent.h"
+#include "SkTypes.h"
#include "glsl/GrGLSLFragmentShaderBuilder.h"
#include "glsl/GrGLSLGeometryProcessor.h"
#include "glsl/GrGLSLProgramDataManager.h"
@@ -132,8 +133,8 @@ static bool compute_vectors(SegmentArray* segments,
normSide = SkPointPriv::kLeft_Side;
}
- *vCount = 0;
- *iCount = 0;
+ int64_t vCount64 = 0;
+ int64_t iCount64 = 0;
// compute normals at all points
for (int a = 0; a < count; ++a) {
Segment& sega = (*segments)[a];
@@ -149,11 +150,11 @@ static bool compute_vectors(SegmentArray* segments,
prevPt = &segb.fPts[p];
}
if (Segment::kLine == segb.fType) {
- *vCount += 5;
- *iCount += 9;
+ vCount64 += 5;
+ iCount64 += 9;
} else {
- *vCount += 6;
- *iCount += 12;
+ vCount64 += 6;
+ iCount64 += 12;
}
}
@@ -166,9 +167,14 @@ static bool compute_vectors(SegmentArray* segments,
segb.fMid = segb.fNorms[0] + sega.endNorm();
segb.fMid.normalize();
// corner wedges
- *vCount += 4;
- *iCount += 6;
+ vCount64 += 4;
+ iCount64 += 6;
}
+ if (vCount64 > SK_MaxS32 || iCount64 > SK_MaxS32) {
+ return false;
+ }
+ *vCount = vCount64;
+ *iCount = iCount64;
return true;
}
diff --git a/src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp b/src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp
index 2176e0914b..2c1ea50fc3 100644
--- a/src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp
+++ b/src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp
@@ -255,10 +255,10 @@ private:
int instanceCount = fPaths.count();
- int vertexCount = 0;
- int indexCount = 0;
- int maxVertices = DEFAULT_BUFFER_SIZE;
- int maxIndices = DEFAULT_BUFFER_SIZE;
+ int64_t vertexCount = 0;
+ int64_t indexCount = 0;
+ int64_t maxVertices = DEFAULT_BUFFER_SIZE;
+ int64_t maxIndices = DEFAULT_BUFFER_SIZE;
uint8_t* vertices = (uint8_t*) sk_malloc_throw(maxVertices * vertexStride);
uint16_t* indices = (uint16_t*) sk_malloc_throw(maxIndices * sizeof(uint16_t));
for (int i = 0; i < instanceCount; i++) {
@@ -270,8 +270,8 @@ private:
continue;
}
- int currentIndices = tess.numIndices();
- if (indexCount + currentIndices > static_cast<int>(UINT16_MAX)) {
+ int currentVertices = tess.numPts();
+ if (vertexCount + currentVertices > static_cast<int>(UINT16_MAX)) {
// if we added the current instance, we would overflow the indices we can store in a
// uint16_t. Draw what we've got so far and reset.
this->draw(target, gp.get(), pipeline, vertexCount, vertexStride, vertices,
@@ -279,13 +279,23 @@ private:
vertexCount = 0;
indexCount = 0;
}
- int currentVertices = tess.numPts();
if (vertexCount + currentVertices > maxVertices) {
maxVertices = SkTMax(vertexCount + currentVertices, maxVertices * 2);
+ if (maxVertices * vertexStride > SK_MaxS32) {
+ sk_free(vertices);
+ sk_free(indices);
+ return;
+ }
vertices = (uint8_t*) sk_realloc_throw(vertices, maxVertices * vertexStride);
}
+ int currentIndices = tess.numIndices();
if (indexCount + currentIndices > maxIndices) {
maxIndices = SkTMax(indexCount + currentIndices, maxIndices * 2);
+ if (maxIndices * sizeof(uint16_t) > SK_MaxS32) {
+ sk_free(vertices);
+ sk_free(indices);
+ return;
+ }
indices = (uint16_t*) sk_realloc_throw(indices, maxIndices * sizeof(uint16_t));
}
@@ -295,8 +305,10 @@ private:
vertexCount += currentVertices;
indexCount += currentIndices;
}
- this->draw(target, gp.get(), pipeline, vertexCount, vertexStride, vertices, indexCount,
- indices);
+ if (vertexCount <= SK_MaxS32 && indexCount <= SK_MaxS32) {
+ this->draw(target, gp.get(), pipeline, vertexCount, vertexStride, vertices, indexCount,
+ indices);
+ }
sk_free(vertices);
sk_free(indices);
}
diff --git a/src/gpu/ops/GrSmallPathRenderer.cpp b/src/gpu/ops/GrSmallPathRenderer.cpp
index cbf1f68ac4..2ad23cbeaf 100644
--- a/src/gpu/ops/GrSmallPathRenderer.cpp
+++ b/src/gpu/ops/GrSmallPathRenderer.cpp
@@ -351,6 +351,12 @@ private:
SkASSERT(vertexStride == sizeof(SkPoint) + sizeof(GrColor) + 2*sizeof(uint16_t));
const GrBuffer* vertexBuffer;
+
+ // We need to make sure we don't overflow a 32 bit int when we request space in the
+ // makeVertexSpace call below.
+ if (instanceCount > SK_MaxS32 / kVerticesPerQuad) {
+ return;
+ }
void* vertices = target->makeVertexSpace(vertexStride,
kVerticesPerQuad * instanceCount,
&vertexBuffer,