29 #ifndef HB_SANITIZE_HH
30 #define HB_SANITIZE_HH
104 #ifndef HB_SANITIZE_MAX_EDITS
105 #define HB_SANITIZE_MAX_EDITS 32
107 #ifndef HB_SANITIZE_MAX_OPS_FACTOR
108 #define HB_SANITIZE_MAX_OPS_FACTOR 64
110 #ifndef HB_SANITIZE_MAX_OPS_MIN
111 #define HB_SANITIZE_MAX_OPS_MIN 16384
113 #ifndef HB_SANITIZE_MAX_OPS_MAX
114 #define HB_SANITIZE_MAX_OPS_MAX 0x3FFFFFFF
116 #ifndef HB_SANITIZE_MAX_SUBTABLES
117 #define HB_SANITIZE_MAX_SUBTABLES 0x4000
125 max_ops (0), max_subtables (0),
127 writable (
false), edit_count (0),
130 num_glyphs_set (
false) {}
133 template <
typename T,
typename F>
135 {
return format->sanitize (
this); }
142 max_subtables +=
count;
147 template <
typename T,
typename ...Ts>
auto
149 (
obj.sanitize (
this, std::forward<Ts> (ds)...) )
150 template <
typename T,
typename ...Ts>
auto
152 (
obj.dispatch (
this, std::forward<Ts> (ds)...) )
154 template <
typename T,
typename ...Ts>
auto
162 this->writable =
false;
165 void set_num_glyphs (
unsigned int num_glyphs_)
167 num_glyphs = num_glyphs_;
168 num_glyphs_set =
true;
170 unsigned int get_num_glyphs () {
return num_glyphs; }
172 void set_max_ops (
int max_ops_) { max_ops = max_ops_; }
174 template <
typename T>
175 void set_object (
const T *
obj)
181 const char *obj_start = (
const char *)
obj;
186 this->
start = obj_start;
187 this->
end = obj_start + hb_min (
size_t (this->
end - obj_start),
obj->get_size ());
198 void start_processing ()
207 this->edit_count = 0;
209 this->recursion_depth = 0;
212 "start [%p..%p] (%lu bytes)",
214 (
unsigned long) (this->
end - this->
start));
217 void end_processing ()
220 "end [%p..%p] %u edit requests",
221 this->
start, this->
end, this->edit_count);
224 this->blob =
nullptr;
228 unsigned get_edit_count () {
return edit_count; }
230 bool check_range (
const void *
base,
231 unsigned int len)
const
233 const char *
p = (
const char *)
base;
237 (
unsigned int) (this->
end -
p) >=
len &&
238 (this->max_ops -=
len) > 0);
241 "check_range [%p..%p]"
242 " (%d bytes) in [%p..%p] -> %s",
245 ok ?
"OK" :
"OUT-OF-RANGE");
250 template <
typename T>
251 bool check_range (
const T *
base,
253 unsigned int b)
const
255 return !hb_unsigned_mul_overflows (
a,
b) &&
256 this->check_range (
base,
a *
b);
259 template <
typename T>
260 bool check_range (
const T *
base,
263 unsigned int c)
const
265 return !hb_unsigned_mul_overflows (
a,
b) &&
266 this->check_range (
base,
a *
b,
c);
269 template <
typename T>
270 bool check_array (
const T *
base,
unsigned int len)
const
275 template <
typename T>
276 bool check_array (
const T *
base,
278 unsigned int b)
const
283 bool check_start_recursion (
int max_depth)
285 if (
unlikely (recursion_depth >= max_depth))
return false;
286 return ++recursion_depth;
289 bool end_recursion (
bool result)
295 template <
typename Type>
296 bool check_struct (
const Type *
obj)
const
297 {
return likely (this->check_range (
obj,
obj->min_size)); }
299 bool may_edit (
const void *
base,
unsigned int len)
304 const char *
p = (
const char *)
base;
308 "may_edit(%u) [%p..%p] (%d bytes) in [%p..%p] -> %s",
312 this->writable ?
"GRANTED" :
"DENIED");
314 return this->writable;
317 template <
typename Type,
typename ValueType>
328 template <
typename Type>
348 sane =
t->sanitize (
this);
353 DEBUG_MSG_FUNC (SANITIZE,
start,
"passed first round with %d edits; going for second round", edit_count);
357 sane =
t->sanitize (
this);
359 DEBUG_MSG_FUNC (SANITIZE,
start,
"requested %d edits in second round; FAILLING", edit_count);
366 if (edit_count && !writable) {
395 template <
typename Type>
404 mutable int max_ops, max_subtables;
408 unsigned int edit_count;
410 unsigned int num_glyphs;
416 template <
typename T>
418 {
c->set_object (
obj); }
420 {
c->reset_object (); }
hb_blob_t * hb_blob_get_empty()
void hb_blob_make_immutable(hb_blob_t *blob)
hb_blob_t * hb_blob_reference(hb_blob_t *blob)
void hb_blob_destroy(hb_blob_t *blob)
char * hb_blob_get_data_writable(hb_blob_t *blob, unsigned int *length)
#define DEBUG_MSG_FUNC(WHAT, OBJ,...)
#define DEBUG_MSG_LEVEL(WHAT, OBJ, LEVEL, LEVEL_DIR,...)
void const void *obj HB_UNUSED
unsigned int hb_face_get_glyph_count(const hb_face_t *face)
hb_blob_t * hb_face_reference_table(const hb_face_t *face, hb_tag_t tag)
#define HB_SANITIZE_MAX_OPS_MIN
#define HB_SANITIZE_MAX_OPS_MAX
#define HB_SANITIZE_MAX_EDITS
#define HB_SANITIZE_MAX_OPS_FACTOR
#define HB_SANITIZE_MAX_SUBTABLES
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro vuzp8 reg2 vuzp d d ®2 endm macro vzip8 reg2 vzip d d ®2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld[DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld init[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp skip1 beq endif SRC MASK if dst_r_bpp DST_R else add endif PF add sub src_basereg pixdeinterleave mask_basereg pixdeinterleave dst_r_basereg process_pixblock_head pixblock_size cache_preload_simple process_pixblock_tail pixinterleave dst_w_basereg irp beq endif process_pixblock_tail_head tst beq irp if pixblock_size chunk_size tst beq pixld SRC pixld MASK if DST_R else pixld DST_R endif if src_basereg pixdeinterleave mask_basereg pixdeinterleave dst_r_basereg process_pixblock_head if pixblock_size cache_preload_simple endif process_pixblock_tail pixinterleave dst_w_basereg irp if pixblock_size chunk_size tst beq if DST_W else pixst DST_W else mov ORIG_W endif add lsl if lsl endif if lsl endif lsl endif lsl endif lsl endif subs mov DST_W if regs_shortage str endif bge start_of_loop_label endm macro generate_composite_function
GLboolean GLboolean GLboolean b
GLsizei const GLfloat * v
[13]
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLenum GLsizei count
GLint GLsizei GLsizei GLenum format
return_t dispatch(const T &obj, Ts &&... ds)
bool stop_sublookup_iteration(const return_t r) const
static return_t no_dispatch_return_value()
bool may_dispatch(const T *obj HB_UNUSED, const F *format)
static return_t default_return_value()
bool visit_subtables(unsigned count)
~hb_sanitize_with_object_t()
hb_sanitize_with_object_t(hb_sanitize_context_t *c, const T &obj)