Commit graph

79425 commits

Author SHA1 Message Date
Jelle Raaijmakers
cf3bb8c129 LibWeb: Distinguish first and last baseline sets in box_baseline()
box_baseline() applied CSS2's bottom margin edge rule for non-visible
overflow to every caller, so flex items with hidden overflow were
baseline-aligned by their margin edge instead of their text. CSS Align
scopes that rule to a box's last baseline set, while flex baseline
alignment and table cells use the first set, which always derives from
content. Parameterize box_baseline() on the requested baseline set and
propagate it through the recursive child lookup.
2026-06-16 10:39:02 +02:00
Jelle Raaijmakers
eb85264e44 CI: Switch macOS runners to macos-26
All our self-hosted runners have been updated.
2026-06-16 09:44:38 +02:00
Callum Law
1fa1de72fd LibWeb: Simplify ImageProvider frame getters
Merge `current_image_frame` and `current_image_frame_sized` into a
single method which takes an `Optional<Gfx::IntSize>`.

Rename `default_image_frame_sized` to `default_image_frame` and make
it's `Gfx::IntSize` argument `Optional`.
2026-06-16 09:26:15 +02:00
Callum Law
a40b1183ad LibWeb: Hoist overloaded ImageProvider methods to base class
All of these overloads did the same thing so lets just define them in
the base class
2026-06-16 09:26:15 +02:00
Callum Law
60c6cc2f0f LibWeb: Remove unused ImageProvider methods 2026-06-16 09:26:15 +02:00
Callum Law
1bdcdaf088 LibWeb: Format create_image_bitmap_impl comments 2026-06-16 09:26:15 +02:00
Callum Law
79cb52bb34 LibWeb: Simplify BitmapDecodedImageData
As of 97986f9 `BitmapDecodedImageData` can only ever hold a single
frame.

Also `::create` is infallible so there's no need for it to return
`ErrorOr`.
2026-06-16 09:26:15 +02:00
Callum Law
34df191e54 LibWeb: Remove unused SVGDecodedImageData::surface()
The only caller was removed in 395a126
2026-06-16 09:26:15 +02:00
Shannon Booth
6719f01a40 LibHTTP: Treat PSL star-rule domains as public suffixes
Use IncludeStarRule::Yes for cookie public-suffix checks so domains not
explicitly listed in the PSL still get treated as public suffixes via
the implicit * rule. This fixes accepting cookies for bare TLD-like
domains.
2026-06-16 06:14:07 +02:00
Shannon Booth
3f7b31fc78 LibURL: Let Host use PublicSuffixData star rule matching
Ever since PublicSuffixData was created, it was using "no star rule"
matching, which is what is needed for the address bar to distinguish
between a domain and a search. URL::Host on the other hand requires
the fallback star rule. Which rule is needed depends on the use case
of the PSL. Support both use cases by a flag in PublicSuffixData.
2026-06-16 06:14:07 +02:00
Shannon Booth
928007356c LibHTTP: Preserve single-dot cookie domains
I suspect this is not an important case, but since both Firefox and
Chromium implement it, let's match their behaviour. While this does
not matter the exact letter of the spec, the relevant WPT test was
alongside this spec text as part of a spec change trying to align
to align spec behaviour with Chromium and Firefox, so I believe
what is implemented here to be the intention of the specification
authors.
2026-06-16 06:14:07 +02:00
Andreas Kling
5a000da13e Compositor: Keep pinch zoom transforms in sync
Preserve fractional pinch focal points when updating the
main-thread visual viewport. Only coalesce queued pinch events
that share the same focal point and modifiers so WebContent sees
a transform equivalent to the event sequence seen by the
compositor.

Also clear a speculative async visual viewport transform once
async wheel or pinch admission becomes blocked. At that point the
compositor can no longer advance that transform to match
WebContent. Use a looser translation tolerance when comparing
visual viewport transforms to account for subpixel differences in
the compositor and main-thread math.
2026-06-16 02:03:59 +02:00
Andreas Kling
4e047ae97b LibWeb: Keep pinch zoom out of client rects
Keep the visual viewport transform out of Element client rects and
IntersectionObserver geometry. Pinch zoom should change the visual
viewport, but not the layout viewport coordinates exposed through DOM
geometry APIs.

Thread an opt-out through rectangle mapping so paint and hit testing
still use the full visual transform while web-observable geometry can
stay in layout viewport coordinates. This matches the Blink and WebKit
page scale model and keeps responsive script from treating pinch zoom
like a relayout.

Add coverage for getBoundingClientRect() under pinch zoom and visual
viewport IntersectionObserver geometry.
2026-06-16 02:03:59 +02:00
Andreas Kling
a11c281dc3 Compositor: Handle pinch zoom asynchronously
Apply pinch zoom deltas to the compositor's visual viewport transform
so the currently presented display list can respond without waiting for
the WebContent main thread. Keep the normal WebContent pinch event path
so the real VisualViewport state and DOM-visible events catch up after.

Only take the compositor path when async scrolling is enabled and there
are no blocking wheel listeners, since pinch zoom dispatches a synthetic
wheel event that script may cancel. Coalesce queued pinch events in
WebContent so main-thread catch-up can adopt multiple gesture deltas
together.

Use the compositor visual viewport transform for wheel hit testing and
consume wheel deltas as visual viewport pan while zoomed. Scale the
handoff to layout viewport scrolling by the inverse visual viewport
scale, so touchpad momentum does not jump when the visual viewport hits
an edge.
2026-06-16 02:03:59 +02:00
Tim Ledbetter
5378c389aa LibSandbox: Return ENOENT for getcwd() instead of trapping
Previously, passing a certificate using `--certificate` that had a
relative path would  cause a sandbox violation on the first https
connection.
2026-06-16 01:03:43 +02:00
Aliaksandr Kalenik
be9ee28afc LibGfx: Stop caching Skia images during canvas playback
The decoded-frame Skia image cache is useful for display-list
rasterization because decoded image resources can be replayed over many
frames. The cache lets that path reuse SkImage wrappers and GPU-backed
copies instead of rebuilding them whenever the same resource is painted.

For canvas, commands are consumed into one backing surface and decoded
frames are already held by the command or paint style for the draw. A
per-painter cache does not match that usage model, and can keep decoded
frames and Skia images alive after the draw has consumed them.

This removes the cache from PainterSkia and drops the now-unused pruning
hook from CanvasCommandPlayer. With the cache gone, PainterSkia can hold
its painting surface directly instead of allocating a private Impl.
DisplayListPlayerSkia keeps owning the cache, so display-list
rasterization keeps the SkImage reuse behavior.
2026-06-16 00:38:30 +02:00
Andreas Kling
394312ab5a LibWeb: Let newer navigations win history races
Treat pending session history entries as absent from the used step
graph, and share that through a small step_value() helper so
snapshotting, Navigation API entry construction, target-entry lookup,
and forward clearing do not drift apart.

Keep cross-document history application tied to the navigation id that
created it. Queued changing-navigable work now finishes without
applying when a later navigation has already replaced its target, and
any traversal sentinel is cleared through the shared setter so queued
navigations can drain.

When navigation arrives while traversal is still ongoing, keep only the
newest pending navigation. This matches Chromium, WebKit, and Gecko on
sites that click through product or category links while prior loads
settle.

Revalidate queued same-document child continuations before running them
from null-document tasks, so removed frames or frames claimed by newer
navigations do not receive stale history state.

Preserve nested-history descriptors even when all child entries are
pending, keeping live child navigable identity available for later UI
process history seeds.

Add regression coverage for iframe renavigation during history commit,
for pending child history followed by a real navigation, and for removed
iframes with queued history updates.
2026-06-16 00:00:38 +02:00
Andreas Kling
2d9db6c1f8 LibWeb: Keep stale child history tasks runnable
Child navigables can lose document-associated apply-history tasks when
a parent page replaces or destroys the child document. Queue child tasks
with no document association so they remain runnable, and share that
choice for both activation and update-only continuations. Keep top-level
work associated with the active document to preserve initial about:blank
Window reuse.

Also abandon a queued child fetch if its parent document is already gone
before reading the parent's relevant settings object. This matches
browser behavior for detached frame navigations and avoids resuming
stale work against a discarded parent.

The Twinings menu to Black Tea to Earl Grey product flow now reaches the
product main content under Ladybird WebDriver. Existing navigation
coverage and the full LibWeb text suite cover the local history cases.
2026-06-16 00:00:38 +02:00
Andreas Kling
b06955277a LibWeb: Stabilize same-document history mirrors
Same-document navigations now commit synchronously in WebContent, while
the UI process mirror learns about them over asynchronous IPC. A stale
UI seed could be accepted back into a live non-initial document and
overwrite its latest entry, making queued traversals target unreachable
entries.

Share descriptor comparison helpers between LibWeb and LibWebView.
Reject stale top-level seeds against the active document latest entry,
and let the UI process adopt WebContent current snapshots when a seed is
rejected. Test-only session history dumps now first send WebContent
current state synchronously, so dumps observe the converged state.

Allow post-load UI seeds to carry UI-owned nested histories that the
freshly loaded top-level document has not reconstructed yet. Add unit
coverage for matching those seeds while still checking top-level state.
2026-06-16 00:00:38 +02:00
Andreas Kling
327437cfc6 LibWeb: Commit same-document navigations synchronously
Finalize fragment navigations and URL/history updates immediately when
no traversal state is active. Keep the queued same-document finalizer as
the fallback for reentrant traversal work and child navigables whose
nested history is not installed yet.

Share the entry-list portion of same-document navigation finalization
between the fast path and queued fallback, so append and replace
bookkeeping cannot drift.

Preserve unrelated ongoing cross-document navigations when a page starts
a load and then performs a same-document history update in the same
task. This matches Chromium, WebKit, and Gecko: the same-document
update must not cancel the pending real navigation.

The session-history mirror tests now observe synchronous UI updates. A
navigation test covers the pending-load plus pushState race.
2026-06-16 00:00:38 +02:00
Ali Mohammad Pur
340d87efd6 LibWasm: Catch SIGFPE on jitted code too
SIGFPE can happen if we emit a bare idiv.
2026-06-15 16:09:51 +02:00
Shannon Booth
fc740068d2 LibURL/Pattern: Avoid eliding default ports in port patterns 2026-06-15 13:45:37 +02:00
Shannon Booth
2bc0ea3945 Tests/LibWeb: Sync to latest URLPattern WPT test data 2026-06-15 13:45:37 +02:00
sideshowbarker
602e7fe2bd LibGfx: Reject a BMP V5 ICC profile offset that points out of bounds
Problem: A BMP V5 image whose embedded ICC profile offset points past
the end of the file triggers an OOB read.

Cause: The bounds check summed the profile offset, the file-header size,
and the profile size in 32-bit arithmetic. So, a large offset (e.g.
0xfffffff0) wraps the sum back into range and passes the check. The
decoder then returns a span pointing far past the end of the file.

Fix: Compute the sum in 64 bits — so an out-of-bounds offset can no
longer wrap, and the profile’s rejected.

Fixes: https://github.com/LadybirdBrowser/ladybird/issues/9967
2026-06-15 20:19:33 +09:00
sideshowbarker
9bde8a5c88 LibGfx: Avoid undefined behavior on a BMP with an INT_MIN height
Problem: Decoding a BMP whose height is INT_MIN triggered a UBSan error.
A top-down BMP legitimately uses a negative height — and unlike width,
it’s not rejected, so it can be INT_MIN.

Cause: decode_bmp_pixel_data() took the magnitude of the i32 width and
height with abs(). Negating INT_MIN is undefined behavior.

Fix: Widen to i64 before taking the absolute value — so the magnitude of
INT_MIN is representable. The resulting out-of-range dimension is still
rejected by Bitmap::create — so only the undefined behavior changes.

Fixes: https://github.com/LadybirdBrowser/ladybird/issues/9994
2026-06-15 09:44:27 +02:00
sideshowbarker
20b1129352 LibGfx: Fix heap overflow applying Exif transpose to non-square images
Problem: Decoding a non-square image whose Exif orientation is 5
(transpose) writes one pixel past the end of the destination bitmap —
an ASan heap-buffer-overflow in ExifOrientedBitmap::set_pixel.

Cause: oriented_position() mapped orientation 5 by composing the
“flip-horizontally” and “rotate-90-clockwise” helpers. Each helper
mirrors using the source width. But after the rotate, the point is
already in the transposed coordinate space — where the relevant
dimension is the source height. For a non-square image, that composition
produces x-coordinates past the destination width. Only square images
happened to stay in bounds. The destination bitmap is the transposed
size — so the out-of-range column wrote past its allocation.

Fix: Map orientation 5 directly as a transpose across the main diagonal:
source (x, y) to destination (y, x).

Fixes https://github.com/LadybirdBrowser/ladybird/issues/10102
2026-06-15 09:31:12 +02:00
Aliaksandr Kalenik
69654a3a7c Compositor: Use GPU bitmap stores with Direct3D
The compositor already used a GPU surface with bitmap readback when a
Vulkan Skia context existed but no native shared surface path was
available. The new Windows Direct3D backend has the same constraint for
now: it can render with Skia on the GPU, while publication still uses
shareable bitmaps.
2026-06-15 04:50:29 +02:00
Aliaksandr Kalenik
3ded5bdcdf LibGfx: Add a Direct3D Skia backend
With Windows backend selection fixed to Direct3D, LibGfx needs a native
GPU context that can feed Skia directly. Add a Direct3DContext helper
that owns the DXGI adapter, D3D12 device, and direct command queue, then
pass that state to Skia through GrDirectContext::MakeDirect3D..
2026-06-15 04:50:29 +02:00
Aliaksandr Kalenik
d858c7219b Meta: Use Direct3D instead of Vulkan on Windows
Windows has a platform-native GPU stack based around Direct3D and DXGI.
The browser's Windows integration will need to share GPU resources with
Skia, ANGLE, and the UI process through that stack, especially when
backing stores move from bitmap readback to shared handles. Keeping
Vulkan as the Windows backend would put painting on a parallel API that
does not match the resources the rest of the native Windows pipeline
needs to exchange.
2026-06-15 04:50:29 +02:00
Andreas Kling
1f36340419 LibJS: Remove unused C++ local variable wrapper
The Rust bytecode generator only passes local variable names to C++ now,
and no C++ code observes declaration kind metadata from LocalVariable.
Store local names directly as Utf16FlyString values and remove the stale
C++ wrapper type.
2026-06-15 02:41:57 +02:00
Andreas Kling
1979d24783 LibJS: Remove unused bytecode instruction stream iterator
InstructionStreamIterator no longer has any C++ users now that bytecode
block collection has moved to Rust. Remove the iterator and include the
bytecode field types needed by generated C++ instruction definitions
directly in Instruction.h.
2026-06-15 02:41:57 +02:00
Andreas Kling
e5bcffc3d5 LibJS: Move bytecode block counting to Rust
Use the Rust bytecode dumper's basic block collection logic for the
metadata block count. This removes the last C++ bytecode label walk and
lets us delete the generated C++ label and operand visitor helpers.
2026-06-15 02:41:57 +02:00
Andreas Kling
984d3033e9 LibJS: Remove obsolete bytecode dump formatting helpers
The Rust bytecode dumper now formats exception handler labels, raw
operands, builtins, labels, and registers. Remove the C++ dump-only
formatters and flatten Operand to expose only the runtime value-array
layout that C++ still observes.
2026-06-15 02:41:57 +02:00
Andreas Kling
7a6af95db3 LibJS: Move bytecode instruction dumping to Rust
Generate Rust bytecode dump helpers from Bytecode.def and route
Executable::dump() through them for instruction stream formatting.

Add a small Rust runtime::value helper for decoding encoded LibJS
Values so immediate Value operands are formatted on the Rust side. C++
callbacks remain only for local names and GC-backed Value payloads that
still need LibJS object access.

Remove the generated C++ to_byte_string_impl() methods and the old
Instruction::to_byte_string() dispatch. The bytecode dump tests cover
output compatibility.
2026-06-15 02:41:57 +02:00
Andreas Kling
5aac297558 LibWeb: Keep child navigable history updates coherent
Normalize the target step again at the end of applying a history
step, since iframe removal can leave the originally computed target
step unused before the asynchronous application finishes. Let the UI
history snapshot use the same used-step mapping when it serializes a
current item for the UI process.

Handle late child-frame navigation commits whose original nested
history entry disappeared before finalization. Removed iframes have no
live nested history list to update, and initial about:blank still needs
its first real navigation to replace the remaining initial child entry.

Add coverage for iframe pushState before nested history readiness and
for removing and recreating an iframe after an initial same-document
history update.
2026-06-15 01:15:09 +02:00
Aliaksandr Kalenik
5d8880a899 Compositor+WebContent: Initialize WebContent transport peer pid
A WebContent display-list update can send compositor resource
attachments over the WebContent-to-compositor transport. On Windows,
serializing an attachment requires the destination process id, but this
secondary transport never exchanged peer pids before the first message.

That left TransportSocketWindows with m_peer_pid == -1 and hit the
serialize_attachments() verification when WebContent tried to send the
first attachment-bearing compositor update. Add InitTransport to this
endpoint and run it immediately after WebContent creates the compositor
connection, before any other IPC uses the channel.
2026-06-15 00:50:02 +02:00
Shannon Booth
c39ff8eb81 Tests: Attempt to unskip some MacOS IPC related tests
We have since fixed a lot of issues with this implementation, and
have had other worker tests enabled without issue. Let's hope that
the flake issues with these tests have now been fixed.
2026-06-15 00:26:10 +02:00
Shannon Booth
0d656c3027 LibWeb: Record abspos inline static positions as line-box markers
The static position of an absolutely positioned inline child is the
in-flow insertion point on the line where it appears. Previously this
was reconstructed after layout by walking previous siblings for a
line-box fragment. That lookup could match a fragment from an earlier
line and collapse multiple abspos children onto the same position,
especially in white-space preserving content.

Instead, drop a zero-width static-position marker into the line box at
the insertion point when each abspos child is encountered. The marker is
carried through normal line post-processing, including float intrusion,
text-align, justification, trailing-whitespace trimming and ellipsis, so
the final static position is resolved from the line itself.

Resolve marker-only trailing lines before removing them, so they can
provide static position without contributing line height.
2026-06-14 22:12:06 +02:00
Shannon Booth
96aa4b3ad3 LibWeb: Only apply CSS transforms to transformable elements
Add Node::is_transformable() per the CSS Transforms spec and gate
transform handling on it, so non-replaced inline boxes are no longer
transformed.
2026-06-14 22:12:00 +02:00
Shannon Booth
a8cb98ccf7 Tests: Support WPT reftests with multiple references
Store reftest expectations as a list of match/mismatch reference URLs
and evaluate each reference in sequence.

This lets test-web run WPT reftests that specify multiple reference
relations, such as tests with both match and mismatch links.
2026-06-14 22:12:00 +02:00
Shannon Booth
de90aeb07c Tests/LibWeb: Re-import floats reftests with their mismatch references
Re-import these tests now that the importer supports multiple
references, so their mismatch *-notref.xht files are present instead
of pointing at unimported paths.
2026-06-14 22:12:00 +02:00
Shannon Booth
06f4ac367e Meta: Support importing WPT reftests with multiple references
Collect all match and mismatch links when identifying WPT reftests
instead of rejecting tests with more than one reference.

Map and rewrite every imported reference URL so tests with both match
and mismatch expectations can be imported.
2026-06-14 22:12:00 +02:00
Andreas Kling
ea72bd3863 Tests: Wait for mirrored history before UI traversal
Wait for the WebDriver session history test to observe the UI-process
mirror after a same-document pushState setup before it starts testing a
browser UI history traversal.

The script-visible URL changes before the asynchronous session history
snapshot reaches the UI process, especially in sanitizer CI. The test
already needs the UI and WebContent histories to match at this point, so
wait for that condition directly instead of sampling the mirror at once.
2026-06-14 21:23:28 +02:00
Andreas Kling
a29e1f5cf3 LibJS: Remove unused Executable::dump_to_string
The bytecode dump path only writes directly to stderr now.
Remove the unused string-returning dump API.

Also remove the private helper mode that only existed for that API.
2026-06-14 20:27:59 +02:00
Andreas Kling
ef8ac6ea7d LibJS: Remove unused C++ bytecode block classes
The Rust bytecode generator now owns basic block construction.
The old C++ BasicBlock class no longer has any users.

Label no longer needs to translate from BasicBlock.
Remove the now-empty Label.cpp from the build as well.
2026-06-14 20:27:59 +02:00
Andreas Kling
0af548b27d LibJS: Sync AsmInt program counter before slow paths
Move the execution context program counter update from ASM_TRY() to the
generated slow-path call boundary. Slow paths still enter C++ with the
current bytecode offset visible to stack and source location code, while
ASM_TRY() only handles completion unwrapping and exception dispatch.
2026-06-14 20:27:59 +02:00
Andreas Kling
ad7002ba99 LibJS: Pass instruction pointers to AsmInt slow paths
Have generated AsmInt calls pass the current instruction pointer as a
third argument to slow-path handlers. This lets the C++ handlers use a
typed Op pointer directly instead of refetching bytecode from the VM and
recomputing the instruction address from the program counter.
2026-06-14 20:27:59 +02:00
Andreas Kling
213403542c LibJS: Remove AsmInt slow path stats collection
Remove the optional slow path hit counters from AsmSlowPaths.cpp. This
also drops the registration call from the AsmInt entry path, leaving
slow paths focused on executing the out-of-line instruction behavior.
2026-06-14 20:27:59 +02:00
Andreas Kling
97a6807ffa LibJS: Remove JS_BYTECODE_DEBUG
Remove the stale bytecode execution debug hook from Interpreter.cpp now
that bytecode dispatch always enters AsmInt directly. The remaining
bytecode dump flag is separate and still used by parser/codegen paths.
2026-06-14 20:27:59 +02:00
Andreas Kling
8fee268851 LibJS: Call AsmInt directly from run_executable
Remove the empty AsmInterpreter wrapper and the VM::run_bytecode()
trampoline now that the bytecode interpreter only enters AsmInt. Move
the stack-limit check and generated assembly entry call into
run_executable(), then drop the stale wrapper source file and includes.
2026-06-14 20:27:59 +02:00