1 // Copyright 2013 Google Inc. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 // 15 // The parts of ots.h & opentype-sanitiser.h that we need, taken from the 16 // https://code.google.com/p/ots/ project. 17 18 #ifndef WOFF2_BUFFER_H_ 19 #define WOFF2_BUFFER_H_ 20 21 #if defined(_WIN32) 22 #include <stdlib.h> 23 typedef signed char int8_t; 24 typedef unsigned char uint8_t; 25 typedef short int16_t; 26 typedef unsigned short uint16_t; 27 typedef int int32_t; 28 typedef unsigned int uint32_t; 29 typedef __int64 int64_t; 30 typedef unsigned __int64 uint64_t; 31 #define ntohl(x) _byteswap_ulong (x) 32 #define ntohs(x) _byteswap_ushort (x) 33 #define htonl(x) _byteswap_ulong (x) 34 #define htons(x) _byteswap_ushort (x) 35 #else 36 #include <arpa/inet.h> 37 #include <stdint.h> 38 #endif 39 40 #include <cstdlib> 41 #include <cstring> 42 #include <limits> 43 44 namespace woff2 { 45 46 #if defined(_MSC_VER) || !defined(FONT_COMPRESSION_DEBUG) 47 #define FONT_COMPRESSION_FAILURE() false 48 #else 49 #define FONT_COMPRESSION_FAILURE() \ 50 util::compression::font::Failure(__FILE__, __LINE__, __PRETTY_FUNCTION__) 51 inline bool Failure(const char *f, int l, const char *fn) { 52 std::fprintf(stderr, "ERROR at %s:%d (%s)\n", f, l, fn); 53 std::fflush(stderr); 54 return false; 55 } 56 #endif 57 58 // ----------------------------------------------------------------------------- 59 // Buffer helper class 60 // 61 // This class perform some trival buffer operations while checking for 62 // out-of-bounds errors. As a family they return false if anything is amiss, 63 // updating the current offset otherwise. 64 // ----------------------------------------------------------------------------- 65 class Buffer { 66 public: 67 Buffer(const uint8_t *buffer, size_t len) 68 : buffer_(buffer), 69 length_(len), 70 offset_(0) { } 71 72 bool Skip(size_t n_bytes) { 73 return Read(NULL, n_bytes); 74 } 75 76 bool Read(uint8_t *buffer, size_t n_bytes) { 77 if (n_bytes > 1024 * 1024 * 1024) { 78 return FONT_COMPRESSION_FAILURE(); 79 } 80 if ((offset_ + n_bytes > length_) || 81 (offset_ > length_ - n_bytes)) { 82 return FONT_COMPRESSION_FAILURE(); 83 } 84 if (buffer) { 85 std::memcpy(buffer, buffer_ + offset_, n_bytes); 86 } 87 offset_ += n_bytes; 88 return true; 89 } 90 91 inline bool ReadU8(uint8_t *value) { 92 if (offset_ + 1 > length_) { 93 return FONT_COMPRESSION_FAILURE(); 94 } 95 *value = buffer_[offset_]; 96 ++offset_; 97 return true; 98 } 99 100 bool ReadU16(uint16_t *value) { 101 if (offset_ + 2 > length_) { 102 return FONT_COMPRESSION_FAILURE(); 103 } 104 std::memcpy(value, buffer_ + offset_, sizeof(uint16_t)); 105 *value = ntohs(*value); 106 offset_ += 2; 107 return true; 108 } 109 110 bool ReadS16(int16_t *value) { 111 return ReadU16(reinterpret_cast<uint16_t*>(value)); 112 } 113 114 bool ReadU24(uint32_t *value) { 115 if (offset_ + 3 > length_) { 116 return FONT_COMPRESSION_FAILURE(); 117 } 118 *value = static_cast<uint32_t>(buffer_[offset_]) << 16 | 119 static_cast<uint32_t>(buffer_[offset_ + 1]) << 8 | 120 static_cast<uint32_t>(buffer_[offset_ + 2]); 121 offset_ += 3; 122 return true; 123 } 124 125 bool ReadU32(uint32_t *value) { 126 if (offset_ + 4 > length_) { 127 return FONT_COMPRESSION_FAILURE(); 128 } 129 std::memcpy(value, buffer_ + offset_, sizeof(uint32_t)); 130 *value = ntohl(*value); 131 offset_ += 4; 132 return true; 133 } 134 135 bool ReadS32(int32_t *value) { 136 return ReadU32(reinterpret_cast<uint32_t*>(value)); 137 } 138 139 bool ReadTag(uint32_t *value) { 140 if (offset_ + 4 > length_) { 141 return FONT_COMPRESSION_FAILURE(); 142 } 143 std::memcpy(value, buffer_ + offset_, sizeof(uint32_t)); 144 offset_ += 4; 145 return true; 146 } 147 148 bool ReadR64(uint64_t *value) { 149 if (offset_ + 8 > length_) { 150 return FONT_COMPRESSION_FAILURE(); 151 } 152 std::memcpy(value, buffer_ + offset_, sizeof(uint64_t)); 153 offset_ += 8; 154 return true; 155 } 156 157 const uint8_t *buffer() const { return buffer_; } 158 size_t offset() const { return offset_; } 159 size_t length() const { return length_; } 160 161 void set_offset(size_t newoffset) { offset_ = newoffset; } 162 163 private: 164 const uint8_t * const buffer_; 165 const size_t length_; 166 size_t offset_; 167 }; 168 169 } // namespace woff2 170 171 #endif // WOFF2_BUFFER_H_ 172