Limit the maximum number of dash segments per path
https://crbug.com/165432 In order to avoid trivial out-of-memory exploits, cap path dashing at 1000000 segments per path. R=reed@google.com BUG= Review URL: https://codereview.appspot.com/6948063 git-svn-id: http://skia.googlecode.com/svn/trunk@6845 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
6c0e5225a0
commit
6b18d2471f
@ -164,6 +164,7 @@ bool SkDashPathEffect::filterPath(SkPath* dst, const SkPath& src,
|
||||
|
||||
SkPathMeasure meas(src, false);
|
||||
const SkScalar* intervals = fIntervals;
|
||||
SkScalar dashCount = 0;
|
||||
|
||||
SpecialLineRec lineRec;
|
||||
const bool specialLine = lineRec.init(src, dst, rec, meas.getLength(),
|
||||
@ -176,6 +177,21 @@ bool SkDashPathEffect::filterPath(SkPath* dst, const SkPath& src,
|
||||
int index = fInitialDashIndex;
|
||||
SkScalar scale = SK_Scalar1;
|
||||
|
||||
// Since the path length / dash length ratio may be arbitrarily large, we can exert
|
||||
// significant memory pressure while attempting to build the filtered path. To avoid this,
|
||||
// we simply give up dashing beyond a certain threshold.
|
||||
//
|
||||
// The original bug report (http://crbug.com/165432) is based on a path yielding more than
|
||||
// 90 million dash segments and crashing the memory allocator. A limit of 1 million
|
||||
// segments seems reasonable: at 2 verbs per segment * 9 bytes per verb, this caps the
|
||||
// maximum dash memory overhead at roughly 17MB per path.
|
||||
static const SkScalar kMaxDashCount = 1000000;
|
||||
dashCount += length * (fCount >> 1) / fIntervalLength;
|
||||
if (dashCount > kMaxDashCount) {
|
||||
dst->reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fScaleToFit) {
|
||||
if (fIntervalLength >= length) {
|
||||
scale = SkScalarDiv(length, fIntervalLength);
|
||||
|
@ -241,6 +241,26 @@ static void test_infinite_dash(skiatest::Reporter* reporter) {
|
||||
REPORTER_ASSERT(reporter, true);
|
||||
}
|
||||
|
||||
// http://crbug.com/165432
|
||||
// Limit extreme dash path effects to avoid exhausting the system memory.
|
||||
static void test_crbug_165432(skiatest::Reporter* reporter) {
|
||||
SkPath path;
|
||||
path.moveTo(0, 0);
|
||||
path.lineTo(10000000, 0);
|
||||
|
||||
SkScalar intervals[] = { 0.5f, 0.5f };
|
||||
SkDashPathEffect dash(intervals, 2, 0);
|
||||
|
||||
SkPaint paint;
|
||||
paint.setStyle(SkPaint::kStroke_Style);
|
||||
paint.setPathEffect(&dash);
|
||||
|
||||
SkPath filteredPath;
|
||||
SkStrokeRec rec(paint);
|
||||
REPORTER_ASSERT(reporter, !dash.filterPath(&filteredPath, path, &rec));
|
||||
REPORTER_ASSERT(reporter, filteredPath.isEmpty());
|
||||
}
|
||||
|
||||
static void TestDrawPath(skiatest::Reporter* reporter) {
|
||||
test_giantaa(reporter);
|
||||
test_bug533(reporter);
|
||||
@ -251,6 +271,7 @@ static void TestDrawPath(skiatest::Reporter* reporter) {
|
||||
test_inversepathwithclip(reporter);
|
||||
// test_crbug131181(reporter);
|
||||
test_infinite_dash(reporter);
|
||||
test_crbug_165432(reporter);
|
||||
}
|
||||
|
||||
#include "TestClassDef.h"
|
||||
|
Loading…
Reference in New Issue
Block a user