forked from Grouper-AOSP/platform_manifest
-
Notifications
You must be signed in to change notification settings - Fork 13
/
frameworks_minikin.patch
107 lines (101 loc) · 4.14 KB
/
frameworks_minikin.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
diff --git a/libs/minikin/CmapCoverage.cpp b/libs/minikin/CmapCoverage.cpp
index 2961d2f..da1cf3e 100644
--- a/libs/minikin/CmapCoverage.cpp
+++ b/libs/minikin/CmapCoverage.cpp
@@ -25,6 +25,8 @@ using std::vector;
#include <minikin/SparseBitSet.h>
#include <minikin/CmapCoverage.h>
+#include "MinikinInternal.h"
+
namespace android {
// These could perhaps be optimized to use __builtin_bswap16 and friends.
@@ -37,15 +39,25 @@ static uint32_t readU32(const uint8_t* data, size_t offset) {
((uint32_t)data[offset + 2]) << 8 | ((uint32_t)data[offset + 3]);
}
-static void addRange(vector<uint32_t> &coverage, uint32_t start, uint32_t end) {
+// The start must be larger than or equal to coverage.back() if coverage is not empty.
+// Returns true if the range is appended. Otherwise returns false as an error.
+static bool addRange(vector<uint32_t> &coverage, uint32_t start, uint32_t end) {
#ifdef VERBOSE_DEBUG
ALOGD("adding range %d-%d\n", start, end);
#endif
if (coverage.empty() || coverage.back() < start) {
coverage.push_back(start);
coverage.push_back(end);
- } else {
+ return true;
+ } else if (coverage.back() == start) {
coverage.back() = end;
+ return true;
+ } else {
+ // Reject unordered range input since SparseBitSet assumes that the given range vector is
+ // sorted. OpenType specification says cmap entries are sorted in order of code point
+ // values, thus for OpenType compliant font files, we don't reach here.
+ android_errorWriteLog(0x534e4554, "32178311");
+ return false;
}
}
@@ -74,11 +86,15 @@ static bool getCoverageFormat4(vector<uint32_t>& coverage, const uint8_t* data,
if (rangeOffset == 0) {
uint32_t delta = readU16(data, kHeaderSize + 2 * (2 * segCount + i));
if (((end + delta) & 0xffff) > end - start) {
- addRange(coverage, start, end + 1);
+ if (!addRange(coverage, start, end + 1)) {
+ return false;
+ }
} else {
for (uint32_t j = start; j < end + 1; j++) {
if (((j + delta) & 0xffff) != 0) {
- addRange(coverage, j, j + 1);
+ if (!addRange(coverage, j, j + 1)) {
+ return false;
+ }
}
}
}
@@ -92,7 +108,9 @@ static bool getCoverageFormat4(vector<uint32_t>& coverage, const uint8_t* data,
}
uint32_t glyphId = readU16(data, actualRangeOffset);
if (glyphId != 0) {
- addRange(coverage, j, j + 1);
+ if (!addRange(coverage, j, j + 1)) {
+ return false;
+ }
}
}
}
@@ -126,7 +144,22 @@ static bool getCoverageFormat12(vector<uint32_t>& coverage, const uint8_t* data,
android_errorWriteLog(0x534e4554, "26413177");
return false;
}
- addRange(coverage, start, end + 1); // file is inclusive, vector is exclusive
+
+ // No need to read outside of Unicode code point range.
+ if (start > MAX_UNICODE_CODE_POINT) {
+ return true;
+ }
+ if (end > MAX_UNICODE_CODE_POINT) {
+ // file is inclusive, vector is exclusive
+ addRange(coverage, start, MAX_UNICODE_CODE_POINT + 1);
+ if (end == 0xFFFFFFFF) {
+ android_errorWriteLog(0x534e4554, "62134807");
+ }
+ return true;
+ }
+ if (!addRange(coverage, start, end + 1)) { // file is inclusive, vector is exclusive
+ return false;
+ }
}
return true;
}
diff --git a/libs/minikin/MinikinInternal.h b/libs/minikin/MinikinInternal.h
index 88cc947..c6c5b29 100644
--- a/libs/minikin/MinikinInternal.h
+++ b/libs/minikin/MinikinInternal.h
@@ -47,6 +47,8 @@ bool isEmojiModifier(uint32_t c);
hb_blob_t* getFontTable(MinikinFont* minikinFont, uint32_t tag);
+constexpr uint32_t MAX_UNICODE_CODE_POINT = 0x10FFFF;
+
// An RAII wrapper for hb_blob_t
class HbBlob {
public: