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

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

Issue 41253002: Checking structure sizes before reading them from memory to avoid overflowing the buffer's stream. (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: 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
OLDNEW
1 1
2 /* 2 /*
3 * Copyright 2006 The Android Open Source Project 3 * Copyright 2006 The Android Open Source Project
4 * 4 *
5 * Use of this source code is governed by a BSD-style license that can be 5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 6 * found in the LICENSE file.
7 */ 7 */
8 8
9 9
10 #include "SkRegionPriv.h" 10 #include "SkRegionPriv.h"
11 #include "SkFlattenableBuffers.h"
11 #include "SkTemplates.h" 12 #include "SkTemplates.h"
12 #include "SkThread.h" 13 #include "SkThread.h"
13 #include "SkUtils.h" 14 #include "SkUtils.h"
14 15
15 /* Region Layout 16 /* Region Layout
16 * 17 *
17 * TOP 18 * TOP
18 * 19 *
19 * [ Bottom, X-Intervals, [Left, Right]..., X-Sentinel ] 20 * [ Bottom, X-Intervals, [Left, Right]..., X-Sentinel ]
20 * ... 21 * ...
(...skipping 1072 matching lines...) Expand 10 before | Expand all | Expand 10 after
1093 1094
1094 bool SkRegion::op(const SkRegion& rgna, const SkRegion& rgnb, Op op) { 1095 bool SkRegion::op(const SkRegion& rgna, const SkRegion& rgnb, Op op) {
1095 SkDEBUGCODE(this->validate();) 1096 SkDEBUGCODE(this->validate();)
1096 return SkRegion::Oper(rgna, rgnb, op, this); 1097 return SkRegion::Oper(rgna, rgnb, op, this);
1097 } 1098 }
1098 1099
1099 /////////////////////////////////////////////////////////////////////////////// 1100 ///////////////////////////////////////////////////////////////////////////////
1100 1101
1101 #include "SkBuffer.h" 1102 #include "SkBuffer.h"
1102 1103
1104 uint32_t SkRegion::sizeInMemory() const {
1105 uint32_t size = sizeof(int32_t); // -1 (empty), 0 (rect), runCount
1106 if (!this->isEmpty()) {
1107 size += sizeof(fBounds);
1108 if (this->isComplex()) {
1109 size += 2 * sizeof(int32_t); // ySpanCount + intervalCount
1110 size += fRunHead->fRunCount * sizeof(RunType);
1111 }
1112 }
1113 return size;
1114 }
1115
1116 uint32_t SkRegion::SizeToRead(SkFlattenableReadBuffer& buffer) {
1117 uint32_t size = sizeof(int32_t);
1118 uint32_t ucount = buffer.getArrayCount();
1119 int32_t count = *(int32_t*)ucount; // -1 (empty), 0 (rect), runCount
1120 if (count >= 0) {
1121 size += sizeof(SkIRect); // fBounds
1122 if (count > 0) {
1123 size += 2 * sizeof(int32_t); // ySpanCount + intervalCount
1124 size += count * sizeof(RunType);
1125 }
1126 }
1127 return size;
1128 }
1129
1103 uint32_t SkRegion::writeToMemory(void* storage) const { 1130 uint32_t SkRegion::writeToMemory(void* storage) const {
1104 if (NULL == storage) { 1131 if (NULL == storage) {
1105 uint32_t size = sizeof(int32_t); // -1 (empty), 0 (rect), runCount 1132 return sizeInMemory();
1106 if (!this->isEmpty()) {
1107 size += sizeof(fBounds);
1108 if (this->isComplex()) {
1109 size += 2 * sizeof(int32_t); // ySpanCount + intervalCount
1110 size += fRunHead->fRunCount * sizeof(RunType);
1111 }
1112 }
1113 return size;
1114 } 1133 }
1115 1134
1116 SkWBuffer buffer(storage); 1135 SkWBuffer buffer(storage);
1117 1136
1118 if (this->isEmpty()) { 1137 if (this->isEmpty()) {
1119 buffer.write32(-1); 1138 buffer.write32(-1);
1120 } else { 1139 } else {
1121 bool isRect = this->isRect(); 1140 bool isRect = this->isRect();
1122 1141
1123 buffer.write32(isRect ? 0 : fRunHead->fRunCount); 1142 buffer.write32(isRect ? 0 : fRunHead->fRunCount);
1124 buffer.write(&fBounds, sizeof(fBounds)); 1143 buffer.write(&fBounds, sizeof(fBounds));
1125 1144
1126 if (!isRect) { 1145 if (!isRect) {
1127 buffer.write32(fRunHead->getYSpanCount()); 1146 buffer.write32(fRunHead->getYSpanCount());
1128 buffer.write32(fRunHead->getIntervalCount()); 1147 buffer.write32(fRunHead->getIntervalCount());
1129 buffer.write(fRunHead->readonly_runs(), 1148 buffer.write(fRunHead->readonly_runs(),
1130 fRunHead->fRunCount * sizeof(RunType)); 1149 fRunHead->fRunCount * sizeof(RunType));
1131 } 1150 }
1132 } 1151 }
1133 return buffer.pos(); 1152 uint32_t writeSize = SkToU32(buffer.pos());
1153 SkASSERT(sizeInMemory() == writeSize);
1154 return writeSize;
1134 } 1155 }
1135 1156
1136 uint32_t SkRegion::readFromMemory(const void* storage) { 1157 uint32_t SkRegion::readFromMemory(const void* storage) {
1137 SkRBuffer buffer(storage); 1158 SkRBuffer buffer(storage);
1138 SkRegion tmp; 1159 SkRegion tmp;
1139 int32_t count; 1160 int32_t count;
1140 1161
1141 count = buffer.readS32(); 1162 count = buffer.readS32();
1142 if (count >= 0) { 1163 if (count >= 0) {
1143 buffer.read(&tmp.fBounds, sizeof(tmp.fBounds)); 1164 buffer.read(&tmp.fBounds, sizeof(tmp.fBounds));
1144 if (count == 0) { 1165 if (count == 0) {
1145 tmp.fRunHead = SkRegion_gRectRunHeadPtr; 1166 tmp.fRunHead = SkRegion_gRectRunHeadPtr;
1146 } else { 1167 } else {
1147 int32_t ySpanCount = buffer.readS32(); 1168 int32_t ySpanCount = buffer.readS32();
1148 int32_t intervalCount = buffer.readS32(); 1169 int32_t intervalCount = buffer.readS32();
1149 tmp.allocateRuns(count, ySpanCount, intervalCount); 1170 tmp.allocateRuns(count, ySpanCount, intervalCount);
1150 buffer.read(tmp.fRunHead->writable_runs(), count * sizeof(RunType)); 1171 buffer.read(tmp.fRunHead->writable_runs(), count * sizeof(RunType));
1151 } 1172 }
1152 } 1173 }
1153 this->swap(tmp); 1174 this->swap(tmp);
1154 return buffer.pos(); 1175 uint32_t readSize = SkToU32(buffer.pos());
1176 SkASSERT(sizeInMemory() == readSize);
1177 return readSize;
1155 } 1178 }
1156 1179
1157 /////////////////////////////////////////////////////////////////////////////// 1180 ///////////////////////////////////////////////////////////////////////////////
1158 1181
1159 const SkRegion& SkRegion::GetEmptyRegion() { 1182 const SkRegion& SkRegion::GetEmptyRegion() {
1160 static SkRegion gEmpty; 1183 static SkRegion gEmpty;
1161 return gEmpty; 1184 return gEmpty;
1162 } 1185 }
1163 1186
1164 /////////////////////////////////////////////////////////////////////////////// 1187 ///////////////////////////////////////////////////////////////////////////////
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after
1473 bool SkRegion::debugSetRuns(const RunType runs[], int count) { 1496 bool SkRegion::debugSetRuns(const RunType runs[], int count) {
1474 // we need to make a copy, since the real method may modify the array, and 1497 // we need to make a copy, since the real method may modify the array, and
1475 // so it cannot be const. 1498 // so it cannot be const.
1476 1499
1477 SkAutoTArray<RunType> storage(count); 1500 SkAutoTArray<RunType> storage(count);
1478 memcpy(storage.get(), runs, count * sizeof(RunType)); 1501 memcpy(storage.get(), runs, count * sizeof(RunType));
1479 return this->setRuns(storage.get(), count); 1502 return this->setRuns(storage.get(), count);
1480 } 1503 }
1481 1504
1482 #endif 1505 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698