LibWeb: Use document resolution context in canvas set_font

When a canvas belongs to a detached document (e.g. one created via
document.implementation.createHTMLDocument()), document->window()
returns null, causing a null pointer crash in set_font.

Use Length::ResolutionContext::for_document() instead of for_window(),
which handles the no-navigable case gracefully and is already the
recommended pattern (per existing FIXME in Length.h). This also fixes
the same crash path via fillText, strokeText, and measureText which
trigger lazy font initialization through set_font.

Fixes #8515.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Dylan Hart 2026-03-27 01:01:04 -05:00 committed by Jelle Raaijmakers
parent fd3a09a8ce
commit 9be298e39c
3 changed files with 28 additions and 1 deletions

View file

@ -112,7 +112,7 @@ void CanvasTextDrawingStyles<IncludingClass, CanvasType>::set_font(StringView fo
// NOTE: The initial value here is non-standard as the default font is "10px sans-serif"
// FIXME: Investigate whether this is the correct resolution context (i.e. whether we should instead use
// a font-size of 10px) for OffscreenCanvas
auto length_resolution_context = CSS::Length::ResolutionContext::for_window(*document->window());
auto length_resolution_context = CSS::Length::ResolutionContext::for_document(*document);
Optional<DOM::AbstractElement> abstract_element;
if constexpr (SameAs<CanvasType, HTML::HTMLCanvasElement>) {

View file

@ -0,0 +1,4 @@
set_font: PASS
fillText: PASS
strokeText: PASS
measureText: PASS

View file

@ -0,0 +1,23 @@
<!DOCTYPE html>
<script src="../include.js"></script>
<script>
test(() => {
const doc = document.implementation.createHTMLDocument("");
// Setting font on a canvas belonging to a detached document should not crash.
const canvas1 = doc.createElement("canvas");
const ctx1 = canvas1.getContext("2d");
ctx1.font = "bold 24px serif";
println("set_font: PASS");
// Calling fillText/strokeText/measureText with default font (lazy init) should not crash.
const canvas2 = doc.createElement("canvas");
const ctx2 = canvas2.getContext("2d");
ctx2.fillText("hello", 0, 0);
println("fillText: PASS");
ctx2.strokeText("hello", 0, 0);
println("strokeText: PASS");
const metrics = ctx2.measureText("hello");
println("measureText: PASS");
});
</script>