diff options
author | Raph Levien <raph@google.com> | 2015-11-30 15:04:59 -0800 |
---|---|---|
committer | The Android Automerger <android-build@google.com> | 2015-12-10 16:11:55 -0800 |
commit | 715e31e7334db3c196d64dd83e5bf2de4f1c711d (patch) | |
tree | 4952f4146f9b7a155d714db59c75a50c248ef160 | |
parent | 86542797761632890092ef89b7fb58c2c2cdfc11 (diff) | |
download | android_frameworks_minikin-715e31e7334db3c196d64dd83e5bf2de4f1c711d.tar.gz android_frameworks_minikin-715e31e7334db3c196d64dd83e5bf2de4f1c711d.tar.bz2 android_frameworks_minikin-715e31e7334db3c196d64dd83e5bf2de4f1c711d.zip |
Avoid integer overflows in parsing fonts
A malformed TTF can cause size calculations to overflow. This patch
checks the maximum reasonable value so that the total size fits in 32
bits. It also adds some explicit casting to avoid possible technical
undefined behavior when parsing sized unsigned values.
Bug: 25645298
Change-Id: Id4716132041a6f4f1fbb73ec4e445391cf7d9616
(cherry picked from commit 183c9ec2800baa2ce099ee260c6cbc6121cf1274)
-rw-r--r-- | libs/minikin/CmapCoverage.cpp | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/libs/minikin/CmapCoverage.cpp b/libs/minikin/CmapCoverage.cpp index 7503372..6431000 100644 --- a/libs/minikin/CmapCoverage.cpp +++ b/libs/minikin/CmapCoverage.cpp @@ -29,11 +29,12 @@ namespace android { // These could perhaps be optimized to use __builtin_bswap16 and friends. static uint32_t readU16(const uint8_t* data, size_t offset) { - return data[offset] << 8 | data[offset + 1]; + return ((uint32_t)data[offset]) << 8 | ((uint32_t)data[offset + 1]); } static uint32_t readU32(const uint8_t* data, size_t offset) { - return data[offset] << 24 | data[offset + 1] << 16 | data[offset + 2] << 8 | data[offset + 3]; + return ((uint32_t)data[offset]) << 24 | ((uint32_t)data[offset + 1]) << 16 | + ((uint32_t)data[offset + 2]) << 8 | ((uint32_t)data[offset + 3]); } static void addRange(vector<uint32_t> &coverage, uint32_t start, uint32_t end) { @@ -101,11 +102,13 @@ static bool getCoverageFormat12(vector<uint32_t>& coverage, const uint8_t* data, const size_t kGroupSize = 12; const size_t kStartCharCodeOffset = 0; const size_t kEndCharCodeOffset = 4; + const size_t kMaxNGroups = 0xfffffff0 / kGroupSize; // protection against overflow + // For all values < kMaxNGroups, kFirstGroupOffset + nGroups * kGroupSize fits in 32 bits. if (kFirstGroupOffset > size) { return false; } uint32_t nGroups = readU32(data, kNGroupsOffset); - if (kFirstGroupOffset + nGroups * kGroupSize > size) { + if (nGroups >= kMaxNGroups || kFirstGroupOffset + nGroups * kGroupSize > size) { return false; } for (uint32_t i = 0; i < nGroups; i++) { |