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

Side by Side Diff: src/core/SkValidatingReadBuffer.cpp

Issue 23021015: Initial error handling code (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Adapting code to sk_once changes Created 7 years, 2 months 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
« no previous file with comments | « src/core/SkValidatingReadBuffer.h ('k') | src/core/SkValidationUtils.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright 2013 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #include "SkBitmap.h"
9 #include "SkErrorInternals.h"
10 #include "SkValidatingReadBuffer.h"
11 #include "SkStream.h"
12 #include "SkTypeface.h"
13
14 SkValidatingReadBuffer::SkValidatingReadBuffer(const void* data, size_t size) {
15 this->setMemory(data, size);
16 fError = false;
17
18 this->setFlags(SkFlattenableReadBuffer::kValidation_Flag);
19 }
20
21 SkValidatingReadBuffer::~SkValidatingReadBuffer() {
22 }
23
24 void SkValidatingReadBuffer::setMemory(const void* data, size_t size) {
25 fError = fError || !IsPtrAlign4(data) || (SkAlign4(size) != size);
26 if (!fError) {
27 fReader.setMemory(data, size);
28 }
29 }
30
31 const void* SkValidatingReadBuffer::skip(size_t size) {
32 size_t inc = SkAlign4(size);
33 const void* addr = fReader.peek();
34 fError = fError || !IsPtrAlign4(addr) || !fReader.isAvailable(inc);
35 if (!fError) {
36 fReader.skip(size);
37 }
38 return addr;
39 }
40
41 // All the methods in this file funnel down into either readInt(), readScalar() or skip(),
42 // followed by a memcpy. So we've got all our validation in readInt(), readScala r() and skip();
43 // if they fail they'll return a zero value or skip nothing, respectively, and s et fError to
44 // true, which the caller should check to see if an error occurred during the re ad operation.
45
46 bool SkValidatingReadBuffer::readBool() {
47 return this->readInt() != 0;
48 }
49
50 SkColor SkValidatingReadBuffer::readColor() {
51 return this->readInt();
52 }
53
54 SkFixed SkValidatingReadBuffer::readFixed() {
55 return this->readInt();
56 }
57
58 int32_t SkValidatingReadBuffer::readInt() {
59 const size_t inc = sizeof(int32_t);
60 fError = fError || !IsPtrAlign4(fReader.peek()) || !fReader.isAvailable(inc) ;
61 return fError ? 0 : fReader.readInt();
62 }
63
64 SkScalar SkValidatingReadBuffer::readScalar() {
65 const size_t inc = sizeof(SkScalar);
66 fError = fError || !IsPtrAlign4(fReader.peek()) || !fReader.isAvailable(inc) ;
67 return fError ? 0 : fReader.readScalar();
68 }
69
70 uint32_t SkValidatingReadBuffer::readUInt() {
71 return this->readInt();
72 }
73
74 int32_t SkValidatingReadBuffer::read32() {
75 return this->readInt();
76 }
77
78 void SkValidatingReadBuffer::readString(SkString* string) {
79 const size_t len = this->readInt();
80 const void* ptr = fReader.peek();
81 const char* cptr = (const char*)ptr;
82
83 // skip over the string + '\0' and then pad to a multiple of 4
84 const size_t alignedSize = SkAlign4(len + 1);
85 this->skip(alignedSize);
86 fError = fError || (cptr[len] != '\0');
87 if (!fError) {
88 string->set(cptr, len);
89 }
90 }
91
92 void* SkValidatingReadBuffer::readEncodedString(size_t* length, SkPaint::TextEnc oding encoding) {
93 const int32_t encodingType = fReader.readInt();
94 fError = fError || (encodingType != encoding);
95 *length = this->readInt();
96 const void* ptr = this->skip(SkAlign4(*length));
97 void* data = NULL;
98 if (!fError) {
99 data = sk_malloc_throw(*length);
100 memcpy(data, ptr, *length);
101 }
102 return data;
103 }
104
105 void SkValidatingReadBuffer::readPoint(SkPoint* point) {
106 point->fX = fReader.readScalar();
107 point->fY = fReader.readScalar();
108 }
109
110 void SkValidatingReadBuffer::readMatrix(SkMatrix* matrix) {
111 const size_t size = matrix->readFromMemory(fReader.peek());
112 fError = fError || (SkAlign4(size) != size);
113 if (!fError) {
114 (void)this->skip(size);
115 }
116 }
117
118 void SkValidatingReadBuffer::readIRect(SkIRect* rect) {
119 const void* ptr = this->skip(sizeof(SkIRect));
120 if (!fError) {
121 memcpy(rect, ptr, sizeof(SkIRect));
122 }
123 }
124
125 void SkValidatingReadBuffer::readRect(SkRect* rect) {
126 const void* ptr = this->skip(sizeof(SkRect));
127 if (!fError) {
128 memcpy(rect, ptr, sizeof(SkRect));
129 }
130 }
131
132 void SkValidatingReadBuffer::readRegion(SkRegion* region) {
133 const size_t size = region->readFromMemory(fReader.peek());
134 fError = fError || (SkAlign4(size) != size);
135 if (!fError) {
136 (void)this->skip(size);
137 }
138 }
139
140 void SkValidatingReadBuffer::readPath(SkPath* path) {
141 const size_t size = path->readFromMemory(fReader.peek());
142 fError = fError || (SkAlign4(size) != size);
143 if (!fError) {
144 (void)this->skip(size);
145 }
146 }
147
148 uint32_t SkValidatingReadBuffer::readByteArray(void* value) {
149 const uint32_t length = this->readUInt();
150 const void* ptr = this->skip(SkAlign4(length));
151 if (!fError) {
152 memcpy(value, ptr, length);
153 return length;
154 }
155 return 0;
156 }
157
158 uint32_t SkValidatingReadBuffer::readColorArray(SkColor* colors) {
159 const uint32_t count = this->readUInt();
160 const uint32_t byteLength = count * sizeof(SkColor);
161 const void* ptr = this->skip(SkAlign4(byteLength));
162 if (!fError) {
163 memcpy(colors, ptr, byteLength);
164 return count;
165 }
166 return 0;
167 }
168
169 uint32_t SkValidatingReadBuffer::readIntArray(int32_t* values) {
170 const uint32_t count = this->readUInt();
171 const uint32_t byteLength = count * sizeof(int32_t);
172 const void* ptr = this->skip(SkAlign4(byteLength));
173 if (!fError) {
174 memcpy(values, ptr, byteLength);
175 return count;
176 }
177 return 0;
178 }
179
180 uint32_t SkValidatingReadBuffer::readPointArray(SkPoint* points) {
181 const uint32_t count = this->readUInt();
182 const uint32_t byteLength = count * sizeof(SkPoint);
183 const void* ptr = this->skip(SkAlign4(byteLength));
184 if (!fError) {
185 memcpy(points, ptr, byteLength);
186 return count;
187 }
188 return 0;
189 }
190
191 uint32_t SkValidatingReadBuffer::readScalarArray(SkScalar* values) {
192 const uint32_t count = this->readUInt();
193 const uint32_t byteLength = count * sizeof(SkScalar);
194 const void* ptr = this->skip(SkAlign4(byteLength));
195 if (!fError) {
196 memcpy(values, ptr, byteLength);
197 return count;
198 }
199 return 0;
200 }
201
202 uint32_t SkValidatingReadBuffer::getArrayCount() {
203 return *(uint32_t*)fReader.peek();
204 }
205
206 void SkValidatingReadBuffer::readBitmap(SkBitmap* bitmap) {
207 const int width = this->readInt();
208 const int height = this->readInt();
209 const size_t length = this->readUInt();
210 // A size of zero means the SkBitmap was simply flattened.
211 fError = fError || (length != 0);
212 if (fError) {
213 return;
214 }
215 bitmap->unflatten(*this);
216 fError = fError || (bitmap->width() != width) || (bitmap->height() != height );
217 }
218
219 SkFlattenable* SkValidatingReadBuffer::readFlattenable(SkFlattenable::Type type) {
220 SkString name;
221 this->readString(&name);
222 if (fError) {
223 return NULL;
224 }
225
226 // Is this the type we wanted ?
227 const char* cname = name.c_str();
228 SkFlattenable::Type baseType;
229 if (!SkFlattenable::NameToType(cname, &baseType) || (baseType != type)) {
230 return NULL;
231 }
232
233 SkFlattenable::Factory factory = SkFlattenable::NameToFactory(cname);
234 if (NULL == factory) {
235 return NULL; // writer failed to give us the flattenable
236 }
237
238 // if we get here, factory may still be null, but if that is the case, the
239 // failure was ours, not the writer.
240 SkFlattenable* obj = NULL;
241 uint32_t sizeRecorded = this->readUInt();
242 if (factory) {
243 uint32_t offset = fReader.offset();
244 obj = (*factory)(*this);
245 // check that we read the amount we expected
246 uint32_t sizeRead = fReader.offset() - offset;
247 fError = fError || (sizeRecorded != sizeRead);
248 if (fError) {
249 // we could try to fix up the offset...
250 delete obj;
251 obj = NULL;
252 }
253 } else {
254 // we must skip the remaining data
255 this->skip(sizeRecorded);
256 SkASSERT(false);
257 }
258 return obj;
259 }
OLDNEW
« no previous file with comments | « src/core/SkValidatingReadBuffer.h ('k') | src/core/SkValidationUtils.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698