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: OTSStream()77 OTSStream() : chksum_(0) {} 78 ~OTSStream()79 virtual ~OTSStream() {} 80 81 // This should be implemented to perform the actual write. 82 virtual bool WriteRaw(const void *data, size_t length) = 0; 83 Write(const void * data,size_t length)84 bool Write(const void *data, size_t length) { 85 if (!length) return false; 86 87 const size_t orig_length = length; 88 size_t offset = 0; 89 90 size_t chksum_offset = Tell() & 3; 91 if (chksum_offset) { 92 const size_t l = std::min(length, static_cast<size_t>(4) - chksum_offset); 93 uint32_t tmp = 0; 94 std::memcpy(reinterpret_cast<uint8_t *>(&tmp) + chksum_offset, data, l); 95 chksum_ += ots_ntohl(tmp); 96 length -= l; 97 offset += l; 98 } 99 100 while (length >= 4) { 101 uint32_t tmp; 102 std::memcpy(&tmp, reinterpret_cast<const uint8_t *>(data) + offset, 103 sizeof(uint32_t)); 104 chksum_ += ots_ntohl(tmp); 105 length -= 4; 106 offset += 4; 107 } 108 109 if (length) { 110 if (length > 4) return false; // not reached 111 uint32_t tmp = 0; 112 std::memcpy(&tmp, 113 reinterpret_cast<const uint8_t*>(data) + offset, length); 114 chksum_ += ots_ntohl(tmp); 115 } 116 117 return WriteRaw(data, orig_length); 118 } 119 120 virtual bool Seek(off_t position) = 0; 121 virtual off_t Tell() const = 0; 122 Pad(size_t bytes)123 virtual bool Pad(size_t bytes) { 124 static const uint32_t kZero = 0; 125 while (bytes >= 4) { 126 if (!Write(&kZero, 4)) return false; 127 bytes -= 4; 128 } 129 while (bytes) { 130 static const uint8_t kZerob = 0; 131 if (!Write(&kZerob, 1)) return false; 132 bytes--; 133 } 134 return true; 135 } 136 WriteU8(uint8_t v)137 bool WriteU8(uint8_t v) { 138 return Write(&v, sizeof(v)); 139 } 140 WriteU16(uint16_t v)141 bool WriteU16(uint16_t v) { 142 v = ots_htons(v); 143 return Write(&v, sizeof(v)); 144 } 145 WriteS16(int16_t v)146 bool WriteS16(int16_t v) { 147 v = ots_htons(v); 148 return Write(&v, sizeof(v)); 149 } 150 WriteU24(uint32_t v)151 bool WriteU24(uint32_t v) { 152 v = ots_htonl(v); 153 return Write(reinterpret_cast<uint8_t*>(&v)+1, 3); 154 } 155 WriteU32(uint32_t v)156 bool WriteU32(uint32_t v) { 157 v = ots_htonl(v); 158 return Write(&v, sizeof(v)); 159 } 160 WriteS32(int32_t v)161 bool WriteS32(int32_t v) { 162 v = ots_htonl(v); 163 return Write(&v, sizeof(v)); 164 } 165 WriteR64(uint64_t v)166 bool WriteR64(uint64_t v) { 167 return Write(&v, sizeof(v)); 168 } 169 ResetChecksum()170 void ResetChecksum() { 171 assert((Tell() & 3) == 0); 172 chksum_ = 0; 173 } 174 chksum()175 uint32_t chksum() const { 176 return chksum_; 177 } 178 179 protected: 180 uint32_t chksum_; 181 }; 182 183 #ifdef __GCC__ 184 #define MSGFUNC_FMT_ATTR __attribute__((format(printf, 2, 3))) 185 #else 186 #define MSGFUNC_FMT_ATTR 187 #endif 188 189 enum TableAction { 190 TABLE_ACTION_DEFAULT, // Use OTS's default action for that table 191 TABLE_ACTION_SANITIZE, // Sanitize the table, potentially dropping it 192 TABLE_ACTION_PASSTHRU, // Serialize the table unchanged 193 TABLE_ACTION_DROP // Drop the table 194 }; 195 196 class OTS_API OTSContext { 197 public: OTSContext()198 OTSContext() {} ~OTSContext()199 virtual ~OTSContext() {} 200 201 // Process a given OpenType file and write out a sanitized version 202 // output: a pointer to an object implementing the OTSStream interface. The 203 // sanitisied output will be written to this. In the even of a failure, 204 // partial output may have been written. 205 // input: the OpenType file 206 // length: the size, in bytes, of |input| 207 // index: if the input is a font collection and index is specified, then 208 // the corresponding font will be returned, otherwise the whole 209 // collection. Ignored for non-collection fonts. 210 bool Process(OTSStream *output, const uint8_t *input, size_t length, uint32_t index = -1); 211 212 // This function will be called when OTS is reporting an error. 213 // level: the severity of the generated message: 214 // 0: error messages in case OTS fails to sanitize the font. 215 // 1: warning messages about issue OTS fixed in the sanitized font. Message(int level OTS_UNUSED,const char * format OTS_UNUSED,...)216 virtual void Message(int level OTS_UNUSED, const char *format OTS_UNUSED, ...) MSGFUNC_FMT_ATTR {} 217 218 // This function will be called when OTS needs to decide what to do for a 219 // font table. 220 // tag: table tag formed with OTS_TAG() macro GetTableAction(uint32_t tag OTS_UNUSED)221 virtual TableAction GetTableAction(uint32_t tag OTS_UNUSED) { return ots::TABLE_ACTION_DEFAULT; } 222 }; 223 224 } // namespace ots 225 226 #endif // OPENTYPE_SANITISER_H_ 227