Fixing crash in cloning empty SkPicture object
BUG=https://code.google.com/p/chromium/issues/detail?id=172062
TEST=Pictures unit test, test_clone_empty
Review URL: https://codereview.appspot.com/7223048
git-svn-id: http://skia.googlecode.com/svn/trunk@7430 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/core/SkPicturePlayback.cpp b/src/core/SkPicturePlayback.cpp
index 21fa034..7cd25cc 100644
--- a/src/core/SkPicturePlayback.cpp
+++ b/src/core/SkPicturePlayback.cpp
@@ -181,6 +181,7 @@
SkSafeRef(fStateTree);
if (deepCopyInfo) {
+ int paintCount = SafeCount(src.fPaints);
if (src.fBitmaps) {
fBitmaps = SkTRefArray<SkBitmap>::Create(src.fBitmaps->begin(), src.fBitmaps->count());
@@ -192,7 +193,7 @@
* this point we would need to pass the SkBitmapHeap so that we don't unnecessarily
* flatten the pixels in a bitmap shader.
*/
- deepCopyInfo->paintData.setCount(src.fPaints->count());
+ deepCopyInfo->paintData.setCount(paintCount);
/* Use an SkBitmapHeap to avoid flattening bitmaps in shaders. If there already is one,
* use it. If this SkPicturePlayback was created from a stream, fBitmapHeap will be
@@ -209,7 +210,7 @@
}
SkDEBUGCODE(int heapSize = SafeCount(fBitmapHeap.get());)
- for (int i = 0; i < src.fPaints->count(); i++) {
+ for (int i = 0; i < paintCount; i++) {
if (needs_deep_copy(src.fPaints->at(i))) {
deepCopyInfo->paintData[i] = SkFlatData::Create(&deepCopyInfo->controller,
&src.fPaints->at(i), 0,
@@ -226,11 +227,11 @@
deepCopyInfo->initialized = true;
}
- fPaints = SkTRefArray<SkPaint>::Create(src.fPaints->count());
- SkASSERT(deepCopyInfo->paintData.count() == src.fPaints->count());
+ fPaints = SkTRefArray<SkPaint>::Create(paintCount);
+ SkASSERT(deepCopyInfo->paintData.count() == paintCount);
SkBitmapHeap* bmHeap = deepCopyInfo->controller.getBitmapHeap();
SkTypefacePlayback* tfPlayback = deepCopyInfo->controller.getTypefacePlayback();
- for (int i = 0; i < src.fPaints->count(); i++) {
+ for (int i = 0; i < paintCount; i++) {
if (deepCopyInfo->paintData[i]) {
deepCopyInfo->paintData[i]->unflatten(&fPaints->writableAt(i),
&SkUnflattenObjectProc<SkPaint>,
diff --git a/tests/PictureTest.cpp b/tests/PictureTest.cpp
index 395ce4a..f6a18c1 100644
--- a/tests/PictureTest.cpp
+++ b/tests/PictureTest.cpp
@@ -395,6 +395,28 @@
REPORTER_ASSERT(reporter, picture1->equals(picture2));
}
+static void test_clone_empty(skiatest::Reporter* reporter) {
+ // This is a regression test for crbug.com/172062
+ // Before the fix, we used to crash accessing a null pointer when we
+ // had a picture with no paints. This test passes by not crashing.
+ {
+ SkPicture picture;
+ picture.beginRecording(1, 1);
+ picture.endRecording();
+ SkPicture* destPicture = picture.clone();
+ REPORTER_ASSERT(reporter, NULL != destPicture);
+ destPicture->unref();
+ }
+ {
+ // Test without call to endRecording
+ SkPicture picture;
+ picture.beginRecording(1, 1);
+ SkPicture* destPicture = picture.clone();
+ REPORTER_ASSERT(reporter, NULL != destPicture);
+ destPicture->unref();
+ }
+}
+
static void TestPicture(skiatest::Reporter* reporter) {
#ifdef SK_DEBUG
test_deleting_empty_playback();
@@ -405,6 +427,7 @@
test_peephole(reporter);
test_gatherpixelrefs(reporter);
test_bitmap_with_encoded_data(reporter);
+ test_clone_empty(reporter);
}
#include "TestClassDef.h"