1 : // Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #ifndef OTS_H_
6 : #define OTS_H_
7 :
8 : #include <stddef.h>
9 : #include <cstdarg>
10 : #include <cstddef>
11 : #include <cstdio>
12 : #include <cstdlib>
13 : #include <cstring>
14 :
15 : #include "opentype-sanitiser.h"
16 :
17 : namespace ots {
18 :
19 : #if defined(_MSC_VER) || !defined(OTS_DEBUG)
20 : #define OTS_FAILURE() false
21 : #else
22 : #define OTS_FAILURE() ots::Failure(__FILE__, __LINE__, __PRETTY_FUNCTION__)
23 : bool Failure(const char *f, int l, const char *fn);
24 : #endif
25 :
26 : #if defined(_MSC_VER)
27 : // MSVC supports C99 style variadic macros.
28 : #define OTS_WARNING(format, ...)
29 : #else
30 : // GCC
31 : #if defined(OTS_DEBUG)
32 : #define OTS_WARNING(format, args...) \
33 : ots::Warning(__FILE__, __LINE__, format, ##args)
34 : void Warning(const char *f, int l, const char *format, ...)
35 : __attribute__((format(printf, 3, 4)));
36 : #else
37 : #define OTS_WARNING(format, args...)
38 : #endif
39 : #endif
40 :
41 : // Define OTS_NO_TRANSCODE_HINTS (i.e., g++ -DOTS_NO_TRANSCODE_HINTS) if you
42 : // want to omit TrueType hinting instructions and variables in glyf, fpgm, prep,
43 : // and cvt tables.
44 : #if defined(OTS_NO_TRANSCODE_HINTS)
45 : const bool g_transcode_hints = false;
46 : #else
47 : const bool g_transcode_hints = true;
48 : #endif
49 :
50 : // -----------------------------------------------------------------------------
51 : // Buffer helper class
52 : //
53 : // This class perform some trival buffer operations while checking for
54 : // out-of-bounds errors. As a family they return false if anything is amiss,
55 : // updating the current offset otherwise.
56 : // -----------------------------------------------------------------------------
57 : class Buffer {
58 : public:
59 0 : Buffer(const uint8_t *buffer, size_t len)
60 : : buffer_(buffer),
61 : length_(len),
62 0 : offset_(0) { }
63 :
64 0 : bool Skip(size_t n_bytes) {
65 0 : return Read(NULL, n_bytes);
66 : }
67 :
68 0 : bool Read(uint8_t *buffer, size_t n_bytes) {
69 0 : if (n_bytes > 1024 * 1024 * 1024) {
70 0 : return OTS_FAILURE();
71 : }
72 0 : if ((offset_ + n_bytes > length_) ||
73 : (offset_ > length_ - n_bytes)) {
74 0 : return OTS_FAILURE();
75 : }
76 0 : if (buffer) {
77 0 : std::memcpy(buffer, buffer_ + offset_, n_bytes);
78 : }
79 0 : offset_ += n_bytes;
80 0 : return true;
81 : }
82 :
83 0 : inline bool ReadU8(uint8_t *value) {
84 0 : if (offset_ + 1 > length_) {
85 0 : return OTS_FAILURE();
86 : }
87 0 : *value = buffer_[offset_];
88 0 : ++offset_;
89 0 : return true;
90 : }
91 :
92 0 : bool ReadU16(uint16_t *value) {
93 0 : if (offset_ + 2 > length_) {
94 0 : return OTS_FAILURE();
95 : }
96 0 : std::memcpy(value, buffer_ + offset_, sizeof(uint16_t));
97 0 : *value = ntohs(*value);
98 0 : offset_ += 2;
99 0 : return true;
100 : }
101 :
102 0 : bool ReadS16(int16_t *value) {
103 0 : return ReadU16(reinterpret_cast<uint16_t*>(value));
104 : }
105 :
106 0 : bool ReadU24(uint32_t *value) {
107 0 : if (offset_ + 3 > length_) {
108 0 : return OTS_FAILURE();
109 : }
110 0 : *value = static_cast<uint32_t>(buffer_[offset_]) << 16 |
111 0 : static_cast<uint32_t>(buffer_[offset_ + 1]) << 8 |
112 0 : static_cast<uint32_t>(buffer_[offset_ + 2]);
113 0 : offset_ += 3;
114 0 : return true;
115 : }
116 :
117 0 : bool ReadU32(uint32_t *value) {
118 0 : if (offset_ + 4 > length_) {
119 0 : return OTS_FAILURE();
120 : }
121 0 : std::memcpy(value, buffer_ + offset_, sizeof(uint32_t));
122 0 : *value = ntohl(*value);
123 0 : offset_ += 4;
124 0 : return true;
125 : }
126 :
127 0 : bool ReadS32(int32_t *value) {
128 0 : return ReadU32(reinterpret_cast<uint32_t*>(value));
129 : }
130 :
131 0 : bool ReadTag(uint32_t *value) {
132 0 : if (offset_ + 4 > length_) {
133 0 : return OTS_FAILURE();
134 : }
135 0 : std::memcpy(value, buffer_ + offset_, sizeof(uint32_t));
136 0 : offset_ += 4;
137 0 : return true;
138 : }
139 :
140 0 : bool ReadR64(uint64_t *value) {
141 0 : if (offset_ + 8 > length_) {
142 0 : return OTS_FAILURE();
143 : }
144 0 : std::memcpy(value, buffer_ + offset_, sizeof(uint64_t));
145 0 : offset_ += 8;
146 0 : return true;
147 : }
148 :
149 0 : const uint8_t *buffer() const { return buffer_; }
150 0 : size_t offset() const { return offset_; }
151 0 : size_t length() const { return length_; }
152 :
153 0 : void set_offset(size_t newoffset) { offset_ = newoffset; }
154 :
155 : private:
156 : const uint8_t * const buffer_;
157 : const size_t length_;
158 : size_t offset_;
159 : };
160 :
161 : #define FOR_EACH_TABLE_TYPE \
162 : F(cff, CFF) \
163 : F(cmap, CMAP) \
164 : F(cvt, CVT) \
165 : F(fpgm, FPGM) \
166 : F(gasp, GASP) \
167 : F(gdef, GDEF) \
168 : F(glyf, GLYF) \
169 : F(gpos, GPOS) \
170 : F(gsub, GSUB) \
171 : F(hdmx, HDMX) \
172 : F(head, HEAD) \
173 : F(hhea, HHEA) \
174 : F(hmtx, HMTX) \
175 : F(kern, KERN) \
176 : F(loca, LOCA) \
177 : F(ltsh, LTSH) \
178 : F(maxp, MAXP) \
179 : F(name, NAME) \
180 : F(os2, OS2) \
181 : F(post, POST) \
182 : F(prep, PREP) \
183 : F(vdmx, VDMX) \
184 : F(vorg, VORG) \
185 : F(vhea, VHEA) \
186 : F(vmtx, VMTX) \
187 : F(silf, SILF) \
188 : F(sill, SILL) \
189 : F(glat, GLAT) \
190 : F(gloc, GLOC) \
191 : F(feat, FEAT)
192 :
193 : #define F(name, capname) struct OpenType##capname;
194 : FOR_EACH_TABLE_TYPE
195 : #undef F
196 :
197 : struct OpenTypeFile {
198 0 : OpenTypeFile() {
199 : #define F(name, capname) name = NULL;
200 0 : FOR_EACH_TABLE_TYPE
201 : #undef F
202 0 : }
203 :
204 : uint32_t version;
205 : uint16_t num_tables;
206 : uint16_t search_range;
207 : uint16_t entry_selector;
208 : uint16_t range_shift;
209 :
210 : // This is used to tell the relevant parsers whether to preserve the
211 : // Graphite layout tables (currently _without_ any checking)
212 : bool preserve_graphite;
213 :
214 : #define F(name, capname) OpenType##capname *name;
215 : FOR_EACH_TABLE_TYPE
216 : #undef F
217 : };
218 :
219 : #define F(name, capname) \
220 : bool ots_##name##_parse(OpenTypeFile *f, const uint8_t *d, size_t l); \
221 : bool ots_##name##_should_serialise(OpenTypeFile *f); \
222 : bool ots_##name##_serialise(OTSStream *s, OpenTypeFile *f); \
223 : void ots_##name##_free(OpenTypeFile *f);
224 : // TODO(yusukes): change these function names to follow Chromium coding rule.
225 : FOR_EACH_TABLE_TYPE
226 : #undef F
227 :
228 : } // namespace ots
229 :
230 : #endif // OTS_H_
|