hb-open-type-private.hh revision 173fde7087c0db3e99409f1119530477c14072f5
164aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod/* 2f9b37727985191c9b4aedb0e9835736027e59260Behdad Esfahbod * Copyright (C) 2007,2008,2009,2010 Red Hat, Inc. 364aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * 4c755cb3e3ac55156d0d2ec05adea7a650b97cc41Behdad Esfahbod * This is part of HarfBuzz, a text shaping 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 35c85c3620675f38ffdca59134aeec2641485f40caBehdad Esfahbod/* Table/script/language-system/feature/... not found */ 36706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod#define NO_INDEX ((unsigned int) 0xFFFF) 375a0b791184cf6ef39eae0570e14aca21abc32845Behdad Esfahbod 38706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 39a3263aa773ad7a914496792466c69047048b093cBehdad Esfahbod 40196598bbccff08415ff5192314cba044df258cadBehdad Esfahbod/* 41196598bbccff08415ff5192314cba044df258cadBehdad Esfahbod * Casts 42196598bbccff08415ff5192314cba044df258cadBehdad Esfahbod */ 43196598bbccff08415ff5192314cba044df258cadBehdad Esfahbod 440dfcc13a4668cdd2c2ebdd5f4a7540a51222cf2fBehdad Esfahbod/* Cast to "const char *" and "char *" */ 45a3263aa773ad7a914496792466c69047048b093cBehdad Esfahbodtemplate <typename Type> 46a3263aa773ad7a914496792466c69047048b093cBehdad Esfahbodinline const char * CharP (const Type* X) 47a3263aa773ad7a914496792466c69047048b093cBehdad Esfahbod{ return reinterpret_cast<const char *>(X); } 48a3263aa773ad7a914496792466c69047048b093cBehdad Esfahbodtemplate <typename Type> 49a3263aa773ad7a914496792466c69047048b093cBehdad Esfahbodinline char * CharP (Type* X) 50a3263aa773ad7a914496792466c69047048b093cBehdad Esfahbod{ return reinterpret_cast<char *>(X); } 512b5a59c277f4c5bf7aac9a9005054763e322e02dBehdad Esfahbod 52187454c595559ce48d072fee6bccb51f3de283d4Behdad Esfahbod/* Cast to struct T, reference to reference */ 53a3263aa773ad7a914496792466c69047048b093cBehdad Esfahbodtemplate<typename Type, typename TObject> 54187454c595559ce48d072fee6bccb51f3de283d4Behdad Esfahbodinline const Type& CastR(const TObject &X) 55a3263aa773ad7a914496792466c69047048b093cBehdad Esfahbod{ return reinterpret_cast<const Type&> (X); } 56a3263aa773ad7a914496792466c69047048b093cBehdad Esfahbodtemplate<typename Type, typename TObject> 57187454c595559ce48d072fee6bccb51f3de283d4Behdad Esfahbodinline Type& CastR(TObject &X) 58a3263aa773ad7a914496792466c69047048b093cBehdad Esfahbod{ return reinterpret_cast<Type&> (X); } 59196598bbccff08415ff5192314cba044df258cadBehdad Esfahbod 60187454c595559ce48d072fee6bccb51f3de283d4Behdad Esfahbod/* Cast to struct T, pointer to pointer */ 61187454c595559ce48d072fee6bccb51f3de283d4Behdad Esfahbodtemplate<typename Type, typename TObject> 62187454c595559ce48d072fee6bccb51f3de283d4Behdad Esfahbodinline const Type* CastP(const TObject *X) 63187454c595559ce48d072fee6bccb51f3de283d4Behdad Esfahbod{ return reinterpret_cast<const Type*> (X); } 64187454c595559ce48d072fee6bccb51f3de283d4Behdad Esfahbodtemplate<typename Type, typename TObject> 65187454c595559ce48d072fee6bccb51f3de283d4Behdad Esfahbodinline Type* CastP(TObject *X) 66187454c595559ce48d072fee6bccb51f3de283d4Behdad Esfahbod{ return reinterpret_cast<Type*> (X); } 67187454c595559ce48d072fee6bccb51f3de283d4Behdad Esfahbod 68a3263aa773ad7a914496792466c69047048b093cBehdad Esfahbod/* StructAtOffset<T>(X,Ofs) returns the struct T& that is placed at memory 69a3263aa773ad7a914496792466c69047048b093cBehdad Esfahbod * location of X plus Ofs bytes. */ 70a3263aa773ad7a914496792466c69047048b093cBehdad Esfahbodtemplate<typename Type, typename TObject> 71a3263aa773ad7a914496792466c69047048b093cBehdad Esfahbodinline const Type& StructAtOffset(const TObject &X, unsigned int offset) 72d632ec4000b3079150e6424e88a3ab7509f7445cBehdad Esfahbod{ return * reinterpret_cast<const Type*> (CharP(&X) + offset); } 73a3263aa773ad7a914496792466c69047048b093cBehdad Esfahbodtemplate<typename Type, typename TObject> 74a3263aa773ad7a914496792466c69047048b093cBehdad Esfahbodinline Type& StructAtOffset(TObject &X, unsigned int offset) 75d632ec4000b3079150e6424e88a3ab7509f7445cBehdad Esfahbod{ return * reinterpret_cast<Type*> (CharP(&X) + offset); } 7670de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 772e2f43edf2f49f4047e28b1ce2ea95938536de9cBehdad Esfahbod/* StructAfter<T>(X) returns the struct T& that is placed after X. 7829c3f5e1b6212c775a7b911becd44ba093b7b0ebBehdad Esfahbod * Works with X of variable size also. X must implement get_size() */ 79e961c86c579fd98ee604342a9c70c4e7f8d4f220Behdad Esfahbodtemplate<typename Type, typename TObject> 80e961c86c579fd98ee604342a9c70c4e7f8d4f220Behdad Esfahbodinline const Type& StructAfter(const TObject &X) 81a3263aa773ad7a914496792466c69047048b093cBehdad Esfahbod{ return StructAtOffset<Type>(X, X.get_size()); } 82e961c86c579fd98ee604342a9c70c4e7f8d4f220Behdad Esfahbodtemplate<typename Type, typename TObject> 83e961c86c579fd98ee604342a9c70c4e7f8d4f220Behdad Esfahbodinline Type& StructAfter(TObject &X) 84a3263aa773ad7a914496792466c69047048b093cBehdad Esfahbod{ return StructAtOffset<Type>(X, X.get_size()); } 85a3263aa773ad7a914496792466c69047048b093cBehdad Esfahbod 86e961c86c579fd98ee604342a9c70c4e7f8d4f220Behdad Esfahbod 87d3480ba37fbb5d4be75b094060f5b2f1ce98fb53Behdad Esfahbod 8870de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod/* 89600e5eb80f553ea8eb862e6784133574c74ca513Behdad Esfahbod * Class features 90600e5eb80f553ea8eb862e6784133574c74ca513Behdad Esfahbod */ 91600e5eb80f553ea8eb862e6784133574c74ca513Behdad Esfahbod 928b8358033184198ff638ee1379093717596e162dBehdad Esfahbod 938b8358033184198ff638ee1379093717596e162dBehdad Esfahbod/* Null objects */ 948b8358033184198ff638ee1379093717596e162dBehdad Esfahbod 958b8358033184198ff638ee1379093717596e162dBehdad Esfahbod/* Global nul-content Null pool. Enlarge as necessary. */ 969d3677899f90abdc7fb3e3d854db654a8707a84bBehdad Esfahbodstatic const void *_NullPool[32 / sizeof (void *)]; 978b8358033184198ff638ee1379093717596e162dBehdad Esfahbod 988b8358033184198ff638ee1379093717596e162dBehdad Esfahbod/* Generic template for nul-content sizeof-sized Null objects. */ 998b8358033184198ff638ee1379093717596e162dBehdad Esfahbodtemplate <typename Type> 1009d3677899f90abdc7fb3e3d854db654a8707a84bBehdad Esfahbodstatic inline const Type& Null () { 1019d3677899f90abdc7fb3e3d854db654a8707a84bBehdad Esfahbod ASSERT_STATIC (sizeof (Type) <= sizeof (_NullPool)); 102187454c595559ce48d072fee6bccb51f3de283d4Behdad Esfahbod return *CastP<Type> (_NullPool); 1039d3677899f90abdc7fb3e3d854db654a8707a84bBehdad Esfahbod} 1048b8358033184198ff638ee1379093717596e162dBehdad Esfahbod 1058b8358033184198ff638ee1379093717596e162dBehdad Esfahbod/* Specializaiton for arbitrary-content arbitrary-sized Null objects. */ 1068b8358033184198ff638ee1379093717596e162dBehdad Esfahbod#define DEFINE_NULL_DATA(Type, size, data) \ 107565c80bd2960366ace2d10dd71beaaf2a80213c8Behdad Esfahbodstatic const char _Null##Type[size + 1] = data; /* +1 is for nul-termination in data */ \ 1088b8358033184198ff638ee1379093717596e162dBehdad Esfahbodtemplate <> \ 1099d3677899f90abdc7fb3e3d854db654a8707a84bBehdad Esfahbodinline const Type& Null<Type> () { \ 110187454c595559ce48d072fee6bccb51f3de283d4Behdad Esfahbod return *CastP<Type> (_Null##Type); \ 111565c80bd2960366ace2d10dd71beaaf2a80213c8Behdad Esfahbod} /* The following line really exists such that we end in a place needing semicolon */ \ 112565c80bd2960366ace2d10dd71beaaf2a80213c8Behdad EsfahbodASSERT_STATIC (sizeof (Type) + 1 <= sizeof (_Null##Type)) 1138b8358033184198ff638ee1379093717596e162dBehdad Esfahbod 1148b8358033184198ff638ee1379093717596e162dBehdad Esfahbod/* Accessor macro. */ 1159d3677899f90abdc7fb3e3d854db654a8707a84bBehdad Esfahbod#define Null(Type) Null<Type>() 1168b8358033184198ff638ee1379093717596e162dBehdad Esfahbod 1178b8358033184198ff638ee1379093717596e162dBehdad Esfahbod 118600e5eb80f553ea8eb862e6784133574c74ca513Behdad Esfahbod 119577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod/* 120577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod * Sanitize 121577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod */ 122577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod 12395e202403ffa543c817f45cca21fbc116eb8e807Behdad Esfahbod#ifndef HB_DEBUG_SANITIZE 124807c5b03a2251a3c29a520852639421783101b55Behdad Esfahbod#define HB_DEBUG_SANITIZE HB_DEBUG+0 12595e202403ffa543c817f45cca21fbc116eb8e807Behdad Esfahbod#endif 12695e202403ffa543c817f45cca21fbc116eb8e807Behdad Esfahbod 127bc200457430c083914a64bf4b056153506749610Behdad Esfahbod#define TRACE_SANITIZE() \ 128bc200457430c083914a64bf4b056153506749610Behdad Esfahbod HB_STMT_START { \ 129bc200457430c083914a64bf4b056153506749610Behdad Esfahbod if (HB_DEBUG_SANITIZE) \ 130bc200457430c083914a64bf4b056153506749610Behdad Esfahbod _hb_trace ("SANITIZE", __PRETTY_FUNCTION__, this, sanitize_depth, HB_DEBUG_SANITIZE); \ 131bc200457430c083914a64bf4b056153506749610Behdad Esfahbod } HB_STMT_END 132807c5b03a2251a3c29a520852639421783101b55Behdad Esfahbod 133b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod 13441895506cb6a41b1a833866f8822261ea449ea0bBehdad Esfahbod#define SANITIZE_ARG_DEF \ 135bc200457430c083914a64bf4b056153506749610Behdad Esfahbod hb_sanitize_context_t *context, \ 136bc200457430c083914a64bf4b056153506749610Behdad Esfahbod unsigned int sanitize_depth HB_GNUC_UNUSED 13741895506cb6a41b1a833866f8822261ea449ea0bBehdad Esfahbod#define SANITIZE_ARG \ 138bc200457430c083914a64bf4b056153506749610Behdad Esfahbod context, \ 139bc200457430c083914a64bf4b056153506749610Behdad Esfahbod (HB_DEBUG_SANITIZE ? sanitize_depth + 1 : 0) 140173fde7087c0db3e99409f1119530477c14072f5Behdad Esfahbod 14141895506cb6a41b1a833866f8822261ea449ea0bBehdad Esfahbod 142577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbodtypedef struct _hb_sanitize_context_t hb_sanitize_context_t; 143577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbodstruct _hb_sanitize_context_t 144577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod{ 145577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod const char *start, *end; 146254933c397f1ce9796f59689a25f9fc2e58df4eaBehdad Esfahbod hb_bool_t writable; 147254933c397f1ce9796f59689a25f9fc2e58df4eaBehdad Esfahbod unsigned int edit_count; 148577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod}; 149577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod 150577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbodstatic HB_GNUC_UNUSED void 1514e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod_hb_sanitize_init (hb_sanitize_context_t *context, 1524e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod hb_blob_t *blob) 153577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod{ 154577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod context->start = hb_blob_lock (blob); 155577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod context->end = context->start + hb_blob_get_length (blob); 156254933c397f1ce9796f59689a25f9fc2e58df4eaBehdad Esfahbod context->writable = hb_blob_is_writable (blob); 157577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod context->edit_count = 0; 1584f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod 15995e202403ffa543c817f45cca21fbc116eb8e807Behdad Esfahbod#if HB_DEBUG_SANITIZE 1607acb389569cf99c6bae9db31a8ed7c7007fbb566Behdad Esfahbod fprintf (stderr, "sanitize %p init [%p..%p] (%u bytes)\n", 161a92f0fda7fee9d60b399b8865541bf73e6e30141Behdad Esfahbod blob, context->start, context->end, context->end - context->start); 1624f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod#endif 163577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod} 164577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod 165577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbodstatic HB_GNUC_UNUSED void 1661d720192b193f48b44be0385eda3c2c5d5cd28adBehdad Esfahbod_hb_sanitize_fini (hb_sanitize_context_t *context HB_GNUC_UNUSED, 1678dfdca599c0a3ba5255131002910bca3b381acacBehdad Esfahbod hb_blob_t *blob) 168577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod{ 16995e202403ffa543c817f45cca21fbc116eb8e807Behdad Esfahbod#if HB_DEBUG_SANITIZE 1707acb389569cf99c6bae9db31a8ed7c7007fbb566Behdad Esfahbod fprintf (stderr, "sanitize %p fini [%p..%p] %u edit requests\n", 1718dfdca599c0a3ba5255131002910bca3b381acacBehdad Esfahbod blob, context->start, context->end, context->edit_count); 1724f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod#endif 1734f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod 1748dfdca599c0a3ba5255131002910bca3b381acacBehdad Esfahbod hb_blob_unlock (blob); 175577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod} 176577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod 1774f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbodstatic HB_GNUC_UNUSED inline bool 17841895506cb6a41b1a833866f8822261ea449ea0bBehdad Esfahbod_hb_sanitize_check (SANITIZE_ARG_DEF, 17941895506cb6a41b1a833866f8822261ea449ea0bBehdad Esfahbod const char *base, 18041895506cb6a41b1a833866f8822261ea449ea0bBehdad Esfahbod unsigned int len) 18141895506cb6a41b1a833866f8822261ea449ea0bBehdad Esfahbod{ 182ae728e51e94d18d731b7c8dc524da1a4f427d63bBehdad Esfahbod bool ret = context->start <= base && 183ae728e51e94d18d731b7c8dc524da1a4f427d63bBehdad Esfahbod base <= context->end && 184ae728e51e94d18d731b7c8dc524da1a4f427d63bBehdad Esfahbod (unsigned int) (context->end - base) >= len; 185ae728e51e94d18d731b7c8dc524da1a4f427d63bBehdad Esfahbod 18695e202403ffa543c817f45cca21fbc116eb8e807Behdad Esfahbod#if HB_DEBUG_SANITIZE 18795e202403ffa543c817f45cca21fbc116eb8e807Behdad Esfahbod if (sanitize_depth < HB_DEBUG_SANITIZE) \ 188ae728e51e94d18d731b7c8dc524da1a4f427d63bBehdad Esfahbod fprintf (stderr, "SANITIZE(%p) %-*d-> check [%p..%p] (%d bytes) in [%p..%p] -> %s\n", \ 189ae728e51e94d18d731b7c8dc524da1a4f427d63bBehdad Esfahbod base, 190ae728e51e94d18d731b7c8dc524da1a4f427d63bBehdad Esfahbod sanitize_depth, sanitize_depth, 191ae728e51e94d18d731b7c8dc524da1a4f427d63bBehdad Esfahbod base, base+len, len, 192ae728e51e94d18d731b7c8dc524da1a4f427d63bBehdad Esfahbod context->start, context->end, 193ae728e51e94d18d731b7c8dc524da1a4f427d63bBehdad Esfahbod ret ? "pass" : "FAIL"); 194ae728e51e94d18d731b7c8dc524da1a4f427d63bBehdad Esfahbod#endif 195ae728e51e94d18d731b7c8dc524da1a4f427d63bBehdad Esfahbod return ret; 19641895506cb6a41b1a833866f8822261ea449ea0bBehdad Esfahbod} 19741895506cb6a41b1a833866f8822261ea449ea0bBehdad Esfahbod 19841895506cb6a41b1a833866f8822261ea449ea0bBehdad Esfahbodstatic HB_GNUC_UNUSED inline bool 199815a73e4202ca17677f12e862b70ca8724cf2f57Behdad Esfahbod_hb_sanitize_array (SANITIZE_ARG_DEF, 200815a73e4202ca17677f12e862b70ca8724cf2f57Behdad Esfahbod const char *base, 201815a73e4202ca17677f12e862b70ca8724cf2f57Behdad Esfahbod unsigned int record_size, 202815a73e4202ca17677f12e862b70ca8724cf2f57Behdad Esfahbod unsigned int len) 203815a73e4202ca17677f12e862b70ca8724cf2f57Behdad Esfahbod{ 204815a73e4202ca17677f12e862b70ca8724cf2f57Behdad Esfahbod bool overflows = len >= ((unsigned int) -1) / record_size; 205815a73e4202ca17677f12e862b70ca8724cf2f57Behdad Esfahbod 20695e202403ffa543c817f45cca21fbc116eb8e807Behdad Esfahbod#if HB_DEBUG_SANITIZE 20795e202403ffa543c817f45cca21fbc116eb8e807Behdad Esfahbod if (sanitize_depth < HB_DEBUG_SANITIZE) \ 208815a73e4202ca17677f12e862b70ca8724cf2f57Behdad Esfahbod fprintf (stderr, "SANITIZE(%p) %-*d-> array [%p..%p] (%d*%d=%ld bytes) in [%p..%p] -> %s\n", \ 209815a73e4202ca17677f12e862b70ca8724cf2f57Behdad Esfahbod base, 210815a73e4202ca17677f12e862b70ca8724cf2f57Behdad Esfahbod sanitize_depth, sanitize_depth, 211815a73e4202ca17677f12e862b70ca8724cf2f57Behdad Esfahbod base, base + (record_size * len), record_size, len, (unsigned long) record_size * len, 212815a73e4202ca17677f12e862b70ca8724cf2f57Behdad Esfahbod context->start, context->end, 213815a73e4202ca17677f12e862b70ca8724cf2f57Behdad Esfahbod !overflows ? "does not overflow" : "OVERFLOWS FAIL"); 214815a73e4202ca17677f12e862b70ca8724cf2f57Behdad Esfahbod#endif 215254933c397f1ce9796f59689a25f9fc2e58df4eaBehdad Esfahbod 216815a73e4202ca17677f12e862b70ca8724cf2f57Behdad Esfahbod return HB_LIKELY (!overflows) && _hb_sanitize_check (SANITIZE_ARG, base, record_size * len); 217815a73e4202ca17677f12e862b70ca8724cf2f57Behdad Esfahbod} 218815a73e4202ca17677f12e862b70ca8724cf2f57Behdad Esfahbod 219815a73e4202ca17677f12e862b70ca8724cf2f57Behdad Esfahbodstatic HB_GNUC_UNUSED inline bool 22041895506cb6a41b1a833866f8822261ea449ea0bBehdad Esfahbod_hb_sanitize_edit (SANITIZE_ARG_DEF, 2214f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod const char *base HB_GNUC_UNUSED, 2224f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod unsigned int len HB_GNUC_UNUSED) 223577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod{ 224f4b58d3fc2956a9d1b6178588d809c781f7a5c0cBehdad Esfahbod context->edit_count++; 2254f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod 22695e202403ffa543c817f45cca21fbc116eb8e807Behdad Esfahbod#if HB_DEBUG_SANITIZE 227ae728e51e94d18d731b7c8dc524da1a4f427d63bBehdad Esfahbod fprintf (stderr, "SANITIZE(%p) %-*d-> edit(%u) [%p..%p] (%d bytes) in [%p..%p] -> %s\n", \ 228ae728e51e94d18d731b7c8dc524da1a4f427d63bBehdad Esfahbod base, 229ae728e51e94d18d731b7c8dc524da1a4f427d63bBehdad Esfahbod sanitize_depth, sanitize_depth, 230ae728e51e94d18d731b7c8dc524da1a4f427d63bBehdad Esfahbod context->edit_count, 231ae728e51e94d18d731b7c8dc524da1a4f427d63bBehdad Esfahbod base, base+len, len, 232ae728e51e94d18d731b7c8dc524da1a4f427d63bBehdad Esfahbod context->start, context->end, 233254933c397f1ce9796f59689a25f9fc2e58df4eaBehdad Esfahbod context->writable ? "granted" : "REJECTED"); 2344f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod#endif 235254933c397f1ce9796f59689a25f9fc2e58df4eaBehdad Esfahbod 236254933c397f1ce9796f59689a25f9fc2e58df4eaBehdad Esfahbod return context->writable; 237577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod} 238577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod 239577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod#define SANITIZE(X) HB_LIKELY ((X).sanitize (SANITIZE_ARG)) 240577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod#define SANITIZE2(X,Y) (SANITIZE (X) && SANITIZE (Y)) 241577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod 24262c0fd75737a69721dbf29e773405a4c529f8b6dBehdad Esfahbod#define SANITIZE_THIS(X) HB_LIKELY ((X).sanitize (SANITIZE_ARG, CharP(this))) 243577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod#define SANITIZE_THIS2(X,Y) (SANITIZE_THIS (X) && SANITIZE_THIS (Y)) 244577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod#define SANITIZE_THIS3(X,Y,Z) (SANITIZE_THIS (X) && SANITIZE_THIS (Y) && SANITIZE_THIS(Z)) 245577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod 246577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod#define SANITIZE_BASE(X,B) HB_LIKELY ((X).sanitize (SANITIZE_ARG, B)) 247577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod#define SANITIZE_BASE2(X,Y,B) (SANITIZE_BASE (X,B) && SANITIZE_BASE (Y,B)) 248577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod 249577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod#define SANITIZE_SELF() SANITIZE_OBJ (*this) 250577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod#define SANITIZE_OBJ(X) SANITIZE_MEM(&(X), sizeof (X)) 251577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod 2520dfcc13a4668cdd2c2ebdd5f4a7540a51222cf2fBehdad Esfahbod#define SANITIZE_MEM(B,L) HB_LIKELY (_hb_sanitize_check (SANITIZE_ARG, CharP(B), (L))) 253577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod 2540dfcc13a4668cdd2c2ebdd5f4a7540a51222cf2fBehdad Esfahbod#define SANITIZE_ARRAY(A,S,L) HB_LIKELY (_hb_sanitize_array (SANITIZE_ARG, CharP(A), S, L)) 255815a73e4202ca17677f12e862b70ca8724cf2f57Behdad Esfahbod 25666d6eb30eb0b8d61e00f86ea0c7829abaddb52faBehdad Esfahbod#define NEUTER(Obj, Val) \ 25766d6eb30eb0b8d61e00f86ea0c7829abaddb52faBehdad Esfahbod (SANITIZE_OBJ (Obj) && \ 25866d6eb30eb0b8d61e00f86ea0c7829abaddb52faBehdad Esfahbod _hb_sanitize_edit (SANITIZE_ARG, CharP(&(Obj)), (Obj).get_size ()) && \ 25966d6eb30eb0b8d61e00f86ea0c7829abaddb52faBehdad Esfahbod ((Obj).set (Val), true)) 260577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod 261577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod 2624e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod/* Template to sanitize an object. */ 2634e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbodtemplate <typename Type> 2644e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbodstruct Sanitizer 2654e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod{ 2664e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod static hb_blob_t *sanitize (hb_blob_t *blob) { 267173fde7087c0db3e99409f1119530477c14072f5Behdad Esfahbod hb_sanitize_context_t context[1]; 268173fde7087c0db3e99409f1119530477c14072f5Behdad Esfahbod unsigned int sanitize_depth = 0; 2694e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod bool sane; 2704e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod 271d0b657379bbe63602953412d6bc944b2a0f430ebBehdad Esfahbod /* TODO is_sane() stuff */ 2724e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod 2734e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod retry: 27495e202403ffa543c817f45cca21fbc116eb8e807Behdad Esfahbod#if HB_DEBUG_SANITIZE 2757acb389569cf99c6bae9db31a8ed7c7007fbb566Behdad Esfahbod fprintf (stderr, "Sanitizer %p start %s\n", blob, __PRETTY_FUNCTION__); 2764f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod#endif 2774f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod 278173fde7087c0db3e99409f1119530477c14072f5Behdad Esfahbod _hb_sanitize_init (context, blob); 2794e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod 280efb324a46ff64adb4ec8612b4089e8daff1e6d8eBehdad Esfahbod /* Note: We drop const here */ 281173fde7087c0db3e99409f1119530477c14072f5Behdad Esfahbod Type *t = CastP<Type> ((void *) context->start); 2824e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod 283173fde7087c0db3e99409f1119530477c14072f5Behdad Esfahbod sane = t->sanitize (SANITIZE_ARG); 2844e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod if (sane) { 285173fde7087c0db3e99409f1119530477c14072f5Behdad Esfahbod if (context->edit_count) { 28695e202403ffa543c817f45cca21fbc116eb8e807Behdad Esfahbod#if HB_DEBUG_SANITIZE 287ad3653751b1e4a03f7058200cb83f64db46722d5Behdad Esfahbod fprintf (stderr, "Sanitizer %p passed first round with %d edits; doing a second round %s\n", 288173fde7087c0db3e99409f1119530477c14072f5Behdad Esfahbod blob, context->edit_count, __PRETTY_FUNCTION__); 2890d77ab8a73f57c9fca4c6f9301dae394d79526e3Behdad Esfahbod#endif 2908b5346130425c7c101f6ff2432874ba2fd372edcBehdad Esfahbod /* sanitize again to ensure no toe-stepping */ 291173fde7087c0db3e99409f1119530477c14072f5Behdad Esfahbod context->edit_count = 0; 292173fde7087c0db3e99409f1119530477c14072f5Behdad Esfahbod sane = t->sanitize (SANITIZE_ARG); 293173fde7087c0db3e99409f1119530477c14072f5Behdad Esfahbod if (context->edit_count) { 29495e202403ffa543c817f45cca21fbc116eb8e807Behdad Esfahbod#if HB_DEBUG_SANITIZE 295ae728e51e94d18d731b7c8dc524da1a4f427d63bBehdad Esfahbod fprintf (stderr, "Sanitizer %p requested %d edits in second round; FAILLING %s\n", 296173fde7087c0db3e99409f1119530477c14072f5Behdad Esfahbod blob, context->edit_count, __PRETTY_FUNCTION__); 2970d77ab8a73f57c9fca4c6f9301dae394d79526e3Behdad Esfahbod#endif 2984e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod sane = false; 2994e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod } 3004e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod } 301173fde7087c0db3e99409f1119530477c14072f5Behdad Esfahbod _hb_sanitize_fini (context, blob); 3024e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod } else { 303173fde7087c0db3e99409f1119530477c14072f5Behdad Esfahbod unsigned int edit_count = context->edit_count; 304173fde7087c0db3e99409f1119530477c14072f5Behdad Esfahbod _hb_sanitize_fini (context, blob); 305977eeb714454630bd045bb11f58ff6397f10b143Behdad Esfahbod if (edit_count && !hb_blob_is_writable (blob) && hb_blob_try_writable (blob)) { 306977eeb714454630bd045bb11f58ff6397f10b143Behdad Esfahbod /* ok, we made it writable by relocating. try again */ 30795e202403ffa543c817f45cca21fbc116eb8e807Behdad Esfahbod#if HB_DEBUG_SANITIZE 3087acb389569cf99c6bae9db31a8ed7c7007fbb566Behdad Esfahbod fprintf (stderr, "Sanitizer %p retry %s\n", blob, __PRETTY_FUNCTION__); 3094f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod#endif 3104e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod goto retry; 3114e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod } 3124e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod } 3134e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod 31495e202403ffa543c817f45cca21fbc116eb8e807Behdad Esfahbod#if HB_DEBUG_SANITIZE 315ae728e51e94d18d731b7c8dc524da1a4f427d63bBehdad Esfahbod fprintf (stderr, "Sanitizer %p %s %s\n", blob, sane ? "passed" : "FAILED", __PRETTY_FUNCTION__); 3164f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod#endif 3174e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod if (sane) 3184e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod return blob; 3194e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod else { 3204e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod hb_blob_destroy (blob); 3214e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod return hb_blob_create_empty (); 3224e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod } 3234e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod } 3244e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod}; 3254e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod 3262d15e72c75931398db5e027e660f1320bb979117Behdad Esfahbod 327b6e62bc5db76ae342177b2b646c37f45eccad975Behdad Esfahbod/* 328b6e62bc5db76ae342177b2b646c37f45eccad975Behdad Esfahbod * 329bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod * The OpenType Font File: Data Types 330b6e62bc5db76ae342177b2b646c37f45eccad975Behdad Esfahbod */ 331b6e62bc5db76ae342177b2b646c37f45eccad975Behdad Esfahbod 332b6e62bc5db76ae342177b2b646c37f45eccad975Behdad Esfahbod 333b6e62bc5db76ae342177b2b646c37f45eccad975Behdad Esfahbod/* "The following data types are used in the OpenType font file. 334b6e62bc5db76ae342177b2b646c37f45eccad975Behdad Esfahbod * All OpenType fonts use Motorola-style byte ordering (Big Endian):" */ 335b6e62bc5db76ae342177b2b646c37f45eccad975Behdad Esfahbod 3365f810363acc3ad3cba631a68620e3d37e54c95c4Behdad Esfahbod/* 3375f810363acc3ad3cba631a68620e3d37e54c95c4Behdad Esfahbod * Int types 3385f810363acc3ad3cba631a68620e3d37e54c95c4Behdad Esfahbod */ 3395f810363acc3ad3cba631a68620e3d37e54c95c4Behdad Esfahbod 3406b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod 341e032ed9f75d4a0f365649a25706871bbb5ae6651Behdad Esfahbodtemplate <typename Type, int Bytes> class BEInt; 342e032ed9f75d4a0f365649a25706871bbb5ae6651Behdad Esfahbod 343f1aaa2a43654c28405ffd393de2cb127437c99a5Behdad Esfahbod/* LONGTERMTODO: On machines allowing unaligned access, we can make the 344f1aaa2a43654c28405ffd393de2cb127437c99a5Behdad Esfahbod * following tighter by using byteswap instructions on ints directly. */ 345e032ed9f75d4a0f365649a25706871bbb5ae6651Behdad Esfahbodtemplate <typename Type> 346e032ed9f75d4a0f365649a25706871bbb5ae6651Behdad Esfahbodclass BEInt<Type, 2> 347e032ed9f75d4a0f365649a25706871bbb5ae6651Behdad Esfahbod{ 348e032ed9f75d4a0f365649a25706871bbb5ae6651Behdad Esfahbod public: 34901c01618e98283611628cd54d5ba4bf122f24cd9Behdad Esfahbod inline class BEInt<Type,2>& operator = (Type i) { hb_be_uint16_put (v,i); return *this; } 35001c01618e98283611628cd54d5ba4bf122f24cd9Behdad Esfahbod inline operator Type () const { return hb_be_uint16_get (v); } 35101c01618e98283611628cd54d5ba4bf122f24cd9Behdad Esfahbod inline bool operator == (const BEInt<Type, 2>& o) const { return hb_be_uint16_cmp (v, o.v); } 35201c01618e98283611628cd54d5ba4bf122f24cd9Behdad Esfahbod inline bool operator != (const BEInt<Type, 2>& o) const { return !(*this == o); } 353e032ed9f75d4a0f365649a25706871bbb5ae6651Behdad Esfahbod private: uint8_t v[2]; 354e032ed9f75d4a0f365649a25706871bbb5ae6651Behdad Esfahbod}; 355e032ed9f75d4a0f365649a25706871bbb5ae6651Behdad Esfahbodtemplate <typename Type> 356e032ed9f75d4a0f365649a25706871bbb5ae6651Behdad Esfahbodclass BEInt<Type, 4> 357e032ed9f75d4a0f365649a25706871bbb5ae6651Behdad Esfahbod{ 358e032ed9f75d4a0f365649a25706871bbb5ae6651Behdad Esfahbod public: 35901c01618e98283611628cd54d5ba4bf122f24cd9Behdad Esfahbod inline class BEInt<Type,4>& operator = (Type i) { hb_be_uint32_put (v,i); return *this; } 36001c01618e98283611628cd54d5ba4bf122f24cd9Behdad Esfahbod inline operator Type () const { return hb_be_uint32_get (v); } 36101c01618e98283611628cd54d5ba4bf122f24cd9Behdad Esfahbod inline bool operator == (const BEInt<Type, 4>& o) const { return hb_be_uint32_cmp (v, o.v); } 36201c01618e98283611628cd54d5ba4bf122f24cd9Behdad Esfahbod inline bool operator != (const BEInt<Type, 4>& o) const { return !(*this == o); } 363e032ed9f75d4a0f365649a25706871bbb5ae6651Behdad Esfahbod private: uint8_t v[4]; 364e032ed9f75d4a0f365649a25706871bbb5ae6651Behdad Esfahbod}; 365e032ed9f75d4a0f365649a25706871bbb5ae6651Behdad Esfahbod 3662467c669c2aee4de2a6621a9d06cba0262376d41Behdad Esfahbod/* Integer types in big-endian order and no alignment requirement */ 367e032ed9f75d4a0f365649a25706871bbb5ae6651Behdad Esfahbodtemplate <typename Type> 368e032ed9f75d4a0f365649a25706871bbb5ae6651Behdad Esfahbodstruct IntType 369e032ed9f75d4a0f365649a25706871bbb5ae6651Behdad Esfahbod{ 370e032ed9f75d4a0f365649a25706871bbb5ae6651Behdad Esfahbod static inline unsigned int get_size () { return sizeof (Type); } 37101c01618e98283611628cd54d5ba4bf122f24cd9Behdad Esfahbod inline void set (Type i) { v = i; } 37201c01618e98283611628cd54d5ba4bf122f24cd9Behdad Esfahbod inline operator Type(void) const { return v; } 37301c01618e98283611628cd54d5ba4bf122f24cd9Behdad Esfahbod inline bool operator == (const IntType<Type> &o) const { return v == o.v; } 37401c01618e98283611628cd54d5ba4bf122f24cd9Behdad Esfahbod inline bool operator != (const IntType<Type> &o) const { return v != o.v; } 375e032ed9f75d4a0f365649a25706871bbb5ae6651Behdad Esfahbod inline bool sanitize (SANITIZE_ARG_DEF) { 376e032ed9f75d4a0f365649a25706871bbb5ae6651Behdad Esfahbod TRACE_SANITIZE (); 377e032ed9f75d4a0f365649a25706871bbb5ae6651Behdad Esfahbod return SANITIZE_SELF (); 378e032ed9f75d4a0f365649a25706871bbb5ae6651Behdad Esfahbod } 379e032ed9f75d4a0f365649a25706871bbb5ae6651Behdad Esfahbod private: BEInt<Type, sizeof (Type)> v; 380e032ed9f75d4a0f365649a25706871bbb5ae6651Behdad Esfahbod}; 381e032ed9f75d4a0f365649a25706871bbb5ae6651Behdad Esfahbod 382e032ed9f75d4a0f365649a25706871bbb5ae6651Behdad Esfahbodtypedef IntType<uint16_t> USHORT; /* 16-bit unsigned integer. */ 383e032ed9f75d4a0f365649a25706871bbb5ae6651Behdad Esfahbodtypedef IntType<int16_t> SHORT; /* 16-bit signed integer. */ 384e032ed9f75d4a0f365649a25706871bbb5ae6651Behdad Esfahbodtypedef IntType<uint32_t> ULONG; /* 32-bit unsigned integer. */ 385e032ed9f75d4a0f365649a25706871bbb5ae6651Behdad Esfahbodtypedef IntType<int32_t> LONG; /* 32-bit signed integer. */ 386e032ed9f75d4a0f365649a25706871bbb5ae6651Behdad Esfahbod 387e032ed9f75d4a0f365649a25706871bbb5ae6651Behdad EsfahbodASSERT_SIZE (USHORT, 2); 388e032ed9f75d4a0f365649a25706871bbb5ae6651Behdad EsfahbodASSERT_SIZE (SHORT, 2); 389e032ed9f75d4a0f365649a25706871bbb5ae6651Behdad EsfahbodASSERT_SIZE (ULONG, 4); 390e032ed9f75d4a0f365649a25706871bbb5ae6651Behdad EsfahbodASSERT_SIZE (LONG, 4); 391bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod 3926b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod/* Array of four uint8s (length = 32 bits) used to identify a script, language 3936b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod * system, feature, or baseline */ 39420cc86b3592db33731de671f008d7d222776be49Behdad Esfahbodstruct Tag : ULONG 39560d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 396befc022affd2386b3f46cd7d11e4262f6c8bce9fBehdad Esfahbod /* What the char* converters return is NOT nul-terminated. Print using "%.4s" */ 3970dfcc13a4668cdd2c2ebdd5f4a7540a51222cf2fBehdad Esfahbod inline operator const char* (void) const { return CharP(this); } 398198facdc55756cb48cdfb8ba7fa50916fac54ec3Behdad Esfahbod inline operator char* (void) { return CharP(this); } 3996b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod}; 400303fe62824d4e99df554b6bfaacba05d068522fbBehdad EsfahbodASSERT_SIZE (Tag, 4); 4019d3677899f90abdc7fb3e3d854db654a8707a84bBehdad EsfahbodDEFINE_NULL_DATA (Tag, 4, " "); 4026b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod 4036b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod/* Glyph index number, same as uint16 (length = 16 bits) */ 4046ad8d5f3c7028147b371137ae4bca6aae66b3489Behdad Esfahbodtypedef USHORT GlyphID; 4056b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod 4061f437e6f47fb6c15761021bd2078f31778f2179cBehdad Esfahbod/* Offset to a table, same as uint16 (length = 16 bits), Null offset = 0x0000 */ 4076ad8d5f3c7028147b371137ae4bca6aae66b3489Behdad Esfahbodtypedef USHORT Offset; 4086ad8d5f3c7028147b371137ae4bca6aae66b3489Behdad Esfahbod 4096ad8d5f3c7028147b371137ae4bca6aae66b3489Behdad Esfahbod/* LongOffset to a table, same as uint32 (length = 32 bits), Null offset = 0x00000000 */ 4106ad8d5f3c7028147b371137ae4bca6aae66b3489Behdad Esfahbodtypedef ULONG LongOffset; 4116ad8d5f3c7028147b371137ae4bca6aae66b3489Behdad Esfahbod 4126b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod 4136b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod/* CheckSum */ 41460d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct CheckSum : ULONG 41560d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 41660d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod static uint32_t CalcTableChecksum (ULONG *Table, uint32_t Length) 41760d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 4186b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod uint32_t Sum = 0L; 4194b8487d83e0c10076a6c573cb3487790ce366607Behdad Esfahbod ULONG *EndPtr = Table+((Length+3) & ~3) / ULONG::get_size (); 4206b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod 4216b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod while (Table < EndPtr) 4226b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod Sum += *Table++; 4236b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod return Sum; 4246b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod } 4256b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod}; 4268b8358033184198ff638ee1379093717596e162dBehdad EsfahbodASSERT_SIZE (CheckSum, 4); 4276b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod 4286b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod 4296b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod/* 4306b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod * Version Numbers 4316b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod */ 4326b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod 43387fcdcbe3644da10154688765db2d62eb9ac079aBehdad Esfahbodstruct FixedVersion 43460d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 43509c292e3b688a67fbae67b645d1e6ffcf8d8eb6eBehdad Esfahbod inline operator uint32_t (void) const { return (major << 16) + minor; } 43696908b898476ca5d7da5f386b15be76f9e83d76eBehdad Esfahbod 437cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod inline bool sanitize (SANITIZE_ARG_DEF) { 4383e2401f6c53d2b047954d75c37aef5e5e7cdc51aBehdad Esfahbod TRACE_SANITIZE (); 439cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod return SANITIZE_SELF (); 440cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod } 441cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod 4426ad8d5f3c7028147b371137ae4bca6aae66b3489Behdad Esfahbod USHORT major; 44387fcdcbe3644da10154688765db2d62eb9ac079aBehdad Esfahbod USHORT minor; 4446b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod}; 44587fcdcbe3644da10154688765db2d62eb9ac079aBehdad EsfahbodASSERT_SIZE (FixedVersion, 4); 4466b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod 44792b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod 44892b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod 4495f810363acc3ad3cba631a68620e3d37e54c95c4Behdad Esfahbod/* 45092b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod * Template subclasses of Offset and LongOffset that do the dereferencing. 45192b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod * Use: (this+memberName) 4525f810363acc3ad3cba631a68620e3d37e54c95c4Behdad Esfahbod */ 4535f810363acc3ad3cba631a68620e3d37e54c95c4Behdad Esfahbod 45492b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbodtemplate <typename OffsetType, typename Type> 45592b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbodstruct GenericOffsetTo : OffsetType 45692b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod{ 45700e23fcc6fd0eee5c582251bf3de6a2703fbbd3eBehdad Esfahbod inline const Type& operator () (const void *base) const 45892b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod { 45992b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod unsigned int offset = *this; 46092b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod if (HB_UNLIKELY (!offset)) return Null(Type); 461a3263aa773ad7a914496792466c69047048b093cBehdad Esfahbod return StructAtOffset<Type> (*CharP(base), offset); 46292b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod } 46392b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod 46462c0fd75737a69721dbf29e773405a4c529f8b6dBehdad Esfahbod inline bool sanitize (SANITIZE_ARG_DEF, void *base) { 4653e2401f6c53d2b047954d75c37aef5e5e7cdc51aBehdad Esfahbod TRACE_SANITIZE (); 46695528131b5ab9fc9e265ace715832135ebd457a4Behdad Esfahbod if (!SANITIZE_SELF ()) return false; 46792b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod unsigned int offset = *this; 46892b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod if (HB_UNLIKELY (!offset)) return true; 469a3263aa773ad7a914496792466c69047048b093cBehdad Esfahbod return SANITIZE (StructAtOffset<Type> (*CharP(base), offset)) || NEUTER (*this, 0); 47092b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod } 47162c0fd75737a69721dbf29e773405a4c529f8b6dBehdad Esfahbod inline bool sanitize (SANITIZE_ARG_DEF, void *base, void *base2) { 4723e2401f6c53d2b047954d75c37aef5e5e7cdc51aBehdad Esfahbod TRACE_SANITIZE (); 47395528131b5ab9fc9e265ace715832135ebd457a4Behdad Esfahbod if (!SANITIZE_SELF ()) return false; 474b508e5ccd528f3f0f49f545bd5f30a525d5abd5aBehdad Esfahbod unsigned int offset = *this; 475b508e5ccd528f3f0f49f545bd5f30a525d5abd5aBehdad Esfahbod if (HB_UNLIKELY (!offset)) return true; 476a3263aa773ad7a914496792466c69047048b093cBehdad Esfahbod return SANITIZE_BASE (StructAtOffset<Type> (*CharP(base), offset), base2) || NEUTER (*this, 0); 477b508e5ccd528f3f0f49f545bd5f30a525d5abd5aBehdad Esfahbod } 47862c0fd75737a69721dbf29e773405a4c529f8b6dBehdad Esfahbod inline bool sanitize (SANITIZE_ARG_DEF, void *base, unsigned int user_data) { 4793e2401f6c53d2b047954d75c37aef5e5e7cdc51aBehdad Esfahbod TRACE_SANITIZE (); 48095528131b5ab9fc9e265ace715832135ebd457a4Behdad Esfahbod if (!SANITIZE_SELF ()) return false; 48142b778f89e0818fe06910ce04e2203485823da09Behdad Esfahbod unsigned int offset = *this; 48242b778f89e0818fe06910ce04e2203485823da09Behdad Esfahbod if (HB_UNLIKELY (!offset)) return true; 483a3263aa773ad7a914496792466c69047048b093cBehdad Esfahbod return SANITIZE_BASE (StructAtOffset<Type> (*CharP(base), offset), user_data) || NEUTER (*this, 0); 48442b778f89e0818fe06910ce04e2203485823da09Behdad Esfahbod } 48592b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod}; 48692b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbodtemplate <typename Base, typename OffsetType, typename Type> 48792b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbodinline const Type& operator + (const Base &base, GenericOffsetTo<OffsetType, Type> offset) { return offset (base); } 48892b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod 4895f810363acc3ad3cba631a68620e3d37e54c95c4Behdad Esfahbodtemplate <typename Type> 49092b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbodstruct OffsetTo : GenericOffsetTo<Offset, Type> {}; 49192b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod 49292b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbodtemplate <typename Type> 49392b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbodstruct LongOffsetTo : GenericOffsetTo<LongOffset, Type> {}; 494bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod 495bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod 49692b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod/* 49792b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod * Array Types 49892b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod */ 49992b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod 50092b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbodtemplate <typename LenType, typename Type> 50192b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbodstruct GenericArrayOf 50260d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 5032cb08458f674301cde9d962c13911035a251f7c5Behdad Esfahbod const Type *array(void) const { return &StructAfter<Type> (len); } 5042e2f43edf2f49f4047e28b1ce2ea95938536de9cBehdad Esfahbod Type *array(void) { return &StructAfter<Type> (len); } 505d3480ba37fbb5d4be75b094060f5b2f1ce98fb53Behdad Esfahbod 5064f5f1c34dda1e0629bfa6d7b0ffa2e1ce003b7c7Behdad Esfahbod const Type *sub_array (unsigned int start_offset, unsigned int *pcount /* IN/OUT */) const 50748de3730cdf91b9f6473509e22260a902ccec992Behdad Esfahbod { 50848de3730cdf91b9f6473509e22260a902ccec992Behdad Esfahbod unsigned int count = len; 50948de3730cdf91b9f6473509e22260a902ccec992Behdad Esfahbod if (HB_UNLIKELY (start_offset > count)) 51048de3730cdf91b9f6473509e22260a902ccec992Behdad Esfahbod count = 0; 51148de3730cdf91b9f6473509e22260a902ccec992Behdad Esfahbod else 51248de3730cdf91b9f6473509e22260a902ccec992Behdad Esfahbod count -= start_offset; 51348de3730cdf91b9f6473509e22260a902ccec992Behdad Esfahbod count = MIN (count, *pcount); 51448de3730cdf91b9f6473509e22260a902ccec992Behdad Esfahbod *pcount = count; 5152cb08458f674301cde9d962c13911035a251f7c5Behdad Esfahbod return array() + start_offset; 51648de3730cdf91b9f6473509e22260a902ccec992Behdad Esfahbod } 51748de3730cdf91b9f6473509e22260a902ccec992Behdad Esfahbod 51860d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod inline const Type& operator [] (unsigned int i) const 51960d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 5205f810363acc3ad3cba631a68620e3d37e54c95c4Behdad Esfahbod if (HB_UNLIKELY (i >= len)) return Null(Type); 5212cb08458f674301cde9d962c13911035a251f7c5Behdad Esfahbod return array()[i]; 5225f810363acc3ad3cba631a68620e3d37e54c95c4Behdad Esfahbod } 52360d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod inline unsigned int get_size () const 5244b8487d83e0c10076a6c573cb3487790ce366607Behdad Esfahbod { return len.get_size () + len * Type::get_size (); } 525e8cbaaf6d538036ff9b880b018db402e0895ed01Behdad Esfahbod 526e5546a4352c54311ac4a9ef138b187378155ebe1Behdad Esfahbod inline bool sanitize_shallow (SANITIZE_ARG_DEF) { 527e5546a4352c54311ac4a9ef138b187378155ebe1Behdad Esfahbod TRACE_SANITIZE (); 528e5546a4352c54311ac4a9ef138b187378155ebe1Behdad Esfahbod return SANITIZE_SELF() && SANITIZE_ARRAY (this, Type::get_size (), len); 529e5546a4352c54311ac4a9ef138b187378155ebe1Behdad Esfahbod } 530e5546a4352c54311ac4a9ef138b187378155ebe1Behdad Esfahbod 53120b035dad41247076815a2bbb0346d63058b322fBehdad Esfahbod inline bool sanitize (SANITIZE_ARG_DEF) { 5323e2401f6c53d2b047954d75c37aef5e5e7cdc51aBehdad Esfahbod TRACE_SANITIZE (); 533e5546a4352c54311ac4a9ef138b187378155ebe1Behdad Esfahbod if (!HB_LIKELY (sanitize_shallow (SANITIZE_ARG))) return false; 53440d73bc68dd828cf68f90fde0f9499a6ce9fbb19Behdad Esfahbod /* Note: for structs that do not reference other structs, 53540d73bc68dd828cf68f90fde0f9499a6ce9fbb19Behdad Esfahbod * we do not need to call their sanitize() as we already did 53640d73bc68dd828cf68f90fde0f9499a6ce9fbb19Behdad Esfahbod * a bound check on the aggregate array size, hence the return. 53740d73bc68dd828cf68f90fde0f9499a6ce9fbb19Behdad Esfahbod */ 5383564ee5216004d45d30b0ded61184cf8dde5dd89Behdad Esfahbod return true; 53940d73bc68dd828cf68f90fde0f9499a6ce9fbb19Behdad Esfahbod /* We do keep this code though to make sure the structs pointed 54040d73bc68dd828cf68f90fde0f9499a6ce9fbb19Behdad Esfahbod * to do have a simple sanitize(), ie. they do not reference 54140d73bc68dd828cf68f90fde0f9499a6ce9fbb19Behdad Esfahbod * other structs. */ 54270de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod unsigned int count = len; 54370de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 544d3480ba37fbb5d4be75b094060f5b2f1ce98fb53Behdad Esfahbod if (!SANITIZE (array()[i])) 54570de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod return false; 5469bd629ccd064e739789e504c41ad875eed93abbaBehdad Esfahbod return true; 54770de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 54862c0fd75737a69721dbf29e773405a4c529f8b6dBehdad Esfahbod inline bool sanitize (SANITIZE_ARG_DEF, void *base) { 5493e2401f6c53d2b047954d75c37aef5e5e7cdc51aBehdad Esfahbod TRACE_SANITIZE (); 550e5546a4352c54311ac4a9ef138b187378155ebe1Behdad Esfahbod if (!HB_LIKELY (sanitize_shallow (SANITIZE_ARG))) return false; 551e6ab2c59ba2d37942ac5fcbfe61d38b7e359ac8cBehdad Esfahbod unsigned int count = len; 552e6ab2c59ba2d37942ac5fcbfe61d38b7e359ac8cBehdad Esfahbod for (unsigned int i = 0; i < count; i++) 553d3480ba37fbb5d4be75b094060f5b2f1ce98fb53Behdad Esfahbod if (!array()[i].sanitize (SANITIZE_ARG, base)) 554e6ab2c59ba2d37942ac5fcbfe61d38b7e359ac8cBehdad Esfahbod return false; 5559bd629ccd064e739789e504c41ad875eed93abbaBehdad Esfahbod return true; 556e6ab2c59ba2d37942ac5fcbfe61d38b7e359ac8cBehdad Esfahbod } 55762c0fd75737a69721dbf29e773405a4c529f8b6dBehdad Esfahbod inline bool sanitize (SANITIZE_ARG_DEF, void *base, void *base2) { 5583e2401f6c53d2b047954d75c37aef5e5e7cdc51aBehdad Esfahbod TRACE_SANITIZE (); 559e5546a4352c54311ac4a9ef138b187378155ebe1Behdad Esfahbod if (!HB_LIKELY (sanitize_shallow (SANITIZE_ARG))) return false; 560b508e5ccd528f3f0f49f545bd5f30a525d5abd5aBehdad Esfahbod unsigned int count = len; 561b508e5ccd528f3f0f49f545bd5f30a525d5abd5aBehdad Esfahbod for (unsigned int i = 0; i < count; i++) 562d3480ba37fbb5d4be75b094060f5b2f1ce98fb53Behdad Esfahbod if (!array()[i].sanitize (SANITIZE_ARG, base, base2)) 563b508e5ccd528f3f0f49f545bd5f30a525d5abd5aBehdad Esfahbod return false; 5649bd629ccd064e739789e504c41ad875eed93abbaBehdad Esfahbod return true; 565b508e5ccd528f3f0f49f545bd5f30a525d5abd5aBehdad Esfahbod } 56662c0fd75737a69721dbf29e773405a4c529f8b6dBehdad Esfahbod inline bool sanitize (SANITIZE_ARG_DEF, void *base, unsigned int user_data) { 5673e2401f6c53d2b047954d75c37aef5e5e7cdc51aBehdad Esfahbod TRACE_SANITIZE (); 568e5546a4352c54311ac4a9ef138b187378155ebe1Behdad Esfahbod if (!HB_LIKELY (sanitize_shallow (SANITIZE_ARG))) return false; 56942b778f89e0818fe06910ce04e2203485823da09Behdad Esfahbod unsigned int count = len; 57042b778f89e0818fe06910ce04e2203485823da09Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 571d3480ba37fbb5d4be75b094060f5b2f1ce98fb53Behdad Esfahbod if (!array()[i].sanitize (SANITIZE_ARG, base, user_data)) 57242b778f89e0818fe06910ce04e2203485823da09Behdad Esfahbod return false; 5739bd629ccd064e739789e504c41ad875eed93abbaBehdad Esfahbod return true; 57442b778f89e0818fe06910ce04e2203485823da09Behdad Esfahbod } 57570de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 57692b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod LenType len; 577d3480ba37fbb5d4be75b094060f5b2f1ce98fb53Behdad Esfahbod/*Type array[VAR];*/ 578e8cbaaf6d538036ff9b880b018db402e0895ed01Behdad Esfahbod}; 579e8cbaaf6d538036ff9b880b018db402e0895ed01Behdad Esfahbod 58092b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod/* An array with a USHORT number of elements. */ 58192b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbodtemplate <typename Type> 58292b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbodstruct ArrayOf : GenericArrayOf<USHORT, Type> {}; 58392b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod 58492b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod/* An array with a ULONG number of elements. */ 58592b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbodtemplate <typename Type> 58692b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbodstruct LongArrayOf : GenericArrayOf<ULONG, Type> {}; 58792b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod 58892b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod/* Array of Offset's */ 58992b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbodtemplate <typename Type> 59092b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbodstruct OffsetArrayOf : ArrayOf<OffsetTo<Type> > {}; 59192b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod 59292b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod/* Array of LongOffset's */ 59392b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbodtemplate <typename Type> 59492b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbodstruct LongOffsetArrayOf : ArrayOf<LongOffsetTo<Type> > {}; 59592b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod 59692b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod/* LongArray of LongOffset's */ 59792b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbodtemplate <typename Type> 59892b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbodstruct LongOffsetLongArrayOf : LongArrayOf<LongOffsetTo<Type> > {}; 59992b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod 60080e2aa2e1bfa2c8ecedcfa4cce8cadeb15792ac3Behdad Esfahbod/* Array of offsets relative to the beginning of the array itself. */ 60180e2aa2e1bfa2c8ecedcfa4cce8cadeb15792ac3Behdad Esfahbodtemplate <typename Type> 60280e2aa2e1bfa2c8ecedcfa4cce8cadeb15792ac3Behdad Esfahbodstruct OffsetListOf : OffsetArrayOf<Type> 60380e2aa2e1bfa2c8ecedcfa4cce8cadeb15792ac3Behdad Esfahbod{ 60480e2aa2e1bfa2c8ecedcfa4cce8cadeb15792ac3Behdad Esfahbod inline const Type& operator [] (unsigned int i) const 60580e2aa2e1bfa2c8ecedcfa4cce8cadeb15792ac3Behdad Esfahbod { 60680e2aa2e1bfa2c8ecedcfa4cce8cadeb15792ac3Behdad Esfahbod if (HB_UNLIKELY (i >= this->len)) return Null(Type); 6072cb08458f674301cde9d962c13911035a251f7c5Behdad Esfahbod return this+this->array()[i]; 60880e2aa2e1bfa2c8ecedcfa4cce8cadeb15792ac3Behdad Esfahbod } 60980e2aa2e1bfa2c8ecedcfa4cce8cadeb15792ac3Behdad Esfahbod 61080e2aa2e1bfa2c8ecedcfa4cce8cadeb15792ac3Behdad Esfahbod inline bool sanitize (SANITIZE_ARG_DEF) { 6113e2401f6c53d2b047954d75c37aef5e5e7cdc51aBehdad Esfahbod TRACE_SANITIZE (); 61262c0fd75737a69721dbf29e773405a4c529f8b6dBehdad Esfahbod return OffsetArrayOf<Type>::sanitize (SANITIZE_ARG, CharP(this)); 61380e2aa2e1bfa2c8ecedcfa4cce8cadeb15792ac3Behdad Esfahbod } 61480e2aa2e1bfa2c8ecedcfa4cce8cadeb15792ac3Behdad Esfahbod inline bool sanitize (SANITIZE_ARG_DEF, unsigned int user_data) { 6153e2401f6c53d2b047954d75c37aef5e5e7cdc51aBehdad Esfahbod TRACE_SANITIZE (); 61662c0fd75737a69721dbf29e773405a4c529f8b6dBehdad Esfahbod return OffsetArrayOf<Type>::sanitize (SANITIZE_ARG, CharP(this), user_data); 61780e2aa2e1bfa2c8ecedcfa4cce8cadeb15792ac3Behdad Esfahbod } 61880e2aa2e1bfa2c8ecedcfa4cce8cadeb15792ac3Behdad Esfahbod}; 61980e2aa2e1bfa2c8ecedcfa4cce8cadeb15792ac3Behdad Esfahbod 62080e2aa2e1bfa2c8ecedcfa4cce8cadeb15792ac3Behdad Esfahbod 621e8cbaaf6d538036ff9b880b018db402e0895ed01Behdad Esfahbod/* An array with a USHORT number of elements, 622e8cbaaf6d538036ff9b880b018db402e0895ed01Behdad Esfahbod * starting at second element. */ 623e8cbaaf6d538036ff9b880b018db402e0895ed01Behdad Esfahbodtemplate <typename Type> 62460d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct HeadlessArrayOf 62560d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 6262cb08458f674301cde9d962c13911035a251f7c5Behdad Esfahbod const Type *array(void) const { return &StructAfter<Type> (len); } 6272e2f43edf2f49f4047e28b1ce2ea95938536de9cBehdad Esfahbod Type *array(void) { return &StructAfter<Type> (len); } 628d3480ba37fbb5d4be75b094060f5b2f1ce98fb53Behdad Esfahbod 62960d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod inline const Type& operator [] (unsigned int i) const 63060d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 631e8cbaaf6d538036ff9b880b018db402e0895ed01Behdad Esfahbod if (HB_UNLIKELY (i >= len || !i)) return Null(Type); 6322cb08458f674301cde9d962c13911035a251f7c5Behdad Esfahbod return array()[i-1]; 633e8cbaaf6d538036ff9b880b018db402e0895ed01Behdad Esfahbod } 63460d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod inline unsigned int get_size () const 6354b8487d83e0c10076a6c573cb3487790ce366607Behdad Esfahbod { return len.get_size () + (len ? len - 1 : 0) * Type::get_size (); } 6365f810363acc3ad3cba631a68620e3d37e54c95c4Behdad Esfahbod 637e5546a4352c54311ac4a9ef138b187378155ebe1Behdad Esfahbod inline bool sanitize_shallow (SANITIZE_ARG_DEF) { 638e5546a4352c54311ac4a9ef138b187378155ebe1Behdad Esfahbod TRACE_SANITIZE (); 639e5546a4352c54311ac4a9ef138b187378155ebe1Behdad Esfahbod return SANITIZE_SELF() && SANITIZE_ARRAY (this, Type::get_size (), len); 640e5546a4352c54311ac4a9ef138b187378155ebe1Behdad Esfahbod } 641e5546a4352c54311ac4a9ef138b187378155ebe1Behdad Esfahbod 64220b035dad41247076815a2bbb0346d63058b322fBehdad Esfahbod inline bool sanitize (SANITIZE_ARG_DEF) { 6433e2401f6c53d2b047954d75c37aef5e5e7cdc51aBehdad Esfahbod TRACE_SANITIZE (); 644e5546a4352c54311ac4a9ef138b187378155ebe1Behdad Esfahbod if (!HB_LIKELY (sanitize_shallow (SANITIZE_ARG))) return false; 64540d73bc68dd828cf68f90fde0f9499a6ce9fbb19Behdad Esfahbod /* Note: for structs that do not reference other structs, 64640d73bc68dd828cf68f90fde0f9499a6ce9fbb19Behdad Esfahbod * we do not need to call their sanitize() as we already did 64740d73bc68dd828cf68f90fde0f9499a6ce9fbb19Behdad Esfahbod * a bound check on the aggregate array size, hence the return. 64840d73bc68dd828cf68f90fde0f9499a6ce9fbb19Behdad Esfahbod */ 6493564ee5216004d45d30b0ded61184cf8dde5dd89Behdad Esfahbod return true; 65040d73bc68dd828cf68f90fde0f9499a6ce9fbb19Behdad Esfahbod /* We do keep this code though to make sure the structs pointed 65140d73bc68dd828cf68f90fde0f9499a6ce9fbb19Behdad Esfahbod * to do have a simple sanitize(), ie. they do not reference 65240d73bc68dd828cf68f90fde0f9499a6ce9fbb19Behdad Esfahbod * other structs. */ 65315164d9258a74122a4db748d35532bd72c47cec2Behdad Esfahbod unsigned int count = len ? len - 1 : 0; 654d3480ba37fbb5d4be75b094060f5b2f1ce98fb53Behdad Esfahbod Type *a = array(); 65570de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 656d3480ba37fbb5d4be75b094060f5b2f1ce98fb53Behdad Esfahbod if (!SANITIZE (a[i])) 65770de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod return false; 6589bd629ccd064e739789e504c41ad875eed93abbaBehdad Esfahbod return true; 65970de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 66070de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 6615f810363acc3ad3cba631a68620e3d37e54c95c4Behdad Esfahbod USHORT len; 662d3480ba37fbb5d4be75b094060f5b2f1ce98fb53Behdad Esfahbod/*Type array[VAR];*/ 6635f810363acc3ad3cba631a68620e3d37e54c95c4Behdad Esfahbod}; 6645f810363acc3ad3cba631a68620e3d37e54c95c4Behdad Esfahbod 6656b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod 6661e91434569a9e9535ef021ca52b60b2e2af75d19Behdad Esfahbod#endif /* HB_OPEN_TYPE_PRIVATE_HH */ 667