mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-10-20 06:59:47 +00:00
LibWeb/HTML: Avoid crash for extreme bitmap sizes in OffscreenCanvas
This commit is contained in:
parent
de3f32a5c9
commit
e3b5507113
Notes:
github-actions[bot]
2025-09-22 11:38:58 +00:00
Author: https://github.com/shannonbooth
Commit: e3b5507113
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/6251
Reviewed-by: https://github.com/AtkinsSJ ✅
4 changed files with 51 additions and 5 deletions
|
@ -134,12 +134,18 @@ void OffscreenCanvas::reset_context_to_default_state()
|
|||
});
|
||||
}
|
||||
|
||||
void OffscreenCanvas::set_new_bitmap_size(Gfx::IntSize new_size)
|
||||
WebIDL::ExceptionOr<void> OffscreenCanvas::set_new_bitmap_size(Gfx::IntSize new_size)
|
||||
{
|
||||
if (new_size.width() == 0 || new_size.height() == 0)
|
||||
m_bitmap = nullptr;
|
||||
else {
|
||||
m_bitmap = MUST(Gfx::Bitmap::create(Gfx::BitmapFormat::RGBA8888, Gfx::IntSize { new_size.width(), new_size.height() }));
|
||||
// FIXME: Other browsers appear to not throw for unreasonable sizes being set. We could consider deferring allocation of the bitmap until it is used,
|
||||
// but for now, lets just allocate it here and throw if it fails instead of crashing.
|
||||
auto bitmap_or_error = Gfx::Bitmap::create(Gfx::BitmapFormat::RGBA8888, Gfx::IntSize { new_size.width(), new_size.height() });
|
||||
if (bitmap_or_error.is_error()) {
|
||||
return WebIDL::InvalidStateError::create(realm(), Utf16String::formatted("Error in allocating bitmap: {}", bitmap_or_error.error()));
|
||||
}
|
||||
m_bitmap = bitmap_or_error.release_value();
|
||||
}
|
||||
|
||||
m_context.visit(
|
||||
|
@ -155,7 +161,9 @@ void OffscreenCanvas::set_new_bitmap_size(Gfx::IntSize new_size)
|
|||
[](Empty) {
|
||||
// Do nothing.
|
||||
});
|
||||
return {};
|
||||
}
|
||||
|
||||
RefPtr<Gfx::Bitmap> OffscreenCanvas::bitmap() const
|
||||
{
|
||||
return m_bitmap;
|
||||
|
@ -166,7 +174,7 @@ WebIDL::ExceptionOr<void> OffscreenCanvas::set_width(WebIDL::UnsignedLong value)
|
|||
Gfx::IntSize current_size = bitmap_size_for_canvas();
|
||||
current_size.set_width(value);
|
||||
|
||||
set_new_bitmap_size(current_size);
|
||||
TRY(set_new_bitmap_size(current_size));
|
||||
reset_context_to_default_state();
|
||||
return {};
|
||||
}
|
||||
|
@ -175,7 +183,7 @@ WebIDL::ExceptionOr<void> OffscreenCanvas::set_height(WebIDL::UnsignedLong value
|
|||
Gfx::IntSize current_size = bitmap_size_for_canvas();
|
||||
current_size.set_height(value);
|
||||
|
||||
set_new_bitmap_size(current_size);
|
||||
TRY(set_new_bitmap_size(current_size));
|
||||
reset_context_to_default_state();
|
||||
return {};
|
||||
}
|
||||
|
|
|
@ -80,7 +80,7 @@ private:
|
|||
JS::ThrowCompletionOr<HasOrCreatedContext> create_2d_context(JS::Value options);
|
||||
|
||||
void reset_context_to_default_state();
|
||||
void set_new_bitmap_size(Gfx::IntSize new_size);
|
||||
WebIDL::ExceptionOr<void> set_new_bitmap_size(Gfx::IntSize new_size);
|
||||
|
||||
Variant<GC::Ref<HTML::OffscreenCanvasRenderingContext2D>, GC::Ref<WebGL::WebGLRenderingContext>, GC::Ref<WebGL::WebGL2RenderingContext>, Empty> m_context;
|
||||
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
Harness status: OK
|
||||
|
||||
Found 1 tests
|
||||
|
||||
1 Fail
|
||||
Fail OffscreenCanvas test: 2d.canvas.host.size.large
|
|
@ -0,0 +1,32 @@
|
|||
<!DOCTYPE html>
|
||||
<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
|
||||
<meta charset="UTF-8">
|
||||
<title>OffscreenCanvas test: 2d.canvas.host.size.large</title>
|
||||
<script src="../../../../resources/testharness.js"></script>
|
||||
<script src="../../../../resources/testharnessreport.js"></script>
|
||||
<script src="../../../../html/canvas/resources/canvas-tests.js"></script>
|
||||
|
||||
<h1>2d.canvas.host.size.large</h1>
|
||||
<p class="desc"></p>
|
||||
|
||||
<p class="notes">Not sure how reasonable this is, but the spec doesn't say there's an upper limit on the size.
|
||||
<script>
|
||||
var t = async_test("");
|
||||
var t_pass = t.done.bind(t);
|
||||
var t_fail = t.step_func(function(reason) {
|
||||
throw reason;
|
||||
});
|
||||
t.step(function() {
|
||||
|
||||
var canvas = new OffscreenCanvas(100, 50);
|
||||
var ctx = canvas.getContext('2d');
|
||||
|
||||
var n = 2147483647; // 2^31 - 1, which should be supported by any sensible definition of "long"
|
||||
canvas.width = n;
|
||||
canvas.height = n;
|
||||
_assertSame(canvas.width, n, "canvas.width", "n");
|
||||
_assertSame(canvas.height, n, "canvas.height", "n");
|
||||
t.done();
|
||||
|
||||
});
|
||||
</script>
|
Loading…
Add table
Add a link
Reference in a new issue