1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 21:17:44 +00:00

AK: Replace unsafe offset_pointer usage in OpenType code

In OpenType code, replace unsafe Span::offset_pointer with Span::offset,
which includes bounds checks.
This commit is contained in:
Gabriel Nava Marino 2023-09-22 15:01:46 -07:00 committed by Jelle Raaijmakers
parent 40808fe1cd
commit 3a071bc4dd
3 changed files with 47 additions and 47 deletions

View file

@ -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;

View file

@ -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")) {

View file

@ -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;