aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/ports
diff options
context:
space:
mode:
authorGravatar agl@chromium.org <agl@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2009-04-13 21:43:40 +0000
committerGravatar agl@chromium.org <agl@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2009-04-13 21:43:40 +0000
commitfc3ac327d8e041e11049d7f0dfc7f491590cda75 (patch)
treef73607acad65c9107f6b7cce98666a5f6f1c5868 /src/ports
parentadd8808a42efa041a7c2acdcd06a8e020f56927a (diff)
SkFontHost_tables: fix minor bugs
http://codereview.appspot.com/33092 git-svn-id: http://skia.googlecode.com/svn/trunk@154 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/ports')
-rw-r--r--src/ports/SkFontHost_tables.cpp24
1 files changed, 17 insertions, 7 deletions
diff --git a/src/ports/SkFontHost_tables.cpp b/src/ports/SkFontHost_tables.cpp
index f14e085575..fdf0b063fe 100644
--- a/src/ports/SkFontHost_tables.cpp
+++ b/src/ports/SkFontHost_tables.cpp
@@ -51,7 +51,10 @@ static int count_tables(SkStream* stream, size_t* offsetToDir = NULL) {
if (offsetToDir) {
*offsetToDir = offset;
}
+ } else {
+ *offsetToDir = 0;
}
+
return SkEndian_SwapBE16(shared.fSingle.fNumTables);
}
@@ -60,7 +63,7 @@ static int count_tables(SkStream* stream, size_t* offsetToDir = NULL) {
struct SfntHeader {
SfntHeader() : fCount(0), fDir(NULL) {}
~SfntHeader() { sk_free(fDir); }
-
+
bool init(SkStream* stream) {
size_t offsetToDir;
fCount = count_tables(stream, &offsetToDir);
@@ -69,7 +72,8 @@ struct SfntHeader {
}
stream->rewind();
- if (stream->skip(offsetToDir) != offsetToDir) {
+ const size_t tableRecordOffset = offsetToDir + sizeof(SkSFNTHeader);
+ if (stream->skip(tableRecordOffset) != tableRecordOffset) {
return false;
}
@@ -77,7 +81,7 @@ struct SfntHeader {
fDir = reinterpret_cast<SkSFNTDirEntry*>(sk_malloc_throw(size));
return stream->read(fDir, size) == size;
}
-
+
int fCount;
SkSFNTDirEntry* fDir;
};
@@ -99,13 +103,13 @@ int SkFontHost::GetTableTags(SkFontID fontID, SkFontTableTag tags[]) {
if (NULL == stream) {
return 0;
}
-
+
SkAutoUnref au(stream);
SfntHeader header;
if (!header.init(stream)) {
return 0;
}
-
+
for (int i = 0; i < header.fCount; i++) {
tags[i] = SkEndian_SwapBE32(header.fDir[i].fTag);
}
@@ -117,7 +121,7 @@ size_t SkFontHost::GetTableSize(SkFontID fontID, SkFontTableTag tag) {
if (NULL == stream) {
return 0;
}
-
+
SkAutoUnref au(stream);
SfntHeader header;
if (!header.init(stream)) {
@@ -138,7 +142,7 @@ size_t SkFontHost::GetTableData(SkFontID fontID, SkFontTableTag tag,
if (NULL == stream) {
return 0;
}
-
+
SkAutoUnref au(stream);
SfntHeader header;
if (!header.init(stream)) {
@@ -153,6 +157,12 @@ size_t SkFontHost::GetTableData(SkFontID fontID, SkFontTableTag tag,
if (offset >= realLength) {
return 0;
}
+ // if the caller is trusting the length from the file, then a
+ // hostile file might choose a value which would overflow offset +
+ // length.
+ if (offset + length < offset) {
+ return 0;
+ }
if (offset + length > realLength) {
length = realLength - offset;
}