diff options
author | Colin Cross <ccross@android.com> | 2017-06-06 03:31:38 +0000 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2017-06-06 03:31:38 +0000 |
commit | a47999b814fe6a1c411aa7af3eb5eb4df96fd16b (patch) | |
tree | a1d53259acad0538184ab273ccb7c8ff663a57b9 /cpp/src/sfntly/data/readable_font_data.cc | |
parent | 4a6d4ae2f674cea237235b8038689ec527b5e09f (diff) | |
parent | e070d6c91d084990bc4c4103090a251557ca7c2b (diff) | |
download | sfntly-a47999b814fe6a1c411aa7af3eb5eb4df96fd16b.tar.gz |
Merge remote-tracking branch 'aosp/upstream-master' into master am: d7c3ad1d95 am: fd76129cde am: 3d3aab44bf am: ad302cbfd8 am: 31db13c42a am: 47b38c7df8 am: 1f8dca48cb am: 959c8f3447
am: e070d6c91d
Change-Id: I9bbd63fe2eaa1c6bcd0b6f01962a730eb62672d4
Diffstat (limited to 'cpp/src/sfntly/data/readable_font_data.cc')
-rw-r--r-- | cpp/src/sfntly/data/readable_font_data.cc | 131 |
1 files changed, 95 insertions, 36 deletions
diff --git a/cpp/src/sfntly/data/readable_font_data.cc b/cpp/src/sfntly/data/readable_font_data.cc index 06d783f..07a0db6 100644 --- a/cpp/src/sfntly/data/readable_font_data.cc +++ b/cpp/src/sfntly/data/readable_font_data.cc @@ -18,6 +18,8 @@ #include <stdio.h> +#include <limits> + #include "sfntly/data/memory_byte_array.h" #include "sfntly/data/writable_font_data.h" #include "sfntly/port/exception_type.h" @@ -59,23 +61,25 @@ void ReadableFontData::SetCheckSumRanges(const IntegerList& ranges) { int32_t ReadableFontData::ReadUByte(int32_t index) { int32_t b = array_->Get(BoundOffset(index)); -#if !defined (SFNTLY_NO_EXCEPTION) if (b < 0) { +#if !defined (SFNTLY_NO_EXCEPTION) throw IndexOutOfBoundException( "Index attempted to be read from is out of bounds", index); - } #endif + return kInvalidUnsigned; + } return b; } int32_t ReadableFontData::ReadByte(int32_t index) { int32_t b = array_->Get(BoundOffset(index)); -#if !defined (SFNTLY_NO_EXCEPTION) if (b < 0) { +#if !defined (SFNTLY_NO_EXCEPTION) throw IndexOutOfBoundException( "Index attempted to be read from is out of bounds", index); - } #endif + return kInvalidByte; + } return (b << 24) >> 24; } @@ -91,24 +95,54 @@ int32_t ReadableFontData::ReadChar(int32_t index) { } int32_t ReadableFontData::ReadUShort(int32_t index) { - return 0xffff & (ReadUByte(index) << 8 | ReadUByte(index + 1)); + int32_t b1 = ReadUByte(index); + if (b1 < 0) + return kInvalidUnsigned; + int32_t b2 = ReadUByte(index + 1); + if (b2 < 0) + return kInvalidUnsigned; + return 0xffff & (b1 << 8 | b2); } int32_t ReadableFontData::ReadShort(int32_t index) { - return ((ReadByte(index) << 8 | ReadUByte(index + 1)) << 16) >> 16; + int32_t b1 = ReadByte(index); + if (b1 == kInvalidByte) + return kInvalidShort; + int32_t b2 = ReadUByte(index + 1); + if (b2 < 0) + return kInvalidShort; + + uint32_t result = static_cast<uint32_t>(b1) << 8 | b2; + return static_cast<int32_t>(result << 16) >> 16; } int32_t ReadableFontData::ReadUInt24(int32_t index) { - return 0xffffff & (ReadUByte(index) << 16 | - ReadUByte(index + 1) << 8 | - ReadUByte(index + 2)); + int32_t b1 = ReadUByte(index); + if (b1 < 0) + return kInvalidUnsigned; + int32_t b2 = ReadUByte(index + 1); + if (b2 < 0) + return kInvalidUnsigned; + int32_t b3 = ReadUByte(index + 2); + if (b3 < 0) + return kInvalidUnsigned; + return 0xffffff & (b1 << 16 | b2 << 8 | b3); } int64_t ReadableFontData::ReadULong(int32_t index) { - return 0xffffffffL & (ReadUByte(index) << 24 | - ReadUByte(index + 1) << 16 | - ReadUByte(index + 2) << 8 | - ReadUByte(index + 3)); + int32_t b1 = ReadUByte(index); + if (b1 < 0) + return kInvalidUnsigned; + int32_t b2 = ReadUByte(index + 1); + if (b2 < 0) + return kInvalidUnsigned; + int32_t b3 = ReadUByte(index + 2); + if (b3 < 0) + return kInvalidUnsigned; + int32_t b4 = ReadUByte(index + 3); + if (b4 < 0) + return kInvalidUnsigned; + return 0xffffffffL & (b1 << 24 | b2 << 16 | b3 << 8 | b4); } int32_t ReadableFontData::ReadULongAsInt(int32_t index) { @@ -122,17 +156,35 @@ int32_t ReadableFontData::ReadULongAsInt(int32_t index) { } int64_t ReadableFontData::ReadULongLE(int32_t index) { - return 0xffffffffL & (ReadUByte(index) | - ReadUByte(index + 1) << 8 | - ReadUByte(index + 2) << 16 | - ReadUByte(index + 3) << 24); + int32_t b1 = ReadUByte(index); + if (b1 < 0) + return kInvalidUnsigned; + int32_t b2 = ReadUByte(index + 1); + if (b2 < 0) + return kInvalidUnsigned; + int32_t b3 = ReadUByte(index + 2); + if (b3 < 0) + return kInvalidUnsigned; + int32_t b4 = ReadUByte(index + 3); + if (b4 < 0) + return kInvalidUnsigned; + return 0xffffffffL & (b1 | b2 << 8 | b3 << 16 | b4 << 24); } int32_t ReadableFontData::ReadLong(int32_t index) { - return ReadByte(index) << 24 | - ReadUByte(index + 1) << 16 | - ReadUByte(index + 2) << 8 | - ReadUByte(index + 3); + int32_t b1 = ReadByte(index); + if (b1 == kInvalidByte) + return kInvalidLong; + int32_t b2 = ReadUByte(index + 1); + if (b2 < 0) + return kInvalidLong; + int32_t b3 = ReadUByte(index + 2); + if (b3 < 0) + return kInvalidLong; + int32_t b4 = ReadUByte(index + 3); + if (b4 < 0) + return kInvalidLong; + return static_cast<uint32_t>(b1) << 24 | b2 << 16 | b3 << 8 | b4; } int32_t ReadableFontData::ReadFixed(int32_t index) { @@ -140,7 +192,13 @@ int32_t ReadableFontData::ReadFixed(int32_t index) { } int64_t ReadableFontData::ReadDateTimeAsLong(int32_t index) { - return (int64_t)ReadULong(index) << 32 | ReadULong(index + 4); + int32_t high = ReadULong(index); + if (high == kInvalidUnsigned) + return kInvalidLongDateTime; + int32_t low = ReadULong(index + 4); + if (low == kInvalidUnsigned) + return kInvalidLongDateTime; + return (int64_t)high << 32 | low; } int32_t ReadableFontData::ReadFWord(int32_t index) { @@ -187,12 +245,11 @@ int32_t ReadableFontData::SearchUShort(int32_t start_index, #if defined (SFNTLY_DEBUG_FONTDATA) fprintf(stderr, "**start: %d; end: %d\n", location_start, location_end); #endif - if (key <= location_end) { + if (key <= location_end) return location; - } else { - // location is above the current location - bottom = location + 1; - } + + // location is above the current location + bottom = location + 1; } } return -1; @@ -208,14 +265,15 @@ int32_t ReadableFontData::SearchUShort(int32_t start_index, while (top != bottom) { location = (top + bottom) / 2; int32_t location_start = ReadUShort(start_index + location * start_offset); + if (key == location_start) + return location; + if (key < location_start) { // location is below current location top = location; - } else if (key > location_start) { + } else { // location is above current location bottom = location + 1; - } else { - return location; } } return -1; @@ -243,12 +301,11 @@ int32_t ReadableFontData::SearchULong(int32_t start_index, #if defined (SFNTLY_DEBUG_FONTDATA) fprintf(stderr, "**start: %d; end: %d\n", location_start, location_end); #endif - if (key <= location_end) { + if (key <= location_end) return location; - } else { - // location is above the current location - bottom = location + 1; - } + + // location is above the current location + bottom = location + 1; } } return -1; @@ -256,7 +313,9 @@ int32_t ReadableFontData::SearchULong(int32_t start_index, CALLER_ATTACH FontData* ReadableFontData::Slice(int32_t offset, int32_t length) { - if (offset < 0 || offset + length > Size()) { + if (offset < 0 || length < 0 || + offset > std::numeric_limits<int32_t>::max() - length || + offset + length > Size()) { #if !defined (SFNTLY_NO_EXCEPTION) throw IndexOutOfBoundsException( "Attempt to bind data outside of its limits"); |