Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(414)

Side by Side Diff: tests/SerializationTest.cpp

Issue 92793002: Fixed bad bitmap size crashes (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Changed getSize name to getAllocatedSizeInBytes Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright 2013 Google Inc. 2 * Copyright 2013 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkBitmapDevice.h"
9 #include "SkBitmapSource.h"
10 #include "SkCanvas.h"
11 #include "SkMallocPixelRef.h"
8 #include "SkOrderedWriteBuffer.h" 12 #include "SkOrderedWriteBuffer.h"
9 #include "SkValidatingReadBuffer.h" 13 #include "SkValidatingReadBuffer.h"
14 #include "SkXfermodeImageFilter.h"
10 #include "Test.h" 15 #include "Test.h"
11 16
12 static const uint32_t kArraySize = 64; 17 static const uint32_t kArraySize = 64;
13 18
14 template<typename T> 19 template<typename T>
15 static void TestAlignment(T* testObj, skiatest::Reporter* reporter) { 20 static void TestAlignment(T* testObj, skiatest::Reporter* reporter) {
16 // Test memory read/write functions directly 21 // Test memory read/write functions directly
17 unsigned char dataWritten[1024]; 22 unsigned char dataWritten[1024];
18 size_t bytesWrittenToMemory = testObj->writeToMemory(dataWritten); 23 size_t bytesWrittenToMemory = testObj->writeToMemory(dataWritten);
19 REPORTER_ASSERT(reporter, SkAlign4(bytesWrittenToMemory) == bytesWrittenToMe mory); 24 REPORTER_ASSERT(reporter, SkAlign4(bytesWrittenToMemory) == bytesWrittenToMe mory);
20 size_t bytesReadFromMemory = testObj->readFromMemory(dataWritten, bytesWritt enToMemory); 25 size_t bytesReadFromMemory = testObj->readFromMemory(dataWritten, bytesWritt enToMemory);
21 REPORTER_ASSERT(reporter, SkAlign4(bytesReadFromMemory) == bytesReadFromMemo ry); 26 REPORTER_ASSERT(reporter, SkAlign4(bytesReadFromMemory) == bytesReadFromMemo ry);
22 } 27 }
23 28
24 template<typename T> struct SerializationUtils { 29 template<typename T> struct SerializationUtils {
30 // Generic case for flattenables
31 static void Write(SkOrderedWriteBuffer& writer, const T* flattenable) {
32 writer.writeFlattenable(flattenable);
33 }
34 static void Read(SkValidatingReadBuffer& reader, T** flattenable) {
35 *flattenable = (T*)reader.readFlattenable(T::GetFlattenableType());
36 }
25 }; 37 };
26 38
27 template<> struct SerializationUtils<SkMatrix> { 39 template<> struct SerializationUtils<SkMatrix> {
28 static void Write(SkOrderedWriteBuffer& writer, const SkMatrix* matrix) { 40 static void Write(SkOrderedWriteBuffer& writer, const SkMatrix* matrix) {
29 writer.writeMatrix(*matrix); 41 writer.writeMatrix(*matrix);
30 } 42 }
31 static void Read(SkValidatingReadBuffer& reader, SkMatrix* matrix) { 43 static void Read(SkValidatingReadBuffer& reader, SkMatrix* matrix) {
32 reader.readMatrix(matrix); 44 reader.readMatrix(matrix);
33 } 45 }
34 }; 46 };
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
120 SerializationUtils<T>::Read(buffer2, &obj2); 132 SerializationUtils<T>::Read(buffer2, &obj2);
121 const unsigned char* peekAfter = static_cast<const unsigned char*>(buffer2.s kip(0)); 133 const unsigned char* peekAfter = static_cast<const unsigned char*>(buffer2.s kip(0));
122 // This should have succeeded, since there are enough bytes to read this 134 // This should have succeeded, since there are enough bytes to read this
123 REPORTER_ASSERT(reporter, buffer2.validate(true)); 135 REPORTER_ASSERT(reporter, buffer2.validate(true));
124 REPORTER_ASSERT(reporter, static_cast<size_t>(peekAfter - peekBefore) == byt esWritten); 136 REPORTER_ASSERT(reporter, static_cast<size_t>(peekAfter - peekBefore) == byt esWritten);
125 137
126 TestAlignment(testObj, reporter); 138 TestAlignment(testObj, reporter);
127 } 139 }
128 140
129 template<typename T> 141 template<typename T>
142 static T* TestFlattenableSerialization(T* testObj, bool shouldSucceed,
143 skiatest::Reporter* reporter) {
144 SkOrderedWriteBuffer writer(1024);
145 writer.setFlags(SkOrderedWriteBuffer::kValidation_Flag);
146 SerializationUtils<T>::Write(writer, testObj);
147 size_t bytesWritten = writer.bytesWritten();
148 REPORTER_ASSERT(reporter, SkAlign4(bytesWritten) == bytesWritten);
149
150 unsigned char dataWritten[1024];
151 writer.writeToMemory(dataWritten);
152
153 // Make sure this fails when it should (test with smaller size, but still mu ltiple of 4)
154 SkValidatingReadBuffer buffer(dataWritten, bytesWritten - 4);
155 T* obj = NULL;
156 SerializationUtils<T>::Read(buffer, &obj);
157 REPORTER_ASSERT(reporter, !buffer.validate(true));
158 REPORTER_ASSERT(reporter, NULL == obj);
159
160 // Make sure this succeeds when it should
161 SkValidatingReadBuffer buffer2(dataWritten, bytesWritten);
162 const unsigned char* peekBefore = static_cast<const unsigned char*>(buffer2. skip(0));
163 T* obj2 = NULL;
164 SerializationUtils<T>::Read(buffer2, &obj2);
165 const unsigned char* peekAfter = static_cast<const unsigned char*>(buffer2.s kip(0));
166 if (shouldSucceed) {
167 // This should have succeeded, since there are enough bytes to read this
168 REPORTER_ASSERT(reporter, buffer2.validate(true));
169 REPORTER_ASSERT(reporter, static_cast<size_t>(peekAfter - peekBefore) == bytesWritten);
170 REPORTER_ASSERT(reporter, NULL != obj2);
171 } else {
172 // If the deserialization was supposed to fail, make sure it did
173 REPORTER_ASSERT(reporter, !buffer.validate(true));
174 REPORTER_ASSERT(reporter, NULL == obj2);
175 }
176
177 return obj2; // Return object to perform further validity tests on it
178 }
179
180 template<typename T>
130 static void TestArraySerialization(T* data, skiatest::Reporter* reporter) { 181 static void TestArraySerialization(T* data, skiatest::Reporter* reporter) {
131 SkOrderedWriteBuffer writer(1024); 182 SkOrderedWriteBuffer writer(1024);
132 writer.setFlags(SkOrderedWriteBuffer::kValidation_Flag); 183 writer.setFlags(SkOrderedWriteBuffer::kValidation_Flag);
133 SerializationUtils<T>::Write(writer, data, kArraySize); 184 SerializationUtils<T>::Write(writer, data, kArraySize);
134 size_t bytesWritten = writer.bytesWritten(); 185 size_t bytesWritten = writer.bytesWritten();
135 // This should write the length (in 4 bytes) and the array 186 // This should write the length (in 4 bytes) and the array
136 REPORTER_ASSERT(reporter, (4 + kArraySize * sizeof(T)) == bytesWritten); 187 REPORTER_ASSERT(reporter, (4 + kArraySize * sizeof(T)) == bytesWritten);
137 188
138 unsigned char dataWritten[1024]; 189 unsigned char dataWritten[1024];
139 writer.writeToMemory(dataWritten); 190 writer.writeToMemory(dataWritten);
140 191
141 // Make sure this fails when it should 192 // Make sure this fails when it should
142 SkValidatingReadBuffer buffer(dataWritten, bytesWritten); 193 SkValidatingReadBuffer buffer(dataWritten, bytesWritten);
143 T dataRead[kArraySize]; 194 T dataRead[kArraySize];
144 bool success = SerializationUtils<T>::Read(buffer, dataRead, kArraySize / 2) ; 195 bool success = SerializationUtils<T>::Read(buffer, dataRead, kArraySize / 2) ;
145 // This should have failed, since the provided size was too small 196 // This should have failed, since the provided size was too small
146 REPORTER_ASSERT(reporter, !success); 197 REPORTER_ASSERT(reporter, !success);
147 198
148 // Make sure this succeeds when it should 199 // Make sure this succeeds when it should
149 SkValidatingReadBuffer buffer2(dataWritten, bytesWritten); 200 SkValidatingReadBuffer buffer2(dataWritten, bytesWritten);
150 success = SerializationUtils<T>::Read(buffer2, dataRead, kArraySize); 201 success = SerializationUtils<T>::Read(buffer2, dataRead, kArraySize);
151 // This should have succeeded, since there are enough bytes to read this 202 // This should have succeeded, since there are enough bytes to read this
152 REPORTER_ASSERT(reporter, success); 203 REPORTER_ASSERT(reporter, success);
153 } 204 }
154 205
206 static void TestBitmapSerialization(const SkBitmap& validBitmap,
207 const SkBitmap& invalidBitmap,
208 bool shouldSucceed,
209 skiatest::Reporter* reporter) {
210 SkBitmapSource validBitmapSource(validBitmap);
211 SkBitmapSource invalidBitmapSource(invalidBitmap);
212 SkAutoTUnref<SkXfermode> mode(SkXfermode::Create(SkXfermode::kSrcOver_Mode)) ;
213 SkXfermodeImageFilter xfermodeImageFilter(mode, &invalidBitmapSource, &valid BitmapSource);
214
215 SkAutoTUnref<SkImageFilter> deserializedFilter(
216 TestFlattenableSerialization<SkImageFilter>(
217 &xfermodeImageFilter, shouldSucceed, reporter));
218
219 // Try to render a small bitmap using the invalid deserialized filter
220 // to make sure we don't crash while trying to render it
221 if (shouldSucceed) {
222 SkBitmap bitmap;
223 bitmap.setConfig(SkBitmap::kARGB_8888_Config, 24, 24);
224 bitmap.allocPixels();
225 SkBitmapDevice device(bitmap);
226 SkCanvas canvas(&device);
227 canvas.clear(0x00000000);
228 SkPaint paint;
229 paint.setImageFilter(deserializedFilter);
230 canvas.clipRect(SkRect::MakeXYWH(0, 0, SkIntToScalar(24), SkIntToScalar( 24)));
231 canvas.drawBitmap(bitmap, 0, 0, &paint);
232 }
233 }
234
155 static void Tests(skiatest::Reporter* reporter) { 235 static void Tests(skiatest::Reporter* reporter) {
156 // Test matrix serialization 236 // Test matrix serialization
157 { 237 {
158 SkMatrix matrix = SkMatrix::I(); 238 SkMatrix matrix = SkMatrix::I();
159 TestObjectSerialization(&matrix, reporter); 239 TestObjectSerialization(&matrix, reporter);
160 } 240 }
161 241
162 // Test path serialization 242 // Test path serialization
163 { 243 {
164 SkPath path; 244 SkPath path;
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
205 { 285 {
206 SkPoint data[kArraySize] = { {6, 7}, {42, 128} }; 286 SkPoint data[kArraySize] = { {6, 7}, {42, 128} };
207 TestArraySerialization(data, reporter); 287 TestArraySerialization(data, reporter);
208 } 288 }
209 289
210 // Test readScalarArray 290 // Test readScalarArray
211 { 291 {
212 SkScalar data[kArraySize] = { SK_Scalar1, SK_ScalarHalf, SK_ScalarMax }; 292 SkScalar data[kArraySize] = { SK_Scalar1, SK_ScalarHalf, SK_ScalarMax };
213 TestArraySerialization(data, reporter); 293 TestArraySerialization(data, reporter);
214 } 294 }
295
296 // Test invalid deserializations
297 {
298 SkBitmap validBitmap;
299 validBitmap.setConfig(SkBitmap::kARGB_8888_Config, 256, 256);
300
301 // Create a bitmap with a really large height
302 SkBitmap invalidBitmap;
303 invalidBitmap.setConfig(SkBitmap::kARGB_8888_Config, 256, 1000000000);
304
305 // The deserialization should succeed, and the rendering shouldn't crash ,
306 // even when the device fails to initialize, due to its size
307 TestBitmapSerialization(validBitmap, invalidBitmap, true, reporter);
308
309 // Create a bitmap with a pixel ref too small
310 SkBitmap invalidBitmap2;
311 invalidBitmap2.setConfig(SkBitmap::kARGB_8888_Config, 256, 256);
312 invalidBitmap2.setPixelRef(SkNEW_ARGS(SkMallocPixelRef,
313 (NULL, 256, NULL)))->unref();
314
315 // The deserialization should detect the pixel ref being too small and f ail
316 TestBitmapSerialization(validBitmap, invalidBitmap2, false, reporter);
317 }
215 } 318 }
216 319
217 #include "TestClassDef.h" 320 #include "TestClassDef.h"
218 DEFINE_TESTCLASS("Serialization", SerializationClass, Tests) 321 DEFINE_TESTCLASS("Serialization", SerializationClass, Tests)
OLDNEW
« include/core/SkMallocPixelRef.h ('K') | « src/image/SkDataPixelRef.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698