path hang

In release, path hangs because buffers overflow.
Debug shows that the clipped cubic generates 34 points although
a maximum of 32 are expected.

The path has very small numbers that fool MaxCurvature into
thinking that there are more places to break the cubic than
are necessary.

To make this bullet-proof, increase the verbs and points.

Allow (1 line + 1 cubic) * (3 x-pieces) * (3 y-pieces) == 18 verbs.
Allow (6 points for line + cubic + line) * 9 pieces    == 54 points.

R=reed@google.com,liyuqian@google.com
BUG=698714

Change-Id: I04fad10c151c79d0c53465a2b658aa4dd59f1c98
Reviewed-on: https://skia-review.googlesource.com/9983
Reviewed-by: Yuqian Li <liyuqian@google.com>
Commit-Queue: Cary Clark <caryclark@google.com>
This commit is contained in:
Cary Clark 2017-03-21 16:11:54 -04:00 committed by Skia Commit-Bot
parent de1a605346
commit 44c1b111c7
2 changed files with 43 additions and 2 deletions

View File

@ -32,8 +32,8 @@ private:
const bool fCanCullToTheRight;
enum {
kMaxVerbs = 13,
kMaxPoints = 32
kMaxVerbs = 18, // max curvature in X and Y split cubic into 9 pieces, * (line + cubic)
kMaxPoints = 54 // 2 lines + 1 cubic require 6 points; times 9 pieces
};
SkPoint fPoints[kMaxPoints];
SkPath::Verb fVerbs[kMaxVerbs];

View File

@ -162,3 +162,44 @@ DEF_TEST(ClipCubic, reporter) {
test_giantClip();
}
#include "SkSurface.h"
DEF_TEST(test_fuzz_crbug_698714, reporter) {
auto surface(SkSurface::MakeRasterN32Premul(500, 500));
SkCanvas* canvas = surface->getCanvas();
SkPaint paint;
paint.setAntiAlias(true);
SkPath path;
path.setFillType(SkPath::kWinding_FillType);
path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0x00000000)); // 0,0
path.lineTo(SkBits2Float(0x43434343), SkBits2Float(0x43430143)); //195.263f, 195.005f
path.lineTo(SkBits2Float(0x43434343), SkBits2Float(0x43434343)); //195.263f, 195.263f
path.lineTo(SkBits2Float(0xb5434343), SkBits2Float(0x434300be)); //-7.2741e-07f, 195.003f
// 195.263f, 195.263f, -1.16387e-05f, 3.58641e-38f, 3.85088e-29f,1.86082e-39f
path.cubicTo(SkBits2Float(0x43434343), SkBits2Float(0x43434341),
SkBits2Float(0xb74343bd), SkBits2Float(0x01434343),
SkBits2Float(0x10434343), SkBits2Float(0x00144332));
// 4.11823e-38f, 195.263f, 195.263f, 195.263f, -7.2741e-07f, 195.263f
path.cubicTo(SkBits2Float(0x016037c0), SkBits2Float(0x43434343),
SkBits2Float(0x43434343), SkBits2Float(0x43434343),
SkBits2Float(0xb5434343), SkBits2Float(0x43434343));
// 195.263f, 195.263f, -1.16387e-05f, 3.58641e-38f, 195.263f, -2
path.cubicTo(SkBits2Float(0x43434344), SkBits2Float(0x43434341),
SkBits2Float(0xb74343bd), SkBits2Float(0x01434343),
SkBits2Float(0x43434343), SkBits2Float(0xc0000014));
// -5.87228e+06f, 3.7773e-07f, 3.60231e-13f, -6.64511e+06f,2.77692e-15f, 2.48803e-15f
path.cubicTo(SkBits2Float(0xcab33535), SkBits2Float(0x34cacaca),
SkBits2Float(0x2acacaca), SkBits2Float(0xcacacae3),
SkBits2Float(0x27481927), SkBits2Float(0x27334805));
path.lineTo(SkBits2Float(0xb5434343), SkBits2Float(0x43434343)); //-7.2741e-07f, 195.263f
// 195.263f, 195.263f, -1.16387e-05f, 195.212f, 195.263f, -2
path.cubicTo(SkBits2Float(0x43434343), SkBits2Float(0x43434341),
SkBits2Float(0xb74343b9), SkBits2Float(0x43433643),
SkBits2Float(0x43434343), SkBits2Float(0xc0000014));
path.lineTo(SkBits2Float(0xc7004343), SkBits2Float(0x27480527)); //-32835.3f, 2.77584e-15f
path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0x00000000)); // 0,0
path.close();
canvas->clipRect({0, 0, 65, 202});
canvas->drawPath(path, paint);
}