From a9fe787a11fc391d9a43a4ea19e6eb1c474199bd Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 22 Nov 2018 22:12:36 -0500 Subject: [PATCH] [sanitizer] Add reset_object(), make set_object() do bounds-check Affects morx/kerx run-time only currently. Will adjust their sanitize next. --- src/hb-aat-layout-kerx-table.hh | 1 + src/hb-aat-layout-morx-table.hh | 1 + src/hb-machinery.hh | 32 ++++++++++++++++++++------------ 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh index 210972767..8292dca67 100644 --- a/src/hb-aat-layout-kerx-table.hh +++ b/src/hb-aat-layout-kerx-table.hh @@ -934,6 +934,7 @@ struct KerxTable st = &StructAfter (*st); c->set_lookup_index (c->lookup_index + 1); } + c->sanitizer.reset_object (); return ret; } diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index bbe952fa1..cb871d2aa 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -1041,6 +1041,7 @@ struct Chain subtable = &StructAfter > (*subtable); c->set_lookup_index (c->lookup_index + 1); } + c->sanitizer.reset_object (); } inline unsigned int get_size (void) const { return length; } diff --git a/src/hb-machinery.hh b/src/hb-machinery.hh index cb30e9907..edef54053 100644 --- a/src/hb-machinery.hh +++ b/src/hb-machinery.hh @@ -259,26 +259,34 @@ struct hb_sanitize_context_t : inline void set_max_ops (int max_ops_) { max_ops = max_ops_; } - /* TODO - * This set_object() thing is to use sanitize at runtime lookup - * application time. This is very distinct from the regular - * sanitizer operation, so, eventually, separate into another - * type and make hb_aat_apply_context_t use that one instead - * of abusing this one. - */ template inline void set_object (const T& obj) { - this->start = (const char *) &obj; - this->end = (const char *) &obj + obj.get_size (); + reset_object (); + + const char *obj_start = (const char *) &obj; + const char *obj_end = (const char *) &obj + obj.get_size (); + assert (obj_start <= obj_end); /* Must not overflow. */ + + if (unlikely (obj_end < this->start || this->end < obj_start)) + this->start = this->end = nullptr; + else + { + this->start = MAX (this->start, obj_start); + this->end = MIN (this->end , obj_end ); + } + } + + inline void reset_object (void) + { + this->start = this->blob->data; + this->end = this->start + this->blob->length; assert (this->start <= this->end); /* Must not overflow. */ } inline void start_processing (void) { - this->start = this->blob->data; - this->end = this->start + this->blob->length; - assert (this->start <= this->end); /* Must not overflow. */ + reset_object (); this->max_ops = MAX ((unsigned int) (this->end - this->start) * HB_SANITIZE_MAX_OPS_FACTOR, (unsigned) HB_SANITIZE_MAX_OPS_MIN); this->edit_count = 0;