summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaph Levien <raph@google.com>2015-11-30 15:04:59 -0800
committerJessica Wagantall <jwagantall@cyngn.com>2016-01-05 15:00:23 -0800
commit7f7784e9f17837c36ac27f4ba5eccfdf55429385 (patch)
tree7bcf2ce6b7cd2cf91c8703780bfba13274f55b80
parenteff9f1e9373a61d65217fdfec3702d376a793978 (diff)
downloadandroid_frameworks_minikin-7f7784e9f17837c36ac27f4ba5eccfdf55429385.tar.gz
android_frameworks_minikin-7f7784e9f17837c36ac27f4ba5eccfdf55429385.tar.bz2
android_frameworks_minikin-7f7784e9f17837c36ac27f4ba5eccfdf55429385.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. Ticket: CYNGNOS-1404 Bug: 25645298 Change-Id: Id4716132041a6f4f1fbb73ec4e445391cf7d9616 (cherry picked from commit 183c9ec2800baa2ce099ee260c6cbc6121cf1274)
-rw-r--r--libs/minikin/CmapCoverage.cpp9
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++) {