blob: f71f6a8fe55fcb2996f43864a3e5cb227416d6b4 [file] [log] [blame]
Roderick Sheeter437bbad2013-11-19 14:32:56 -08001// 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
Kenichi Ishibashi142d8882014-05-30 09:06:32 +090018#ifndef WOFF2_BUFFER_H_
19#define WOFF2_BUFFER_H_
Roderick Sheeter437bbad2013-11-19 14:32:56 -080020
Roderick Sheeter2e5995b2013-12-12 10:43:05 -080021#include <stdint.h>
22#include <arpa/inet.h>
Roderick Sheeter437bbad2013-11-19 14:32:56 -080023#include <cstdlib>
24#include <cstring>
25#include <limits>
26
Kenichi Ishibashi142d8882014-05-30 09:06:32 +090027namespace woff2 {
Roderick Sheeter437bbad2013-11-19 14:32:56 -080028
Kenichi Ishibashi142d8882014-05-30 09:06:32 +090029#if defined(_MSC_VER) || !defined(FONT_COMPRESSION_DEBUG)
30#define FONT_COMPRESSION_FAILURE() false
Roderick Sheeter437bbad2013-11-19 14:32:56 -080031#else
Kenichi Ishibashi142d8882014-05-30 09:06:32 +090032#define FONT_COMPRESSION_FAILURE() \
33 util::compression::font::Failure(__FILE__, __LINE__, __PRETTY_FUNCTION__)
Roderick Sheeter437bbad2013-11-19 14:32:56 -080034inline bool Failure(const char *f, int l, const char *fn) {
35 std::fprintf(stderr, "ERROR at %s:%d (%s)\n", f, l, fn);
36 std::fflush(stderr);
37 return false;
38}
39#endif
40
41// -----------------------------------------------------------------------------
42// Buffer helper class
43//
44// This class perform some trival buffer operations while checking for
45// out-of-bounds errors. As a family they return false if anything is amiss,
46// updating the current offset otherwise.
47// -----------------------------------------------------------------------------
48class Buffer {
49 public:
50 Buffer(const uint8_t *buffer, size_t len)
51 : buffer_(buffer),
52 length_(len),
53 offset_(0) { }
54
55 bool Skip(size_t n_bytes) {
56 return Read(NULL, n_bytes);
57 }
58
59 bool Read(uint8_t *buffer, size_t n_bytes) {
60 if (n_bytes > 1024 * 1024 * 1024) {
Kenichi Ishibashi142d8882014-05-30 09:06:32 +090061 return FONT_COMPRESSION_FAILURE();
Roderick Sheeter437bbad2013-11-19 14:32:56 -080062 }
63 if ((offset_ + n_bytes > length_) ||
64 (offset_ > length_ - n_bytes)) {
Kenichi Ishibashi142d8882014-05-30 09:06:32 +090065 return FONT_COMPRESSION_FAILURE();
Roderick Sheeter437bbad2013-11-19 14:32:56 -080066 }
67 if (buffer) {
68 std::memcpy(buffer, buffer_ + offset_, n_bytes);
69 }
70 offset_ += n_bytes;
71 return true;
72 }
73
74 inline bool ReadU8(uint8_t *value) {
75 if (offset_ + 1 > length_) {
Kenichi Ishibashi142d8882014-05-30 09:06:32 +090076 return FONT_COMPRESSION_FAILURE();
Roderick Sheeter437bbad2013-11-19 14:32:56 -080077 }
78 *value = buffer_[offset_];
79 ++offset_;
80 return true;
81 }
82
83 bool ReadU16(uint16_t *value) {
84 if (offset_ + 2 > length_) {
Kenichi Ishibashi142d8882014-05-30 09:06:32 +090085 return FONT_COMPRESSION_FAILURE();
Roderick Sheeter437bbad2013-11-19 14:32:56 -080086 }
87 std::memcpy(value, buffer_ + offset_, sizeof(uint16_t));
88 *value = ntohs(*value);
89 offset_ += 2;
90 return true;
91 }
92
93 bool ReadS16(int16_t *value) {
94 return ReadU16(reinterpret_cast<uint16_t*>(value));
95 }
96
97 bool ReadU24(uint32_t *value) {
98 if (offset_ + 3 > length_) {
Kenichi Ishibashi142d8882014-05-30 09:06:32 +090099 return FONT_COMPRESSION_FAILURE();
Roderick Sheeter437bbad2013-11-19 14:32:56 -0800100 }
101 *value = static_cast<uint32_t>(buffer_[offset_]) << 16 |
102 static_cast<uint32_t>(buffer_[offset_ + 1]) << 8 |
103 static_cast<uint32_t>(buffer_[offset_ + 2]);
104 offset_ += 3;
105 return true;
106 }
107
108 bool ReadU32(uint32_t *value) {
109 if (offset_ + 4 > length_) {
Kenichi Ishibashi142d8882014-05-30 09:06:32 +0900110 return FONT_COMPRESSION_FAILURE();
Roderick Sheeter437bbad2013-11-19 14:32:56 -0800111 }
112 std::memcpy(value, buffer_ + offset_, sizeof(uint32_t));
113 *value = ntohl(*value);
114 offset_ += 4;
115 return true;
116 }
117
118 bool ReadS32(int32_t *value) {
119 return ReadU32(reinterpret_cast<uint32_t*>(value));
120 }
121
122 bool ReadTag(uint32_t *value) {
123 if (offset_ + 4 > length_) {
Kenichi Ishibashi142d8882014-05-30 09:06:32 +0900124 return FONT_COMPRESSION_FAILURE();
Roderick Sheeter437bbad2013-11-19 14:32:56 -0800125 }
126 std::memcpy(value, buffer_ + offset_, sizeof(uint32_t));
127 offset_ += 4;
128 return true;
129 }
130
131 bool ReadR64(uint64_t *value) {
132 if (offset_ + 8 > length_) {
Kenichi Ishibashi142d8882014-05-30 09:06:32 +0900133 return FONT_COMPRESSION_FAILURE();
Roderick Sheeter437bbad2013-11-19 14:32:56 -0800134 }
135 std::memcpy(value, buffer_ + offset_, sizeof(uint64_t));
136 offset_ += 8;
137 return true;
138 }
139
140 const uint8_t *buffer() const { return buffer_; }
141 size_t offset() const { return offset_; }
142 size_t length() const { return length_; }
143
144 void set_offset(size_t newoffset) { offset_ = newoffset; }
145
146 private:
147 const uint8_t * const buffer_;
148 const size_t length_;
149 size_t offset_;
150};
151
Kenichi Ishibashi142d8882014-05-30 09:06:32 +0900152} // namespace woff2
Roderick Sheeter437bbad2013-11-19 14:32:56 -0800153
Kenichi Ishibashi142d8882014-05-30 09:06:32 +0900154#endif // WOFF2_BUFFER_H_