Browse Source

AK: Replace unsafe offset_pointer usage in OpenType code

In OpenType code, replace unsafe Span::offset_pointer with Span::offset,
which includes bounds checks.
Gabriel Nava Marino 1 year ago
parent
commit
3a071bc4dd

+ 19 - 19
Userland/Libraries/LibGfx/Font/OpenType/Cmap.cpp

@@ -31,7 +31,7 @@ Optional<Cmap::Subtable::Platform> Cmap::Subtable::platform_id() const
 
 Cmap::Subtable::Format Cmap::Subtable::format() const
 {
-    switch (be_u16(m_slice.offset_pointer(0))) {
+    switch (be_u16(m_slice.offset(0))) {
     case 0:
         return Format::ByteEncoding;
     case 2:
@@ -57,7 +57,7 @@ Cmap::Subtable::Format Cmap::Subtable::format() const
 
 u32 Cmap::num_subtables() const
 {
-    return be_u16(m_slice.offset_pointer((u32)Offsets::NumTables));
+    return be_u16(m_slice.offset((u32)Offsets::NumTables));
 }
 
 Optional<Cmap::Subtable> Cmap::subtable(u32 index) const
@@ -66,12 +66,12 @@ Optional<Cmap::Subtable> Cmap::subtable(u32 index) const
         return {};
     }
     u32 record_offset = (u32)Sizes::TableHeader + index * (u32)Sizes::EncodingRecord;
-    u16 platform_id = be_u16(m_slice.offset_pointer(record_offset));
-    u16 encoding_id = be_u16(m_slice.offset_pointer(record_offset + (u32)Offsets::EncodingRecord_EncodingID));
-    u32 subtable_offset = be_u32(m_slice.offset_pointer(record_offset + (u32)Offsets::EncodingRecord_Offset));
+    u16 platform_id = be_u16(m_slice.offset(record_offset));
+    u16 encoding_id = be_u16(m_slice.offset(record_offset + (u32)Offsets::EncodingRecord_EncodingID));
+    u32 subtable_offset = be_u32(m_slice.offset(record_offset + (u32)Offsets::EncodingRecord_Offset));
     if (subtable_offset >= m_slice.size())
         return {};
-    auto subtable_slice = ReadonlyBytes(m_slice.offset_pointer(subtable_offset), m_slice.size() - subtable_offset);
+    auto subtable_slice = ReadonlyBytes(m_slice.offset(subtable_offset), m_slice.size() - subtable_offset);
     return Subtable(subtable_slice, platform_id, encoding_id);
 }
 
@@ -102,7 +102,7 @@ u32 Cmap::Subtable::glyph_id_for_code_point_table_0(u32 code_point) const
 
 u32 Cmap::Subtable::glyph_id_for_code_point_table_4(u32 code_point) const
 {
-    u32 segcount_x2 = be_u16(m_slice.offset_pointer((u32)Table4Offsets::SegCountX2));
+    u32 segcount_x2 = be_u16(m_slice.offset((u32)Table4Offsets::SegCountX2));
     if (m_slice.size() < segcount_x2 * (u32)Table4Sizes::NonConstMultiplier + (u32)Table4Sizes::Constant)
         return 0;
 
@@ -110,7 +110,7 @@ u32 Cmap::Subtable::glyph_id_for_code_point_table_4(u32 code_point) const
     u32 l = 0, r = segcount - 1;
     while (l < r) {
         u32 mid = l + (r - l) / 2;
-        u32 end_code_point_at_mid = be_u16(m_slice.offset_pointer((u32)Table4Offsets::EndConstBase + (mid * 2)));
+        u32 end_code_point_at_mid = be_u16(m_slice.offset((u32)Table4Offsets::EndConstBase + (mid * 2)));
         if (code_point <= end_code_point_at_mid)
             r = mid;
         else
@@ -118,47 +118,47 @@ u32 Cmap::Subtable::glyph_id_for_code_point_table_4(u32 code_point) const
     }
 
     u32 offset = l * 2;
-    u32 start_code_point = be_u16(m_slice.offset_pointer((u32)Table4Offsets::StartConstBase + segcount_x2 + offset));
+    u32 start_code_point = be_u16(m_slice.offset((u32)Table4Offsets::StartConstBase + segcount_x2 + offset));
     if (start_code_point > code_point)
         return 0;
 
-    u32 delta = be_u16(m_slice.offset_pointer((u32)Table4Offsets::DeltaConstBase + segcount_x2 * 2 + offset));
-    u32 range = be_u16(m_slice.offset_pointer((u32)Table4Offsets::RangeConstBase + segcount_x2 * 3 + offset));
+    u32 delta = be_u16(m_slice.offset((u32)Table4Offsets::DeltaConstBase + segcount_x2 * 2 + offset));
+    u32 range = be_u16(m_slice.offset((u32)Table4Offsets::RangeConstBase + segcount_x2 * 3 + offset));
     if (range == 0)
         return (code_point + delta) & 0xffff;
     u32 glyph_offset = (u32)Table4Offsets::GlyphOffsetConstBase + segcount_x2 * 3 + offset + range + (code_point - start_code_point) * 2;
     VERIFY(glyph_offset + 2 <= m_slice.size());
-    return (be_u16(m_slice.offset_pointer(glyph_offset)) + delta) & 0xffff;
+    return (be_u16(m_slice.offset(glyph_offset)) + delta) & 0xffff;
 }
 
 u32 Cmap::Subtable::glyph_id_for_code_point_table_6(u32 code_point) const
 {
-    u32 first_code = be_u16(m_slice.offset_pointer((u32)Table6Offsets::FirstCode));
+    u32 first_code = be_u16(m_slice.offset((u32)Table6Offsets::FirstCode));
     if (code_point < first_code)
         return 0;
 
-    u32 entry_count = be_u16(m_slice.offset_pointer((u32)Table6Offsets::EntryCount));
+    u32 entry_count = be_u16(m_slice.offset((u32)Table6Offsets::EntryCount));
     u32 code_offset = code_point - first_code;
     if (code_offset > entry_count)
         return 0;
 
-    return be_u16(m_slice.offset_pointer((u32)Table6Offsets::GlyphIdArray + code_offset * 2));
+    return be_u16(m_slice.offset((u32)Table6Offsets::GlyphIdArray + code_offset * 2));
 }
 
 u32 Cmap::Subtable::glyph_id_for_code_point_table_12(u32 code_point) const
 {
-    u32 num_groups = be_u32(m_slice.offset_pointer((u32)Table12Offsets::NumGroups));
+    u32 num_groups = be_u32(m_slice.offset((u32)Table12Offsets::NumGroups));
     VERIFY(m_slice.size() >= (u32)Table12Sizes::Header + (u32)Table12Sizes::Record * num_groups);
     for (u32 offset = 0; offset < num_groups * (u32)Table12Sizes::Record; offset += (u32)Table12Sizes::Record) {
-        u32 start_code_point = be_u32(m_slice.offset_pointer((u32)Table12Offsets::Record_StartCode + offset));
+        u32 start_code_point = be_u32(m_slice.offset((u32)Table12Offsets::Record_StartCode + offset));
         if (code_point < start_code_point)
             break;
 
-        u32 end_code_point = be_u32(m_slice.offset_pointer((u32)Table12Offsets::Record_EndCode + offset));
+        u32 end_code_point = be_u32(m_slice.offset((u32)Table12Offsets::Record_EndCode + offset));
         if (code_point > end_code_point)
             continue;
 
-        u32 glyph_offset = be_u32(m_slice.offset_pointer((u32)Table12Offsets::Record_StartGlyph + offset));
+        u32 glyph_offset = be_u32(m_slice.offset((u32)Table12Offsets::Record_StartGlyph + offset));
         return code_point - start_code_point + glyph_offset;
     }
     return 0;

+ 8 - 8
Userland/Libraries/LibGfx/Font/OpenType/Font.cpp

@@ -326,7 +326,7 @@ String Name::string_for_id(NameId id) const
 
     if (platform_id == to_underlying(Platform::Windows)) {
         static auto& decoder = *TextCodec::decoder_for("utf-16be"sv);
-        return decoder.to_utf8(StringView { (char const*)m_slice.offset_pointer(storage_offset + offset), length }).release_value_but_fixme_should_propagate_errors();
+        return decoder.to_utf8(StringView { (char const*)m_slice.offset(storage_offset + offset), length }).release_value_but_fixme_should_propagate_errors();
     }
 
     return String::from_utf8(m_slice.slice(storage_offset + offset, length)).release_value_but_fixme_should_propagate_errors();
@@ -343,7 +343,7 @@ GlyphHorizontalMetrics Hmtx::get_glyph_horizontal_metrics(u32 glyph_id) const
         };
     }
 
-    auto const* left_side_bearings = bit_cast<BigEndian<u16> const*>(m_slice.offset_pointer(m_number_of_h_metrics * sizeof(LongHorMetric)));
+    auto const* left_side_bearings = bit_cast<BigEndian<u16> const*>(m_slice.offset(m_number_of_h_metrics * sizeof(LongHorMetric)));
     return GlyphHorizontalMetrics {
         .advance_width = static_cast<u16>(long_hor_metrics[m_number_of_h_metrics - 1].advance_width),
         .left_side_bearing = static_cast<i16>(left_side_bearings[glyph_id - m_number_of_h_metrics]),
@@ -369,7 +369,7 @@ ErrorOr<NonnullRefPtr<Font>> Font::try_load_from_externally_owned_memory(Readonl
         if (buffer.size() < (u32)Sizes::TTCHeaderV1 + sizeof(u32) * (index + 1))
             return Error::from_string_literal("Font file too small");
 
-        u32 offset = be_u32(buffer.offset_pointer((u32)Sizes::TTCHeaderV1 + sizeof(u32) * index));
+        u32 offset = be_u32(buffer.offset((u32)Sizes::TTCHeaderV1 + sizeof(u32) * index));
         return try_load_from_offset(buffer, offset);
     }
     if (tag == tag_from_str("OTTO"))
@@ -417,15 +417,15 @@ ErrorOr<NonnullRefPtr<Font>> Font::try_load_from_offset(ReadonlyBytes buffer, u3
     Optional<CBDT> cbdt;
     Optional<GPOS> gpos;
 
-    auto num_tables = be_u16(buffer.offset_pointer(offset + (u32)Offsets::NumTables));
+    auto num_tables = be_u16(buffer.offset(offset + (u32)Offsets::NumTables));
     if (buffer.size() < offset + (u32)Sizes::OffsetTable + num_tables * (u32)Sizes::TableRecord)
         return Error::from_string_literal("Font file too small");
 
     for (auto i = 0; i < num_tables; i++) {
         u32 record_offset = offset + (u32)Sizes::OffsetTable + i * (u32)Sizes::TableRecord;
-        u32 tag = be_u32(buffer.offset_pointer(record_offset));
-        u32 table_offset = be_u32(buffer.offset_pointer(record_offset + (u32)Offsets::TableRecord_Offset));
-        u32 table_length = be_u32(buffer.offset_pointer(record_offset + (u32)Offsets::TableRecord_Length));
+        u32 tag = be_u32(buffer.offset(record_offset));
+        u32 table_offset = be_u32(buffer.offset(record_offset + (u32)Offsets::TableRecord_Offset));
+        u32 table_length = be_u32(buffer.offset(record_offset + (u32)Offsets::TableRecord_Length));
 
         if (Checked<u32>::addition_would_overflow(table_offset, table_length))
             return Error::from_string_literal("Invalid table offset or length in font");
@@ -433,7 +433,7 @@ ErrorOr<NonnullRefPtr<Font>> Font::try_load_from_offset(ReadonlyBytes buffer, u3
         if (buffer.size() < table_offset + table_length)
             return Error::from_string_literal("Font file too small");
 
-        auto buffer_here = ReadonlyBytes(buffer.offset_pointer(table_offset), table_length);
+        auto buffer_here = ReadonlyBytes(buffer.offset(table_offset), table_length);
 
         // Get the table offsets we need.
         if (tag == tag_from_str("head")) {

+ 20 - 20
Userland/Libraries/LibGfx/Font/OpenType/Glyf.cpp

@@ -68,7 +68,7 @@ public:
         }
         switch (m_flag & (u8)SimpleGlyfFlags::XMask) {
         case (u8)SimpleGlyfFlags::XLongVector:
-            m_last_point.set_x(m_last_point.x() + be_i16(m_slice.offset_pointer(m_x_offset)));
+            m_last_point.set_x(m_last_point.x() + be_i16(m_slice.offset(m_x_offset)));
             m_x_offset += 2;
             break;
         case (u8)SimpleGlyfFlags::XNegativeShortVector:
@@ -82,7 +82,7 @@ public:
         }
         switch (m_flag & (u8)SimpleGlyfFlags::YMask) {
         case (u8)SimpleGlyfFlags::YLongVector:
-            m_last_point.set_y(m_last_point.y() + be_i16(m_slice.offset_pointer(m_y_offset)));
+            m_last_point.set_y(m_last_point.y() + be_i16(m_slice.offset(m_y_offset)));
             m_y_offset += 2;
             break;
         case (u8)SimpleGlyfFlags::YNegativeShortVector:
@@ -119,15 +119,15 @@ Optional<Glyf::Glyph::ComponentIterator::Item> Glyf::Glyph::ComponentIterator::n
     if (!m_has_more) {
         return {};
     }
-    u16 flags = be_u16(m_slice.offset_pointer(m_offset));
+    u16 flags = be_u16(m_slice.offset(m_offset));
     m_offset += 2;
-    u16 glyph_id = be_u16(m_slice.offset_pointer(m_offset));
+    u16 glyph_id = be_u16(m_slice.offset(m_offset));
     m_offset += 2;
     i16 arg1 = 0, arg2 = 0;
     if (flags & (u16)CompositeFlags::Arg1AndArg2AreWords) {
-        arg1 = be_i16(m_slice.offset_pointer(m_offset));
+        arg1 = be_i16(m_slice.offset(m_offset));
         m_offset += 2;
-        arg2 = be_i16(m_slice.offset_pointer(m_offset));
+        arg2 = be_i16(m_slice.offset(m_offset));
         m_offset += 2;
     } else {
         arg1 = (i8)m_slice[m_offset++];
@@ -135,21 +135,21 @@ Optional<Glyf::Glyph::ComponentIterator::Item> Glyf::Glyph::ComponentIterator::n
     }
     float a = 1.0, b = 0.0, c = 0.0, d = 1.0, e = 0.0, f = 0.0;
     if (flags & (u16)CompositeFlags::WeHaveATwoByTwo) {
-        a = be_fword(m_slice.offset_pointer(m_offset));
+        a = be_fword(m_slice.offset(m_offset));
         m_offset += 2;
-        b = be_fword(m_slice.offset_pointer(m_offset));
+        b = be_fword(m_slice.offset(m_offset));
         m_offset += 2;
-        c = be_fword(m_slice.offset_pointer(m_offset));
+        c = be_fword(m_slice.offset(m_offset));
         m_offset += 2;
-        d = be_fword(m_slice.offset_pointer(m_offset));
+        d = be_fword(m_slice.offset(m_offset));
         m_offset += 2;
     } else if (flags & (u16)CompositeFlags::WeHaveAnXAndYScale) {
-        a = be_fword(m_slice.offset_pointer(m_offset));
+        a = be_fword(m_slice.offset(m_offset));
         m_offset += 2;
-        d = be_fword(m_slice.offset_pointer(m_offset));
+        d = be_fword(m_slice.offset(m_offset));
         m_offset += 2;
     } else if (flags & (u16)CompositeFlags::WeHaveAScale) {
-        a = be_fword(m_slice.offset_pointer(m_offset));
+        a = be_fword(m_slice.offset(m_offset));
         m_offset += 2;
         d = a;
     }
@@ -199,9 +199,9 @@ u32 Loca::get_glyph_offset(u32 glyph_id) const
     VERIFY(glyph_id <= m_num_glyphs);
     switch (m_index_to_loc_format) {
     case IndexToLocFormat::Offset16:
-        return ((u32)be_u16(m_slice.offset_pointer(glyph_id * 2))) * 2;
+        return ((u32)be_u16(m_slice.offset(glyph_id * 2))) * 2;
     case IndexToLocFormat::Offset32:
-        return be_u32(m_slice.offset_pointer(glyph_id * 4));
+        return be_u32(m_slice.offset(glyph_id * 4));
     default:
         VERIFY_NOT_REACHED();
     }
@@ -241,15 +241,15 @@ static void get_ttglyph_offsets(ReadonlyBytes slice, u32 num_points, u32 flags_o
 ReadonlyBytes Glyf::Glyph::program() const
 {
     auto instructions_start = m_num_contours * 2;
-    u16 num_instructions = be_u16(m_slice.offset_pointer(instructions_start));
+    u16 num_instructions = be_u16(m_slice.offset(instructions_start));
     return m_slice.slice(instructions_start + 2, num_instructions);
 }
 
 void Glyf::Glyph::rasterize_impl(Gfx::Painter& painter, Gfx::AffineTransform const& transform) const
 {
     // Get offset for flags, x, and y.
-    u16 num_points = be_u16(m_slice.offset_pointer((m_num_contours - 1) * 2)) + 1;
-    u16 num_instructions = be_u16(m_slice.offset_pointer(m_num_contours * 2));
+    u16 num_points = be_u16(m_slice.offset((m_num_contours - 1) * 2)) + 1;
+    u16 num_instructions = be_u16(m_slice.offset(m_num_contours * 2));
     u32 flags_offset = m_num_contours * 2 + 2 + num_instructions;
     u32 x_offset = 0;
     u32 y_offset = 0;
@@ -261,7 +261,7 @@ void Glyf::Glyph::rasterize_impl(Gfx::Painter& painter, Gfx::AffineTransform con
 
     u32 current_point_index = 0;
     for (u16 contour_index = 0; contour_index < m_num_contours; contour_index++) {
-        u32 current_contour_last_point_index = be_u16(m_slice.offset_pointer(contour_index * 2));
+        u32 current_contour_last_point_index = be_u16(m_slice.offset(contour_index * 2));
         Optional<Gfx::FloatPoint> start_off_curve_point;
         Optional<Gfx::FloatPoint> start_on_curve_point;
         Optional<Gfx::FloatPoint> unprocessed_off_curve_point;
@@ -351,7 +351,7 @@ Optional<Glyf::Glyph> Glyf::glyph(u32 offset) const
     if (offset + sizeof(GlyphHeader) > m_slice.size())
         return {};
     VERIFY(m_slice.size() >= offset + sizeof(GlyphHeader));
-    auto const& glyph_header = *bit_cast<GlyphHeader const*>(m_slice.offset_pointer(offset));
+    auto const& glyph_header = *bit_cast<GlyphHeader const*>(m_slice.offset(offset));
     i16 num_contours = glyph_header.number_of_contours;
     i16 xmin = glyph_header.x_min;
     i16 ymin = glyph_header.y_min;