mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 18:27:35 +00:00
LibWeb: Add convenience methods {,de}serialize_{u,i}64()
To avoid differing logic for serializing and deserializing similar types, move the logic into separate helpers. Also, adds security checks like VERIFY to avoid reading past the end of the serialized data. If we try to read past the end of the serialized data, either our program logic is wrong or our serialized data has somehow been corrupted. Therefore, at least currently, it is better to crash by VERIFYing.
This commit is contained in:
parent
d269ac611e
commit
4751ab9f0b
3 changed files with 38 additions and 11 deletions
|
@ -106,7 +106,7 @@ WebIDL::ExceptionOr<void> File::serialization_steps(HTML::SerializationRecord& r
|
||||||
TRY(HTML::serialize_string(vm, record, m_name));
|
TRY(HTML::serialize_string(vm, record, m_name));
|
||||||
|
|
||||||
// 4. Set serialized.[[LastModified]] to the value of value’s lastModified attribute.
|
// 4. Set serialized.[[LastModified]] to the value of value’s lastModified attribute.
|
||||||
record.append(bit_cast<u32*>(&m_last_modified), 2);
|
HTML::serialize_i64(record, m_last_modified);
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -128,10 +128,7 @@ WebIDL::ExceptionOr<void> File::deserialization_steps(ReadonlySpan<u32> const& r
|
||||||
m_name = TRY(HTML::deserialize_string(vm, record, position));
|
m_name = TRY(HTML::deserialize_string(vm, record, position));
|
||||||
|
|
||||||
// 4. Initialize the value of value’s lastModified attribute to serialized.[[LastModified]].
|
// 4. Initialize the value of value’s lastModified attribute to serialized.[[LastModified]].
|
||||||
u32 bits[2] = {};
|
m_last_modified = HTML::deserialize_i64(record, position);
|
||||||
bits[0] = record[position++];
|
|
||||||
bits[1] = record[position++];
|
|
||||||
m_last_modified = *bit_cast<i64*>(&bits);
|
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
|
@ -507,11 +507,21 @@ WebIDL::ExceptionOr<void> serialize_reg_exp_object(JS::VM& vm, SerializationReco
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void serialize_u64(SerializationRecord& serialized, u64 value)
|
||||||
|
{
|
||||||
|
serialized.append(bit_cast<u32*>(&value), 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void serialize_i64(SerializationRecord& serialized, i64 value)
|
||||||
|
{
|
||||||
|
serialized.append(bit_cast<u32*>(&value), 2);
|
||||||
|
}
|
||||||
|
|
||||||
WebIDL::ExceptionOr<void> serialize_bytes(JS::VM& vm, Vector<u32>& vector, ReadonlyBytes bytes)
|
WebIDL::ExceptionOr<void> serialize_bytes(JS::VM& vm, Vector<u32>& vector, ReadonlyBytes bytes)
|
||||||
{
|
{
|
||||||
// Append size of the buffer to the serialized structure.
|
// Append size of the buffer to the serialized structure.
|
||||||
u64 const size = bytes.size();
|
u64 const size = bytes.size();
|
||||||
TRY_OR_THROW_OOM(vm, vector.try_append(bit_cast<u32*>(&size), 2));
|
serialize_u64(vector, size);
|
||||||
// Append the bytes of the buffer to the serialized structure.
|
// Append the bytes of the buffer to the serialized structure.
|
||||||
u64 byte_position = 0;
|
u64 byte_position = 0;
|
||||||
while (byte_position < size) {
|
while (byte_position < size) {
|
||||||
|
@ -1044,13 +1054,29 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::RegExpObject>> deserialize_reg_exp_obje
|
||||||
return TRY(JS::regexp_create(realm.vm(), move(pattern), move(flags)));
|
return TRY(JS::regexp_create(realm.vm(), move(pattern), move(flags)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u64 deserialize_u64(ReadonlySpan<u32> const& serialized, size_t& position)
|
||||||
|
{
|
||||||
|
VERIFY(position + 2 <= serialized.size());
|
||||||
|
u32 const bits[2] {
|
||||||
|
serialized[position++],
|
||||||
|
serialized[position++],
|
||||||
|
};
|
||||||
|
return *bit_cast<u64*>(&bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
i64 deserialize_i64(ReadonlySpan<u32> const& serialized, size_t& position)
|
||||||
|
{
|
||||||
|
VERIFY(position + 2 <= serialized.size());
|
||||||
|
u32 const bits[2] {
|
||||||
|
serialized[position++],
|
||||||
|
serialized[position++],
|
||||||
|
};
|
||||||
|
return *bit_cast<i64*>(&bits);
|
||||||
|
}
|
||||||
|
|
||||||
WebIDL::ExceptionOr<ByteBuffer> deserialize_bytes(JS::VM& vm, ReadonlySpan<u32> vector, size_t& position)
|
WebIDL::ExceptionOr<ByteBuffer> deserialize_bytes(JS::VM& vm, ReadonlySpan<u32> vector, size_t& position)
|
||||||
{
|
{
|
||||||
VERIFY(position + 2 <= vector.size());
|
u64 const size = deserialize_u64(vector, position);
|
||||||
u32 size_bits[2];
|
|
||||||
size_bits[0] = vector[position++];
|
|
||||||
size_bits[1] = vector[position++];
|
|
||||||
u64 const size = *bit_cast<u64*>(&size_bits);
|
|
||||||
|
|
||||||
auto bytes = TRY_OR_THROW_OOM(vm, ByteBuffer::create_uninitialized(size));
|
auto bytes = TRY_OR_THROW_OOM(vm, ByteBuffer::create_uninitialized(size));
|
||||||
u64 byte_position = 0;
|
u64 byte_position = 0;
|
||||||
|
|
|
@ -61,6 +61,8 @@ WebIDL::ExceptionOr<void> serialize_big_int_object(JS::VM& vm, SerializationReco
|
||||||
WebIDL::ExceptionOr<void> serialize_string_object(JS::VM& vm, SerializationRecord& serialized, JS::Value& value);
|
WebIDL::ExceptionOr<void> serialize_string_object(JS::VM& vm, SerializationRecord& serialized, JS::Value& value);
|
||||||
void serialize_date_object(SerializationRecord& serialized, JS::Value& value);
|
void serialize_date_object(SerializationRecord& serialized, JS::Value& value);
|
||||||
WebIDL::ExceptionOr<void> serialize_reg_exp_object(JS::VM& vm, SerializationRecord& serialized, JS::Value& value);
|
WebIDL::ExceptionOr<void> serialize_reg_exp_object(JS::VM& vm, SerializationRecord& serialized, JS::Value& value);
|
||||||
|
void serialize_u64(SerializationRecord& serialized, u64 value);
|
||||||
|
void serialize_i64(SerializationRecord& serialized, i64 value);
|
||||||
|
|
||||||
WebIDL::ExceptionOr<void> serialize_bytes(JS::VM& vm, Vector<u32>& vector, ReadonlyBytes bytes);
|
WebIDL::ExceptionOr<void> serialize_bytes(JS::VM& vm, Vector<u32>& vector, ReadonlyBytes bytes);
|
||||||
WebIDL::ExceptionOr<void> serialize_string(JS::VM& vm, Vector<u32>& vector, DeprecatedFlyString const& string);
|
WebIDL::ExceptionOr<void> serialize_string(JS::VM& vm, Vector<u32>& vector, DeprecatedFlyString const& string);
|
||||||
|
@ -78,6 +80,8 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::BigIntObject>> deserialize_big_int_obje
|
||||||
WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::StringObject>> deserialize_string_object(JS::Realm& realm, ReadonlySpan<u32> const& serialized, size_t& position);
|
WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::StringObject>> deserialize_string_object(JS::Realm& realm, ReadonlySpan<u32> const& serialized, size_t& position);
|
||||||
JS::NonnullGCPtr<JS::Date> deserialize_date_object(JS::Realm& realm, ReadonlySpan<u32> const& serialized, size_t& position);
|
JS::NonnullGCPtr<JS::Date> deserialize_date_object(JS::Realm& realm, ReadonlySpan<u32> const& serialized, size_t& position);
|
||||||
WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::RegExpObject>> deserialize_reg_exp_object(JS::Realm& realm, ReadonlySpan<u32> const& serialized, size_t& position);
|
WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::RegExpObject>> deserialize_reg_exp_object(JS::Realm& realm, ReadonlySpan<u32> const& serialized, size_t& position);
|
||||||
|
u64 deserialize_u64(ReadonlySpan<u32> const& serialized, size_t& position);
|
||||||
|
i64 deserialize_i64(ReadonlySpan<u32> const& serialized, size_t& position);
|
||||||
|
|
||||||
WebIDL::ExceptionOr<ByteBuffer> deserialize_bytes(JS::VM& vm, ReadonlySpan<u32> vector, size_t& position);
|
WebIDL::ExceptionOr<ByteBuffer> deserialize_bytes(JS::VM& vm, ReadonlySpan<u32> vector, size_t& position);
|
||||||
WebIDL::ExceptionOr<String> deserialize_string(JS::VM& vm, ReadonlySpan<u32> vector, size_t& position);
|
WebIDL::ExceptionOr<String> deserialize_string(JS::VM& vm, ReadonlySpan<u32> vector, size_t& position);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue