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:
parent
40808fe1cd
commit
3a071bc4dd
3 changed files with 47 additions and 47 deletions
|
@ -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;
|
||||
|
|
|
@ -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")) {
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue