Commit Graph

31 Commits

Author SHA1 Message Date
Andreas Kling
5da72570b8 LibWeb: Harden UA event handlers on range and number inputs
These handlers crashed on several kinds of JS-dispatched input:
zero-width range (divide by zero in the slider mouse handler),
step="any" (MUST(step_up) throws InvalidStateError), plain Event
without clientX/deltaY/key (unchecked as_foo() asserts on
undefined), min > max (trips clamp()'s VERIFY), and input.type
changes leaving the range listeners attached to dereference empty
Optionals from the range-only min()/max() accessors.

Gate each handler on its expected type_state() and on
allowed_value_step() having a value, validate event property types
before converting, and bail out on zero-width rects or min > max.
Six crash tests cover the new paths.

Hit on a Cloudflare challenge page.
2026-04-24 07:58:34 +02:00
Andreas Kling
354a20217c LibWeb: Handle null active document in destroy_the_child_navigable
When an ancestor document is unloaded, its child documents are unloaded
(and destroyed) first, which leaves their navigable's active document
null. If the ancestor's pagehide handler then removes a subtree
containing one of those iframe containers, destroy_the_child_navigable
crashed dereferencing the null active document.

Treat the "destroy a document and its descendants" step as a no-op when
there is no document left to destroy, and still run the remaining
post-destruction cleanup.

This fixes a crash when closing a GMail tab.
2026-04-16 12:38:38 +02:00
Andreas Kling
0f4575e7d0 LibWeb: Clear stale layout state for inactive documents
IntersectionObserver can keep elements from a navigated iframe's old
document alive until a later rendering update. Once that document tears
down its layout tree, descendant nodes and pseudo-elements can still
retain stale layout and paintable pointers, and destruction can bypass
the usual inactive-document teardown entirely.

Clear per-node layout and paintable pointers across the inactive
document subtree before tearing down the layout tree, and do the same
from destroy() for documents that never go through
did_stop_being_active_document_in_navigable().

Add a crash test that observes an iframe target, navigates the iframe,
and waits for rendering updates without touching stale layout state.

Fixes #8670
2026-04-11 16:03:26 +02:00
Zaggy1024
84e0b7d36f LibWeb: Increment the fetch generation when cancelling media fetch
The case of an unsupported format error wasn't covered for this,
meaning that it could crash if the fetch completed successfully after
the fetch was cancelled due to such an error.

A crash test is included for this issue, using an echo of a large
corrupted WebM file to ensure that the fetch completes after media
init.
2026-04-08 13:03:39 +02:00
Zaggy1024
8208d6f3c5 LibMedia: Ignore unknown track types in FFmpegDemuxer
Fixes #8804.
2026-04-08 13:03:39 +02:00
Tim Ledbetter
648ececa62 LibWeb: Remove unused ran_media_element_task variable
Writing to this variable triggered a stack use after return ASAN error.
This variable is safe to remove since it was written to but never read.
2026-04-08 05:10:40 +02:00
Zaggy1024
666ce0f854 LibMedia: Deal with tracks being toggled during seeks properly
This fixes a crash when a track is enabled and then disabled while a
seek is in progress.

The logic in SeekingStateHandler is reworked to keep track of the
tracks that are currently being seeked, and when a track is disabled,
it is no longer counted against the seek completion. Any seek
completion callback that was instated is cleared by calling seek with
a null callback.

It may be worth making a separate function on the data providers to
clear the current seek instead, to avoid the extra work of seeking, but
this scenario is a very rare one unless someone intentionally triggers
it, and the cost is minimal unless the toggles are spammed.

A crash test is included, which both tests for the crash, and would
also time out if the failing VERIFY in on_track_enabled() was avoided
with the previous seeking implementation, due to the originally-enabled
video track's seek callback being clobbered by on_track_enabled()'s
seek.
2026-04-03 20:13:15 -05:00
Guilherme Mendes
2064bde5f9 LibWeb: Add case when <br> has display other than 'none'
When <br> element style display is not 'none', it must be an inline box.
Add a condition to ensure <br> is treated as an inline element
instead of a table, flex, or grid in that case,
preventing program from crashing.
Fixes #5568
2026-03-30 12:34:46 +01:00
Johan Dahlin
78d883a779 LibWeb: Fix canvas text crash on documents without a navigable
Use ResolutionContext::for_document() instead of for_window() in
canvas set_font() so it works when document->window() is null.
2026-03-30 11:27:47 +01:00
Tim Ledbetter
cbd01b8efc LibWeb: Use fallible FormAssociatedElement cast in form elements filter
The `HTMLFormControlsCollection` filter iterates all descendants of the
form's root, which may include non HTMLElement elements such as SVG
elements. The unchecked `as<FormAssociatedElement>` cast would crash on
these elements. Use `as_if` with a null check instead.

This fixes a regression introduced in 9af3e34875.
2026-03-26 08:31:00 +01:00
Jelle Raaijmakers
dd6d17d60d LibWeb: Don't crash accessing stale nested navigable paintable
The scroll state collection loop in
record_display_list_and_scroll_state() called paintable() on hosted
documents, which asserts layout is up to date. This crashes when a
nested document has stale layout but a cached display list, e.g. a
render-blocked iframe whose DOM was modified by document.open().
Since scroll offsets are independent of layout freshness, use
unsafe_paintable() to skip the assertion.
2026-03-24 12:47:02 +01:00
Johan Dahlin
dfe5d009d0 LibWeb: Fix CSS style computation crashes on detached documents
Replace VERIFY assertions with fallbacks in Length::for_element()
when computed_properties or root element is null. Guard
inheritance_parent->computed_properties() in StyleComputer.
2026-03-20 15:56:50 -05:00
Tim Ledbetter
849551714b LibWeb: Handle null navigable in Location::reload()
The specification says that a document's node navigable is null if
there is no such navigable.
2026-03-20 15:56:27 -05:00
Tim Ledbetter
26389363ad LibGfx+LibWeb: Move Skia backend context to process level singleton
Previously, this was attached to the traversable navigable. Using a
singleton instead allows us to use the context for detached documents.
2026-03-19 13:35:16 +01:00
Tim Ledbetter
40dd06491b LibWeb: Ensure list has child elements before invalidating ordinals
Previously, updating the `reversed`, `start` or `type` attribute of an
ordered list with text only children would cause a crash.
2026-03-17 16:50:06 +01:00
Tim Ledbetter
a4f6ce3662 LibWeb: Use unsafe_layout_node() when handling alt attribute changes
The layout node is only accessed to clear the cached alt value, so the
layout tree doesn't need to be up to date in this case.
2026-03-17 09:07:10 +01:00
Tim Ledbetter
87df9a9718 LibWeb: Update layout before accessing paintable in label activation 2026-03-03 16:35:37 +01:00
Andreas Kling
ed26fdaa81 LibWeb: Remove ViewportClient from ImagePaintable and VideoBox
Neither of these classes did anything useful as ViewportClients:

- ImagePaintable called set_visible_in_viewport() which is a FIXME
  no-op in every ImageProvider implementation.
- VideoBox had an empty did_set_viewport_rect() with a FIXME comment.

More importantly, they caused a crash when a DOM node was adopted into
a different document: the old ImagePaintable/VideoBox would still be
registered with the old document, but their document() accessor (which
goes through the DOM node) would return the new document. During GC
finalization, unregister_viewport_client() would fail because it was
trying to unregister from the wrong document.

The only meaningful ViewportClient is HTMLImageElement (for responsive
image source selection), which already handles document adoption
correctly in adopted_from().

Fixes crash when loading https://msn.com/
2026-02-26 09:25:25 +01:00
Tim Ledbetter
91b7525e18 LibWeb: Ensure favicon URL is valid before fetching it
Previously, we would crash when attempting to fetch the favicon if
the `<base>` element had an invalid URL.
2026-02-24 15:05:31 +01:00
Zaggy1024
470248e00d LibMedia+LibWeb: Stop ref counting PlaybackManager
PlaybackManager's ref counting was only used to keep it alive in a few
callbacks. Instead, the callbacks can use weak references that can only
be used from the thread that the PlaybackManager was created on, to
ensure that the PlaybackManager can't be destroyed while being
accessed.

This ensures that:
- The PlaybackManager is destroyed immediately when it is reassigned
  by HTMLMediaElement
- No callbacks are invoked after that point

This fixes the crash initially being addressed by #8081. The test from
that PR has been included as a regression test.
2026-02-23 08:49:13 +00:00
Tim Ledbetter
db35fa5f6a LibWeb: Don't crash in Storage::broadcast() if document has no navigable 2026-02-12 15:33:13 +00:00
Andreas Kling
d0fd5dd731 Tests/LibWeb: Add crash tests for image loading in removed iframes
Add 18 crash tests covering various scenarios where image loading
callbacks fire after an iframe has been removed from the DOM,
making its document inactive. These tests cover microtasks,
element tasks, batching dispatcher callbacks, decode promises,
lazy loading, srcset, picture elements, nested iframes, document
adoption, and iframe reattach/remove cycles.
2026-02-10 21:19:35 +01:00
Tim Ledbetter
e04446802f LibWeb: Implement label activation behavior in the DOM layer
Previously, click handling for labels was handled in layout and
painting code. This change implements activation_behavior on
HTMLLabelElement, which clicks and focuses the element.
2026-01-27 18:35:38 +01:00
InvalidUsernameException
375020d8ce LibWeb: Do not attempt to access elements of empty list
This recovers 750+ WPT subtests that were lost when
https://github.com/web-platform-tests/wpt/pull/56913 was merged and
added new testcases, two of which exposed this crash.

I have added my own testcase instead of importing the affected WPT tests
since they are large and complex, which makes it hard to understand
where the problem is coming from based on them alone. Also this is only
a crash test (i.e. not a different kind) because the tested scenario
doesn't actually behave correctly yet for seemingly unrelated reasons.
2026-01-02 10:14:07 +01:00
Gingeh
dd15dfffd1 LibWeb: Check null in getComputedStyle on inactive view transition 2025-12-17 14:12:47 +00:00
Zaggy1024
d9e663fc44 Tests: Add a crash test for setting HTMLMediaElement src repeatedly 2025-10-27 17:28:49 -07:00
Lyra
39dae6fb2d LibWeb: Fix SRI handling of badly-formatted strings 2025-05-06 13:02:58 -04:00
Shannon Booth
a14481ee05 LibWeb/HTML: Handle no parent element for Element::list_owner
Fixes a crash when running Speedometer 3.0 as reduced in the included
test case.
2025-04-18 10:48:47 +02:00
Aliaksandr Kalenik
0f697193f0 LibWeb: Check if navigable has active window before navigating
Fixes https://github.com/LadybirdBrowser/ladybird/issues/3733
2025-02-28 23:15:35 +01:00
Tim Ledbetter
dd8cca180f LibWeb: Remove unintentional recursion in ValidityState::valid 2025-02-18 21:58:35 +01:00
Andreas Kling
a0b44ff5e7 LibWeb: Iterate over a copy of associated form controls in form.reset()
DOM structure may change during reset algorithm invocation, which may
lead to form controls being unregistered.
2025-01-21 17:02:51 +01:00