opentype-sanitiser.h (6502B)
1 // Copyright (c) 2009-2017 The OTS 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) || defined(__CYGWIN__) 9 #define OTS_DLL_IMPORT __declspec(dllimport) 10 #define OTS_DLL_EXPORT __declspec(dllexport) 11 #else 12 #if __GNUC__ >= 4 13 #define OTS_DLL_IMPORT __attribute__((visibility ("default"))) 14 #define OTS_DLL_EXPORT __attribute__((visibility ("default"))) 15 #endif 16 #endif 17 18 #ifdef OTS_DLL 19 #ifdef OTS_DLL_EXPORTS 20 #define OTS_API OTS_DLL_EXPORT 21 #else 22 #define OTS_API OTS_DLL_IMPORT 23 #endif 24 #else 25 #define OTS_API 26 #endif 27 28 #if defined(_WIN32) 29 #include <stdlib.h> 30 typedef signed char int8_t; 31 typedef unsigned char uint8_t; 32 typedef short int16_t; 33 typedef unsigned short uint16_t; 34 typedef int int32_t; 35 typedef unsigned int uint32_t; 36 typedef __int64 int64_t; 37 typedef unsigned __int64 uint64_t; 38 #define ots_ntohl(x) _byteswap_ulong (x) 39 #define ots_ntohs(x) _byteswap_ushort (x) 40 #define ots_htonl(x) _byteswap_ulong (x) 41 #define ots_htons(x) _byteswap_ushort (x) 42 #else 43 #include <arpa/inet.h> 44 #include <stdint.h> 45 #define ots_ntohl(x) ntohl (x) 46 #define ots_ntohs(x) ntohs (x) 47 #define ots_htonl(x) htonl (x) 48 #define ots_htons(x) htons (x) 49 #endif 50 51 #include <sys/types.h> 52 53 #include <algorithm> 54 #include <cassert> 55 #include <cstddef> 56 #include <cstring> 57 58 #define OTS_TAG(c1,c2,c3,c4) ((uint32_t)((((uint8_t)(c1))<<24)|(((uint8_t)(c2))<<16)|(((uint8_t)(c3))<<8)|((uint8_t)(c4)))) 59 #define OTS_UNTAG(tag) ((char)((tag)>>24)), ((char)((tag)>>16)), ((char)((tag)>>8)), ((char)(tag)) 60 61 #if defined(__GNUC__) && (__GNUC__ >= 4) || (__clang__) 62 #define OTS_UNUSED __attribute__((unused)) 63 #elif defined(_MSC_VER) 64 #define OTS_UNUSED __pragma(warning(suppress: 4100 4101)) 65 #else 66 #define OTS_UNUSED 67 #endif 68 69 namespace ots { 70 71 // ----------------------------------------------------------------------------- 72 // This is an interface for an abstract stream class which is used for writing 73 // the serialised results out. 74 // ----------------------------------------------------------------------------- 75 class OTSStream { 76 public: 77 OTSStream() : chksum_(0) {} 78 79 virtual ~OTSStream() {} 80 81 virtual size_t size() = 0; 82 83 // This should be implemented to perform the actual write. 84 virtual bool WriteRaw(const void *data, size_t length) = 0; 85 86 bool Write(const void *data, size_t length) { 87 if (!length) return false; 88 89 const size_t orig_length = length; 90 size_t offset = 0; 91 92 size_t chksum_offset = Tell() & 3; 93 if (chksum_offset) { 94 const size_t l = std::min(length, static_cast<size_t>(4) - chksum_offset); 95 uint32_t tmp = 0; 96 std::memcpy(reinterpret_cast<uint8_t *>(&tmp) + chksum_offset, data, l); 97 chksum_ += ots_ntohl(tmp); 98 length -= l; 99 offset += l; 100 } 101 102 while (length >= 4) { 103 uint32_t tmp; 104 std::memcpy(&tmp, reinterpret_cast<const uint8_t *>(data) + offset, 105 sizeof(uint32_t)); 106 chksum_ += ots_ntohl(tmp); 107 length -= 4; 108 offset += 4; 109 } 110 111 if (length) { 112 if (length > 4) return false; // not reached 113 uint32_t tmp = 0; 114 std::memcpy(&tmp, 115 reinterpret_cast<const uint8_t*>(data) + offset, length); 116 chksum_ += ots_ntohl(tmp); 117 } 118 119 return WriteRaw(data, orig_length); 120 } 121 122 virtual bool Seek(off_t position) = 0; 123 virtual off_t Tell() const = 0; 124 125 virtual bool Pad(size_t bytes) { 126 static const uint32_t kZero = 0; 127 while (bytes >= 4) { 128 if (!Write(&kZero, 4)) return false; 129 bytes -= 4; 130 } 131 while (bytes) { 132 static const uint8_t kZerob = 0; 133 if (!Write(&kZerob, 1)) return false; 134 bytes--; 135 } 136 return true; 137 } 138 139 bool WriteU8(uint8_t v) { 140 return Write(&v, sizeof(v)); 141 } 142 143 bool WriteU16(uint16_t v) { 144 v = ots_htons(v); 145 return Write(&v, sizeof(v)); 146 } 147 148 bool WriteS16(int16_t v) { 149 v = ots_htons(v); 150 return Write(&v, sizeof(v)); 151 } 152 153 bool WriteU24(uint32_t v) { 154 v = ots_htonl(v); 155 return Write(reinterpret_cast<uint8_t*>(&v)+1, 3); 156 } 157 158 bool WriteU32(uint32_t v) { 159 v = ots_htonl(v); 160 return Write(&v, sizeof(v)); 161 } 162 163 bool WriteS32(int32_t v) { 164 v = ots_htonl(v); 165 return Write(&v, sizeof(v)); 166 } 167 168 bool WriteR64(uint64_t v) { 169 return Write(&v, sizeof(v)); 170 } 171 172 void ResetChecksum() { 173 assert((Tell() & 3) == 0); 174 chksum_ = 0; 175 } 176 177 uint32_t chksum() const { 178 return chksum_; 179 } 180 181 protected: 182 uint32_t chksum_; 183 }; 184 185 #ifdef __GCC__ 186 #define MSGFUNC_FMT_ATTR __attribute__((format(printf, 2, 3))) 187 #else 188 #define MSGFUNC_FMT_ATTR 189 #endif 190 191 enum TableAction { 192 TABLE_ACTION_DEFAULT, // Use OTS's default action for that table 193 TABLE_ACTION_SANITIZE, // Sanitize the table, potentially dropping it 194 TABLE_ACTION_PASSTHRU, // Serialize the table unchanged 195 TABLE_ACTION_DROP, // Drop the table 196 TABLE_ACTION_SANITIZE_SOFT, // Sanitize the table, but without failing overall 197 // sanitzation even if this table fails/is dropped 198 }; 199 200 class OTS_API OTSContext { 201 public: 202 OTSContext() {} 203 virtual ~OTSContext() {} 204 205 // Process a given OpenType file and write out a sanitized version 206 // output: a pointer to an object implementing the OTSStream interface. The 207 // sanitisied output will be written to this. In the even of a failure, 208 // partial output may have been written. 209 // input: the OpenType file 210 // length: the size, in bytes, of |input| 211 // index: if the input is a font collection and index is specified, then 212 // the corresponding font will be returned, otherwise the whole 213 // collection. Ignored for non-collection fonts. 214 bool Process(OTSStream *output, const uint8_t *input, size_t length, uint32_t index = -1); 215 216 // This function will be called when OTS is reporting an error. 217 // level: the severity of the generated message: 218 // 0: error messages in case OTS fails to sanitize the font. 219 // 1: warning messages about issue OTS fixed in the sanitized font. 220 virtual void Message(int level OTS_UNUSED, const char *format OTS_UNUSED, ...) MSGFUNC_FMT_ATTR {} 221 222 // This function will be called when OTS needs to decide what to do for a 223 // font table. 224 // tag: table tag formed with OTS_TAG() macro 225 virtual TableAction GetTableAction(uint32_t tag OTS_UNUSED) { return ots::TABLE_ACTION_DEFAULT; } 226 }; 227 228 } // namespace ots 229 230 #endif // OPENTYPE_SANITISER_H_