hb-open-type-private.hh revision 20b035dad41247076815a2bbb0346d63058b322f
164aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod/* 2ee58aaebd296ea8237516754fd4e825d524b11b7Behdad Esfahbod * Copyright (C) 2007,2008,2009 Red Hat, Inc. 364aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * 464aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * This is part of HarfBuzz, an OpenType Layout engine library. 564aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * 664aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * Permission is hereby granted, without written agreement and without 764aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * license or royalty fees, to use, copy, modify, and distribute this 864aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * software and its documentation for any purpose, provided that the 964aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * above copyright notice and the following two paragraphs appear in 1064aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * all copies of this software. 1164aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * 1264aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 1364aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 1464aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 1564aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 1664aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * DAMAGE. 1764aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * 1864aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 1964aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 2064aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 2164aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 2264aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 2364aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * 2464aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * Red Hat Author(s): Behdad Esfahbod 2564aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod */ 2664aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod 275f5b24f99f52bbc922e238b65c06061ba07c8548Behdad Esfahbod#ifndef HB_OPEN_TYPES_PRIVATE_HH 285f5b24f99f52bbc922e238b65c06061ba07c8548Behdad Esfahbod#define HB_OPEN_TYPES_PRIVATE_HH 2912c4568c680ea2b9b98a16a8b7402ca185c90ef6Behdad Esfahbod 302098a021a826e76ee27d5db74e32738d7d1c3d30Behdad Esfahbod#include "hb-private.h" 3112c4568c680ea2b9b98a16a8b7402ca185c90ef6Behdad Esfahbod 3270de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod#include "hb-blob.h" 3370de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 34a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod 35706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod#define NO_INDEX ((unsigned int) 0xFFFF) 362e8fb6c38dbc01cb77b384c0ae0212514dfbb588Behdad Esfahbod#define NO_CONTEXT ((unsigned int) 0x110000) 372e8fb6c38dbc01cb77b384c0ae0212514dfbb588Behdad Esfahbod#define NOT_COVERED ((unsigned int) 0x110000) 382e8fb6c38dbc01cb77b384c0ae0212514dfbb588Behdad Esfahbod#define MAX_NESTING_LEVEL 8 395a0b791184cf6ef39eae0570e14aca21abc32845Behdad Esfahbod 40706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 41196598bbccff08415ff5192314cba044df258cadBehdad Esfahbod/* 42196598bbccff08415ff5192314cba044df258cadBehdad Esfahbod * Casts 43196598bbccff08415ff5192314cba044df258cadBehdad Esfahbod */ 44196598bbccff08415ff5192314cba044df258cadBehdad Esfahbod 452b5a59c277f4c5bf7aac9a9005054763e322e02dBehdad Esfahbod#define CONST_CHARP(X) (reinterpret_cast<const char *>(X)) 462b5a59c277f4c5bf7aac9a9005054763e322e02dBehdad Esfahbod#define DECONST_CHARP(X) ((char *)reinterpret_cast<const char *>(X)) 472b5a59c277f4c5bf7aac9a9005054763e322e02dBehdad Esfahbod#define CHARP(X) (reinterpret_cast<char *>(X)) 482b5a59c277f4c5bf7aac9a9005054763e322e02dBehdad Esfahbod 492b5a59c277f4c5bf7aac9a9005054763e322e02dBehdad Esfahbod#define CONST_CAST(T,X,Ofs) (*(reinterpret_cast<const T *>(CONST_CHARP(&(X)) + Ofs))) 502b5a59c277f4c5bf7aac9a9005054763e322e02dBehdad Esfahbod#define DECONST_CAST(T,X,Ofs) (*(reinterpret_cast<T *>((char *)CONST_CHARP(&(X)) + Ofs))) 512b5a59c277f4c5bf7aac9a9005054763e322e02dBehdad Esfahbod#define CAST(T,X,Ofs) (*(reinterpret_cast<T *>(CHARP(&(X)) + Ofs))) 52196598bbccff08415ff5192314cba044df258cadBehdad Esfahbod 53284899ccbe79fda7405ab09d3092fc25fd89e810Behdad Esfahbod#define CONST_NEXT(T,X) (*(reinterpret_cast<const T *>(CONST_CHARP(&(X)) + (X).get_size ()))) 54284899ccbe79fda7405ab09d3092fc25fd89e810Behdad Esfahbod#define NEXT(T,X) (*(reinterpret_cast<T *>(CHARP(&(X)) + (X).get_size ()))) 5570de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 5670de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod/* 57600e5eb80f553ea8eb862e6784133574c74ca513Behdad Esfahbod * Class features 58600e5eb80f553ea8eb862e6784133574c74ca513Behdad Esfahbod */ 59600e5eb80f553ea8eb862e6784133574c74ca513Behdad Esfahbod 608b8358033184198ff638ee1379093717596e162dBehdad Esfahbod 618b8358033184198ff638ee1379093717596e162dBehdad Esfahbod/* Null objects */ 628b8358033184198ff638ee1379093717596e162dBehdad Esfahbod 638b8358033184198ff638ee1379093717596e162dBehdad Esfahbod/* Global nul-content Null pool. Enlarge as necessary. */ 648b8358033184198ff638ee1379093717596e162dBehdad Esfahbodstatic const char NullPool[16] = ""; 658b8358033184198ff638ee1379093717596e162dBehdad Esfahbod 668b8358033184198ff638ee1379093717596e162dBehdad Esfahbod/* Generic template for nul-content sizeof-sized Null objects. */ 678b8358033184198ff638ee1379093717596e162dBehdad Esfahbodtemplate <typename Type> 6860d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct Null 6960d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 70f8dc67b3c24dfc805da756a73cb217b36e16b4b8Behdad Esfahbod ASSERT_STATIC (sizeof (Type) <= sizeof (NullPool)); 714497af0069a94c69fc1518b1db2c1282721b732aBehdad Esfahbod static inline const Type &get () { return *(const Type*)NullPool; } 728b8358033184198ff638ee1379093717596e162dBehdad Esfahbod}; 738b8358033184198ff638ee1379093717596e162dBehdad Esfahbod 748b8358033184198ff638ee1379093717596e162dBehdad Esfahbod/* Specializaiton for arbitrary-content arbitrary-sized Null objects. */ 758b8358033184198ff638ee1379093717596e162dBehdad Esfahbod#define DEFINE_NULL_DATA(Type, size, data) \ 76cc6c644ff2af5f6669b6ec100ff13e904872b21cBehdad Esfahbodstatic const char _Null##Type[size] = data; \ 778b8358033184198ff638ee1379093717596e162dBehdad Esfahbodtemplate <> \ 7860d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct Null <Type> \ 7960d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ \ 804497af0069a94c69fc1518b1db2c1282721b732aBehdad Esfahbod static inline const Type &get () { return *(const Type*)_Null##Type; } \ 818b8358033184198ff638ee1379093717596e162dBehdad Esfahbod} 828b8358033184198ff638ee1379093717596e162dBehdad Esfahbod 838b8358033184198ff638ee1379093717596e162dBehdad Esfahbod/* Accessor macro. */ 848b8358033184198ff638ee1379093717596e162dBehdad Esfahbod#define Null(Type) (Null<Type>::get()) 858b8358033184198ff638ee1379093717596e162dBehdad Esfahbod 868b8358033184198ff638ee1379093717596e162dBehdad Esfahbod 878b8358033184198ff638ee1379093717596e162dBehdad Esfahbod#define ASSERT_SIZE_DATA(Type, size, data) \ 881f437e6f47fb6c15761021bd2078f31778f2179cBehdad Esfahbod ASSERT_SIZE (Type, size); \ 891f437e6f47fb6c15761021bd2078f31778f2179cBehdad Esfahbod DEFINE_NULL_DATA (Type, size, data) 901f437e6f47fb6c15761021bd2078f31778f2179cBehdad Esfahbod 91600e5eb80f553ea8eb862e6784133574c74ca513Behdad Esfahbod/* get_for_data() is a static class method returning a reference to an 92600e5eb80f553ea8eb862e6784133574c74ca513Behdad Esfahbod * instance of Type located at the input data location. It's just a 9354e5aac5e2947d4e2864c6f2987e4d275da73100Behdad Esfahbod * fancy, NULL-safe, cast! */ 94fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod#define STATIC_DEFINE_GET_FOR_DATA(Type) \ 9560d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod static inline const Type& get_for_data (const char *data) \ 9660d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { \ 978b8358033184198ff638ee1379093717596e162dBehdad Esfahbod if (HB_UNLIKELY (data == NULL)) return Null(Type); \ 984497af0069a94c69fc1518b1db2c1282721b732aBehdad Esfahbod return *(const Type*)data; \ 99212aba6189d7aaac0bab169b77ae6bdab16800a5Behdad Esfahbod } 100212aba6189d7aaac0bab169b77ae6bdab16800a5Behdad Esfahbod/* Like get_for_data(), but checks major version first. */ 101cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod#define STATIC_DEFINE_GET_FOR_DATA_CHECK_MAJOR_VERSION(Type, MajorMin, MajorMax) \ 102212aba6189d7aaac0bab169b77ae6bdab16800a5Behdad Esfahbod static inline const Type& get_for_data (const char *data) \ 103212aba6189d7aaac0bab169b77ae6bdab16800a5Behdad Esfahbod { \ 104212aba6189d7aaac0bab169b77ae6bdab16800a5Behdad Esfahbod if (HB_UNLIKELY (data == NULL)) return Null(Type); \ 1054497af0069a94c69fc1518b1db2c1282721b732aBehdad Esfahbod const Type& t = *(const Type*)data; \ 106cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod if (HB_UNLIKELY (t.version.major < MajorMin || t.version.major > MajorMax)) return Null(Type); \ 107212aba6189d7aaac0bab169b77ae6bdab16800a5Behdad Esfahbod return t; \ 108212aba6189d7aaac0bab169b77ae6bdab16800a5Behdad Esfahbod } 109600e5eb80f553ea8eb862e6784133574c74ca513Behdad Esfahbod 110600e5eb80f553ea8eb862e6784133574c74ca513Behdad Esfahbod 111577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod/* 112577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod * Sanitize 113577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod */ 114577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod 1159b76a290a94f2603f3cb9498ae976125347cf54bBehdad Esfahbod#if HB_DEBUG 116b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod#define SANITIZE_DEBUG_ARG_DEF , unsigned int sanitize_depth 117b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod#define SANITIZE_DEBUG_ARG , sanitize_depth + 1 1189b76a290a94f2603f3cb9498ae976125347cf54bBehdad Esfahbod#define SANITIZE_DEBUG_ARG_INIT , 1 119b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod#define SANITIZE_DEBUG() \ 120b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod HB_STMT_START { \ 1219b76a290a94f2603f3cb9498ae976125347cf54bBehdad Esfahbod if (sanitize_depth < HB_DEBUG) \ 1227acb389569cf99c6bae9db31a8ed7c7007fbb566Behdad Esfahbod fprintf (stderr, "SANITIZE(%p) %-*d-> %s\n", \ 1237acb389569cf99c6bae9db31a8ed7c7007fbb566Behdad Esfahbod (CONST_CHARP (this) == NullPool) ? 0 : this, \ 1249b76a290a94f2603f3cb9498ae976125347cf54bBehdad Esfahbod sanitize_depth, sanitize_depth, \ 1257acb389569cf99c6bae9db31a8ed7c7007fbb566Behdad Esfahbod __PRETTY_FUNCTION__); \ 126b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod } HB_STMT_END 127b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod#else 128b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod#define SANITIZE_DEBUG_ARG_DEF 129b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod#define SANITIZE_DEBUG_ARG 130b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod#define SANITIZE_DEBUG_ARG_INIT 131b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod#define SANITIZE_DEBUG() HB_STMT_START {} HB_STMT_END 132b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod#endif 133b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod 134577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbodtypedef struct _hb_sanitize_context_t hb_sanitize_context_t; 135577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbodstruct _hb_sanitize_context_t 136577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod{ 137577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod const char *start, *end; 138577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod int edit_count; 139577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod hb_blob_t *blob; 140577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod}; 141577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod 142577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbodstatic HB_GNUC_UNUSED void 1434e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod_hb_sanitize_init (hb_sanitize_context_t *context, 1444e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod hb_blob_t *blob) 145577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod{ 146577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod context->blob = blob; 147577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod context->start = hb_blob_lock (blob); 148577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod context->end = context->start + hb_blob_get_length (blob); 149577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod context->edit_count = 0; 1504f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod 1514f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod#if HB_DEBUG 1527acb389569cf99c6bae9db31a8ed7c7007fbb566Behdad Esfahbod fprintf (stderr, "sanitize %p init [%p..%p] (%u bytes)\n", 1537f96b39a9d5a81ba77e0c3dea8fe2cdb9957c4c7Behdad Esfahbod context->blob, context->start, context->end, context->end - context->start); 1544f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod#endif 155577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod} 156577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod 157577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbodstatic HB_GNUC_UNUSED void 1584e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod_hb_sanitize_fini (hb_sanitize_context_t *context, 1594e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod bool unlock) 160577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod{ 1614f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod#if HB_DEBUG 1627acb389569cf99c6bae9db31a8ed7c7007fbb566Behdad Esfahbod fprintf (stderr, "sanitize %p fini [%p..%p] %u edit requests\n", 1637acb389569cf99c6bae9db31a8ed7c7007fbb566Behdad Esfahbod context->blob, context->start, context->end, context->edit_count); 1644f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod#endif 1654f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod 166577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod if (unlock) 167577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod hb_blob_unlock (context->blob); 168577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod} 169577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod 1704f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbodstatic HB_GNUC_UNUSED inline bool 1714f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod_hb_sanitize_edit (hb_sanitize_context_t *context, 1724f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod const char *base HB_GNUC_UNUSED, 1734f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod unsigned int len HB_GNUC_UNUSED) 174577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod{ 1754f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod bool perm = hb_blob_try_writeable_inplace (context->blob); 176f4b58d3fc2956a9d1b6178588d809c781f7a5c0cBehdad Esfahbod context->edit_count++; 1774f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod 1784f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod#if HB_DEBUG 1797acb389569cf99c6bae9db31a8ed7c7007fbb566Behdad Esfahbod fprintf (stderr, "sanitize %p edit %u requested for [%p..%p] (%d bytes) in [%p..%p] -> %s\n", 1807acb389569cf99c6bae9db31a8ed7c7007fbb566Behdad Esfahbod context->blob, 1814f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod context->edit_count, 1824f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod base, base+len, len, 1834f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod context->start, context->end, 1844f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod perm ? "granted" : "rejected"); 1854f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod#endif 1864f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod return perm; 187577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod} 188577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod 189577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod#define SANITIZE_ARG_DEF \ 190b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod hb_sanitize_context_t *context SANITIZE_DEBUG_ARG_DEF 191577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod#define SANITIZE_ARG \ 192b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod context SANITIZE_DEBUG_ARG 193b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod#define SANITIZE_ARG_INIT \ 194b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod &context SANITIZE_DEBUG_ARG_INIT 195577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod 196577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod#define SANITIZE(X) HB_LIKELY ((X).sanitize (SANITIZE_ARG)) 197577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod#define SANITIZE2(X,Y) (SANITIZE (X) && SANITIZE (Y)) 198577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod 199577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod#define SANITIZE_THIS(X) HB_LIKELY ((X).sanitize (SANITIZE_ARG, CONST_CHARP(this))) 200577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod#define SANITIZE_THIS2(X,Y) (SANITIZE_THIS (X) && SANITIZE_THIS (Y)) 201577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod#define SANITIZE_THIS3(X,Y,Z) (SANITIZE_THIS (X) && SANITIZE_THIS (Y) && SANITIZE_THIS(Z)) 202577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod 203577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod#define SANITIZE_BASE(X,B) HB_LIKELY ((X).sanitize (SANITIZE_ARG, B)) 204577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod#define SANITIZE_BASE2(X,Y,B) (SANITIZE_BASE (X,B) && SANITIZE_BASE (Y,B)) 205577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod 206577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod#define SANITIZE_SELF() SANITIZE_OBJ (*this) 207577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod#define SANITIZE_OBJ(X) SANITIZE_MEM(&(X), sizeof (X)) 208577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod#define SANITIZE_GET_SIZE() SANITIZE_SELF() && SANITIZE_MEM (this, this->get_size ()) 209577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod 210d0b657379bbe63602953412d6bc944b2a0f430ebBehdad Esfahbod/* TODO Optimize this if L is fixed (gcc magic) */ 211d0b657379bbe63602953412d6bc944b2a0f430ebBehdad Esfahbod#define SANITIZE_MEM(B,L) \ 212d0b657379bbe63602953412d6bc944b2a0f430ebBehdad Esfahbod HB_LIKELY (context->start <= CONST_CHARP(B) && \ 213d0b657379bbe63602953412d6bc944b2a0f430ebBehdad Esfahbod CONST_CHARP(B) < context->end && \ 2147f96b39a9d5a81ba77e0c3dea8fe2cdb9957c4c7Behdad Esfahbod context->end - CONST_CHARP(B) >= (L)) 215577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod 216d0b657379bbe63602953412d6bc944b2a0f430ebBehdad Esfahbod#define NEUTER(Var, Val) \ 217d0b657379bbe63602953412d6bc944b2a0f430ebBehdad Esfahbod (SANITIZE_OBJ (Var) && \ 218d0b657379bbe63602953412d6bc944b2a0f430ebBehdad Esfahbod _hb_sanitize_edit (context, CONST_CHARP(&(Var)), sizeof (Var)) && \ 219d0b657379bbe63602953412d6bc944b2a0f430ebBehdad Esfahbod ((Var) = (Val), true)) 220577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod 221577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod 2224e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod/* Template to sanitize an object. */ 2234e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbodtemplate <typename Type> 2244e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbodstruct Sanitizer 2254e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod{ 2264e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod static hb_blob_t *sanitize (hb_blob_t *blob) { 2274e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod hb_sanitize_context_t context; 2284e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod bool sane; 2294e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod 230d0b657379bbe63602953412d6bc944b2a0f430ebBehdad Esfahbod /* TODO is_sane() stuff */ 2314e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod 2324e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod retry: 2334f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod#if HB_DEBUG 2347acb389569cf99c6bae9db31a8ed7c7007fbb566Behdad Esfahbod fprintf (stderr, "Sanitizer %p start %s\n", blob, __PRETTY_FUNCTION__); 2354f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod#endif 2364f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod 2374e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod _hb_sanitize_init (&context, blob); 2384e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod 2398cd6fa28d1b77100491519b8dedb2e113508bf59Behdad Esfahbod Type *t = &CAST (Type, *DECONST_CHARP(context.start), 0); 2404e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod 241b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod sane = t->sanitize (SANITIZE_ARG_INIT); 2424e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod if (sane) { 2434e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod if (context.edit_count) { 2440d77ab8a73f57c9fca4c6f9301dae394d79526e3Behdad Esfahbod#if HB_DEBUG 2450d77ab8a73f57c9fca4c6f9301dae394d79526e3Behdad Esfahbod fprintf (stderr, "Sanitizer %p passed first round with %d edits; going a second round %s\n", 2460d77ab8a73f57c9fca4c6f9301dae394d79526e3Behdad Esfahbod blob, context.edit_count, __PRETTY_FUNCTION__); 2470d77ab8a73f57c9fca4c6f9301dae394d79526e3Behdad Esfahbod#endif 2484e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod /* sanitize again to ensure not toe-stepping */ 2494e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod context.edit_count = 0; 250b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod sane = t->sanitize (SANITIZE_ARG_INIT); 2514e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod if (context.edit_count) { 2520d77ab8a73f57c9fca4c6f9301dae394d79526e3Behdad Esfahbod#if HB_DEBUG 2530d77ab8a73f57c9fca4c6f9301dae394d79526e3Behdad Esfahbod fprintf (stderr, "Sanitizer %p requested %d edits in second round; failing %s\n", 2540d77ab8a73f57c9fca4c6f9301dae394d79526e3Behdad Esfahbod blob, context.edit_count, __PRETTY_FUNCTION__); 2550d77ab8a73f57c9fca4c6f9301dae394d79526e3Behdad Esfahbod#endif 2564e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod sane = false; 2574e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod } 2584e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod } 2594e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod _hb_sanitize_fini (&context, true); 2604e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod } else { 2614f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod unsigned int edit_count = context.edit_count; 2624e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod _hb_sanitize_fini (&context, true); 2634f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod if (edit_count && !hb_blob_is_writeable (blob) && hb_blob_try_writeable (blob)) { 2644e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod /* ok, we made it writeable by relocating. try again */ 2654f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod#if HB_DEBUG 2667acb389569cf99c6bae9db31a8ed7c7007fbb566Behdad Esfahbod fprintf (stderr, "Sanitizer %p retry %s\n", blob, __PRETTY_FUNCTION__); 2674f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod#endif 2684e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod goto retry; 2694e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod } 2704e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod } 2714e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod 2724f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod#if HB_DEBUG 2737acb389569cf99c6bae9db31a8ed7c7007fbb566Behdad Esfahbod fprintf (stderr, "Sanitizer %p %s %s\n", blob, sane ? "passed" : "failed", __PRETTY_FUNCTION__); 2744f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod#endif 2754e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod if (sane) 2764e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod return blob; 2774e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod else { 2784e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod hb_blob_destroy (blob); 2794e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod return hb_blob_create_empty (); 2804e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod } 2814e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod } 2824e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod 283d60bb8ca2ae6edf29b2227b56c57f0d16879370bBehdad Esfahbod static const Type& lock_instance (hb_blob_t *blob) { 2844e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod return Type::get_for_data (hb_blob_lock (blob)); 2854e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod } 2864e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod}; 2874e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod 2882d15e72c75931398db5e027e660f1320bb979117Behdad Esfahbod 289b6e62bc5db76ae342177b2b646c37f45eccad975Behdad Esfahbod/* 290b6e62bc5db76ae342177b2b646c37f45eccad975Behdad Esfahbod * 291bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod * The OpenType Font File: Data Types 292b6e62bc5db76ae342177b2b646c37f45eccad975Behdad Esfahbod */ 293b6e62bc5db76ae342177b2b646c37f45eccad975Behdad Esfahbod 294b6e62bc5db76ae342177b2b646c37f45eccad975Behdad Esfahbod 295b6e62bc5db76ae342177b2b646c37f45eccad975Behdad Esfahbod/* "The following data types are used in the OpenType font file. 296b6e62bc5db76ae342177b2b646c37f45eccad975Behdad Esfahbod * All OpenType fonts use Motorola-style byte ordering (Big Endian):" */ 297b6e62bc5db76ae342177b2b646c37f45eccad975Behdad Esfahbod 2985f810363acc3ad3cba631a68620e3d37e54c95c4Behdad Esfahbod/* 2995f810363acc3ad3cba631a68620e3d37e54c95c4Behdad Esfahbod * Int types 3005f810363acc3ad3cba631a68620e3d37e54c95c4Behdad Esfahbod */ 3015f810363acc3ad3cba631a68620e3d37e54c95c4Behdad Esfahbod 3029e826ea2832f0444bcef9075b445d481a58a09c2Behdad Esfahbod/* TODO On machines that allow unaligned access, use this version. */ 3039e826ea2832f0444bcef9075b445d481a58a09c2Behdad Esfahbod#define _DEFINE_INT_TYPE1_UNALIGNED(NAME, TYPE, BIG_ENDIAN, BYTES) \ 30460d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod struct NAME \ 30560d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { \ 30620cc86b3592db33731de671f008d7d222776be49Behdad Esfahbod inline NAME& operator = (TYPE i) { (TYPE&) v = BIG_ENDIAN (i); return *this; } \ 30720cc86b3592db33731de671f008d7d222776be49Behdad Esfahbod inline operator TYPE(void) const { return BIG_ENDIAN ((TYPE&) v); } \ 30820cc86b3592db33731de671f008d7d222776be49Behdad Esfahbod inline bool operator== (NAME o) const { return (TYPE&) v == (TYPE&) o.v; } \ 309b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod inline bool sanitize (SANITIZE_ARG_DEF) { \ 310b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod SANITIZE_DEBUG (); \ 311b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod return SANITIZE_SELF (); \ 312b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod } \ 3139e826ea2832f0444bcef9075b445d481a58a09c2Behdad Esfahbod private: unsigned char v[BYTES]; \ 3149e826ea2832f0444bcef9075b445d481a58a09c2Behdad Esfahbod }; \ 3159e826ea2832f0444bcef9075b445d481a58a09c2Behdad Esfahbod ASSERT_SIZE (NAME, BYTES) 3169e826ea2832f0444bcef9075b445d481a58a09c2Behdad Esfahbod 3179e826ea2832f0444bcef9075b445d481a58a09c2Behdad Esfahbod#define DEFINE_INT_TYPE1(NAME, TYPE, BIG_ENDIAN, BYTES) \ 3189e826ea2832f0444bcef9075b445d481a58a09c2Behdad Esfahbod struct NAME \ 3199e826ea2832f0444bcef9075b445d481a58a09c2Behdad Esfahbod { \ 3209e826ea2832f0444bcef9075b445d481a58a09c2Behdad Esfahbod inline NAME& operator = (TYPE i) { BIG_ENDIAN##_put_unaligned(v, i); return *this; } \ 3219e826ea2832f0444bcef9075b445d481a58a09c2Behdad Esfahbod inline operator TYPE(void) const { return BIG_ENDIAN##_get_unaligned (v); } \ 3229e826ea2832f0444bcef9075b445d481a58a09c2Behdad Esfahbod inline bool operator== (NAME o) const { return BIG_ENDIAN##_cmp_unaligned (v, o.v); } \ 3239e826ea2832f0444bcef9075b445d481a58a09c2Behdad Esfahbod inline bool sanitize (SANITIZE_ARG_DEF) { \ 3249e826ea2832f0444bcef9075b445d481a58a09c2Behdad Esfahbod SANITIZE_DEBUG (); \ 3259e826ea2832f0444bcef9075b445d481a58a09c2Behdad Esfahbod return SANITIZE_SELF (); \ 3269e826ea2832f0444bcef9075b445d481a58a09c2Behdad Esfahbod } \ 3279e826ea2832f0444bcef9075b445d481a58a09c2Behdad Esfahbod private: unsigned char v[BYTES]; \ 3285f810363acc3ad3cba631a68620e3d37e54c95c4Behdad Esfahbod }; \ 32920cc86b3592db33731de671f008d7d222776be49Behdad Esfahbod ASSERT_SIZE (NAME, BYTES) 330df66028781a7609a515980e64396e6f1044d764aBehdad Esfahbod#define DEFINE_INT_TYPE0(NAME, type, b) DEFINE_INT_TYPE1 (NAME, type##_t, hb_be_##type, b) 331df66028781a7609a515980e64396e6f1044d764aBehdad Esfahbod#define DEFINE_INT_TYPE(NAME, u, w) DEFINE_INT_TYPE0 (NAME, u##int##w, (w / 8)) 3325f810363acc3ad3cba631a68620e3d37e54c95c4Behdad Esfahbod 333b6e62bc5db76ae342177b2b646c37f45eccad975Behdad Esfahbod 33420cc86b3592db33731de671f008d7d222776be49Behdad EsfahbodDEFINE_INT_TYPE (USHORT, u, 16); /* 16-bit unsigned integer. */ 33520cc86b3592db33731de671f008d7d222776be49Behdad EsfahbodDEFINE_INT_TYPE (SHORT, , 16); /* 16-bit signed integer. */ 33620cc86b3592db33731de671f008d7d222776be49Behdad EsfahbodDEFINE_INT_TYPE (ULONG, u, 32); /* 32-bit unsigned integer. */ 33720cc86b3592db33731de671f008d7d222776be49Behdad EsfahbodDEFINE_INT_TYPE (LONG, , 32); /* 32-bit signed integer. */ 3386b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod 339bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod 3406b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod/* Array of four uint8s (length = 32 bits) used to identify a script, language 3416b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod * system, feature, or baseline */ 34220cc86b3592db33731de671f008d7d222776be49Behdad Esfahbodstruct Tag : ULONG 34360d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 3444497af0069a94c69fc1518b1db2c1282721b732aBehdad Esfahbod inline Tag (const Tag &o) { *(ULONG*)this = (ULONG&) o; } 3454497af0069a94c69fc1518b1db2c1282721b732aBehdad Esfahbod inline Tag (uint32_t i) { *(ULONG*)this = i; } 3464497af0069a94c69fc1518b1db2c1282721b732aBehdad Esfahbod inline Tag (const char *c) { *(ULONG*)this = *(ULONG*)c; } 3474497af0069a94c69fc1518b1db2c1282721b732aBehdad Esfahbod inline bool operator== (const char *c) const { return *(ULONG*)this == *(ULONG*)c; } 348befc022affd2386b3f46cd7d11e4262f6c8bce9fBehdad Esfahbod /* What the char* converters return is NOT nul-terminated. Print using "%.4s" */ 3492b5a59c277f4c5bf7aac9a9005054763e322e02dBehdad Esfahbod inline operator const char* (void) const { return CONST_CHARP(this); } 3502b5a59c277f4c5bf7aac9a9005054763e322e02dBehdad Esfahbod inline operator char* (void) { return CHARP(this); } 351738c54d9caa3affc4b434e56bfb810ff6dc9b0b3Behdad Esfahbod 352738c54d9caa3affc4b434e56bfb810ff6dc9b0b3Behdad Esfahbod inline bool sanitize (SANITIZE_ARG_DEF) { 353b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod SANITIZE_DEBUG (); 354738c54d9caa3affc4b434e56bfb810ff6dc9b0b3Behdad Esfahbod /* Note: Only accept ASCII-visible tags (mind DEL) 355738c54d9caa3affc4b434e56bfb810ff6dc9b0b3Behdad Esfahbod * This is one of the few times (only time?) we check 356738c54d9caa3affc4b434e56bfb810ff6dc9b0b3Behdad Esfahbod * for data integrity, as opposed o just boundary checks 357738c54d9caa3affc4b434e56bfb810ff6dc9b0b3Behdad Esfahbod */ 358738c54d9caa3affc4b434e56bfb810ff6dc9b0b3Behdad Esfahbod return SANITIZE_SELF () && (((uint32_t) *this) & 0x80808080) == 0; 359738c54d9caa3affc4b434e56bfb810ff6dc9b0b3Behdad Esfahbod } 3606b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod}; 361303fe62824d4e99df554b6bfaacba05d068522fbBehdad EsfahbodASSERT_SIZE (Tag, 4); 362da1097bc3b1995776c205707fd2b17603b804646Behdad Esfahbod#define _NULL_TAG_INIT {' ', ' ', ' ', ' '} 363da1097bc3b1995776c205707fd2b17603b804646Behdad EsfahbodDEFINE_NULL_DATA (Tag, 4, _NULL_TAG_INIT); 364da1097bc3b1995776c205707fd2b17603b804646Behdad Esfahbod#undef _NULL_TAG_INIT 3656b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod 3666b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod/* Glyph index number, same as uint16 (length = 16 bits) */ 3676ad8d5f3c7028147b371137ae4bca6aae66b3489Behdad Esfahbodtypedef USHORT GlyphID; 3686b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod 3691f437e6f47fb6c15761021bd2078f31778f2179cBehdad Esfahbod/* Offset to a table, same as uint16 (length = 16 bits), Null offset = 0x0000 */ 3706ad8d5f3c7028147b371137ae4bca6aae66b3489Behdad Esfahbodtypedef USHORT Offset; 3716ad8d5f3c7028147b371137ae4bca6aae66b3489Behdad Esfahbod 3726ad8d5f3c7028147b371137ae4bca6aae66b3489Behdad Esfahbod/* LongOffset to a table, same as uint32 (length = 32 bits), Null offset = 0x00000000 */ 3736ad8d5f3c7028147b371137ae4bca6aae66b3489Behdad Esfahbodtypedef ULONG LongOffset; 3746ad8d5f3c7028147b371137ae4bca6aae66b3489Behdad Esfahbod 3756b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod 3766b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod/* CheckSum */ 37760d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct CheckSum : ULONG 37860d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 37960d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod static uint32_t CalcTableChecksum (ULONG *Table, uint32_t Length) 38060d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 3816b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod uint32_t Sum = 0L; 38201e4fcb032be601f272e62228881e2aabfb9d925Behdad Esfahbod ULONG *EndPtr = Table+((Length+3) & ~3) / sizeof(ULONG); 3836b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod 3846b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod while (Table < EndPtr) 3856b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod Sum += *Table++; 3866b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod return Sum; 3876b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod } 3886b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod}; 3898b8358033184198ff638ee1379093717596e162dBehdad EsfahbodASSERT_SIZE (CheckSum, 4); 3906b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod 3916b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod 3926b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod/* 3936b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod * Version Numbers 3946b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod */ 3956b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod 39687fcdcbe3644da10154688765db2d62eb9ac079aBehdad Esfahbodstruct FixedVersion 39760d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 39809c292e3b688a67fbae67b645d1e6ffcf8d8eb6eBehdad Esfahbod inline operator uint32_t (void) const { return (major << 16) + minor; } 39996908b898476ca5d7da5f386b15be76f9e83d76eBehdad Esfahbod 400cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod inline bool sanitize (SANITIZE_ARG_DEF) { 401b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod SANITIZE_DEBUG (); 402cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod return SANITIZE_SELF (); 403cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod } 404cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod 4056ad8d5f3c7028147b371137ae4bca6aae66b3489Behdad Esfahbod USHORT major; 40687fcdcbe3644da10154688765db2d62eb9ac079aBehdad Esfahbod USHORT minor; 4076b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod}; 40887fcdcbe3644da10154688765db2d62eb9ac079aBehdad EsfahbodASSERT_SIZE (FixedVersion, 4); 4096b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod 41092b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod 41192b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod 4125f810363acc3ad3cba631a68620e3d37e54c95c4Behdad Esfahbod/* 41392b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod * Template subclasses of Offset and LongOffset that do the dereferencing. 41492b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod * Use: (this+memberName) 4155f810363acc3ad3cba631a68620e3d37e54c95c4Behdad Esfahbod */ 4165f810363acc3ad3cba631a68620e3d37e54c95c4Behdad Esfahbod 41792b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbodtemplate <typename OffsetType, typename Type> 41892b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbodstruct GenericOffsetTo : OffsetType 41992b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod{ 42092b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod inline const Type& operator() (const void *base) const 42192b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod { 42292b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod unsigned int offset = *this; 42392b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod if (HB_UNLIKELY (!offset)) return Null(Type); 42495639fccc1ef18eadeb737e8b611d1d1f1315fc2Behdad Esfahbod return CONST_CAST(Type, *CONST_CHARP(base), offset); 42592b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod } 42692b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod 42720b035dad41247076815a2bbb0346d63058b322fBehdad Esfahbod inline bool sanitize (SANITIZE_ARG_DEF, const void *base) { 428b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod SANITIZE_DEBUG (); 42992b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod if (!SANITIZE_OBJ (*this)) return false; 43092b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod unsigned int offset = *this; 43192b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod if (HB_UNLIKELY (!offset)) return true; 432ac26e2a838d1266bb5f39c43245eb2a52c5e072dBehdad Esfahbod return SANITIZE (CAST(Type, *DECONST_CHARP(base), offset)) || NEUTER (DECONST_CAST(OffsetType,*this,0), 0); 43392b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod } 43420b035dad41247076815a2bbb0346d63058b322fBehdad Esfahbod inline bool sanitize (SANITIZE_ARG_DEF, const void *base, const void *base2) { 435b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod SANITIZE_DEBUG (); 436b508e5ccd528f3f0f49f545bd5f30a525d5abd5aBehdad Esfahbod if (!SANITIZE_OBJ (*this)) return false; 437b508e5ccd528f3f0f49f545bd5f30a525d5abd5aBehdad Esfahbod unsigned int offset = *this; 438b508e5ccd528f3f0f49f545bd5f30a525d5abd5aBehdad Esfahbod if (HB_UNLIKELY (!offset)) return true; 439b508e5ccd528f3f0f49f545bd5f30a525d5abd5aBehdad Esfahbod return SANITIZE_BASE (CAST(Type, *DECONST_CHARP(base), offset), base2) || NEUTER (DECONST_CAST(OffsetType,*this,0), 0); 440b508e5ccd528f3f0f49f545bd5f30a525d5abd5aBehdad Esfahbod } 44120b035dad41247076815a2bbb0346d63058b322fBehdad Esfahbod inline bool sanitize (SANITIZE_ARG_DEF, const void *base, unsigned int user_data) { 442b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod SANITIZE_DEBUG (); 44342b778f89e0818fe06910ce04e2203485823da09Behdad Esfahbod if (!SANITIZE_OBJ (*this)) return false; 44442b778f89e0818fe06910ce04e2203485823da09Behdad Esfahbod unsigned int offset = *this; 44542b778f89e0818fe06910ce04e2203485823da09Behdad Esfahbod if (HB_UNLIKELY (!offset)) return true; 446ac26e2a838d1266bb5f39c43245eb2a52c5e072dBehdad Esfahbod return SANITIZE_BASE (CAST(Type, *DECONST_CHARP(base), offset), user_data) || NEUTER (DECONST_CAST(OffsetType,*this,0), 0); 44742b778f89e0818fe06910ce04e2203485823da09Behdad Esfahbod } 44892b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod}; 44992b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbodtemplate <typename Base, typename OffsetType, typename Type> 45092b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbodinline const Type& operator + (const Base &base, GenericOffsetTo<OffsetType, Type> offset) { return offset (base); } 45192b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod 4525f810363acc3ad3cba631a68620e3d37e54c95c4Behdad Esfahbodtemplate <typename Type> 45392b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbodstruct OffsetTo : GenericOffsetTo<Offset, Type> {}; 45492b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod 45592b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbodtemplate <typename Type> 45692b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbodstruct LongOffsetTo : GenericOffsetTo<LongOffset, Type> {}; 457bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod 458bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod 45992b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod/* 46092b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod * Array Types 46192b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod */ 46292b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod 46392b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbodtemplate <typename LenType, typename Type> 46492b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbodstruct GenericArrayOf 46560d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 46660d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod inline const Type& operator [] (unsigned int i) const 46760d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 4685f810363acc3ad3cba631a68620e3d37e54c95c4Behdad Esfahbod if (HB_UNLIKELY (i >= len)) return Null(Type); 4695f810363acc3ad3cba631a68620e3d37e54c95c4Behdad Esfahbod return array[i]; 4705f810363acc3ad3cba631a68620e3d37e54c95c4Behdad Esfahbod } 47160d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod inline unsigned int get_size () const 47279420ad9caf2d5fc94c3693e8292edfa27060b2dBehdad Esfahbod { return sizeof (len) + len * sizeof (array[0]); } 473e8cbaaf6d538036ff9b880b018db402e0895ed01Behdad Esfahbod 47420b035dad41247076815a2bbb0346d63058b322fBehdad Esfahbod inline bool sanitize (SANITIZE_ARG_DEF) { 475b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod SANITIZE_DEBUG (); 476dc9c4d93cd0f3ac991f32df08c1c17fc389054c0Behdad Esfahbod if (!SANITIZE_GET_SIZE()) return false; 477a97ce570ab693190350886e4e80942851c4d5727Behdad Esfahbod /* Note; for non-recursive types, this is not much needed 47870de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod unsigned int count = len; 47970de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 48070de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod if (!SANITIZE (array[i])) 48170de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod return false; 482a97ce570ab693190350886e4e80942851c4d5727Behdad Esfahbod */ 4839bd629ccd064e739789e504c41ad875eed93abbaBehdad Esfahbod return true; 48470de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 48520b035dad41247076815a2bbb0346d63058b322fBehdad Esfahbod inline bool sanitize (SANITIZE_ARG_DEF, const void *base) { 486b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod SANITIZE_DEBUG (); 487dc9c4d93cd0f3ac991f32df08c1c17fc389054c0Behdad Esfahbod if (!SANITIZE_GET_SIZE()) return false; 488e6ab2c59ba2d37942ac5fcbfe61d38b7e359ac8cBehdad Esfahbod unsigned int count = len; 489e6ab2c59ba2d37942ac5fcbfe61d38b7e359ac8cBehdad Esfahbod for (unsigned int i = 0; i < count; i++) 49095639fccc1ef18eadeb737e8b611d1d1f1315fc2Behdad Esfahbod if (!array[i].sanitize (SANITIZE_ARG, base)) 491e6ab2c59ba2d37942ac5fcbfe61d38b7e359ac8cBehdad Esfahbod return false; 4929bd629ccd064e739789e504c41ad875eed93abbaBehdad Esfahbod return true; 493e6ab2c59ba2d37942ac5fcbfe61d38b7e359ac8cBehdad Esfahbod } 49420b035dad41247076815a2bbb0346d63058b322fBehdad Esfahbod inline bool sanitize (SANITIZE_ARG_DEF, const void *base, const void *base2) { 495b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod SANITIZE_DEBUG (); 496b508e5ccd528f3f0f49f545bd5f30a525d5abd5aBehdad Esfahbod if (!SANITIZE_GET_SIZE()) return false; 497b508e5ccd528f3f0f49f545bd5f30a525d5abd5aBehdad Esfahbod unsigned int count = len; 498b508e5ccd528f3f0f49f545bd5f30a525d5abd5aBehdad Esfahbod for (unsigned int i = 0; i < count; i++) 499b508e5ccd528f3f0f49f545bd5f30a525d5abd5aBehdad Esfahbod if (!array[i].sanitize (SANITIZE_ARG, base, base2)) 500b508e5ccd528f3f0f49f545bd5f30a525d5abd5aBehdad Esfahbod return false; 5019bd629ccd064e739789e504c41ad875eed93abbaBehdad Esfahbod return true; 502b508e5ccd528f3f0f49f545bd5f30a525d5abd5aBehdad Esfahbod } 50320b035dad41247076815a2bbb0346d63058b322fBehdad Esfahbod inline bool sanitize (SANITIZE_ARG_DEF, const void *base, unsigned int user_data) { 504b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod SANITIZE_DEBUG (); 50542b778f89e0818fe06910ce04e2203485823da09Behdad Esfahbod if (!SANITIZE_GET_SIZE()) return false; 50642b778f89e0818fe06910ce04e2203485823da09Behdad Esfahbod unsigned int count = len; 50742b778f89e0818fe06910ce04e2203485823da09Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 50842b778f89e0818fe06910ce04e2203485823da09Behdad Esfahbod if (!array[i].sanitize (SANITIZE_ARG, base, user_data)) 50942b778f89e0818fe06910ce04e2203485823da09Behdad Esfahbod return false; 5109bd629ccd064e739789e504c41ad875eed93abbaBehdad Esfahbod return true; 51142b778f89e0818fe06910ce04e2203485823da09Behdad Esfahbod } 51270de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 51392b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod LenType len; 514e8cbaaf6d538036ff9b880b018db402e0895ed01Behdad Esfahbod Type array[]; 515e8cbaaf6d538036ff9b880b018db402e0895ed01Behdad Esfahbod}; 516e8cbaaf6d538036ff9b880b018db402e0895ed01Behdad Esfahbod 51792b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod/* An array with a USHORT number of elements. */ 51892b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbodtemplate <typename Type> 51992b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbodstruct ArrayOf : GenericArrayOf<USHORT, Type> {}; 52092b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod 52192b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod/* An array with a ULONG number of elements. */ 52292b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbodtemplate <typename Type> 52392b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbodstruct LongArrayOf : GenericArrayOf<ULONG, Type> {}; 52492b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod 52592b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod/* Array of Offset's */ 52692b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbodtemplate <typename Type> 52792b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbodstruct OffsetArrayOf : ArrayOf<OffsetTo<Type> > {}; 52892b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod 52992b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod/* Array of LongOffset's */ 53092b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbodtemplate <typename Type> 53192b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbodstruct LongOffsetArrayOf : ArrayOf<LongOffsetTo<Type> > {}; 53292b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod 53392b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod/* LongArray of LongOffset's */ 53492b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbodtemplate <typename Type> 53592b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbodstruct LongOffsetLongArrayOf : LongArrayOf<LongOffsetTo<Type> > {}; 53692b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod 537e8cbaaf6d538036ff9b880b018db402e0895ed01Behdad Esfahbod/* An array with a USHORT number of elements, 538e8cbaaf6d538036ff9b880b018db402e0895ed01Behdad Esfahbod * starting at second element. */ 539e8cbaaf6d538036ff9b880b018db402e0895ed01Behdad Esfahbodtemplate <typename Type> 54060d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct HeadlessArrayOf 54160d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 54260d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod inline const Type& operator [] (unsigned int i) const 54360d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 544e8cbaaf6d538036ff9b880b018db402e0895ed01Behdad Esfahbod if (HB_UNLIKELY (i >= len || !i)) return Null(Type); 545e8cbaaf6d538036ff9b880b018db402e0895ed01Behdad Esfahbod return array[i-1]; 546e8cbaaf6d538036ff9b880b018db402e0895ed01Behdad Esfahbod } 54760d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod inline unsigned int get_size () const 54879420ad9caf2d5fc94c3693e8292edfa27060b2dBehdad Esfahbod { return sizeof (len) + (len ? len - 1 : 0) * sizeof (array[0]); } 5495f810363acc3ad3cba631a68620e3d37e54c95c4Behdad Esfahbod 55020b035dad41247076815a2bbb0346d63058b322fBehdad Esfahbod inline bool sanitize (SANITIZE_ARG_DEF) { 551b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod SANITIZE_DEBUG (); 552dc9c4d93cd0f3ac991f32df08c1c17fc389054c0Behdad Esfahbod if (!SANITIZE_GET_SIZE()) return false; 553a97ce570ab693190350886e4e80942851c4d5727Behdad Esfahbod /* Note; for non-recursive types, this is not much needed 55415164d9258a74122a4db748d35532bd72c47cec2Behdad Esfahbod unsigned int count = len ? len - 1 : 0; 55570de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 55670de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod if (!SANITIZE (array[i])) 55770de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod return false; 558a97ce570ab693190350886e4e80942851c4d5727Behdad Esfahbod */ 5599bd629ccd064e739789e504c41ad875eed93abbaBehdad Esfahbod return true; 56070de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 56170de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 5625f810363acc3ad3cba631a68620e3d37e54c95c4Behdad Esfahbod USHORT len; 5635f810363acc3ad3cba631a68620e3d37e54c95c4Behdad Esfahbod Type array[]; 5645f810363acc3ad3cba631a68620e3d37e54c95c4Behdad Esfahbod}; 5655f810363acc3ad3cba631a68620e3d37e54c95c4Behdad Esfahbod 5666b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod 5675f5b24f99f52bbc922e238b65c06061ba07c8548Behdad Esfahbod#endif /* HB_OPEN_TYPES_PRIVATE_HH */ 568