馃殌 Release BOSS 9.5.5
BOSS v9.5.5
Release Date: 2026-08-29
One change. Opening a link in a new tab - cmd+click, or a target="_blank" button - could land on the page's own analytics beacon instead of the link, because the engine-wide POST capture was allowed to decide the destination and a page's telemetry ping usually fires first. The navigation is now the authority, a capture can only ever contribute a body, and the injected cmd+click handler is restricted to the links it is safe to adopt.
Highlights
- A page's telemetry endpoint could become the tab. Two real cases caught it: a tab on
internal-analytics.odoo.com/api/eventtitled "New Tab", and one oncollector.github.com/github/collecttitled "Collector". Both are POST-only beacon endpoints that appear in no page's markup, so nothing the user clicked could have produced them (#281) - The destination was being recovered from the wrong place.
CreatePopupCallbackis handed the popup's target URL and threw it away, so the handler subscribed toLoadStartedand re-readpopupBrowser.url()- butLoadStartedcarries no URL, so a navigation that had not committed yet never resolved at all and the handler sat out its full 3s timeout with the popup live and running the page's scripts (#281) - The three paths that can open a link now agree on what may become a tab. The adopted popup, the injected cmd+click handler and the fluck-browser plugin's middle-click resolver are all http(s) only, so
javascript:,mailto:,file:,blob:,data:andabout:blank#blockedstay with the page (#281) - The cmd+click script is tested by running it, not by grepping it. An SVG anchor's
hrefis anSVGAnimatedString, so the unguarded handler opened a tab on the literal[object SVGAnimatedString]- a bug no amount of reading the script reveals (#281)
Bug Fixes
- browser: an adopted popup's destination comes from its navigation, with the URL Chromium stated at creation time as the fallback for a popup that never started one.
popupDestinationis a pure function so it can be tested at all - no test can construct aBrowserHandleImpl- and reverting it fails the two tests named for the beacon URLs above (#281) - browser: the POST capture can only contribute a body, and only when it describes the request actually being navigated to. It is an engine-wide
BeforeSendUploadDataCallbackthat claimed any request from the popup carrying a body, so an XHR, a CSP report or asendBeaconping from the popup's own page qualified and the first to fire won. It now claimsMAIN_FRAMErequests only (#281) - browser:
NavigationStartedreplacesLoadStartedas the source of the URL, since it carries one on the event - but it is not a superset of what it replaced. Its subscription is installed after the show request and JxBrowser does not replay to a late subscriber, soLoadStartedis kept alongside it, plus one direct re-read after subscribing (#281) - browser: a cmd+clicked PDF no longer opens a tab that re-triggers its own download. The legacy handler gated on
FluckEngine.isActiveDownload; this path never did, and got away with it only becauseLoadStartednever fires for a download so no URL ever resolved.NavigationStarteddoes fire, so the gate came back, with thenotifyTabOpenedhandshake so a redirect that turns into a file can still be undone (#281) - browser: the popup-target FIFO no longer desyncs by design.
recordskipped an unusable target whileclaimalways popped, sowindow.open('')followed by a cmd+click handed popup 1 the URL of link B.PopupTargetQueuerecords every create and filters at claim (#281) - browser: a form posting to
/print#page2keeps its body. Chromium does not send the fragment to the network, so that submission reaches the upload callback as/print, and demanding an exact URL match silently downgraded it to a GET. Fragments are compared away (#281) - browser: POST capture is keyed by
Enginerather than a process-wideuploadCallbackInstalledboolean. TheEngineFluckEngine builds to recover a wedged renderer never got the callback, so capture stayed silently dead after a renderer recovery (#281) - browser: a popup that dies between the show request and our subscription no longer leaks. It threw out of the callback with its capture entry installed and no coroutine to remove it - a permanent strong reference to a dead
Browserin a process-wide map (#281) - browser: the injected cmd+click handler hijacks the click before the page sees it, and is now guarded: primary button only, not an already-cancelled click, not a download anchor, http(s) only. An SVG anchor's
hrefis read correctly rather than stringified (#281)
Improvements
- browser: popup URLs are logged through
LogSanitizer.maskUriParams, matching the rest of the file. The motivating workload is an EMR whose print URLs carry patient identifiers in the query string (#281) - browser:
PopupTargetQueue's TTL is 2s, down from the previous 10s. Create and show are microseconds apart, and every millisecond in that window is time for an orphaned create to mispair with the next popup. The queue is bounded too, and documents that dropping the oldest pastmaxEntriesknowingly abandons the pairing rather than leaving a reader to assume the FIFO guarantee is universal (#281) - browser: the cmd+click handler's KDoc no longer claims
defaultPreventedtells us the page cancelled the click. It cannot - the listener is on the capture phase, so the page's handlers have not run yet (#281) - tests: 19 tests across three classes, all verified by reverting.
PopupDestinationTestfails with the two beacon URLs from the field,PopupTargetQueueTestwith the off-by-one misroute, and deleting the cmd+click protocol guard fails six cases inscripts/test/test-cmd-click.js(#281) - ci:
node scripts/test/test-cmd-click.jsruns inbuild.yml, reusing the harnesstest-browser-collector.jsandtest-find-key-probe.jsalready established - read the JS out of the Kotlin string and execute it undervmagainst a fake DOM. The grep test it replaces pinned the spelling rather than the behaviour: rewritingevent.button !== 0as0 !== event.buttonfailed the old test while changing nothing, and any guard reworded rather than removed passed it (#281)
Known Limitations
- The FIFO pairing stops at
maxEntries. A page opening popups faster than they are claimed drops the oldest entries, and every later popup shifts by one. Only the fallback destination is affected - the navigation still decides - and the alternative is unbounded growth (#281) - A popup with no resolvable destination is dropped. That is deliberate: sending it somewhere arbitrary is what this change exists to stop (#281)
馃摝 Downloads
| Platform | Architecture | Package |
|---|---|---|
| macOS | Universal (Apple Silicon + Intel) | BOSS-9.5.5-Universal.dmg |
| Windows | x64 | BOSS-9.5.5.msi |
| Windows | ARM64 | BOSS-9.5.5-arm64.msi |
| Linux DEB | AMD64 (x86_64) | BOSS-9.5.5-amd64.deb |
| Linux DEB | ARM64 (aarch64) | BOSS-9.5.5-arm64.deb |
| Linux RPM | AMD64 (x86_64) | BOSS-9.5.5-amd64.rpm |
| Linux RPM | ARM64 (aarch64) | BOSS-9.5.5-arm64.rpm |
| Linux JAR | AMD64 (x86_64) | BOSS-9.5.5-amd64.jar |
| Linux JAR | ARM64 (aarch64) | BOSS-9.5.5-arm64.jar |
Always latest - newest stable release, resolved server-side, so these stay
correct in a bookmark and need no API key:
macOS DMG 路 Windows x64 路 Windows ARM64 路 Linux DEB amd64 路 Linux DEB arm64 路 Linux RPM amd64 路 Linux RPM arm64 路 Linux JAR amd64 路 Linux JAR arm64
Release metadata - version, every asset, sha256 checksums - is at ?app=boss.
Full Changelog: v9.5.4...v9.5.5