Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(51)

Side by Side Diff: third_party/harfbuzz-ng/src/hb-open-type-private.hh

Issue 10510004: Roll harfbuzz-ng 3b8fd9c48f4bde368bf2d465c148b9743a9216ee (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright © 2007,2008,2009,2010 Red Hat, Inc. 2 * Copyright © 2007,2008,2009,2010 Red Hat, Inc.
3 * Copyright © 2012 Google, Inc.
3 * 4 *
4 * This is part of HarfBuzz, a text shaping library. 5 * This is part of HarfBuzz, a text shaping library.
5 * 6 *
6 * Permission is hereby granted, without written agreement and without 7 * Permission is hereby granted, without written agreement and without
7 * license or royalty fees, to use, copy, modify, and distribute this 8 * license or royalty fees, to use, copy, modify, and distribute this
8 * software and its documentation for any purpose, provided that the 9 * software and its documentation for any purpose, provided that the
9 * above copyright notice and the following two paragraphs appear in 10 * above copyright notice and the following two paragraphs appear in
10 * all copies of this software. 11 * all copies of this software.
11 * 12 *
12 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 13 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
13 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 14 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
14 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 15 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
15 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 16 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
16 * DAMAGE. 17 * DAMAGE.
17 * 18 *
18 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 19 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
19 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20 * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 21 * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
21 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 22 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
22 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 23 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
23 * 24 *
24 * Red Hat Author(s): Behdad Esfahbod 25 * Red Hat Author(s): Behdad Esfahbod
26 * Google Author(s): Behdad Esfahbod
25 */ 27 */
26 28
27 #ifndef HB_OPEN_TYPE_PRIVATE_HH 29 #ifndef HB_OPEN_TYPE_PRIVATE_HH
28 #define HB_OPEN_TYPE_PRIVATE_HH 30 #define HB_OPEN_TYPE_PRIVATE_HH
29 31
30 #include "hb-private.hh" 32 #include "hb-private.hh"
31 33
32 #include "hb-blob.h" 34 #include "hb-blob.h"
33 35
34 36
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
146 /* 148 /*
147 * Sanitize 149 * Sanitize
148 */ 150 */
149 151
150 #ifndef HB_DEBUG_SANITIZE 152 #ifndef HB_DEBUG_SANITIZE
151 #define HB_DEBUG_SANITIZE (HB_DEBUG+0) 153 #define HB_DEBUG_SANITIZE (HB_DEBUG+0)
152 #endif 154 #endif
153 155
154 156
155 #define TRACE_SANITIZE() \ 157 #define TRACE_SANITIZE() \
156 » hb_auto_trace_t<HB_DEBUG_SANITIZE> trace (&c->debug_depth, "SANITIZE", t his, NULL, HB_FUNC); 158 » hb_auto_trace_t<HB_DEBUG_SANITIZE> trace (&c->debug_depth, "SANITIZE", t his, HB_FUNC, "");
157 159
158 160
159 struct hb_sanitize_context_t 161 struct hb_sanitize_context_t
160 { 162 {
161 inline void init (hb_blob_t *b) 163 inline void init (hb_blob_t *b)
162 { 164 {
163 this->blob = hb_blob_reference (b); 165 this->blob = hb_blob_reference (b);
164 this->writable = false; 166 this->writable = false;
165 } 167 }
166 168
167 inline void setup (void) 169 inline void start_processing (void)
168 { 170 {
169 this->start = hb_blob_get_data (this->blob, NULL); 171 this->start = hb_blob_get_data (this->blob, NULL);
170 this->end = this->start + hb_blob_get_length (this->blob); 172 this->end = this->start + hb_blob_get_length (this->blob);
171 this->edit_count = 0; 173 this->edit_count = 0;
172 this->debug_depth = 0; 174 this->debug_depth = 0;
173 175
174 DEBUG_MSG (SANITIZE, this->blob, 176 DEBUG_MSG_LEVEL (SANITIZE, this->blob, 0, +1,
175 » "init [%p..%p] (%lu bytes)", 177 » » "start [%p..%p] (%lu bytes)",
176 » this->start, this->end, 178 » » this->start, this->end,
177 » (unsigned long) (this->end - this->start)); 179 » » (unsigned long) (this->end - this->start));
178 } 180 }
179 181
180 inline void finish (void) 182 inline void end_processing (void)
181 { 183 {
182 DEBUG_MSG (SANITIZE, this->blob, 184 DEBUG_MSG_LEVEL (SANITIZE, this->blob, 0, -1,
183 » "fini [%p..%p] %u edit requests", 185 » » "end [%p..%p] %u edit requests",
184 » this->start, this->end, this->edit_count); 186 » » this->start, this->end, this->edit_count);
185 187
186 hb_blob_destroy (this->blob); 188 hb_blob_destroy (this->blob);
187 this->blob = NULL; 189 this->blob = NULL;
188 this->start = this->end = NULL; 190 this->start = this->end = NULL;
189 } 191 }
190 192
191 inline bool check_range (const void *base, unsigned int len) const 193 inline bool check_range (const void *base, unsigned int len) const
192 { 194 {
193 const char *p = (const char *) base; 195 const char *p = (const char *) base;
194 bool ret = this->start <= p &&
195 p <= this->end &&
196 (unsigned int) (this->end - p) >= len;
197 196
198 DEBUG_MSG_LEVEL (SANITIZE, this->blob, this->debug_depth, 197 hb_auto_trace_t<HB_DEBUG_SANITIZE> trace (&this->debug_depth, "SANITIZE", th is->blob, NULL,
199 » » "%-*d-> range [%p..%p] (%d bytes) in [%p..%p] -> %s", 198 » » » » » "check_range [%p..%p] (%d bytes) i n [%p..%p]",
200 » » this->debug_depth, this->debug_depth, 199 » » » » » p, p + len, len,
201 » » p, p + len, len, 200 » » » » » this->start, this->end);
202 » » this->start, this->end,
203 » » ret ? "pass" : "FAIL");
204 201
205 return likely (ret); 202 return TRACE_RETURN (likely (this->start <= p && p <= this->end && (unsigned int) (this->end - p) >= len));
206 } 203 }
207 204
208 inline bool check_array (const void *base, unsigned int record_size, unsigned int len) const 205 inline bool check_array (const void *base, unsigned int record_size, unsigned int len) const
209 { 206 {
210 const char *p = (const char *) base; 207 const char *p = (const char *) base;
211 bool overflows = _hb_unsigned_int_mul_overflows (len, record_size); 208 bool overflows = _hb_unsigned_int_mul_overflows (len, record_size);
212 209
213 DEBUG_MSG_LEVEL (SANITIZE, this->blob, this->debug_depth, 210 hb_auto_trace_t<HB_DEBUG_SANITIZE> trace (&this->debug_depth, "SANITIZE", th is->blob, NULL,
214 » » "%-*d-> array [%p..%p] (%d*%d=%ld bytes) in [%p..%p] -> %s" , 211 » » » » » "check_array [%p..%p] (%d*%d=%ld b ytes) in [%p..%p]",
215 » » this->debug_depth, this->debug_depth, 212 » » » » » p, p + (record_size * len), record _size, len, (unsigned long) record_size * len,
216 » » p, p + (record_size * len), record_size, len, (unsigned lon g) record_size * len, 213 » » » » » this->start, this->end);
217 » » this->start, this->end,
218 » » !overflows ? "does not overflow" : "OVERFLOWS FAIL");
219 214
220 return likely (!overflows && this->check_range (base, record_size * len)); 215 return TRACE_RETURN (likely (!overflows && this->check_range (base, record_s ize * len)));
221 } 216 }
222 217
223 template <typename Type> 218 template <typename Type>
224 inline bool check_struct (const Type *obj) const 219 inline bool check_struct (const Type *obj) const
225 { 220 {
226 return likely (this->check_range (obj, obj->min_size)); 221 return likely (this->check_range (obj, obj->min_size));
227 } 222 }
228 223
229 inline bool can_edit (const void *base HB_UNUSED, unsigned int len HB_UNUSED) 224 inline bool may_edit (const void *base HB_UNUSED, unsigned int len HB_UNUSED)
230 { 225 {
231 const char *p = (const char *) base; 226 const char *p = (const char *) base;
232 this->edit_count++; 227 this->edit_count++;
233 228
234 DEBUG_MSG_LEVEL (SANITIZE, this->blob, this->debug_depth, 229 hb_auto_trace_t<HB_DEBUG_SANITIZE> trace (&this->debug_depth, "SANITIZE", th is->blob, NULL,
235 » » "%-*d-> edit(%u) [%p..%p] (%d bytes) in [%p..%p] -> %s", 230 » » » » » "may_edit(%u) [%p..%p] (%d bytes) in [%p..%p] -> %s",
236 » » this->debug_depth, this->debug_depth, 231 » » » » » this->edit_count,
237 » » this->edit_count, 232 » » » » » p, p + len, len,
238 » » p, p + len, len, 233 » » » » » this->start, this->end);
239 » » this->start, this->end,
240 » » this->writable ? "granted" : "REJECTED");
241 234
242 return this->writable; 235 return TRACE_RETURN (this->writable);
243 } 236 }
244 237
245 unsigned int debug_depth; 238 mutable unsigned int debug_depth;
246 const char *start, *end; 239 const char *start, *end;
247 bool writable; 240 bool writable;
248 unsigned int edit_count; 241 unsigned int edit_count;
249 hb_blob_t *blob; 242 hb_blob_t *blob;
250 }; 243 };
251 244
252 245
253 246
254 /* Template to sanitize an object. */ 247 /* Template to sanitize an object. */
255 template <typename Type> 248 template <typename Type>
256 struct Sanitizer 249 struct Sanitizer
257 { 250 {
258 static hb_blob_t *sanitize (hb_blob_t *blob) { 251 static hb_blob_t *sanitize (hb_blob_t *blob) {
259 hb_sanitize_context_t c[1] = {{0}}; 252 hb_sanitize_context_t c[1] = {{0}};
260 bool sane; 253 bool sane;
261 254
262 /* TODO is_sane() stuff */ 255 /* TODO is_sane() stuff */
263 256
264 c->init (blob); 257 c->init (blob);
265 258
266 retry: 259 retry:
267 DEBUG_MSG_FUNC (SANITIZE, blob, "start"); 260 DEBUG_MSG_FUNC (SANITIZE, blob, "start");
268 261
269 c->setup (); 262 c->start_processing ();
270 263
271 if (unlikely (!c->start)) { 264 if (unlikely (!c->start)) {
272 c->finish (); 265 c->end_processing ();
273 return blob; 266 return blob;
274 } 267 }
275 268
276 Type *t = CastP<Type> (const_cast<char *> (c->start)); 269 Type *t = CastP<Type> (const_cast<char *> (c->start));
277 270
278 sane = t->sanitize (c); 271 sane = t->sanitize (c);
279 if (sane) { 272 if (sane) {
280 if (c->edit_count) { 273 if (c->edit_count) {
281 DEBUG_MSG_FUNC (SANITIZE, blob, "passed first round with %d edits; going for second round", c->edit_count); 274 DEBUG_MSG_FUNC (SANITIZE, blob, "passed first round with %d edits; going for second round", c->edit_count);
282 275
(...skipping 13 matching lines...) Expand all
296 289
297 if (c->start) { 290 if (c->start) {
298 c->writable = true; 291 c->writable = true;
299 /* ok, we made it writable by relocating. try again */ 292 /* ok, we made it writable by relocating. try again */
300 DEBUG_MSG_FUNC (SANITIZE, blob, "retry"); 293 DEBUG_MSG_FUNC (SANITIZE, blob, "retry");
301 goto retry; 294 goto retry;
302 } 295 }
303 } 296 }
304 } 297 }
305 298
306 c->finish (); 299 c->end_processing ();
307 300
308 DEBUG_MSG_FUNC (SANITIZE, blob, sane ? "PASSED" : "FAILED"); 301 DEBUG_MSG_FUNC (SANITIZE, blob, sane ? "PASSED" : "FAILED");
309 if (sane) 302 if (sane)
310 return blob; 303 return blob;
311 else { 304 else {
312 hb_blob_destroy (blob); 305 hb_blob_destroy (blob);
313 return hb_blob_get_empty (); 306 return hb_blob_get_empty ();
314 } 307 }
315 } 308 }
316 309
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 template <typename Type> 360 template <typename Type>
368 struct IntType 361 struct IntType
369 { 362 {
370 inline void set (Type i) { v.set (i); } 363 inline void set (Type i) { v.set (i); }
371 inline operator Type(void) const { return v; } 364 inline operator Type(void) const { return v; }
372 inline bool operator == (const IntType<Type> &o) const { return v == o.v; } 365 inline bool operator == (const IntType<Type> &o) const { return v == o.v; }
373 inline bool operator != (const IntType<Type> &o) const { return v != o.v; } 366 inline bool operator != (const IntType<Type> &o) const { return v != o.v; }
374 inline int cmp (Type a) const { Type b = v; return a < b ? -1 : a == b ? 0 : + 1; } 367 inline int cmp (Type a) const { Type b = v; return a < b ? -1 : a == b ? 0 : + 1; }
375 inline bool sanitize (hb_sanitize_context_t *c) { 368 inline bool sanitize (hb_sanitize_context_t *c) {
376 TRACE_SANITIZE (); 369 TRACE_SANITIZE ();
377 return likely (c->check_struct (this)); 370 return TRACE_RETURN (likely (c->check_struct (this)));
378 } 371 }
379 protected: 372 protected:
380 BEInt<Type, sizeof (Type)> v; 373 BEInt<Type, sizeof (Type)> v;
381 public: 374 public:
382 DEFINE_SIZE_STATIC (sizeof (Type)); 375 DEFINE_SIZE_STATIC (sizeof (Type));
383 }; 376 };
384 377
385 /* Typedef these to avoid clash with windows.h */ 378 /* Typedef these to avoid clash with windows.h */
386 #define USHORT HB_USHORT 379 #define USHORT HB_USHORT
387 #define SHORT HB_SHORT 380 #define SHORT HB_SHORT
388 #define ULONG HB_ULONG 381 #define ULONG HB_ULONG
389 #define LONG HB_LONG 382 #define LONG HB_LONG
390 typedef IntType<uint16_t> USHORT; /* 16-bit unsigned integer. */ 383 typedef IntType<uint16_t> USHORT; /* 16-bit unsigned integer. */
391 typedef IntType<int16_t> SHORT; /* 16-bit signed integer. */ 384 typedef IntType<int16_t> SHORT; /* 16-bit signed integer. */
392 typedef IntType<uint32_t> ULONG; /* 32-bit unsigned integer. */ 385 typedef IntType<uint32_t> ULONG; /* 32-bit unsigned integer. */
393 typedef IntType<int32_t> LONG; /* 32-bit signed integer. */ 386 typedef IntType<int32_t> LONG; /* 32-bit signed integer. */
394 387
395 /* 16-bit signed integer (SHORT) that describes a quantity in FUnits. */ 388 /* 16-bit signed integer (SHORT) that describes a quantity in FUnits. */
396 typedef SHORT FWORD; 389 typedef SHORT FWORD;
397 390
398 /* 16-bit unsigned integer (USHORT) that describes a quantity in FUnits. */ 391 /* 16-bit unsigned integer (USHORT) that describes a quantity in FUnits. */
399 typedef USHORT UFWORD; 392 typedef USHORT UFWORD;
400 393
401 /* Date represented in number of seconds since 12:00 midnight, January 1, 394 /* Date represented in number of seconds since 12:00 midnight, January 1,
402 * 1904. The value is represented as a signed 64-bit integer. */ 395 * 1904. The value is represented as a signed 64-bit integer. */
403 struct LONGDATETIME 396 struct LONGDATETIME
404 { 397 {
405 inline bool sanitize (hb_sanitize_context_t *c) { 398 inline bool sanitize (hb_sanitize_context_t *c) {
406 TRACE_SANITIZE (); 399 TRACE_SANITIZE ();
407 return likely (c->check_struct (this)); 400 return TRACE_RETURN (likely (c->check_struct (this)));
408 } 401 }
409 private: 402 private:
410 LONG major; 403 LONG major;
411 ULONG minor; 404 ULONG minor;
412 public: 405 public:
413 DEFINE_SIZE_STATIC (8); 406 DEFINE_SIZE_STATIC (8);
414 }; 407 };
415 408
416 /* Array of four uint8s (length = 32 bits) used to identify a script, language 409 /* Array of four uint8s (length = 32 bits) used to identify a script, language
417 * system, feature, or baseline */ 410 * system, feature, or baseline */
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
461 /* 454 /*
462 * Version Numbers 455 * Version Numbers
463 */ 456 */
464 457
465 struct FixedVersion 458 struct FixedVersion
466 { 459 {
467 inline uint32_t to_int (void) const { return (major << 16) + minor; } 460 inline uint32_t to_int (void) const { return (major << 16) + minor; }
468 461
469 inline bool sanitize (hb_sanitize_context_t *c) { 462 inline bool sanitize (hb_sanitize_context_t *c) {
470 TRACE_SANITIZE (); 463 TRACE_SANITIZE ();
471 return c->check_struct (this); 464 return TRACE_RETURN (c->check_struct (this));
472 } 465 }
473 466
474 USHORT major; 467 USHORT major;
475 USHORT minor; 468 USHORT minor;
476 public: 469 public:
477 DEFINE_SIZE_STATIC (4); 470 DEFINE_SIZE_STATIC (4);
478 }; 471 };
479 472
480 473
481 474
482 /* 475 /*
483 * Template subclasses of Offset and LongOffset that do the dereferencing. 476 * Template subclasses of Offset and LongOffset that do the dereferencing.
484 * Use: (base+offset) 477 * Use: (base+offset)
485 */ 478 */
486 479
487 template <typename OffsetType, typename Type> 480 template <typename OffsetType, typename Type>
488 struct GenericOffsetTo : OffsetType 481 struct GenericOffsetTo : OffsetType
489 { 482 {
490 inline const Type& operator () (const void *base) const 483 inline const Type& operator () (const void *base) const
491 { 484 {
492 unsigned int offset = *this; 485 unsigned int offset = *this;
493 if (unlikely (!offset)) return Null(Type); 486 if (unlikely (!offset)) return Null(Type);
494 return StructAtOffset<Type> (base, offset); 487 return StructAtOffset<Type> (base, offset);
495 } 488 }
496 489
497 inline bool sanitize (hb_sanitize_context_t *c, void *base) { 490 inline bool sanitize (hb_sanitize_context_t *c, void *base) {
498 TRACE_SANITIZE (); 491 TRACE_SANITIZE ();
499 if (unlikely (!c->check_struct (this))) return false; 492 if (unlikely (!c->check_struct (this))) return TRACE_RETURN (false);
500 unsigned int offset = *this; 493 unsigned int offset = *this;
501 if (unlikely (!offset)) return true; 494 if (unlikely (!offset)) return TRACE_RETURN (true);
502 Type &obj = StructAtOffset<Type> (base, offset); 495 Type &obj = StructAtOffset<Type> (base, offset);
503 return likely (obj.sanitize (c)) || neuter (c); 496 return TRACE_RETURN (likely (obj.sanitize (c)) || neuter (c));
504 } 497 }
505 template <typename T> 498 template <typename T>
506 inline bool sanitize (hb_sanitize_context_t *c, void *base, T user_data) { 499 inline bool sanitize (hb_sanitize_context_t *c, void *base, T user_data) {
507 TRACE_SANITIZE (); 500 TRACE_SANITIZE ();
508 if (unlikely (!c->check_struct (this))) return false; 501 if (unlikely (!c->check_struct (this))) return TRACE_RETURN (false);
509 unsigned int offset = *this; 502 unsigned int offset = *this;
510 if (unlikely (!offset)) return true; 503 if (unlikely (!offset)) return TRACE_RETURN (true);
511 Type &obj = StructAtOffset<Type> (base, offset); 504 Type &obj = StructAtOffset<Type> (base, offset);
512 return likely (obj.sanitize (c, user_data)) || neuter (c); 505 return TRACE_RETURN (likely (obj.sanitize (c, user_data)) || neuter (c));
513 } 506 }
514 507
515 private: 508 private:
516 /* Set the offset to Null */ 509 /* Set the offset to Null */
517 inline bool neuter (hb_sanitize_context_t *c) { 510 inline bool neuter (hb_sanitize_context_t *c) {
518 if (c->can_edit (this, this->static_size)) { 511 if (c->may_edit (this, this->static_size)) {
519 this->set (0); /* 0 is Null offset */ 512 this->set (0); /* 0 is Null offset */
520 return true; 513 return true;
521 } 514 }
522 return false; 515 return false;
523 } 516 }
524 }; 517 };
525 template <typename Base, typename OffsetType, typename Type> 518 template <typename Base, typename OffsetType, typename Type>
526 inline const Type& operator + (const Base &base, GenericOffsetTo<OffsetType, Typ e> offset) { return offset (base); } 519 inline const Type& operator + (const Base &base, GenericOffsetTo<OffsetType, Typ e> offset) { return offset (base); }
527 520
528 template <typename Type> 521 template <typename Type>
(...skipping 25 matching lines...) Expand all
554 inline const Type& operator [] (unsigned int i) const 547 inline const Type& operator [] (unsigned int i) const
555 { 548 {
556 if (unlikely (i >= len)) return Null(Type); 549 if (unlikely (i >= len)) return Null(Type);
557 return array[i]; 550 return array[i];
558 } 551 }
559 inline unsigned int get_size (void) const 552 inline unsigned int get_size (void) const
560 { return len.static_size + len * Type::static_size; } 553 { return len.static_size + len * Type::static_size; }
561 554
562 inline bool sanitize (hb_sanitize_context_t *c) { 555 inline bool sanitize (hb_sanitize_context_t *c) {
563 TRACE_SANITIZE (); 556 TRACE_SANITIZE ();
564 if (unlikely (!sanitize_shallow (c))) return false; 557 if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false);
565 558
566 /* Note: for structs that do not reference other structs, 559 /* Note: for structs that do not reference other structs,
567 * we do not need to call their sanitize() as we already did 560 * we do not need to call their sanitize() as we already did
568 * a bound check on the aggregate array size. We just include 561 * a bound check on the aggregate array size. We just include
569 * a small unreachable expression to make sure the structs 562 * a small unreachable expression to make sure the structs
570 * pointed to do have a simple sanitize(), ie. they do not 563 * pointed to do have a simple sanitize(), ie. they do not
571 * reference other structs via offsets. 564 * reference other structs via offsets.
572 */ 565 */
573 (void) (false && array[0].sanitize (c)); 566 (void) (false && array[0].sanitize (c));
574 567
575 return true; 568 return TRACE_RETURN (true);
576 } 569 }
577 inline bool sanitize (hb_sanitize_context_t *c, void *base) { 570 inline bool sanitize (hb_sanitize_context_t *c, void *base) {
578 TRACE_SANITIZE (); 571 TRACE_SANITIZE ();
579 if (unlikely (!sanitize_shallow (c))) return false; 572 if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false);
580 unsigned int count = len; 573 unsigned int count = len;
581 for (unsigned int i = 0; i < count; i++) 574 for (unsigned int i = 0; i < count; i++)
582 if (unlikely (!array[i].sanitize (c, base))) 575 if (unlikely (!array[i].sanitize (c, base)))
583 return false; 576 return TRACE_RETURN (false);
584 return true; 577 return TRACE_RETURN (true);
585 } 578 }
586 template <typename T> 579 template <typename T>
587 inline bool sanitize (hb_sanitize_context_t *c, void *base, T user_data) { 580 inline bool sanitize (hb_sanitize_context_t *c, void *base, T user_data) {
588 TRACE_SANITIZE (); 581 TRACE_SANITIZE ();
589 if (unlikely (!sanitize_shallow (c))) return false; 582 if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false);
590 unsigned int count = len; 583 unsigned int count = len;
591 for (unsigned int i = 0; i < count; i++) 584 for (unsigned int i = 0; i < count; i++)
592 if (unlikely (!array[i].sanitize (c, base, user_data))) 585 if (unlikely (!array[i].sanitize (c, base, user_data)))
593 return false; 586 return TRACE_RETURN (false);
594 return true; 587 return TRACE_RETURN (true);
595 } 588 }
596 589
597 private: 590 private:
598 inline bool sanitize_shallow (hb_sanitize_context_t *c) { 591 inline bool sanitize_shallow (hb_sanitize_context_t *c) {
599 TRACE_SANITIZE (); 592 TRACE_SANITIZE ();
600 return c->check_struct (this) 593 return TRACE_RETURN (c->check_struct (this) && c->check_array (this, Type::s tatic_size, len));
601 » && c->check_array (this, Type::static_size, len);
602 } 594 }
603 595
604 public: 596 public:
605 LenType len; 597 LenType len;
606 Type array[VAR]; 598 Type array[VAR];
607 public: 599 public:
608 DEFINE_SIZE_ARRAY (sizeof (LenType), array); 600 DEFINE_SIZE_ARRAY (sizeof (LenType), array);
609 }; 601 };
610 602
611 /* An array with a USHORT number of elements. */ 603 /* An array with a USHORT number of elements. */
(...skipping 21 matching lines...) Expand all
633 struct OffsetListOf : OffsetArrayOf<Type> 625 struct OffsetListOf : OffsetArrayOf<Type>
634 { 626 {
635 inline const Type& operator [] (unsigned int i) const 627 inline const Type& operator [] (unsigned int i) const
636 { 628 {
637 if (unlikely (i >= this->len)) return Null(Type); 629 if (unlikely (i >= this->len)) return Null(Type);
638 return this+this->array[i]; 630 return this+this->array[i];
639 } 631 }
640 632
641 inline bool sanitize (hb_sanitize_context_t *c) { 633 inline bool sanitize (hb_sanitize_context_t *c) {
642 TRACE_SANITIZE (); 634 TRACE_SANITIZE ();
643 return OffsetArrayOf<Type>::sanitize (c, this); 635 return TRACE_RETURN (OffsetArrayOf<Type>::sanitize (c, this));
644 } 636 }
645 template <typename T> 637 template <typename T>
646 inline bool sanitize (hb_sanitize_context_t *c, T user_data) { 638 inline bool sanitize (hb_sanitize_context_t *c, T user_data) {
647 TRACE_SANITIZE (); 639 TRACE_SANITIZE ();
648 return OffsetArrayOf<Type>::sanitize (c, this, user_data); 640 return TRACE_RETURN (OffsetArrayOf<Type>::sanitize (c, this, user_data));
649 } 641 }
650 }; 642 };
651 643
652 644
653 /* An array with a USHORT number of elements, 645 /* An array with a USHORT number of elements,
654 * starting at second element. */ 646 * starting at second element. */
655 template <typename Type> 647 template <typename Type>
656 struct HeadlessArrayOf 648 struct HeadlessArrayOf
657 { 649 {
658 inline const Type& operator [] (unsigned int i) const 650 inline const Type& operator [] (unsigned int i) const
659 { 651 {
660 if (unlikely (i >= len || !i)) return Null(Type); 652 if (unlikely (i >= len || !i)) return Null(Type);
661 return array[i-1]; 653 return array[i-1];
662 } 654 }
663 inline unsigned int get_size (void) const 655 inline unsigned int get_size (void) const
664 { return len.static_size + (len ? len - 1 : 0) * Type::static_size; } 656 { return len.static_size + (len ? len - 1 : 0) * Type::static_size; }
665 657
666 inline bool sanitize_shallow (hb_sanitize_context_t *c) { 658 inline bool sanitize_shallow (hb_sanitize_context_t *c) {
667 return c->check_struct (this) 659 return c->check_struct (this)
668 && c->check_array (this, Type::static_size, len); 660 && c->check_array (this, Type::static_size, len);
669 } 661 }
670 662
671 inline bool sanitize (hb_sanitize_context_t *c) { 663 inline bool sanitize (hb_sanitize_context_t *c) {
672 TRACE_SANITIZE (); 664 TRACE_SANITIZE ();
673 if (unlikely (!sanitize_shallow (c))) return false; 665 if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false);
674 666
675 /* Note: for structs that do not reference other structs, 667 /* Note: for structs that do not reference other structs,
676 * we do not need to call their sanitize() as we already did 668 * we do not need to call their sanitize() as we already did
677 * a bound check on the aggregate array size. We just include 669 * a bound check on the aggregate array size. We just include
678 * a small unreachable expression to make sure the structs 670 * a small unreachable expression to make sure the structs
679 * pointed to do have a simple sanitize(), ie. they do not 671 * pointed to do have a simple sanitize(), ie. they do not
680 * reference other structs via offsets. 672 * reference other structs via offsets.
681 */ 673 */
682 (void) (false && array[0].sanitize (c)); 674 (void) (false && array[0].sanitize (c));
683 675
684 return true; 676 return TRACE_RETURN (true);
685 } 677 }
686 678
687 USHORT len; 679 USHORT len;
688 Type array[VAR]; 680 Type array[VAR];
689 public: 681 public:
690 DEFINE_SIZE_ARRAY (sizeof (USHORT), array); 682 DEFINE_SIZE_ARRAY (sizeof (USHORT), array);
691 }; 683 };
692 684
693 685
694 /* An array with sorted elements. Supports binary searching. */ 686 /* An array with sorted elements. Supports binary searching. */
695 template <typename Type> 687 template <typename Type>
696 struct SortedArrayOf : ArrayOf<Type> { 688 struct SortedArrayOf : ArrayOf<Type> {
697 689
698 template <typename SearchType> 690 template <typename SearchType>
699 inline int search (const SearchType &x) const { 691 inline int search (const SearchType &x) const {
700 struct Cmp { 692 struct Cmp {
701 static int cmp (const SearchType *a, const Type *b) { return b->cmp (*a); } 693 static int cmp (const SearchType *a, const Type *b) { return b->cmp (*a); }
702 }; 694 };
703 const Type *p = (const Type *) bsearch (&x, this->array, this->len, sizeof ( this->array[0]), (hb_compare_func_t) Cmp::cmp); 695 const Type *p = (const Type *) bsearch (&x, this->array, this->len, sizeof ( this->array[0]), (hb_compare_func_t) Cmp::cmp);
704 return p ? p - this->array : -1; 696 return p ? p - this->array : -1;
705 } 697 }
706 }; 698 };
707 699
708 700
709 701
710 #endif /* HB_OPEN_TYPE_PRIVATE_HH */ 702 #endif /* HB_OPEN_TYPE_PRIVATE_HH */
OLDNEW
« no previous file with comments | « third_party/harfbuzz-ng/src/hb-open-file-private.hh ('k') | third_party/harfbuzz-ng/src/hb-ot.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698