OLD | NEW |
| (Empty) |
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 OPENTYPE_SANITISER_H_ | |
6 #define OPENTYPE_SANITISER_H_ | |
7 | |
8 #if defined(_WIN32) | |
9 #include <stdlib.h> | |
10 typedef signed char int8_t; | |
11 typedef unsigned char uint8_t; | |
12 typedef short int16_t; | |
13 typedef unsigned short uint16_t; | |
14 typedef int int32_t; | |
15 typedef unsigned int uint32_t; | |
16 typedef __int64 int64_t; | |
17 typedef unsigned __int64 uint64_t; | |
18 #define ntohl(x) _byteswap_ulong (x) | |
19 #define ntohs(x) _byteswap_ushort (x) | |
20 #define htonl(x) _byteswap_ulong (x) | |
21 #define htons(x) _byteswap_ushort (x) | |
22 #else | |
23 #include <arpa/inet.h> | |
24 #include <stdint.h> | |
25 #endif | |
26 | |
27 #include <algorithm> | |
28 #include <cassert> | |
29 #include <cstddef> | |
30 #include <cstring> | |
31 | |
32 namespace ots { | |
33 | |
34 // ----------------------------------------------------------------------------- | |
35 // This is an interface for an abstract stream class which is used for writing | |
36 // the serialised results out. | |
37 // ----------------------------------------------------------------------------- | |
38 class OTSStream { | |
39 public: | |
40 OTSStream() { | |
41 ResetChecksum(); | |
42 } | |
43 | |
44 virtual ~OTSStream() {} | |
45 | |
46 // This should be implemented to perform the actual write. | |
47 virtual bool WriteRaw(const void *data, size_t length) = 0; | |
48 | |
49 bool Write(const void *data, size_t length) { | |
50 if (!length) return false; | |
51 | |
52 const size_t orig_length = length; | |
53 size_t offset = 0; | |
54 if (chksum_buffer_offset_) { | |
55 const size_t l = | |
56 std::min(length, static_cast<size_t>(4) - chksum_buffer_offset_); | |
57 std::memcpy(chksum_buffer_ + chksum_buffer_offset_, data, l); | |
58 chksum_buffer_offset_ += l; | |
59 offset += l; | |
60 length -= l; | |
61 } | |
62 | |
63 if (chksum_buffer_offset_ == 4) { | |
64 uint32_t tmp; | |
65 std::memcpy(&tmp, chksum_buffer_, 4); | |
66 chksum_ += ntohl(tmp); | |
67 chksum_buffer_offset_ = 0; | |
68 } | |
69 | |
70 while (length >= 4) { | |
71 uint32_t tmp; | |
72 std::memcpy(&tmp, reinterpret_cast<const uint8_t *>(data) + offset, | |
73 sizeof(uint32_t)); | |
74 chksum_ += ntohl(tmp); | |
75 length -= 4; | |
76 offset += 4; | |
77 } | |
78 | |
79 if (length) { | |
80 if (chksum_buffer_offset_ != 0) return false; // not reached | |
81 if (length > 4) return false; // not reached | |
82 std::memcpy(chksum_buffer_, | |
83 reinterpret_cast<const uint8_t*>(data) + offset, length); | |
84 chksum_buffer_offset_ = length; | |
85 } | |
86 | |
87 return WriteRaw(data, orig_length); | |
88 } | |
89 | |
90 virtual bool Seek(off_t position) = 0; | |
91 virtual off_t Tell() const = 0; | |
92 | |
93 virtual bool Pad(size_t bytes) { | |
94 static const uint32_t kZero = 0; | |
95 while (bytes >= 4) { | |
96 if (!WriteTag(kZero)) return false; | |
97 bytes -= 4; | |
98 } | |
99 while (bytes) { | |
100 static const uint8_t kZerob = 0; | |
101 if (!Write(&kZerob, 1)) return false; | |
102 bytes--; | |
103 } | |
104 return true; | |
105 } | |
106 | |
107 bool WriteU8(uint8_t v) { | |
108 return Write(&v, sizeof(v)); | |
109 } | |
110 | |
111 bool WriteU16(uint16_t v) { | |
112 v = htons(v); | |
113 return Write(&v, sizeof(v)); | |
114 } | |
115 | |
116 bool WriteS16(int16_t v) { | |
117 v = htons(v); | |
118 return Write(&v, sizeof(v)); | |
119 } | |
120 | |
121 bool WriteU24(uint32_t v) { | |
122 v = htonl(v); | |
123 return Write(reinterpret_cast<uint8_t*>(&v)+1, 3); | |
124 } | |
125 | |
126 bool WriteU32(uint32_t v) { | |
127 v = htonl(v); | |
128 return Write(&v, sizeof(v)); | |
129 } | |
130 | |
131 bool WriteS32(int32_t v) { | |
132 v = htonl(v); | |
133 return Write(&v, sizeof(v)); | |
134 } | |
135 | |
136 bool WriteR64(uint64_t v) { | |
137 return Write(&v, sizeof(v)); | |
138 } | |
139 | |
140 bool WriteTag(uint32_t v) { | |
141 return Write(&v, sizeof(v)); | |
142 } | |
143 | |
144 void ResetChecksum() { | |
145 chksum_ = 0; | |
146 chksum_buffer_offset_ = 0; | |
147 } | |
148 | |
149 uint32_t chksum() const { | |
150 assert(chksum_buffer_offset_ == 0); | |
151 return chksum_; | |
152 } | |
153 | |
154 struct ChecksumState { | |
155 uint32_t chksum; | |
156 uint8_t chksum_buffer[4]; | |
157 unsigned chksum_buffer_offset; | |
158 }; | |
159 | |
160 ChecksumState SaveChecksumState() const { | |
161 ChecksumState s; | |
162 s.chksum = chksum_; | |
163 s.chksum_buffer_offset = chksum_buffer_offset_; | |
164 std::memcpy(s.chksum_buffer, chksum_buffer_, 4); | |
165 | |
166 return s; | |
167 } | |
168 | |
169 void RestoreChecksum(const ChecksumState &s) { | |
170 assert(chksum_buffer_offset_ == 0); | |
171 chksum_ += s.chksum; | |
172 chksum_buffer_offset_ = s.chksum_buffer_offset; | |
173 std::memcpy(chksum_buffer_, s.chksum_buffer, 4); | |
174 } | |
175 | |
176 protected: | |
177 uint32_t chksum_; | |
178 uint8_t chksum_buffer_[4]; | |
179 unsigned chksum_buffer_offset_; | |
180 }; | |
181 | |
182 #ifdef __GCC__ | |
183 #define MSGFUNC_FMT_ATTR __attribute__((format(printf, 2, 3))) | |
184 #else | |
185 #define MSGFUNC_FMT_ATTR | |
186 #endif | |
187 | |
188 enum TableAction { | |
189 TABLE_ACTION_DEFAULT, // Use OTS's default action for that table | |
190 TABLE_ACTION_SANITIZE, // Sanitize the table, potentially droping it | |
191 TABLE_ACTION_PASSTHRU, // Serialize the table unchanged | |
192 TABLE_ACTION_DROP // Drop the table | |
193 }; | |
194 | |
195 class OTSContext { | |
196 public: | |
197 OTSContext() {} | |
198 virtual ~OTSContext() {} | |
199 | |
200 // Process a given OpenType file and write out a sanitised version | |
201 // output: a pointer to an object implementing the OTSStream interface. Th
e | |
202 // sanitisied output will be written to this. In the even of a failure, | |
203 // partial output may have been written. | |
204 // input: the OpenType file | |
205 // length: the size, in bytes, of |input| | |
206 // context: optional context that holds various OTS settings like user cal
lbacks | |
207 bool Process(OTSStream *output, const uint8_t *input, size_t length); | |
208 | |
209 // This function will be called when OTS is reporting an error. | |
210 // level: the severity of the generated message: | |
211 // 0: error messages in case OTS fails to sanitize the font. | |
212 // 1: warning messages about issue OTS fixed in the sanitized font. | |
213 virtual void Message(int level, const char *format, ...) MSGFUNC_FMT_ATTR {} | |
214 | |
215 // This function will be called when OTS needs to decide what to do for a | |
216 // font table. | |
217 // tag: table tag as an integer in big-endian byte order, independent of | |
218 // platform endianness | |
219 virtual TableAction GetTableAction(uint32_t tag) { return ots::TABLE_ACTION_
DEFAULT; } | |
220 }; | |
221 | |
222 // For backward compatibility - remove once Chrome switches over to the new API. | |
223 bool Process(OTSStream *output, const uint8_t *input, size_t length); | |
224 | |
225 // For backward compatibility - remove once https://codereview.chromium.org/7742
53008/ | |
226 // is submitted. | |
227 void EnableWOFF2(); | |
228 | |
229 } // namespace ots | |
230 | |
231 #endif // OPENTYPE_SANITISER_H_ | |
OLD | NEW |