diff --git a/.circleci/config.yml b/.circleci/config.yml index a149b3610..86d0e3b51 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -3,13 +3,13 @@ version: 2.1 executors: win32-executor: docker: - - image: cimg/base:edge-20.04 + - image: cimg/base:2023.10 win64-executor: docker: - - image: cimg/base:edge-20.04 + - image: cimg/base:2023.10 autotools-executor: docker: - - image: cimg/base:edge-20.04 + - image: cimg/base:2023.10 jobs: @@ -75,7 +75,7 @@ jobs: asan-ubsan: docker: - - image: ubuntu:20.04 + - image: ubuntu steps: - checkout - run: apt update || true @@ -112,7 +112,7 @@ jobs: clang-cxx2a: docker: - - image: ubuntu:20.04 + - image: ubuntu steps: - checkout - run: apt update || true diff --git a/src/OT/Color/CBDT/CBDT.hh b/src/OT/Color/CBDT/CBDT.hh index 457039bfc..bcf1848f4 100644 --- a/src/OT/Color/CBDT/CBDT.hh +++ b/src/OT/Color/CBDT/CBDT.hh @@ -204,6 +204,7 @@ struct IndexSubtable { TRACE_SANITIZE (this); if (!u.header.sanitize (c)) return_trace (false); + hb_barrier (); switch (u.header.indexFormat) { case 1: return_trace (u.format1.sanitize (c, glyph_count)); @@ -378,6 +379,7 @@ struct IndexSubtableRecord { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && firstGlyphIndex <= lastGlyphIndex && offsetToSubtable.sanitize (c, base, lastGlyphIndex - firstGlyphIndex + 1)); } @@ -635,6 +637,7 @@ struct BitmapSizeTable { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && indexSubtableArrayOffset.sanitize (c, base, numberOfIndexSubtables) && horizontal.sanitize (c) && vertical.sanitize (c)); @@ -738,7 +741,9 @@ struct CBLC { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && likely (version.major == 2 || version.major == 3) && + hb_barrier () && sizeTables.sanitize (c, this)); } @@ -975,6 +980,7 @@ struct CBDT { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && likely (version.major == 2 || version.major == 3)); } diff --git a/src/OT/Color/COLR/COLR.hh b/src/OT/Color/COLR/COLR.hh index 60b094ecb..b632a1d9e 100644 --- a/src/OT/Color/COLR/COLR.hh +++ b/src/OT/Color/COLR/COLR.hh @@ -1948,10 +1948,11 @@ struct COLR bool has_v0_data () const { return numBaseGlyphs; } bool has_v1_data () const { - if (version == 1) - return (this+baseGlyphList).len > 0; + if (version != 1) + return false; + hb_barrier (); - return false; + return (this+baseGlyphList).len > 0; } unsigned int get_glyph_layers (hb_codepoint_t glyph, @@ -2032,6 +2033,8 @@ struct COLR hb_set_t *palette_indices) const { if (version != 1) return; + hb_barrier (); + hb_set_t visited_glyphs; hb_colrv1_closure_context_t c (this, &visited_glyphs, layer_indices, palette_indices); @@ -2058,10 +2061,12 @@ struct COLR { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && (this+baseGlyphsZ).sanitize (c, numBaseGlyphs) && (this+layersZ).sanitize (c, numLayers) && (version == 0 || - (version == 1 && + (hb_barrier () && + version == 1 && baseGlyphList.sanitize (c, this) && layerList.sanitize (c, this) && clipList.sanitize (c, this) && @@ -2284,6 +2289,8 @@ struct COLR { if (version == 1) { + hb_barrier (); + const Paint *paint = get_base_glyph_paint (glyph); return paint != nullptr; @@ -2313,6 +2320,8 @@ struct COLR if (version == 1) { + hb_barrier (); + const Paint *paint = get_base_glyph_paint (glyph); if (paint) { diff --git a/src/OT/Color/CPAL/CPAL.hh b/src/OT/Color/CPAL/CPAL.hh index c07716c1c..e7d32724c 100644 --- a/src/OT/Color/CPAL/CPAL.hh +++ b/src/OT/Color/CPAL/CPAL.hh @@ -214,13 +214,17 @@ struct CPAL hb_set_t *nameids_to_retain /* OUT */) const { if (version == 1) + { + hb_barrier (); v1 ().collect_name_ids (this, numPalettes, numColors, color_index_map, nameids_to_retain); + } } private: const CPALV1Tail& v1 () const { if (version == 0) return Null (CPALV1Tail); + hb_barrier (); return StructAfter (*this); } @@ -312,7 +316,10 @@ struct CPAL return_trace (false); if (version == 1) + { + hb_barrier (); return_trace (v1 ().serialize (c->serializer, numPalettes, numColors, this, color_index_map)); + } return_trace (true); } @@ -323,7 +330,8 @@ struct CPAL return_trace (c->check_struct (this) && (this+colorRecordsZ).sanitize (c, numColorRecords) && colorRecordIndicesZ.sanitize (c, numPalettes) && - (version == 0 || v1 ().sanitize (c, this, numPalettes, numColors))); + (version == 0 || + (hb_barrier () && v1 ().sanitize (c, this, numPalettes, numColors)))); } protected: diff --git a/src/OT/Color/sbix/sbix.hh b/src/OT/Color/sbix/sbix.hh index ce8693cfb..51ae1a9c6 100644 --- a/src/OT/Color/sbix/sbix.hh +++ b/src/OT/Color/sbix/sbix.hh @@ -368,6 +368,7 @@ struct sbix { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && version >= 1 && strikes.sanitize (c, this))); } diff --git a/src/OT/Color/svg/svg.hh b/src/OT/Color/svg/svg.hh index c7d91b88e..2e1f93510 100644 --- a/src/OT/Color/svg/svg.hh +++ b/src/OT/Color/svg/svg.hh @@ -56,6 +56,7 @@ struct SVGDocumentIndexEntry { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && svgDoc.sanitize (c, base, svgDocLength)); } diff --git a/src/OT/Layout/Common/Coverage.hh b/src/OT/Layout/Common/Coverage.hh index 25056c9bc..344e87afb 100644 --- a/src/OT/Layout/Common/Coverage.hh +++ b/src/OT/Layout/Common/Coverage.hh @@ -64,6 +64,7 @@ struct Coverage { TRACE_SANITIZE (this); if (!u.format.sanitize (c)) return_trace (false); + hb_barrier (); switch (u.format) { case 1: return_trace (u.format1.sanitize (c)); diff --git a/src/OT/Layout/GDEF/GDEF.hh b/src/OT/Layout/GDEF/GDEF.hh index d3611b98f..14a9b5e5c 100644 --- a/src/OT/Layout/GDEF/GDEF.hh +++ b/src/OT/Layout/GDEF/GDEF.hh @@ -291,6 +291,7 @@ struct CaretValue { TRACE_SANITIZE (this); if (!u.format.sanitize (c)) return_trace (false); + hb_barrier (); switch (u.format) { case 1: return_trace (u.format1.sanitize (c)); case 2: return_trace (u.format2.sanitize (c)); @@ -556,6 +557,7 @@ struct MarkGlyphSets { TRACE_SANITIZE (this); if (!u.format.sanitize (c)) return_trace (false); + hb_barrier (); switch (u.format) { case 1: return_trace (u.format1.sanitize (c)); default:return_trace (true); @@ -630,6 +632,7 @@ struct GDEFVersion1_2 attachList.sanitize (c, this) && ligCaretList.sanitize (c, this) && markAttachClassDef.sanitize (c, this) && + hb_barrier () && (version.to_int () < 0x00010002u || markGlyphSetsDef.sanitize (c, this)) && (version.to_int () < 0x00010003u || varStore.sanitize (c, this))); } @@ -750,6 +753,7 @@ struct GDEF { TRACE_SANITIZE (this); if (unlikely (!u.version.sanitize (c))) return_trace (false); + hb_barrier (); switch (u.version.major) { case 1: return_trace (u.version1.sanitize (c)); #ifndef HB_NO_BEYOND_64K diff --git a/src/OT/Layout/GPOS/Anchor.hh b/src/OT/Layout/GPOS/Anchor.hh index 49e76e775..7802e397f 100644 --- a/src/OT/Layout/GPOS/Anchor.hh +++ b/src/OT/Layout/GPOS/Anchor.hh @@ -25,6 +25,7 @@ struct Anchor { TRACE_SANITIZE (this); if (!u.format.sanitize (c)) return_trace (false); + hb_barrier (); switch (u.format) { case 1: return_trace (u.format1.sanitize (c)); case 2: return_trace (u.format2.sanitize (c)); diff --git a/src/OT/Layout/GPOS/AnchorFormat3.hh b/src/OT/Layout/GPOS/AnchorFormat3.hh index 56eda4a57..db89ac925 100644 --- a/src/OT/Layout/GPOS/AnchorFormat3.hh +++ b/src/OT/Layout/GPOS/AnchorFormat3.hh @@ -37,9 +37,9 @@ struct AnchorFormat3 *x = font->em_fscale_x (xCoordinate); *y = font->em_fscale_y (yCoordinate); - if ((font->x_ppem || font->num_coords) && xDeviceTable.sanitize (&c->sanitizer, this)) + if ((font->x_ppem || font->num_coords) && xDeviceTable.sanitize (&c->sanitizer, this) && hb_barrier ()) *x += (this+xDeviceTable).get_x_delta (font, c->var_store, c->var_store_cache); - if ((font->y_ppem || font->num_coords) && yDeviceTable.sanitize (&c->sanitizer, this)) + if ((font->y_ppem || font->num_coords) && yDeviceTable.sanitize (&c->sanitizer, this) && hb_barrier ()) *y += (this+yDeviceTable).get_y_delta (font, c->var_store, c->var_store_cache); } diff --git a/src/OT/Layout/GPOS/AnchorMatrix.hh b/src/OT/Layout/GPOS/AnchorMatrix.hh index e55b8dd63..dff409c8e 100644 --- a/src/OT/Layout/GPOS/AnchorMatrix.hh +++ b/src/OT/Layout/GPOS/AnchorMatrix.hh @@ -18,6 +18,7 @@ struct AnchorMatrix { TRACE_SANITIZE (this); if (!c->check_struct (this)) return_trace (false); + hb_barrier (); if (unlikely (hb_unsigned_mul_overflows (rows, cols))) return_trace (false); unsigned int count = rows * cols; if (!c->check_array (matrixZ.arrayZ, count)) return_trace (false); @@ -25,6 +26,7 @@ struct AnchorMatrix if (c->lazy_some_gpos) return_trace (true); + hb_barrier (); for (unsigned int i = 0; i < count; i++) if (!matrixZ[i].sanitize (c, this)) return_trace (false); return_trace (true); @@ -38,6 +40,7 @@ struct AnchorMatrix if (unlikely (row >= rows || col >= cols)) return Null (Anchor); auto &offset = matrixZ[row * cols + col]; if (unlikely (!offset.sanitize (&c->sanitizer, this))) return Null (Anchor); + hb_barrier (); *found = !offset.is_null (); return this+offset; } diff --git a/src/OT/Layout/GPOS/CursivePosFormat1.hh b/src/OT/Layout/GPOS/CursivePosFormat1.hh index 92505150c..6b019ac51 100644 --- a/src/OT/Layout/GPOS/CursivePosFormat1.hh +++ b/src/OT/Layout/GPOS/CursivePosFormat1.hh @@ -128,6 +128,7 @@ struct CursivePosFormat1 const EntryExitRecord &this_record = entryExitRecord[(this+coverage).get_coverage (buffer->cur().codepoint)]; if (!this_record.entryAnchor || unlikely (!this_record.entryAnchor.sanitize (&c->sanitizer, this))) return_trace (false); + hb_barrier (); hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; skippy_iter.reset_fast (buffer->idx); @@ -145,6 +146,7 @@ struct CursivePosFormat1 buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1); return_trace (false); } + hb_barrier (); unsigned int i = skippy_iter.idx; unsigned int j = buffer->idx; diff --git a/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh b/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh index 70cf07166..57eb782a9 100644 --- a/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh +++ b/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh @@ -42,6 +42,7 @@ struct MarkMarkPosFormat1_2 mark1Coverage.sanitize (c, this) && mark2Coverage.sanitize (c, this) && mark1Array.sanitize (c, this) && + hb_barrier () && mark2Array.sanitize (c, this, (unsigned int) classCount)); } diff --git a/src/OT/Layout/GPOS/PairPosFormat1.hh b/src/OT/Layout/GPOS/PairPosFormat1.hh index fa6460852..ac2774a76 100644 --- a/src/OT/Layout/GPOS/PairPosFormat1.hh +++ b/src/OT/Layout/GPOS/PairPosFormat1.hh @@ -36,6 +36,7 @@ struct PairPosFormat1_3 TRACE_SANITIZE (this); if (!c->check_struct (this)) return_trace (false); + hb_barrier (); unsigned int len1 = valueFormat[0].get_len (); unsigned int len2 = valueFormat[1].get_len (); diff --git a/src/OT/Layout/GPOS/PairSet.hh b/src/OT/Layout/GPOS/PairSet.hh index 461360b63..5560fab17 100644 --- a/src/OT/Layout/GPOS/PairSet.hh +++ b/src/OT/Layout/GPOS/PairSet.hh @@ -45,10 +45,12 @@ struct PairSet : ValueBase bool sanitize (hb_sanitize_context_t *c, const sanitize_closure_t *closure) const { TRACE_SANITIZE (this); - if (!(c->check_struct (this) - && c->check_range (&firstPairValueRecord, + if (!(c->check_struct (this) && + hb_barrier () && + c->check_range (&firstPairValueRecord, len, closure->stride))) return_trace (false); + hb_barrier (); unsigned int count = len; const PairValueRecord *record = &firstPairValueRecord; diff --git a/src/OT/Layout/GPOS/SinglePosFormat1.hh b/src/OT/Layout/GPOS/SinglePosFormat1.hh index 57cb826e6..b2d151d44 100644 --- a/src/OT/Layout/GPOS/SinglePosFormat1.hh +++ b/src/OT/Layout/GPOS/SinglePosFormat1.hh @@ -28,6 +28,7 @@ struct SinglePosFormat1 : ValueBase TRACE_SANITIZE (this); return_trace (c->check_struct (this) && coverage.sanitize (c, this) && + hb_barrier () && /* The coverage table may use a range to represent a set * of glyphs, which means a small number of bytes can * generate a large glyph set. Manually modify the diff --git a/src/OT/Layout/GPOS/ValueFormat.hh b/src/OT/Layout/GPOS/ValueFormat.hh index 89ad7c71a..17f57db1f 100644 --- a/src/OT/Layout/GPOS/ValueFormat.hh +++ b/src/OT/Layout/GPOS/ValueFormat.hh @@ -308,6 +308,7 @@ struct ValueFormat : HBUINT16 if (unlikely (!offset.sanitize (&c, base))) return Null(Device); + hb_barrier (); return base + offset; } @@ -389,6 +390,7 @@ struct ValueFormat : HBUINT16 if (c->lazy_some_gpos) return_trace (true); + hb_barrier (); return_trace (sanitize_values_stride_unsafe (c, base, values, count, size)); } diff --git a/src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh b/src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh index 92bafb5bc..ec374f2f0 100644 --- a/src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh +++ b/src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh @@ -33,9 +33,11 @@ struct ReverseChainSingleSubstFormat1 TRACE_SANITIZE (this); if (!(coverage.sanitize (c, this) && backtrack.sanitize (c, this))) return_trace (false); + hb_barrier (); const auto &lookahead = StructAfter (backtrack); if (!lookahead.sanitize (c, this)) return_trace (false); + hb_barrier (); const auto &substitute = StructAfter (lookahead); return_trace (substitute.sanitize (c)); } diff --git a/src/OT/name/name.hh b/src/OT/name/name.hh index c8de10134..e2a25d4a0 100644 --- a/src/OT/name/name.hh +++ b/src/OT/name/name.hh @@ -242,7 +242,9 @@ struct NameRecord bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && offset.sanitize (c, base, length)); + return_trace (c->check_struct (this) && + hb_barrier () && + offset.sanitize (c, base, length)); } HBUINT16 platformID; /* Platform ID. */ @@ -465,6 +467,7 @@ struct name { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && likely (format == 0 || format == 1) && c->check_array (nameRecordZ.arrayZ, count) && c->check_range (this, stringOffset) && diff --git a/src/graph/classdef-graph.hh b/src/graph/classdef-graph.hh index c1432883f..9cf845a82 100644 --- a/src/graph/classdef-graph.hh +++ b/src/graph/classdef-graph.hh @@ -39,6 +39,7 @@ struct ClassDefFormat1 : public OT::ClassDefFormat1_3 int64_t vertex_len = vertex.obj.tail - vertex.obj.head; constexpr unsigned min_size = OT::ClassDefFormat1_3::min_size; if (vertex_len < min_size) return false; + hb_barrier (); return vertex_len >= min_size + classValue.get_size () - classValue.len.get_size (); } }; @@ -50,6 +51,7 @@ struct ClassDefFormat2 : public OT::ClassDefFormat2_4 int64_t vertex_len = vertex.obj.tail - vertex.obj.head; constexpr unsigned min_size = OT::ClassDefFormat2_4::min_size; if (vertex_len < min_size) return false; + hb_barrier (); return vertex_len >= min_size + rangeRecord.get_size () - rangeRecord.len.get_size (); } }; @@ -114,6 +116,7 @@ struct ClassDef : public OT::ClassDef { int64_t vertex_len = vertex.obj.tail - vertex.obj.head; if (vertex_len < OT::ClassDef::min_size) return false; + hb_barrier (); switch (u.format) { case 1: return ((ClassDefFormat1*)this)->sanitize (vertex); diff --git a/src/graph/coverage-graph.hh b/src/graph/coverage-graph.hh index 4f44e076d..61ca063e3 100644 --- a/src/graph/coverage-graph.hh +++ b/src/graph/coverage-graph.hh @@ -39,6 +39,7 @@ struct CoverageFormat1 : public OT::Layout::Common::CoverageFormat1_3::min_size; if (vertex_len < min_size) return false; + hb_barrier (); return vertex_len >= min_size + glyphArray.get_size () - glyphArray.len.get_size (); } }; @@ -50,6 +51,7 @@ struct CoverageFormat2 : public OT::Layout::Common::CoverageFormat2_4::min_size; if (vertex_len < min_size) return false; + hb_barrier (); return vertex_len >= min_size + rangeRecord.get_size () - rangeRecord.len.get_size (); } }; @@ -138,6 +140,7 @@ struct Coverage : public OT::Layout::Common::Coverage { int64_t vertex_len = vertex.obj.tail - vertex.obj.head; if (vertex_len < OT::Layout::Common::Coverage::min_size) return false; + hb_barrier (); switch (u.format) { case 1: return ((CoverageFormat1*)this)->sanitize (vertex); diff --git a/src/graph/gsubgpos-graph.hh b/src/graph/gsubgpos-graph.hh index 12fcbdc49..0f6d5662e 100644 --- a/src/graph/gsubgpos-graph.hh +++ b/src/graph/gsubgpos-graph.hh @@ -76,6 +76,7 @@ struct Lookup : public OT::Lookup { int64_t vertex_len = vertex.obj.tail - vertex.obj.head; if (vertex_len < OT::Lookup::min_size) return false; + hb_barrier (); return vertex_len >= this->get_size (); } @@ -351,6 +352,7 @@ struct LookupList : public OT::LookupList { int64_t vertex_len = vertex.obj.tail - vertex.obj.head; if (vertex_len < OT::LookupList::min_size) return false; + hb_barrier (); return vertex_len >= OT::LookupList::item_size * this->len; } }; @@ -364,6 +366,7 @@ struct GSTAR : public OT::GSUBGPOS GSTAR* gstar = (GSTAR*) r.obj.head; if (!gstar || !gstar->sanitize (r)) return nullptr; + hb_barrier (); return gstar; } @@ -383,6 +386,7 @@ struct GSTAR : public OT::GSUBGPOS { int64_t len = vertex.obj.tail - vertex.obj.head; if (len < OT::GSUBGPOS::min_size) return false; + hb_barrier (); return len >= get_size (); } diff --git a/src/graph/markbasepos-graph.hh b/src/graph/markbasepos-graph.hh index ae5ebd0d1..fb4166128 100644 --- a/src/graph/markbasepos-graph.hh +++ b/src/graph/markbasepos-graph.hh @@ -40,6 +40,7 @@ struct AnchorMatrix : public OT::Layout::GPOS_impl::AnchorMatrix { int64_t vertex_len = vertex.obj.tail - vertex.obj.head; if (vertex_len < AnchorMatrix::min_size) return false; + hb_barrier (); return vertex_len >= AnchorMatrix::min_size + OT::Offset16::static_size * class_count * this->rows; @@ -128,6 +129,7 @@ struct MarkArray : public OT::Layout::GPOS_impl::MarkArray int64_t vertex_len = vertex.obj.tail - vertex.obj.head; unsigned min_size = MarkArray::min_size; if (vertex_len < min_size) return false; + hb_barrier (); return vertex_len >= get_size (); } @@ -495,6 +497,7 @@ struct MarkBasePos : public OT::Layout::GPOS_impl::MarkBasePos { int64_t vertex_len = vertex.obj.tail - vertex.obj.head; if (vertex_len < u.format.get_size ()) return false; + hb_barrier (); switch (u.format) { case 1: diff --git a/src/graph/pairpos-graph.hh b/src/graph/pairpos-graph.hh index ad158cc9e..f7f74b18c 100644 --- a/src/graph/pairpos-graph.hh +++ b/src/graph/pairpos-graph.hh @@ -42,6 +42,7 @@ struct PairPosFormat1 : public OT::Layout::GPOS_impl::PairPosFormat1_3::min_size; if (vertex_len < min_size) return false; + hb_barrier (); return vertex_len >= min_size + pairSet.get_size () - pairSet.len.get_size(); @@ -198,6 +199,7 @@ struct PairPosFormat2 : public OT::Layout::GPOS_impl::PairPosFormat2_4::min_size; if (vertex_len < min_size) return false; + hb_barrier (); const unsigned class1_count = class1Count; return vertex_len >= @@ -625,6 +627,7 @@ struct PairPos : public OT::Layout::GPOS_impl::PairPos { int64_t vertex_len = vertex.obj.tail - vertex.obj.head; if (vertex_len < u.format.get_size ()) return false; + hb_barrier (); switch (u.format) { case 1: diff --git a/src/hb-aat-layout-ankr-table.hh b/src/hb-aat-layout-ankr-table.hh index 63fac8452..dbb38b1bc 100644 --- a/src/hb-aat-layout-ankr-table.hh +++ b/src/hb-aat-layout-ankr-table.hh @@ -75,6 +75,7 @@ struct ankr { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && version == 0 && c->check_range (this, anchorData) && lookupTable.sanitize (c, this, &(this+anchorData)))); diff --git a/src/hb-aat-layout-bsln-table.hh b/src/hb-aat-layout-bsln-table.hh index bf12d2e69..8e42fab2e 100644 --- a/src/hb-aat-layout-bsln-table.hh +++ b/src/hb-aat-layout-bsln-table.hh @@ -123,6 +123,7 @@ struct bsln TRACE_SANITIZE (this); if (unlikely (!(c->check_struct (this) && defaultBaseline < 32))) return_trace (false); + hb_barrier (); switch (format) { diff --git a/src/hb-aat-layout-common.hh b/src/hb-aat-layout-common.hh index 672f80e0d..05dd58c6d 100644 --- a/src/hb-aat-layout-common.hh +++ b/src/hb-aat-layout-common.hh @@ -191,6 +191,7 @@ struct LookupSegmentArray { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && first <= last && valuesZ.sanitize (c, base, last - first + 1)); } @@ -199,6 +200,7 @@ struct LookupSegmentArray { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && first <= last && valuesZ.sanitize (c, base, last - first + 1, std::forward (ds)...)); } @@ -360,6 +362,7 @@ struct LookupFormat10 { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && valueSize <= 4 && valueArrayZ.sanitize (c, glyphCount * valueSize)); } @@ -415,6 +418,7 @@ struct Lookup { TRACE_SANITIZE (this); if (!u.format.sanitize (c)) return_trace (false); + hb_barrier (); switch (u.format) { case 0: return_trace (u.format0.sanitize (c)); case 2: return_trace (u.format2.sanitize (c)); @@ -429,6 +433,7 @@ struct Lookup { TRACE_SANITIZE (this); if (!u.format.sanitize (c)) return_trace (false); + hb_barrier (); switch (u.format) { case 0: return_trace (u.format0.sanitize (c, base)); case 2: return_trace (u.format2.sanitize (c, base)); @@ -558,6 +563,7 @@ struct StateTable { TRACE_SANITIZE (this); if (unlikely (!(c->check_struct (this) && + hb_barrier () && nClasses >= 4 /* Ensure pre-defined classes fit. */ && classTable.sanitize (c, this)))) return_trace (false); diff --git a/src/hb-aat-layout-feat-table.hh b/src/hb-aat-layout-feat-table.hh index 815a1fd2a..4fbec332e 100644 --- a/src/hb-aat-layout-feat-table.hh +++ b/src/hb-aat-layout-feat-table.hh @@ -138,6 +138,7 @@ struct FeatureName { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && (base+settingTableZ).sanitize (c, nSettings))); } @@ -200,6 +201,7 @@ struct feat { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && version.major == 1 && namesZ.sanitize (c, featureNameCount, this))); } diff --git a/src/hb-aat-layout-just-table.hh b/src/hb-aat-layout-just-table.hh index 8fd3990f8..ee08da172 100644 --- a/src/hb-aat-layout-just-table.hh +++ b/src/hb-aat-layout-just-table.hh @@ -185,6 +185,7 @@ struct ActionSubrecord TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); + hb_barrier (); switch (u.header.actionType) { @@ -220,6 +221,7 @@ struct PostcompensationActionChain TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); + hb_barrier (); unsigned int offset = min_size; for (unsigned int i = 0; i < count; i++) @@ -389,6 +391,7 @@ struct just TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && version.major == 1 && horizData.sanitize (c, this, this) && vertData.sanitize (c, this, this))); diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh index 35d7c84c2..0de54e0a0 100644 --- a/src/hb-aat-layout-kerx-table.hh +++ b/src/hb-aat-layout-kerx-table.hh @@ -54,6 +54,7 @@ kerxTupleKern (int value, unsigned int offset = value; const FWORD *pv = &StructAtOffset (base, offset); if (unlikely (!c->sanitizer.check_array (pv, tupleCount))) return 0; + hb_barrier (); return *pv; } @@ -259,6 +260,7 @@ struct KerxSubTableFormat1 depth = 0; return; } + hb_barrier (); hb_mask_t kern_mask = c->plan->kern_mask; @@ -389,6 +391,7 @@ struct KerxSubTableFormat2 kern_idx = Types::offsetToIndex (kern_idx, this, arrayZ.arrayZ); const FWORD *v = &arrayZ[kern_idx]; if (unlikely (!v->sanitize (&c->sanitizer))) return 0; + hb_barrier (); return kerxTupleKern (*v, header.tuple_count (), this, c); } @@ -429,6 +432,7 @@ struct KerxSubTableFormat2 return_trace (likely (c->check_struct (this) && leftClassTable.sanitize (c, this) && rightClassTable.sanitize (c, this) && + hb_barrier () && c->check_range (this, array))); } @@ -509,6 +513,7 @@ struct KerxSubTableFormat4 double the ankrActionIndex to get the correct offset here. */ const HBUINT16 *data = &ankrData[entry.data.ankrActionIndex * 2]; if (!c->sanitizer.check_array (data, 2)) return; + hb_barrier (); unsigned int markControlPoint = *data++; unsigned int currControlPoint = *data++; hb_position_t markX = 0; @@ -537,6 +542,7 @@ struct KerxSubTableFormat4 double the ankrActionIndex to get the correct offset here. */ const HBUINT16 *data = &ankrData[entry.data.ankrActionIndex * 2]; if (!c->sanitizer.check_array (data, 2)) return; + hb_barrier (); unsigned int markAnchorPoint = *data++; unsigned int currAnchorPoint = *data++; const Anchor &markAnchor = c->ankr_table->get_anchor (c->buffer->info[mark].codepoint, @@ -557,6 +563,7 @@ struct KerxSubTableFormat4 by 4 to get the correct offset for the given action. */ const FWORD *data = (const FWORD *) &ankrData[entry.data.ankrActionIndex * 4]; if (!c->sanitizer.check_array (data, 4)) return; + hb_barrier (); int markX = *data++; int markY = *data++; int currX = *data++; @@ -639,6 +646,7 @@ struct KerxSubTableFormat6 if (unlikely (hb_unsigned_mul_overflows (offset, sizeof (FWORD32)))) return 0; const FWORD32 *v = &StructAtOffset (&(this+t.array), offset * sizeof (FWORD32)); if (unlikely (!v->sanitize (&c->sanitizer))) return 0; + hb_barrier (); return kerxTupleKern (*v, header.tuple_count (), &(this+vector), c); } else @@ -649,6 +657,7 @@ struct KerxSubTableFormat6 unsigned int offset = l + r; const FWORD *v = &StructAtOffset (&(this+t.array), offset * sizeof (FWORD)); if (unlikely (!v->sanitize (&c->sanitizer))) return 0; + hb_barrier (); return kerxTupleKern (*v, header.tuple_count (), &(this+vector), c); } } @@ -674,6 +683,7 @@ struct KerxSubTableFormat6 { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && (is_long () ? ( u.l.rowIndexTable.sanitize (c, this) && @@ -787,9 +797,10 @@ struct KerxSubTable bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (!u.header.sanitize (c) || - u.header.length <= u.header.static_size || - !c->check_range (this, u.header.length)) + if (!(u.header.sanitize (c) && + hb_barrier () && + u.header.length >= u.header.static_size && + c->check_range (this, u.header.length))) return_trace (false); return_trace (dispatch (c)); @@ -936,9 +947,10 @@ struct KerxTable bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (unlikely (!thiz()->version.sanitize (c) || - (unsigned) thiz()->version < (unsigned) T::minVersion || - !thiz()->tableCount.sanitize (c))) + if (unlikely (!(thiz()->version.sanitize (c) && + hb_barrier () && + (unsigned) thiz()->version >= (unsigned) T::minVersion && + thiz()->tableCount.sanitize (c)))) return_trace (false); typedef typename T::SubTable SubTable; @@ -949,6 +961,7 @@ struct KerxTable { if (unlikely (!st->u.header.sanitize (c))) return_trace (false); + hb_barrier (); /* OpenType kern table has 2-byte subtable lengths. That's limiting. * MS implementation also only supports one subtable, of format 0, * anyway. Certain versions of some fonts, like Calibry, contain diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index aac775405..df2f35d0d 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -259,8 +259,9 @@ struct ContextualSubtable unsigned int offset = entry.data.markIndex + buffer->info[mark].codepoint; const UnsizedArrayOf &subs_old = (const UnsizedArrayOf &) subs; replacement = &subs_old[Types::wordOffsetToIndex (offset, table, subs_old.arrayZ)]; - if (!replacement->sanitize (&c->sanitizer) || !*replacement) + if (!(replacement->sanitize (&c->sanitizer) && hb_barrier ()) || !*replacement) replacement = nullptr; + hb_barrier (); } if (replacement) { @@ -287,8 +288,9 @@ struct ContextualSubtable unsigned int offset = entry.data.currentIndex + buffer->info[idx].codepoint; const UnsizedArrayOf &subs_old = (const UnsizedArrayOf &) subs; replacement = &subs_old[Types::wordOffsetToIndex (offset, table, subs_old.arrayZ)]; - if (!replacement->sanitize (&c->sanitizer) || !*replacement) + if (!(replacement->sanitize (&c->sanitizer) && hb_barrier ()) || !*replacement) replacement = nullptr; + hb_barrier (); } if (replacement) { @@ -336,6 +338,7 @@ struct ContextualSubtable unsigned int num_entries = 0; if (unlikely (!machine.sanitize (c, &num_entries))) return_trace (false); + hb_barrier (); if (!Types::extended) return_trace (substitutionTables.sanitize (c, this, 0)); @@ -513,6 +516,7 @@ struct LigatureSubtable if (unlikely (!buffer->move_to (match_positions[--cursor % ARRAY_LENGTH (match_positions)]))) return; if (unlikely (!actionData->sanitize (&c->sanitizer))) break; + hb_barrier (); action = *actionData; uint32_t uoffset = action & LigActionOffset; @@ -523,6 +527,7 @@ struct LigatureSubtable component_idx = Types::wordOffsetToIndex (component_idx, table, component.arrayZ); const HBUINT16 &componentData = component[component_idx]; if (unlikely (!componentData.sanitize (&c->sanitizer))) break; + hb_barrier (); ligature_idx += componentData; DEBUG_MSG (APPLY, nullptr, "Action store %d last %d", @@ -533,6 +538,7 @@ struct LigatureSubtable ligature_idx = Types::offsetToIndex (ligature_idx, table, ligature.arrayZ); const HBGlyphID16 &ligatureData = ligature[ligature_idx]; if (unlikely (!ligatureData.sanitize (&c->sanitizer))) break; + hb_barrier (); hb_codepoint_t lig = ligatureData; DEBUG_MSG (APPLY, nullptr, "Produced ligature %u", lig); @@ -587,6 +593,7 @@ struct LigatureSubtable TRACE_SANITIZE (this); /* The rest of array sanitizations are done at run-time. */ return_trace (c->check_struct (this) && machine.sanitize (c) && + hb_barrier () && ligAction && component && ligature); } @@ -765,6 +772,7 @@ struct InsertionSubtable unsigned int start = entry.data.markedInsertIndex; const HBGlyphID16 *glyphs = &insertionAction[start]; if (unlikely (!c->sanitizer.check_array (glyphs, count))) count = 0; + hb_barrier (); bool before = flags & MarkedInsertBefore; @@ -793,6 +801,7 @@ struct InsertionSubtable unsigned int start = entry.data.currentInsertIndex; const HBGlyphID16 *glyphs = &insertionAction[start]; if (unlikely (!c->sanitizer.check_array (glyphs, count))) count = 0; + hb_barrier (); bool before = flags & CurrentInsertBefore; @@ -849,6 +858,7 @@ struct InsertionSubtable TRACE_SANITIZE (this); /* The rest of array sanitizations are done at run-time. */ return_trace (c->check_struct (this) && machine.sanitize (c) && + hb_barrier () && insertionAction); } @@ -944,9 +954,10 @@ struct ChainSubtable bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (!length.sanitize (c) || - length <= min_size || - !c->check_range (this, length)) + if (!(length.sanitize (c) && + hb_barrier () && + length >= min_size && + c->check_range (this, length))) return_trace (false); hb_sanitize_with_object_t with (c, this); @@ -1089,9 +1100,10 @@ struct Chain bool sanitize (hb_sanitize_context_t *c, unsigned int version HB_UNUSED) const { TRACE_SANITIZE (this); - if (!length.sanitize (c) || - length < min_size || - !c->check_range (this, length)) + if (!(length.sanitize (c) && + hb_barrier () && + length >= min_size && + c->check_range (this, length))) return_trace (false); if (!c->check_array (featureZ.arrayZ, featureCount)) @@ -1103,6 +1115,7 @@ struct Chain { if (!subtable->sanitize (c)) return_trace (false); + hb_barrier (); subtable = &StructAfter> (*subtable); } @@ -1173,7 +1186,10 @@ struct mortmorx bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (!version.sanitize (c) || !version || !chainCount.sanitize (c)) + if (!(version.sanitize (c) && + hb_barrier () && + version && + chainCount.sanitize (c))) return_trace (false); const Chain *chain = &firstChain; @@ -1182,6 +1198,7 @@ struct mortmorx { if (!chain->sanitize (c, version)) return_trace (false); + hb_barrier (); chain = &StructAfter> (*chain); } diff --git a/src/hb-aat-layout-opbd-table.hh b/src/hb-aat-layout-opbd-table.hh index 51b650fc3..9840d3a55 100644 --- a/src/hb-aat-layout-opbd-table.hh +++ b/src/hb-aat-layout-opbd-table.hh @@ -144,6 +144,7 @@ struct opbd TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this) || version.major != 1)) return_trace (false); + hb_barrier (); switch (format) { diff --git a/src/hb-aat-layout-trak-table.hh b/src/hb-aat-layout-trak-table.hh index c72c0865d..345a236e9 100644 --- a/src/hb-aat-layout-trak-table.hh +++ b/src/hb-aat-layout-trak-table.hh @@ -134,6 +134,7 @@ struct TrackData { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && sizeTable.sanitize (c, base, nSizes) && trackTable.sanitize (c, nTracks, base, nSizes))); } @@ -203,6 +204,7 @@ struct trak TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && version.major == 1 && horizData.sanitize (c, this, this) && vertData.sanitize (c, this, this))); diff --git a/src/hb-aat-ltag-table.hh b/src/hb-aat-ltag-table.hh index 6d771e151..c974025d4 100644 --- a/src/hb-aat-ltag-table.hh +++ b/src/hb-aat-ltag-table.hh @@ -46,7 +46,9 @@ struct FTStringRange bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && (base+tag).sanitize (c, length)); + return_trace (c->check_struct (this) && + hb_barrier () && + (base+tag).sanitize (c, length)); } protected: @@ -73,6 +75,7 @@ struct ltag { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && version >= 1 && tagRanges.sanitize (c, this))); } diff --git a/src/hb-atomic.hh b/src/hb-atomic.hh index 303dfe6d0..366fb32b7 100644 --- a/src/hb-atomic.hh +++ b/src/hb-atomic.hh @@ -118,12 +118,12 @@ _hb_atomic_ptr_impl_cmplexch (const void **P, const void *O_, const void *N) */ #ifndef _hb_compiler_memory_r_barrier #if defined(__ATOMIC_ACQUIRE) // gcc-like -#define _hb_compiler_memory_r_barrier() asm volatile("": : :"memory") +static inline void _hb_compiler_memory_r_barrier () { asm volatile("": : :"memory"); } #elif !defined(_MSC_VER) #include #define _hb_compiler_memory_r_barrier() std::atomic_signal_fence (std::memory_order_acquire) #else -#define _hb_compiler_memory_r_barrier() do {} while (0) +static inline void _hb_compiler_memory_r_barrier () {} #endif #endif @@ -218,5 +218,11 @@ struct hb_atomic_ptr_t T *v = nullptr; }; +static inline bool hb_barrier () +{ + _hb_compiler_memory_r_barrier (); + return true; +} + #endif /* HB_ATOMIC_HH */ diff --git a/src/hb-open-file.hh b/src/hb-open-file.hh index 04f144a72..1157ea46d 100644 --- a/src/hb-open-file.hh +++ b/src/hb-open-file.hh @@ -267,6 +267,7 @@ struct TTCHeader { TRACE_SANITIZE (this); if (unlikely (!u.header.version.sanitize (c))) return_trace (false); + hb_barrier (); switch (u.header.version.major) { case 2: /* version 2 is compatible with version 1 */ case 1: return_trace (u.version1.sanitize (c)); @@ -302,6 +303,7 @@ struct ResourceRecord TRACE_SANITIZE (this); return_trace (c->check_struct (this) && offset.sanitize (c, data_base) && + hb_barrier () && get_face (data_base).sanitize (c)); } @@ -337,6 +339,7 @@ struct ResourceTypeRecord { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && resourcesZ.sanitize (c, type_base, get_resource_count (), data_base)); @@ -385,6 +388,7 @@ struct ResourceMap { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && typeList.sanitize (c, this, &(this+typeList), data_base)); @@ -428,6 +432,7 @@ struct ResourceForkHeader { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && data.sanitize (c, this, dataLen) && map.sanitize (c, this, &(this+data))); } @@ -508,6 +513,7 @@ struct OpenTypeFontFile { TRACE_SANITIZE (this); if (unlikely (!u.tag.sanitize (c))) return_trace (false); + hb_barrier (); switch (u.tag) { case CFFTag: /* All the non-collection tags */ case TrueTag: diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index 5581484f1..6967bca3d 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -418,6 +418,7 @@ struct OffsetTo : Offset { TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); + hb_barrier (); //if (unlikely (this->is_null ())) return_trace (true); if (unlikely ((const char *) base + (unsigned) *this < (const char *) base)) return_trace (false); return_trace (true); @@ -431,6 +432,7 @@ struct OffsetTo : Offset { TRACE_SANITIZE (this); return_trace (sanitize_shallow (c, base) && + hb_barrier () && (this->is_null () || c->dispatch (StructAtOffset (base, *this), std::forward (ds)...) || neuter (c))); @@ -536,6 +538,7 @@ struct UnsizedArrayOf TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c, count))) return_trace (false); if (!sizeof... (Ts) && hb_is_trivially_copyable(Type)) return_trace (true); + hb_barrier (); for (unsigned int i = 0; i < count; i++) if (unlikely (!c->dispatch (arrayZ[i], std::forward (ds)...))) return_trace (false); @@ -725,6 +728,7 @@ struct ArrayOf TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return_trace (false); if (!sizeof... (Ts) && hb_is_trivially_copyable(Type)) return_trace (true); + hb_barrier (); unsigned int count = len; for (unsigned int i = 0; i < count; i++) if (unlikely (!c->dispatch (arrayZ[i], std::forward (ds)...))) @@ -735,7 +739,9 @@ struct ArrayOf bool sanitize_shallow (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (len.sanitize (c) && c->check_array_sized (arrayZ, len, sizeof (LenType))); + return_trace (len.sanitize (c) && + hb_barrier () && + c->check_array_sized (arrayZ, len, sizeof (LenType))); } public: @@ -866,6 +872,7 @@ struct HeadlessArrayOf TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return_trace (false); if (!sizeof... (Ts) && hb_is_trivially_copyable(Type)) return_trace (true); + hb_barrier (); unsigned int count = get_length (); for (unsigned int i = 0; i < count; i++) if (unlikely (!c->dispatch (arrayZ[i], std::forward (ds)...))) @@ -878,6 +885,7 @@ struct HeadlessArrayOf { TRACE_SANITIZE (this); return_trace (lenP1.sanitize (c) && + hb_barrier () && (!lenP1 || c->check_array_sized (arrayZ, lenP1 - 1, sizeof (LenType)))); } @@ -919,6 +927,7 @@ struct ArrayOfM1 TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return_trace (false); if (!sizeof... (Ts) && hb_is_trivially_copyable(Type)) return_trace (true); + hb_barrier (); unsigned int count = lenM1 + 1; for (unsigned int i = 0; i < count; i++) if (unlikely (!c->dispatch (arrayZ[i], std::forward (ds)...))) @@ -931,6 +940,7 @@ struct ArrayOfM1 { TRACE_SANITIZE (this); return_trace (lenM1.sanitize (c) && + hb_barrier () && (c->check_array_sized (arrayZ, lenM1 + 1, sizeof (LenType)))); } @@ -1104,6 +1114,7 @@ struct VarSizedBinSearchArrayOf TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return_trace (false); if (!sizeof... (Ts) && hb_is_trivially_copyable(Type)) return_trace (true); + hb_barrier (); unsigned int count = get_length (); for (unsigned int i = 0; i < count; i++) if (unlikely (!(*this)[i].sanitize (c, std::forward (ds)...))) @@ -1130,6 +1141,7 @@ struct VarSizedBinSearchArrayOf { TRACE_SANITIZE (this); return_trace (header.sanitize (c) && + hb_barrier () && Type::static_size <= header.unitSize && c->check_range (bytesZ.arrayZ, header.nUnits, diff --git a/src/hb-ot-cff-common.hh b/src/hb-ot-cff-common.hh index 923a32b26..6375e8b56 100644 --- a/src/hb-ot-cff-common.hh +++ b/src/hb-ot-cff-common.hh @@ -274,8 +274,10 @@ struct CFFIndex { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && (count == 0 || /* empty INDEX */ (count < count + 1u && + hb_barrier () && c->check_struct (&offSize) && offSize >= 1 && offSize <= 4 && c->check_array (offsets, offSize, count + 1u) && c->check_array ((const HBUINT8*) data_base (), 1, offset_at (count)))))); @@ -412,6 +414,7 @@ struct FDSelect0 { TRACE_SANITIZE (this); if (unlikely (!(c->check_struct (this)))) return_trace (false); + hb_barrier (); if (unlikely (!c->check_array (fds, c->get_num_glyphs ()))) return_trace (false); @@ -438,7 +441,9 @@ struct FDSelect3_4_Range bool sanitize (hb_sanitize_context_t *c, const void * /*nullptr*/, unsigned int fdcount) const { TRACE_SANITIZE (this); - return_trace (first < c->get_num_glyphs () && (fd < fdcount)); + return_trace (c->check_struct (this) && + hb_barrier () && + first < c->get_num_glyphs () && (fd < fdcount)); } GID_TYPE first; @@ -456,15 +461,20 @@ struct FDSelect3_4 bool sanitize (hb_sanitize_context_t *c, unsigned int fdcount) const { TRACE_SANITIZE (this); - if (unlikely (!c->check_struct (this) || !ranges.sanitize (c, nullptr, fdcount) || - (nRanges () == 0) || ranges[0].first != 0)) + if (unlikely (!(c->check_struct (this) && + ranges.sanitize (c, nullptr, fdcount) && + hb_barrier () && + (nRanges () != 0) && + ranges[0].first == 0))) return_trace (false); for (unsigned int i = 1; i < nRanges (); i++) if (unlikely (ranges[i - 1].first >= ranges[i].first)) return_trace (false); - if (unlikely (!sentinel().sanitize (c) || (sentinel() != c->get_num_glyphs ()))) + if (unlikely (!(sentinel().sanitize (c) && + hb_barrier () && + (sentinel() == c->get_num_glyphs ())))) return_trace (false); return_trace (true); @@ -559,6 +569,7 @@ struct FDSelect TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); + hb_barrier (); switch (format) { diff --git a/src/hb-ot-cff1-table.hh b/src/hb-ot-cff1-table.hh index 1e81dcb5e..c869e9055 100644 --- a/src/hb-ot-cff1-table.hh +++ b/src/hb-ot-cff1-table.hh @@ -275,6 +275,7 @@ struct Encoding TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); + hb_barrier (); switch (table_format ()) { @@ -376,13 +377,13 @@ struct Charset1_2 { bool sanitize (hb_sanitize_context_t *c, unsigned int num_glyphs, unsigned *num_charset_entries) const { TRACE_SANITIZE (this); - if (unlikely (!c->check_struct (this))) - return_trace (false); num_glyphs--; unsigned i; for (i = 0; num_glyphs > 0; i++) { - if (unlikely (!ranges[i].sanitize (c) || (num_glyphs < ranges[i].nLeft + 1))) + if (unlikely (!(ranges[i].sanitize (c) && + hb_barrier () && + (num_glyphs >= ranges[i].nLeft + 1)))) return_trace (false); num_glyphs -= (ranges[i].nLeft + 1); } @@ -615,6 +616,7 @@ struct Charset TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); + hb_barrier (); switch (format) { @@ -1055,6 +1057,7 @@ struct cff1 { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && likely (version.major == 1)); } @@ -1085,14 +1088,17 @@ struct cff1 nameIndex = &cff->nameIndex (cff); if ((nameIndex == &Null (CFF1NameIndex)) || !nameIndex->sanitize (&sc)) goto fail; + hb_barrier (); topDictIndex = &StructAtOffset (nameIndex, nameIndex->get_size ()); if ((topDictIndex == &Null (CFF1TopDictIndex)) || !topDictIndex->sanitize (&sc) || (topDictIndex->count == 0)) goto fail; + hb_barrier (); { /* parse top dict */ const hb_ubytes_t topDictStr = (*topDictIndex)[0]; if (unlikely (!topDictStr.sanitize (&sc))) goto fail; + hb_barrier (); cff1_top_dict_interp_env_t env (topDictStr); cff1_top_dict_interpreter_t top_interp (env); if (unlikely (!top_interp.interpret (topDict))) goto fail; @@ -1104,6 +1110,7 @@ struct cff1 { charset = &StructAtOffsetOrNull (cff, topDict.CharsetOffset); if (unlikely ((charset == &Null (Charset)) || !charset->sanitize (&sc, &num_charset_entries))) goto fail; + hb_barrier (); } fdCount = 1; @@ -1114,6 +1121,7 @@ struct cff1 if (unlikely ((fdArray == &Null (CFF1FDArray)) || !fdArray->sanitize (&sc) || (fdSelect == &Null (CFF1FDSelect)) || !fdSelect->sanitize (&sc, fdArray->count))) goto fail; + hb_barrier (); fdCount = fdArray->count; } @@ -1134,21 +1142,25 @@ struct cff1 { encoding = &StructAtOffsetOrNull (cff, topDict.EncodingOffset); if (unlikely ((encoding == &Null (Encoding)) || !encoding->sanitize (&sc))) goto fail; + hb_barrier (); } } stringIndex = &StructAtOffset (topDictIndex, topDictIndex->get_size ()); if ((stringIndex == &Null (CFF1StringIndex)) || !stringIndex->sanitize (&sc)) goto fail; + hb_barrier (); globalSubrs = &StructAtOffset (stringIndex, stringIndex->get_size ()); if ((globalSubrs != &Null (CFF1Subrs)) && !globalSubrs->sanitize (&sc)) goto fail; + hb_barrier (); charStrings = &StructAtOffsetOrNull (cff, topDict.charStringsOffset); if ((charStrings == &Null (CFF1CharStrings)) || unlikely (!charStrings->sanitize (&sc))) goto fail; + hb_barrier (); num_glyphs = charStrings->count; if (num_glyphs != sc.get_num_glyphs ()) @@ -1166,6 +1178,7 @@ struct cff1 { hb_ubytes_t fontDictStr = (*fdArray)[i]; if (unlikely (!fontDictStr.sanitize (&sc))) goto fail; + hb_barrier (); cff1_font_dict_values_t *font; cff1_top_dict_interp_env_t env (fontDictStr); cff1_font_dict_interpreter_t font_interp (env); @@ -1177,6 +1190,7 @@ struct cff1 PRIVDICTVAL *priv = &privateDicts[i]; const hb_ubytes_t privDictStr = StructAtOffset (cff, font->privateDictInfo.offset).as_ubytes (font->privateDictInfo.size); if (unlikely (!privDictStr.sanitize (&sc))) goto fail; + hb_barrier (); num_interp_env_t env2 (privDictStr); dict_interpreter_t priv_interp (env2); priv->init (); @@ -1186,6 +1200,7 @@ struct cff1 if (priv->localSubrs != &Null (CFF1Subrs) && unlikely (!priv->localSubrs->sanitize (&sc))) goto fail; + hb_barrier (); } } else /* non-CID */ @@ -1195,6 +1210,7 @@ struct cff1 const hb_ubytes_t privDictStr = StructAtOffset (cff, font->privateDictInfo.offset).as_ubytes (font->privateDictInfo.size); if (unlikely (!privDictStr.sanitize (&sc))) goto fail; + hb_barrier (); num_interp_env_t env (privDictStr); dict_interpreter_t priv_interp (env); priv->init (); @@ -1204,6 +1220,7 @@ struct cff1 if (priv->localSubrs != &Null (CFF1Subrs) && unlikely (!priv->localSubrs->sanitize (&sc))) goto fail; + hb_barrier (); } return; diff --git a/src/hb-ot-cff2-table.hh b/src/hb-ot-cff2-table.hh index af24bb998..652748b73 100644 --- a/src/hb-ot-cff2-table.hh +++ b/src/hb-ot-cff2-table.hh @@ -90,6 +90,7 @@ struct CFF2FDSelect TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); + hb_barrier (); switch (format) { @@ -115,7 +116,10 @@ struct CFF2VariationStore bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this)) && c->check_range (&varStore, size) && varStore.sanitize (c)); + return_trace (c->check_struct (this) && + hb_barrier () && + c->check_range (&varStore, size) && + varStore.sanitize (c)); } bool serialize (hb_serialize_context_t *c, const CFF2VariationStore *varStore) @@ -384,6 +388,7 @@ struct cff2 { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && likely (version.major == 2)); } @@ -414,6 +419,7 @@ struct cff2 { /* parse top dict */ hb_ubytes_t topDictStr = (cff2 + cff2->topDict).as_ubytes (cff2->topDictSize); if (unlikely (!topDictStr.sanitize (&sc))) goto fail; + hb_barrier (); num_interp_env_t env (topDictStr); cff2_top_dict_interpreter_t top_interp (env); topDict.init (); @@ -430,6 +436,7 @@ struct cff2 (charStrings == &Null (CFF2CharStrings)) || unlikely (!charStrings->sanitize (&sc)) || (globalSubrs == &Null (CFF2Subrs)) || unlikely (!globalSubrs->sanitize (&sc)) || (fdArray == &Null (CFF2FDArray)) || unlikely (!fdArray->sanitize (&sc)) || + !hb_barrier () || (((fdSelect != &Null (CFF2FDSelect)) && unlikely (!fdSelect->sanitize (&sc, fdArray->count))))) goto fail; @@ -446,6 +453,7 @@ struct cff2 { const hb_ubytes_t fontDictStr = (*fdArray)[i]; if (unlikely (!fontDictStr.sanitize (&sc))) goto fail; + hb_barrier (); cff2_font_dict_values_t *font; num_interp_env_t env (fontDictStr); cff2_font_dict_interpreter_t font_interp (env); @@ -456,6 +464,7 @@ struct cff2 const hb_ubytes_t privDictStr = StructAtOffsetOrNull (cff2, font->privateDictInfo.offset).as_ubytes (font->privateDictInfo.size); if (unlikely (!privDictStr.sanitize (&sc))) goto fail; + hb_barrier (); cff2_priv_dict_interp_env_t env2 (privDictStr); dict_interpreter_t priv_interp (env2); privateDicts[i].init (); @@ -465,6 +474,7 @@ struct cff2 if (privateDicts[i].localSubrs != &Null (CFF2Subrs) && unlikely (!privateDicts[i].localSubrs->sanitize (&sc))) goto fail; + hb_barrier (); } return; diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh index 30401b192..1d2265933 100644 --- a/src/hb-ot-cmap-table.hh +++ b/src/hb-ot-cmap-table.hh @@ -556,6 +556,7 @@ struct CmapSubtableFormat4 TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); + hb_barrier (); if (unlikely (!c->check_range (this, length))) { @@ -1427,6 +1428,7 @@ struct CmapSubtable { TRACE_SANITIZE (this); if (!u.format.sanitize (c)) return_trace (false); + hb_barrier (); switch (u.format) { case 0: return_trace (u.format0 .sanitize (c)); case 4: return_trace (u.format4 .sanitize (c)); @@ -2060,6 +2062,7 @@ struct cmap { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && likely (version == 0) && encodingRecord.sanitize (c, this)); } diff --git a/src/hb-ot-hdmx-table.hh b/src/hb-ot-hdmx-table.hh index cbcf6f5f2..8582dbe27 100644 --- a/src/hb-ot-hdmx-table.hh +++ b/src/hb-ot-hdmx-table.hh @@ -71,6 +71,7 @@ struct DeviceRecord { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && c->check_range (this, sizeDeviceRecord))); } @@ -152,6 +153,7 @@ struct hdmx { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && !hb_unsigned_mul_overflows (numRecords, sizeDeviceRecord) && min_size + numRecords * sizeDeviceRecord > numRecords * sizeDeviceRecord && sizeDeviceRecord >= DeviceRecord::min_size && diff --git a/src/hb-ot-head-table.hh b/src/hb-ot-head-table.hh index 770cf52d1..4cb6c15c6 100644 --- a/src/hb-ot-head-table.hh +++ b/src/hb-ot-head-table.hh @@ -103,6 +103,7 @@ struct head { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && version.major == 1 && magicNumber == 0x5F0F3CF5u); } diff --git a/src/hb-ot-hhea-table.hh b/src/hb-ot-hhea-table.hh index d9c9bd353..27becfda3 100644 --- a/src/hb-ot-hhea-table.hh +++ b/src/hb-ot-hhea-table.hh @@ -50,7 +50,9 @@ struct _hea bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && likely (version.major == 1)); + return_trace (c->check_struct (this) && + hb_barrier () && + likely (version.major == 1)); } public: diff --git a/src/hb-ot-kern-table.hh b/src/hb-ot-kern-table.hh index ffa11bc24..39444d803 100644 --- a/src/hb-ot-kern-table.hh +++ b/src/hb-ot-kern-table.hh @@ -79,6 +79,7 @@ struct KernSubTableFormat3 { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && c->check_range (kernValueZ, kernValueCount * sizeof (FWORD) + glyphCount * 2 + @@ -147,9 +148,10 @@ struct KernSubTable bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (unlikely (!u.header.sanitize (c) || - u.header.length < u.header.min_size || - !c->check_range (this, u.header.length))) return_trace (false); + if (unlikely (!(u.header.sanitize (c) && + hb_barrier () && + u.header.length >= u.header.min_size && + c->check_range (this, u.header.length)))) return_trace (false); return_trace (dispatch (c)); } @@ -337,6 +339,7 @@ struct kern { TRACE_SANITIZE (this); if (!u.version32.sanitize (c)) return_trace (false); + hb_barrier (); return_trace (dispatch (c)); } diff --git a/src/hb-ot-layout-base-table.hh b/src/hb-ot-layout-base-table.hh index 2b7e9e4b1..a23b6377d 100644 --- a/src/hb-ot-layout-base-table.hh +++ b/src/hb-ot-layout-base-table.hh @@ -135,6 +135,7 @@ struct BaseCoord { TRACE_SANITIZE (this); if (unlikely (!u.format.sanitize (c))) return_trace (false); + hb_barrier (); switch (u.format) { case 1: return_trace (u.format1.sanitize (c)); case 2: return_trace (u.format2.sanitize (c)); @@ -496,6 +497,7 @@ struct BASE { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && likely (version.major == 1) && hAxis.sanitize (c, this) && vAxis.sanitize (c, this) && diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh index bc3c12cf2..6b359cceb 100644 --- a/src/hb-ot-layout-common.hh +++ b/src/hb-ot-layout-common.hh @@ -460,6 +460,7 @@ struct FeatureParamsSize { TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); + hb_barrier (); /* This subtable has some "history", if you will. Some earlier versions of * Adobe tools calculated the offset of the FeatureParams subtable from the @@ -826,6 +827,7 @@ struct Feature TRACE_SANITIZE (this); if (unlikely (!(c->check_struct (this) && lookupIndex.sanitize (c)))) return_trace (false); + hb_barrier (); /* Some earlier versions of Adobe tools calculated the offset of the * FeatureParams subtable from the beginning of the FeatureList table! @@ -844,6 +846,7 @@ struct Feature unsigned int orig_offset = featureParams; if (unlikely (!featureParams.sanitize (c, this, closure ? closure->tag : HB_TAG_NONE))) return_trace (false); + hb_barrier (); if (featureParams == 0 && closure && closure->tag == HB_TAG ('s','i','z','e') && @@ -906,7 +909,8 @@ struct Record { TRACE_SANITIZE (this); const Record_sanitize_closure_t closure = {tag, base}; - return_trace (c->check_struct (this) && offset.sanitize (c, base, &closure)); + return_trace (c->check_struct (this) && + offset.sanitize (c, base, &closure)); } Tag tag; /* 4-byte Tag identifier */ @@ -1407,6 +1411,7 @@ struct Lookup { TRACE_SANITIZE (this); if (!(c->check_struct (this) && subTable.sanitize (c))) return_trace (false); + hb_barrier (); unsigned subtables = get_subtable_count (); if (unlikely (!c->visit_subtables (subtables))) return_trace (false); @@ -1422,6 +1427,8 @@ struct Lookup if (unlikely (get_type () == TSubTable::Extension && !c->get_edit_count ())) { + hb_barrier (); + /* The spec says all subtables of an Extension lookup should * have the same type, which shall not be the Extension type * itself (but we already checked for that). @@ -2172,6 +2179,7 @@ struct ClassDef { TRACE_SANITIZE (this); if (!u.format.sanitize (c)) return_trace (false); + hb_barrier (); switch (u.format) { case 1: return_trace (u.format1.sanitize (c)); case 2: return_trace (u.format2.sanitize (c)); @@ -2550,7 +2558,9 @@ struct VarRegionList bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && axesZ.sanitize (c, axisCount * regionCount)); + return_trace (c->check_struct (this) && + hb_barrier () && + axesZ.sanitize (c, axisCount * regionCount)); } bool serialize (hb_serialize_context_t *c, @@ -2744,6 +2754,7 @@ struct VarData TRACE_SANITIZE (this); return_trace (c->check_struct (this) && regionIndices.sanitize (c) && + hb_barrier () && wordCount () <= regionIndices.len && c->check_range (get_delta_bytes (), itemCount, @@ -3093,6 +3104,7 @@ struct VariationStore TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && format == 1 && regions.sanitize (c, this) && dataSets.sanitize (c, this)); @@ -3442,6 +3454,7 @@ struct Condition { TRACE_SANITIZE (this); if (!u.format.sanitize (c)) return_trace (false); + hb_barrier (); switch (u.format) { case 1: return_trace (u.format1.sanitize (c)); default:return_trace (true); @@ -3716,6 +3729,7 @@ struct FeatureTableSubstitution { TRACE_SANITIZE (this); return_trace (version.sanitize (c) && + hb_barrier () && likely (version.major == 1) && substitutions.sanitize (c, this)); } @@ -3909,6 +3923,7 @@ struct FeatureVariations { TRACE_SANITIZE (this); return_trace (version.sanitize (c) && + hb_barrier () && likely (version.major == 1) && varRecords.sanitize (c, this)); } diff --git a/src/hb-ot-layout-gsubgpos.hh b/src/hb-ot-layout-gsubgpos.hh index c8b531210..499ad673e 100644 --- a/src/hb-ot-layout-gsubgpos.hh +++ b/src/hb-ot-layout-gsubgpos.hh @@ -2051,6 +2051,7 @@ struct Rule { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && c->check_range (inputZ.arrayZ, inputZ.item_size * (inputCount ? inputCount - 1 : 0) + LookupRecord::static_size * lookupCount)); @@ -2826,6 +2827,7 @@ struct ContextFormat3 { TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); + hb_barrier (); unsigned int count = glyphCount; if (unlikely (!count)) return_trace (false); /* We want to access coverageZ[0] freely. */ if (unlikely (!c->check_array (coverageZ.arrayZ, count))) return_trace (false); @@ -3219,10 +3221,13 @@ struct ChainRule TRACE_SANITIZE (this); /* Hyper-optimized sanitized because this is really hot. */ if (unlikely (!backtrack.len.sanitize (c))) return_trace (false); + hb_barrier (); const auto &input = StructAfter (backtrack); if (unlikely (!input.lenP1.sanitize (c))) return_trace (false); + hb_barrier (); const auto &lookahead = StructAfter (input); if (unlikely (!lookahead.len.sanitize (c))) return_trace (false); + hb_barrier (); const auto &lookup = StructAfter (lookahead); return_trace (likely (lookup.sanitize (c))); } @@ -4121,11 +4126,14 @@ struct ChainContextFormat3 { TRACE_SANITIZE (this); if (unlikely (!backtrack.sanitize (c, this))) return_trace (false); + hb_barrier (); const auto &input = StructAfter (backtrack); if (unlikely (!input.sanitize (c, this))) return_trace (false); + hb_barrier (); if (unlikely (!input.len)) return_trace (false); /* To be consistent with Context. */ const auto &lookahead = StructAfter (input); if (unlikely (!lookahead.sanitize (c, this))) return_trace (false); + hb_barrier (); const auto &lookup = StructAfter (lookahead); return_trace (likely (lookup.sanitize (c))); } @@ -4209,6 +4217,7 @@ struct ExtensionFormat1 { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && extensionLookupType != T::SubTable::Extension); } @@ -4506,6 +4515,7 @@ struct GSUBGPOS { TRACE_SANITIZE (this); if (unlikely (!u.version.sanitize (c))) return_trace (false); + hb_barrier (); switch (u.version.major) { case 1: return_trace (u.version1.sanitize (c)); #ifndef HB_NO_BEYOND_64K diff --git a/src/hb-ot-layout-jstf-table.hh b/src/hb-ot-layout-jstf-table.hh index a1c125b11..0ba7eaa2c 100644 --- a/src/hb-ot-layout-jstf-table.hh +++ b/src/hb-ot-layout-jstf-table.hh @@ -214,6 +214,7 @@ struct JSTF { TRACE_SANITIZE (this); return_trace (version.sanitize (c) && + hb_barrier () && likely (version.major == 1) && scriptList.sanitize (c, this)); } diff --git a/src/hb-ot-math-table.hh b/src/hb-ot-math-table.hh index b11da464b..32e497aef 100644 --- a/src/hb-ot-math-table.hh +++ b/src/hb-ot-math-table.hh @@ -333,6 +333,7 @@ struct MathKern { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && c->check_array (mathValueRecordsZ.arrayZ, 2 * heightCount + 1) && sanitize_math_value_records (c)); } @@ -984,6 +985,7 @@ struct MathVariants return_trace (c->check_struct (this) && vertGlyphCoverage.sanitize (c, this) && horizGlyphCoverage.sanitize (c, this) && + hb_barrier () && c->check_array (glyphConstruction.arrayZ, vertGlyphCount + horizGlyphCount) && sanitize_offsets (c)); } @@ -1103,6 +1105,7 @@ struct MATH TRACE_SANITIZE (this); return_trace (version.sanitize (c) && likely (version.major == 1) && + hb_barrier () && mathConstants.sanitize (c, this) && mathGlyphInfo.sanitize (c, this) && mathVariants.sanitize (c, this)); diff --git a/src/hb-ot-maxp-table.hh b/src/hb-ot-maxp-table.hh index 0f4cc414e..8f000526b 100644 --- a/src/hb-ot-maxp-table.hh +++ b/src/hb-ot-maxp-table.hh @@ -85,7 +85,7 @@ struct maxp TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); - + hb_barrier (); if (version.major == 1) { const maxpV1Tail &v1 = StructAfter (*this); @@ -103,6 +103,7 @@ struct maxp maxp_prime->numGlyphs = hb_min (c->plan->num_output_glyphs (), 0xFFFFu); if (maxp_prime->version.major == 1) { + hb_barrier (); const maxpV1Tail *src_v1 = &StructAfter (*this); maxpV1Tail *dest_v1 = c->serializer->embed (src_v1); if (unlikely (!dest_v1)) return_trace (false); diff --git a/src/hb-ot-meta-table.hh b/src/hb-ot-meta-table.hh index e1b68bcf9..658db584c 100644 --- a/src/hb-ot-meta-table.hh +++ b/src/hb-ot-meta-table.hh @@ -51,6 +51,7 @@ struct DataMap { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && dataZ.sanitize (c, base, dataLength))); } @@ -101,6 +102,7 @@ struct meta { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && version == 1 && dataMaps.sanitize (c, this))); } diff --git a/src/hb-ot-os2-table.hh b/src/hb-ot-os2-table.hh index 19330b9bd..c2aaeb2da 100644 --- a/src/hb-ot-os2-table.hh +++ b/src/hb-ot-os2-table.hh @@ -239,6 +239,7 @@ struct OS2 if (os2_prime->version >= 2) { + hb_barrier (); auto *table = & const_cast (os2_prime->v2 ()); HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_X_HEIGHT, sxHeight); HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_CAP_HEIGHT, sCapHeight); @@ -334,9 +335,10 @@ struct OS2 { TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); - if (unlikely (version >= 1 && !v1X.sanitize (c))) return_trace (false); - if (unlikely (version >= 2 && !v2X.sanitize (c))) return_trace (false); - if (unlikely (version >= 5 && !v5X.sanitize (c))) return_trace (false); + hb_barrier (); + if (unlikely (version >= 1 && hb_barrier () && !v1X.sanitize (c))) return_trace (false); + if (unlikely (version >= 2 && hb_barrier () && !v2X.sanitize (c))) return_trace (false); + if (unlikely (version >= 5 && hb_barrier () && !v5X.sanitize (c))) return_trace (false); return_trace (true); } diff --git a/src/hb-ot-post-table.hh b/src/hb-ot-post-table.hh index aaecc348e..3ccb2967d 100644 --- a/src/hb-ot-post-table.hh +++ b/src/hb-ot-post-table.hh @@ -122,7 +122,10 @@ struct post } if (glyph_names && version.major == 2) + { + hb_barrier (); return_trace (v2X.subset (c)); + } return_trace (true); } @@ -138,6 +141,7 @@ struct post version = table->version.to_int (); if (version != 0x00020000) return; + hb_barrier (); const postV2Tail &v2 = table->v2X; @@ -217,10 +221,16 @@ struct post unsigned int get_glyph_count () const { if (version == 0x00010000) + { + hb_barrier (); return format1_names_length; + } if (version == 0x00020000) + { + hb_barrier (); return glyphNameIndex->len; + } return 0; } @@ -245,13 +255,18 @@ struct post { if (version == 0x00010000) { + hb_barrier (); if (glyph >= format1_names_length) return hb_bytes_t (); return format1_names (glyph); } - if (version != 0x00020000 || glyph >= glyphNameIndex->len) + if (version != 0x00020000) + return hb_bytes_t (); + hb_barrier (); + + if (glyph >= glyphNameIndex->len) return hb_bytes_t (); unsigned int index = glyphNameIndex->arrayZ[glyph]; @@ -284,8 +299,9 @@ struct post { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && (version.to_int () == 0x00010000 || - (version.to_int () == 0x00020000 && v2X.sanitize (c)) || + (version.to_int () == 0x00020000 && hb_barrier () && v2X.sanitize (c)) || version.to_int () == 0x00030000)); } diff --git a/src/hb-ot-stat-table.hh b/src/hb-ot-stat-table.hh index f7bb3791c..58b3cd74d 100644 --- a/src/hb-ot-stat-table.hh +++ b/src/hb-ot-stat-table.hh @@ -327,6 +327,7 @@ struct AxisValueFormat4 { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && axisValues.sanitize (c, axisCount))); } @@ -416,6 +417,7 @@ struct AxisValue TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); + hb_barrier (); switch (u.format) { @@ -560,6 +562,7 @@ struct STAT { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && version.major == 1 && version.minor > 0 && designAxesOffset.sanitize (c, this, designAxisCount) && diff --git a/src/hb-ot-var-avar-table.hh b/src/hb-ot-var-avar-table.hh index f3754aa6b..b2e5d87a3 100644 --- a/src/hb-ot-var-avar-table.hh +++ b/src/hb-ot-var-avar-table.hh @@ -273,6 +273,7 @@ struct avar { TRACE_SANITIZE (this); if (!(version.sanitize (c) && + hb_barrier () && (version.major == 1 #ifndef HB_NO_AVAR2 || version.major == 2 @@ -293,6 +294,7 @@ struct avar #ifndef HB_NO_AVAR2 if (version.major < 2) return_trace (true); + hb_barrier (); const auto &v2 = * (const avarV2Tail *) map; if (unlikely (!v2.sanitize (c, this))) @@ -316,6 +318,7 @@ struct avar #ifndef HB_NO_AVAR2 if (version.major < 2) return; + hb_barrier (); for (; count < axisCount; count++) map = &StructAfter (*map); diff --git a/src/hb-ot-var-common.hh b/src/hb-ot-var-common.hh index bc6f740f9..eff6df380 100644 --- a/src/hb-ot-var-common.hh +++ b/src/hb-ot-var-common.hh @@ -119,6 +119,7 @@ struct DeltaSetIndexMapFormat01 { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && c->check_range (mapDataZ.arrayZ, mapCount, get_width ())); @@ -191,6 +192,7 @@ struct DeltaSetIndexMap { TRACE_SANITIZE (this); if (!u.format.sanitize (c)) return_trace (false); + hb_barrier (); switch (u.format) { case 0: return_trace (u.format0.sanitize (c)); case 1: return_trace (u.format1.sanitize (c)); diff --git a/src/hb-ot-var-cvar-table.hh b/src/hb-ot-var-cvar-table.hh index 381ae3c61..3798ad3e3 100644 --- a/src/hb-ot-var-cvar-table.hh +++ b/src/hb-ot-var-cvar-table.hh @@ -45,7 +45,8 @@ struct cvar { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && - version.sanitize (c) && likely (version.major == 1) && + hb_barrier () && + likely (version.major == 1) && tupleVariationData.sanitize (c)); } diff --git a/src/hb-ot-var-fvar-table.hh b/src/hb-ot-var-fvar-table.hh index 4c4957bd7..07d7586ba 100644 --- a/src/hb-ot-var-fvar-table.hh +++ b/src/hb-ot-var-fvar-table.hh @@ -131,6 +131,7 @@ struct InstanceRecord { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && c->check_array (coordinatesZ.arrayZ, axis_count)); } @@ -277,8 +278,10 @@ struct fvar { TRACE_SANITIZE (this); return_trace (version.sanitize (c) && + hb_barrier () && likely (version.major == 1) && c->check_struct (this) && + hb_barrier () && axisSize == 20 && /* Assumed in our code. */ instanceSize >= axisCount * 4 + 4 && get_axes ().sanitize (c) && diff --git a/src/hb-ot-var-gvar-table.hh b/src/hb-ot-var-gvar-table.hh index 8ef9f0ec4..73787d723 100644 --- a/src/hb-ot-var-gvar-table.hh +++ b/src/hb-ot-var-gvar-table.hh @@ -296,7 +296,9 @@ struct gvar bool sanitize_shallow (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && (version.major == 1) && + return_trace (c->check_struct (this) && + hb_barrier () && + (version.major == 1) && sharedTuples.sanitize (c, this, axisCount * sharedTupleCount) && (is_long_offset () ? c->check_array (get_long_offset_array (), c->get_num_glyphs () + 1) : diff --git a/src/hb-ot-var-hvar-table.hh b/src/hb-ot-var-hvar-table.hh index ca1ea1ca8..53a4642d3 100644 --- a/src/hb-ot-var-hvar-table.hh +++ b/src/hb-ot-var-hvar-table.hh @@ -288,6 +288,7 @@ struct HVARVVAR { TRACE_SANITIZE (this); return_trace (version.sanitize (c) && + hb_barrier () && likely (version.major == 1) && varStore.sanitize (c, this) && advMap.sanitize (c, this) && diff --git a/src/hb-ot-var-mvar-table.hh b/src/hb-ot-var-mvar-table.hh index ceabc9a3e..6d6977761 100644 --- a/src/hb-ot-var-mvar-table.hh +++ b/src/hb-ot-var-mvar-table.hh @@ -77,8 +77,10 @@ struct MVAR { TRACE_SANITIZE (this); return_trace (version.sanitize (c) && + hb_barrier () && likely (version.major == 1) && c->check_struct (this) && + hb_barrier () && valueRecordSize >= VariationValueRecord::static_size && varStore.sanitize (c, this) && c->check_range (valuesZ.arrayZ, diff --git a/src/hb-ot-vorg-table.hh b/src/hb-ot-vorg-table.hh index 671b6d2c2..95ae8ef55 100644 --- a/src/hb-ot-vorg-table.hh +++ b/src/hb-ot-vorg-table.hh @@ -117,6 +117,7 @@ struct VORG { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && version.major == 1 && vertYOrigins.sanitize (c)); } diff --git a/src/hb-sanitize.hh b/src/hb-sanitize.hh index f2b7da167..cc1161aa8 100644 --- a/src/hb-sanitize.hh +++ b/src/hb-sanitize.hh @@ -134,7 +134,7 @@ struct hb_sanitize_context_t : const char *get_name () { return "SANITIZE"; } template bool may_dispatch (const T *obj HB_UNUSED, const F *format) - { return format->sanitize (this); } + { return format->sanitize (this) && hb_barrier (); } static return_t default_return_value () { return true; } static return_t no_dispatch_return_value () { return false; } bool stop_sublookup_iteration (const return_t r) const { return !r; }