mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-09-22 09:18:55 +00:00
LibWeb/FileAPI: Make sure to always run the constructor steps for Blob
Previously we did not execute the constructor steps if we constructed a Blob from a ByteBuffer and a String. Though we only construct a Blob from ByteBuffer and String internally we still need to run these steps. By creating the new type 'BlobPartsOrByteBuffer' we can consolidate those two approaches to creating a Blob into our already existing constructor steps.
This commit is contained in:
parent
f9a54d6439
commit
a021134457
Notes:
github-actions[bot]
2025-09-03 19:45:09 +00:00
Author: https://github.com/kennethmyhra
Commit: a021134457
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/6064
Reviewed-by: https://github.com/gmta ✅
4 changed files with 27 additions and 15 deletions
|
@ -30,7 +30,11 @@ GC_DEFINE_ALLOCATOR(Blob);
|
||||||
|
|
||||||
GC::Ref<Blob> Blob::create(JS::Realm& realm, ByteBuffer byte_buffer, String type)
|
GC::Ref<Blob> Blob::create(JS::Realm& realm, ByteBuffer byte_buffer, String type)
|
||||||
{
|
{
|
||||||
return realm.create<Blob>(realm, move(byte_buffer), move(type));
|
BlobPropertyBag options = {
|
||||||
|
.type = move(type),
|
||||||
|
.endings = Bindings::EndingType::Transparent
|
||||||
|
};
|
||||||
|
return create(realm, move(byte_buffer), move(options));
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://w3c.github.io/FileAPI/#convert-line-endings-to-native
|
// https://w3c.github.io/FileAPI/#convert-line-endings-to-native
|
||||||
|
@ -81,7 +85,7 @@ ErrorOr<String> convert_line_endings_to_native(StringView string)
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://w3c.github.io/FileAPI/#process-blob-parts
|
// https://w3c.github.io/FileAPI/#process-blob-parts
|
||||||
ErrorOr<ByteBuffer> process_blob_parts(Vector<BlobPart> const& blob_parts, Optional<BlobPropertyBag> const& options)
|
ErrorOr<ByteBuffer> process_blob_parts(BlobParts const& blob_parts, Optional<BlobPropertyBag> const& options)
|
||||||
{
|
{
|
||||||
// 1. Let bytes be an empty sequence of bytes.
|
// 1. Let bytes be an empty sequence of bytes.
|
||||||
ByteBuffer bytes {};
|
ByteBuffer bytes {};
|
||||||
|
@ -182,16 +186,22 @@ WebIDL::ExceptionOr<void> Blob::deserialization_steps(HTML::TransferDataDecoder&
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://w3c.github.io/FileAPI/#ref-for-dom-blob-blob
|
// https://w3c.github.io/FileAPI/#ref-for-dom-blob-blob
|
||||||
GC::Ref<Blob> Blob::create(JS::Realm& realm, Optional<Vector<BlobPart>> const& blob_parts, Optional<BlobPropertyBag> const& options)
|
GC::Ref<Blob> Blob::create(JS::Realm& realm, Optional<BlobPartsOrByteBuffer> const& blob_parts_or_byte_buffer, Optional<BlobPropertyBag> const& options)
|
||||||
{
|
{
|
||||||
// 1. If invoked with zero parameters, return a new Blob object consisting of 0 bytes, with size set to 0, and with type set to the empty string.
|
// 1. If invoked with zero parameters, return a new Blob object consisting of 0 bytes, with size set to 0, and with type set to the empty string.
|
||||||
if (!blob_parts.has_value() && !options.has_value())
|
if (!blob_parts_or_byte_buffer.has_value() && !options.has_value())
|
||||||
return realm.create<Blob>(realm);
|
return realm.create<Blob>(realm);
|
||||||
|
|
||||||
ByteBuffer byte_buffer {};
|
ByteBuffer byte_buffer {};
|
||||||
// 2. Let bytes be the result of processing blob parts given blobParts and options.
|
// 2. Let bytes be the result of processing blob parts given blobParts and options.
|
||||||
if (blob_parts.has_value()) {
|
if (blob_parts_or_byte_buffer.has_value()) {
|
||||||
byte_buffer = MUST(process_blob_parts(blob_parts.value(), options));
|
byte_buffer = blob_parts_or_byte_buffer->visit(
|
||||||
|
[&](BlobParts const& blob_parts) {
|
||||||
|
return MUST(process_blob_parts(blob_parts, options));
|
||||||
|
},
|
||||||
|
[](ByteBuffer const& byte_buffer) {
|
||||||
|
return byte_buffer;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
auto type = String {};
|
auto type = String {};
|
||||||
|
@ -214,9 +224,9 @@ GC::Ref<Blob> Blob::create(JS::Realm& realm, Optional<Vector<BlobPart>> const& b
|
||||||
return realm.create<Blob>(realm, move(byte_buffer), move(type));
|
return realm.create<Blob>(realm, move(byte_buffer), move(type));
|
||||||
}
|
}
|
||||||
|
|
||||||
WebIDL::ExceptionOr<GC::Ref<Blob>> Blob::construct_impl(JS::Realm& realm, Optional<Vector<BlobPart>> const& blob_parts, Optional<BlobPropertyBag> const& options)
|
WebIDL::ExceptionOr<GC::Ref<Blob>> Blob::construct_impl(JS::Realm& realm, Optional<BlobParts> const& blob_parts, Optional<BlobPropertyBag> const& options)
|
||||||
{
|
{
|
||||||
return Blob::create(realm, blob_parts, options);
|
return create(realm, blob_parts.has_value() ? blob_parts.value() : Optional<BlobPartsOrByteBuffer> {}, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://w3c.github.io/FileAPI/#dfn-slice
|
// https://w3c.github.io/FileAPI/#dfn-slice
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
namespace Web::FileAPI {
|
namespace Web::FileAPI {
|
||||||
|
|
||||||
using BlobPart = Variant<GC::Root<WebIDL::BufferSource>, GC::Root<Blob>, String>;
|
using BlobPart = Variant<GC::Root<WebIDL::BufferSource>, GC::Root<Blob>, String>;
|
||||||
|
using BlobParts = Vector<BlobPart>;
|
||||||
|
using BlobPartsOrByteBuffer = Variant<BlobParts, ByteBuffer>;
|
||||||
|
|
||||||
struct BlobPropertyBag {
|
struct BlobPropertyBag {
|
||||||
String type = String {};
|
String type = String {};
|
||||||
|
@ -25,7 +27,7 @@ struct BlobPropertyBag {
|
||||||
};
|
};
|
||||||
|
|
||||||
[[nodiscard]] ErrorOr<String> convert_line_endings_to_native(StringView string);
|
[[nodiscard]] ErrorOr<String> convert_line_endings_to_native(StringView string);
|
||||||
[[nodiscard]] ErrorOr<ByteBuffer> process_blob_parts(Vector<BlobPart> const& blob_parts, Optional<BlobPropertyBag> const& options = {});
|
[[nodiscard]] ErrorOr<ByteBuffer> process_blob_parts(BlobParts const& blob_parts, Optional<BlobPropertyBag> const& options = {});
|
||||||
[[nodiscard]] bool is_basic_latin(StringView view);
|
[[nodiscard]] bool is_basic_latin(StringView view);
|
||||||
|
|
||||||
class WEB_API Blob
|
class WEB_API Blob
|
||||||
|
@ -38,8 +40,8 @@ public:
|
||||||
virtual ~Blob() override;
|
virtual ~Blob() override;
|
||||||
|
|
||||||
[[nodiscard]] static GC::Ref<Blob> create(JS::Realm&, ByteBuffer, String type);
|
[[nodiscard]] static GC::Ref<Blob> create(JS::Realm&, ByteBuffer, String type);
|
||||||
[[nodiscard]] static GC::Ref<Blob> create(JS::Realm&, Optional<Vector<BlobPart>> const& blob_parts = {}, Optional<BlobPropertyBag> const& options = {});
|
[[nodiscard]] static GC::Ref<Blob> create(JS::Realm&, Optional<BlobPartsOrByteBuffer> const& blob_parts_or_byte_buffer = {}, Optional<BlobPropertyBag> const& options = {});
|
||||||
static WebIDL::ExceptionOr<GC::Ref<Blob>> construct_impl(JS::Realm&, Optional<Vector<BlobPart>> const& blob_parts = {}, Optional<BlobPropertyBag> const& options = {});
|
static WebIDL::ExceptionOr<GC::Ref<Blob>> construct_impl(JS::Realm&, Optional<BlobParts> const& blob_parts = {}, Optional<BlobPropertyBag> const& options = {});
|
||||||
|
|
||||||
// https://w3c.github.io/FileAPI/#dfn-size
|
// https://w3c.github.io/FileAPI/#dfn-size
|
||||||
u64 size() const { return m_byte_buffer.size(); }
|
u64 size() const { return m_byte_buffer.size(); }
|
||||||
|
|
|
@ -43,7 +43,7 @@ GC::Ref<File> File::create(JS::Realm& realm)
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://w3c.github.io/FileAPI/#ref-for-dom-file-file
|
// https://w3c.github.io/FileAPI/#ref-for-dom-file-file
|
||||||
WebIDL::ExceptionOr<GC::Ref<File>> File::create(JS::Realm& realm, Vector<BlobPart> const& file_bits, String const& file_name, Optional<FilePropertyBag> const& options)
|
WebIDL::ExceptionOr<GC::Ref<File>> File::create(JS::Realm& realm, BlobParts const& file_bits, String const& file_name, Optional<FilePropertyBag> const& options)
|
||||||
{
|
{
|
||||||
auto& vm = realm.vm();
|
auto& vm = realm.vm();
|
||||||
|
|
||||||
|
@ -83,7 +83,7 @@ WebIDL::ExceptionOr<GC::Ref<File>> File::create(JS::Realm& realm, Vector<BlobPar
|
||||||
return realm.create<File>(realm, move(bytes), move(name), move(type), last_modified);
|
return realm.create<File>(realm, move(bytes), move(name), move(type), last_modified);
|
||||||
}
|
}
|
||||||
|
|
||||||
WebIDL::ExceptionOr<GC::Ref<File>> File::construct_impl(JS::Realm& realm, Vector<BlobPart> const& file_bits, String const& file_name, Optional<FilePropertyBag> const& options)
|
WebIDL::ExceptionOr<GC::Ref<File>> File::construct_impl(JS::Realm& realm, BlobParts const& file_bits, String const& file_name, Optional<FilePropertyBag> const& options)
|
||||||
{
|
{
|
||||||
return create(realm, file_bits, file_name, options);
|
return create(realm, file_bits, file_name, options);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,8 +20,8 @@ class File : public Blob {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static GC::Ref<File> create(JS::Realm& realm);
|
static GC::Ref<File> create(JS::Realm& realm);
|
||||||
static WebIDL::ExceptionOr<GC::Ref<File>> create(JS::Realm&, Vector<BlobPart> const& file_bits, String const& file_name, Optional<FilePropertyBag> const& options = {});
|
static WebIDL::ExceptionOr<GC::Ref<File>> create(JS::Realm&, BlobParts const& file_bits, String const& file_name, Optional<FilePropertyBag> const& options = {});
|
||||||
static WebIDL::ExceptionOr<GC::Ref<File>> construct_impl(JS::Realm&, Vector<BlobPart> const& file_bits, String const& file_name, Optional<FilePropertyBag> const& options = {});
|
static WebIDL::ExceptionOr<GC::Ref<File>> construct_impl(JS::Realm&, BlobParts const& file_bits, String const& file_name, Optional<FilePropertyBag> const& options = {});
|
||||||
|
|
||||||
virtual ~File() override;
|
virtual ~File() override;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue