Silently ignore invalid rangeOffset values

Some fonts contain a cmap segment for char 0xffff that contains an
invalid rangeOffset. This was rejected by the existing code, which
means the font is considered to have empty Unicode coverage. This patch
just discards the invalid segment (consistent with OpenType Sanitizer),
making the custom font display.

Bug: 18106256
Change-Id: Icc8616a3030f80e62db906332be64d434ae72ea2
This commit is contained in:
Raph Levien 2014-10-23 14:54:42 -07:00 committed by Prashant Malani
parent 6cba4a1dca
commit 92e8cc7071

View File

@ -16,9 +16,8 @@
// Determine coverage of font given its raw "cmap" OpenType table // Determine coverage of font given its raw "cmap" OpenType table
#ifdef PRINTF_DEBUG #define LOG_TAG "Minikin"
#include <stdio.h> #include <cutils/log.h>
#endif
#include <vector> #include <vector>
using std::vector; using std::vector;
@ -38,8 +37,8 @@ static uint32_t readU32(const uint8_t* data, size_t offset) {
} }
static void addRange(vector<uint32_t> &coverage, uint32_t start, uint32_t end) { static void addRange(vector<uint32_t> &coverage, uint32_t start, uint32_t end) {
#ifdef PRINTF_DEBUG #ifdef VERBOSE_DEBUG
printf("adding range %d-%d\n", start, end); ALOGD("adding range %d-%d\n", start, end);
#endif #endif
if (coverage.empty() || coverage.back() < start) { if (coverage.empty() || coverage.back() < start) {
coverage.push_back(start); coverage.push_back(start);
@ -82,7 +81,8 @@ static bool getCoverageFormat4(vector<uint32_t>& coverage, const uint8_t* data,
uint32_t actualRangeOffset = kHeaderSize + 6 * segCount + rangeOffset + uint32_t actualRangeOffset = kHeaderSize + 6 * segCount + rangeOffset +
(i + j - start) * 2; (i + j - start) * 2;
if (actualRangeOffset + 2 > size) { if (actualRangeOffset + 2 > size) {
return false; // invalid rangeOffset is considered a "warning" by OpenType Sanitizer
continue;
} }
int glyphId = readU16(data, actualRangeOffset); int glyphId = readU16(data, actualRangeOffset);
if (glyphId != 0) { if (glyphId != 0) {
@ -146,8 +146,8 @@ bool CmapCoverage::getCoverage(SparseBitSet& coverage, const uint8_t* cmap_data,
bestTable = i; bestTable = i;
} }
} }
#ifdef PRINTF_DEBUG #ifdef VERBOSE_DEBUG
printf("best table = %d\n", bestTable); ALOGD("best table = %d\n", bestTable);
#endif #endif
if (bestTable < 0) { if (bestTable < 0) {
return false; return false;
@ -168,10 +168,11 @@ bool CmapCoverage::getCoverage(SparseBitSet& coverage, const uint8_t* cmap_data,
if (success) { if (success) {
coverage.initFromRanges(&coverageVec.front(), coverageVec.size() >> 1); coverage.initFromRanges(&coverageVec.front(), coverageVec.size() >> 1);
} }
#ifdef PRINTF_DEBUG #ifdef VERBOSE_DEBUG
for (int i = 0; i < coverageVec.size(); i += 2) { for (size_t i = 0; i < coverageVec.size(); i += 2) {
printf("%x:%x\n", coverageVec[i], coverageVec[i + 1]); ALOGD("%x:%x\n", coverageVec[i], coverageVec[i + 1]);
} }
ALOGD("success = %d", success);
#endif #endif
return success; return success;
} }