Commit Graph
61 Commits
Author SHA1 Message Date
Jake Writer 4132dd50a6 refactor(juggler): make the input-dispatch deadlock structurally unreachable
Four deadlocks shipped between 2026-04 and 2026-09 -- exact-edge coordinates
(9270618), humanized trajectory points that bypassed the endpoint's guard
(541ffca, #225/#677), a zero-displacement move (16e5a13), and the near edge
(014cc65, #751/#752). Each was fixed by adding one more coordinate guard at
one more call site. That does not converge, for two reasons.

The trigger set is not enumerable. Whether relative y == 0 reaches the
renderer is decided by Math.round(boundingBox.top) < boundingBox.top -- a
rounding accident in the fractional height of browser chrome, which varies
with the spoofed OS. No review catches that.

And every miss costs the whole process. activateAndRun() serializes input on
a chain shared by every tab; EventWatcher.ensureEvent() waited forever. One
missing ack wedged every later input event in the process, permanently, at 0%
CPU with no diagnostic. #677 shows why review is not the answer: restoring the
humanize trajectory meant writing a bounds check, and the one written was a
copy of the pre-#225 form, reintroducing a fixed deadlock one day before it
was re-fixed.

Three changes, in order of leverage.

1. Bound the waits. EventWatcher.ensureEventWithin() gives up instead of
   waiting forever; MouseDispatch.sendAcked() uses it, drops the event and
   logs the type, coordinate and browser rect. This alone closes all four
   historical deadlocks, including on a build with no coordinate fix at all.

   The 5s deadline is sized from measurement, not intuition. Over 1000+
   dispatches: idle content thread p50 0ms / p99 1ms / max 12ms; a thread
   burning 8ms per event p50 8ms / max 12ms. But the ack is delivered FROM
   the content main thread, so a page running a 3s synchronous script delayed
   a legitimate ack by 2849ms. Block length is page-controlled and unbounded,
   and silently dropping real input on a slow page is the #752 symptom, so
   the deadline sits above the slowest legitimate ack rather than near the
   typical one.

   Bounding each ack is not enough to bound the work: a humanized curve is
   ~110 points in a single activation-chain slot. sendTrajectoryAcked()
   abandons the rest of a curve after the first undelivered point -- not a
   wall-clock budget, which would false-fire on exactly the slow pages the
   deadline exists to tolerate. activateAndRun() carries a 30s backstop for
   the other unbounded waits reachable from the same slot
   (apz-repaints-flushed, TabSwitchDone, the drag path's waits), none of
   which has failed yet.

2. One chokepoint. additions/juggler/input/MouseDispatch.js owns the
   relative-to-absolute conversion, the in-viewport predicate and the ack
   wait. PageHandler's three independent bounds checks and its raw
   jugglerSendMouseEvent/sendWheelEvent calls are gone; it now passes
   relative coordinates and never sees a bounding box. Net effect on that
   vendored file is 92 lines removed against 22 added -- a smaller diff
   against upstream juggler, since the logic moved into a file we own.
   Wheel events go through the same conversion, so a wheel at relative y == 0
   no longer scrolls the tab strip.

3. Enforcement. scripts/check-input-dispatch.py fails the build if anything
   outside the chokepoint dispatches synthesized input or does
   browser-relative coordinate arithmetic. It needs no browser build, so
   .github/workflows/lint.yml gates every pull request -- nothing was
   checking PRs before. Two exemptions, both content-process: PageAgent
   (drag events, already content-relative, no ack) and FrameTree (the ack
   producer). docs/input-dispatch.md states the invariant.

   tests/patches/mouse-boundary-sweep.py replaces hand-picked edge targets,
   which are what let each of the four through: humanize-edge-deadlock.py
   probes only the far edges, and humanize-mouse-trajectory.py pins
   os="linux" -- the one fingerprint immune to #751. It sweeps the whole
   viewport ring across every spoofed OS with humanize on and off, asserting
   each point is acked AND observed by the page. It depends on change 1 to
   run at all: without the backstop the first bad coordinate wedges the
   browser and the sweep dies there.
   tests/patches/input-ack-backstop.py covers the bounded wait itself, by
   blocking the content main thread far longer than the deadline -- a
   legitimate late ack, with no test-only hook in production code.

The sweep immediately found a fifth instance, pre-existing and unreported:
boundingBox.height is consistently 0.5 CSS px less than the innerHeight the
page reports, so the page's last row is half covered. With the box at
1920x977.5 +0+56.5, relative y == 977 -- innerHeight - 1, well inside the
viewport as far as the page is concerned -- dispatches at 1033.5, rounds to
1034, and the content ends at 1034. Deterministic, 4/4, and it deadlocks a
stock build. Fixed by clamping to the last whole pixel inside the element,
symmetric with the near-edge snap; both live in the one conversion now.

All seven patch tests pass: mouse-boundary-sweep (150 ring coordinates over
6 scenarios), near-edge-mouse-deadlock, input-ack-backstop,
humanize-edge-deadlock, humanize-mouse-trajectory, noop-mousemove-deadlock,
trusted-events.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GQgHHGRXNp29jr4xQjK7iv
(cherry picked from commit 827b98d31e)
2026-09-05 14:26:37 -06:00
Jake WriterandClaude Opus 5 41ba997799 build: stage bundled fonts into unpackaged builds
`mach build` leaves dist/bin/fonts holding only TwemojiMozilla.ttf -- the font
bundles and fontconfig are staged by scripts/package.py, so they exist only in
packaged builds. Anything launching the objdir binary through the Python
wrapper therefore starts a browser with no usable content font, because the
wrapper sets FONTCONFIG_FILE to a file that is not there.

It fails confusingly: the browser chrome still has system fonts, so the only
symptom is tofu boxes in page content, and through AsyncCamoufox it surfaces as
a TargetClosedError with no indication of the cause. That cost real time while
writing the tests/patches scripts, hence the note in their docstrings.

`make stage-fonts` copies them in. Idempotent, and a no-op when nothing is
built yet. Not needed by `make run` or `make tests`, which launch the binary
directly and fall back to the system fontconfig.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-30 14:32:42 -06:00
neuregex c4716d2ec1 fix(build): stop dropping the MSVC CRT from Windows packages (#650)
package-windows pulls VCRUNTIME140/VCRUNTIME140_1/MSVCP140 out of the mozbuild
Visual Studio tree through a shell glob that pins one redist version
(14.38.33135) and one toolset (VC143). Windows builds cross-compile on Linux
and get their toolchain from mozbootstrap, so a different version there leaves
the glob unexpanded -- and add_includes_to_package() skipped anything that did
not exist, with no warning.

The package then ships without the CRT. camoufox.exe imports those DLLs, so on
any machine without the Visual C++ Redistributable installed the process dies
immediately and Playwright surfaces only "spawn UNKNOWN".

- glob the redist and toolset versions instead of pinning them
- treat a missing --includes entry as fatal, so an unexpanded glob fails the
  build instead of silently shipping a broken package
2026-07-30 14:32:42 -06:00
daijro fb6d475fd3 Drop Linux i686 support for future releases
Firefox 32-bit Linux Support ended in 2026. This change removes it from the workflow
https://blog.mozilla.org/futurereleases/2025/09/05/firefox-32-bit-linux-support-to-end-in-2026/
2026-07-15 14:20:46 -05:00
daijro 34760a639b Fix patcher attempting to use git after setup-minimal 2026-07-15 07:58:02 -05:00
Jake WriterandClaude Fable 5 26b94797c3 fix(stealth): consolidated stealth/juggler/build fixes (rebased onto FF152)
Consolidates the following individual fixes into one changeset, all rebased
onto the current Firefox 152 base and validated together via a full build:

- webrtc: stop real-IP leak under a proxy; sanitize getStats IP + fabricate a
  synthetic srflx when ICE produces none (TCP-proxy case).
- proxy: re-enable launch-arg proxy by disabling https_first.
- screen: make MaskConfig the single source for screen + CSS device dims so
  matchMedia(device-width) agrees with screen.width.
- stealth: spoof CSS2 system-font keyword resolution (font-system-fonts-css2).
- juggler: filepicker reliability + skip mouse-move coalescing for synthetic
  (juggler) events so input dispatch can't stall under parallel load.
- juggler: emit a single input event for insertText on form fields.
- juggler: reload about:blank via browsingContext.reload.
- locale: propagate launch-arg locale to BrowsingContext.
- build: create v150-removed dirs before copy-additions.
- stealth: BrowserForge headless / impossible-geometry tell corrections and
  speech-voice spoofing (host-voice leak fix).

Supersedes daijro/camoufox #637-#647.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-12 16:20:28 -06:00
Anton f342c20dd2 Version 152.0.2 Upgrade (#658)
* 152 upgrade patches

* remove unused patch

* fix juggler

* add rust cross compile to required deps
2026-07-05 23:03:19 -07:00
icepaq 4f5e4484d1 add install deps script 2026-07-05 13:28:42 -07:00
0ac611c4ad v150 with Windows Support - Python Package Being Merged Separately (#611)
* fix v150 patches

* screen related patch fixes

* fix juggler issues with 150

* Update grading.py

improved build tester scoring

* fix windows build for v150

- scripts/_mixin.py: switch moz_target from x86_64-pc-mingw32 (no longer
  supported in FF150) to x86_64-pc-windows-msvc
- additions/juggler/screencast/HeadlessWindowCapturer.h: typedef pid_t
  on XP_WIN; libwebrtc headers (video_capture.h, desktop_capturer.h)
  reference pid_t which is POSIX-only
- patches/anti-font-fingerprinting.patch: include mozilla/dom/Document.h
  in gfxTextRun.cpp; on Windows it is not transitively included so
  doc->GetInnerWindow() failed with "incomplete type 'Document'"

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* make service test use local binary

* updated ff fingerprint versions

* Update README.md

---------

Co-authored-by: Ubuntu <ubuntu@ip-172-31-15-96.us-east-2.compute.internal>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 15:34:05 -04:00
icepaq 5219a40849 build test fixes (#586)
* build test fixes

* fix wrong references

* Update PULL_REQUEST_TEMPLATE.md
2026-04-25 23:47:31 -04:00
Ruben VereeckenandClaude Opus 4.6 5f3c1f2c64 Allow disabling font spacing perturbation (seed=0 no-op, matching audio) (#548)
* Allow disabling font spacing perturbation (seed=0 no-op, matching audio)

The audio fingerprint manager treats seed==0 as "no perturbation", but
font spacing had a hardcoded fallback (0x6D2B79F5u) that made it always
active — even when no seed was explicitly set.

C++ change: remove the hardcoded fallback and add `if (seed != 0)` guard
around the LCG + glyph offset loop (mirrors AudioFingerprintManager).
Also removes the debug printf that fired on every ShapeText() call.

To disable font spacing from the Python API, set fonts:spacing_seed to 0
in the config/preset — same convention as audio:seed and canvas:seed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Add local channel install script for custom builds

Installs build artifacts to browsers/local/ instead of overwriting
official slots. Survives camoufox fetch. Handles permissions and
version.json automatically.

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 11:06:25 -04:00
icepaq d6540b52ce Service Test and Contributing Guides (#521)
* example files

* contributing guides

* simple service test

* run tests in sync

* update pr template

* pip updates

* Update README.md

* typo fixes

* undo pip package update lol

* upgraded service test

* undo injections

* test with proxies

* auto set timezone and proxy url

* delete checks bundle

* split up service tests

* split up build tests

* rename service tests to service tester

* Update CONTRIBUTING.md

* fix entry vs exit ip

* allow alpha versions

* fix patch issues on macos

* bidirectional patch

* Add note on experimental pip package
2026-03-15 21:31:49 -04:00
icepaq 33b0e0ebcc Build improvements (#3)
* fix asets.car issue

* dist folder issue bruh
2026-01-04 23:26:32 -05:00
icepaqandNirupam Bhowmick dfa62f7070 Juggler fixes (#2)
* fix: migrate Services import to lazy loading pattern and disable dark theme to prevent XPIProvider crash

- Changed Services from ChromeUtils.defineLazyGetter to ChromeUtils.defineESModuleGetters with lazy object
- Updated all Services references to lazy.Services throughout Juggler.js
- Added re-copying of additions and settings after git reset in patch.py
- Removed juggler components.conf copy logic from patch.py (now handled by copy-additions.sh)
- Disabled dark theme preference in camoufox.cfg to

* fix: revert Services import to direct ESM import and re-enable dark theme preference

- Changed Services from lazy loading pattern back to direct ChromeUtils.importESModule()
- Removed lazy object wrapper and ChromeUtils.defineESModuleGetters usage
- Updated all lazy.Services references to Services throughout Juggler.js
- Re-enabled dark theme preference in camoufox.cfg (extensions.activeThemeID)
- Removed XPIProvider crash prevention comment as issue is resolved

* fix: remove redundant Services import as it's available globally in XPCOM component context

- Removed ChromeUtils.importESModule imports for XPCOMUtils, ComponentUtils, and Services
- Added comment explaining Services is available as a global in XPCOM component context
- Services.scriptloader.loadSubScript call continues to work with global Services reference

* fix: correct JugglerFrameChild.sys.mjs path by removing duplicate content directory

- Changed esModuleURI from 'chrome://juggler/content/content/JugglerFrameChild.sys.mjs' to 'chrome://juggler/content/JugglerFrameChild.sys.mjs'
- Removes erroneous duplicate 'content' directory in the child actor module path

* fix: add ESM module entries and correct JugglerFrameChild.jsm path in jar.mn

- Added JugglerFrameParent.sys.mjs entry to juggler.jar manifest
- Added JugglerFrameChild.sys.mjs entry to juggler.jar manifest
- Fixed JugglerFrameChild.jsm path from 'content/content/JugglerFrameChild.jsm' to 'content/JugglerFrameChild.jsm' removing duplicate content directory

* fix: remove redundant Services lazy getter as it's available globally in content process context

- Removed ChromeUtils.defineLazyGetter for Services in main.js
- Added comment explaining Services is available as a global
- Services reference continues to work with global availability in content process

---------

Co-authored-by: Nirupam Bhowmick <48842933+heydryft@users.noreply.github.com>
2026-01-04 11:40:05 -05:00
Anton 3cceb0f4f5 Revert "bring back camoufox branding"
This reverts commit 3258fca5b2.
2026-01-04 11:34:17 -05:00
Anton 3258fca5b2 bring back camoufox branding 2026-01-03 22:33:16 -05:00
Nirupam Bhowmick 7106903bb0 fix: add binary flag to patch command for line ending preservation
- Added --binary flag to preserve line endings (CRLF vs LF)
- Removed -F3 (fuzz factor) flag
- Helps with cross-platform patching where line endings may differ
2025-12-30 00:40:12 +00:00
Nirupam Bhowmick acba61d7aa fix: improve patch command flexibility with whitespace and fuzz tolerance
- Changed --fuzz=3 to -F3 for consistent short option format
- Added -l flag to ignore whitespace differences when applying patches
- Maintains --forward flag to skip already applied patches
2025-12-30 00:30:18 +00:00
Nirupam Bhowmick ee997d1518 make patching more lenient 2025-12-29 23:37:39 +00:00
Nirupam Bhowmick f7a9bf7fbd refactor: move MOZ_APP_VENDOR and MOZ_APP_PROFILE to moz.configure and fix juggler component registration
- Removed MOZ_APP_VENDOR and MOZ_APP_PROFILE from configure.sh branding file
- Added note that these must be set via imply_option() in browser/moz.configure
- Updated disable-data-reporting-at-compile-time.patch to set MOZ_APP_VENDOR="Camoufox" and MOZ_APP_PROFILE="camoufox"
- Changed juggler components.conf to use "type" instead of "constructor" for Firefox 146+ compatibility
- Added automatic
2025-12-27 20:23:41 +00:00
Nirupam Bhowmick 32122430be fix: every patch patches except 0, 1 playwright and roverfox context 2025-12-27 02:58:10 +00:00
Nirupam Bhowmick 75fb8d2f78 fix: auto-update 6 line numbers in 0-playwright.patch 2025-12-25 18:25:54 +00:00
Nirupam Bhowmick 08ecd86746 feat: add Firefox v147 patch update task list and tracking document
Add comprehensive task list documenting the Firefox upgrade from v135.0.1 to v147.0b3 (12 major versions). Includes status tracking for all 45 patches after syncing with upstream LibreWolf (Firefox 146) and Playwright repositories.

Key changes:
- 25 broken patches identified (56% failure rate)
- 20 patches applying cleanly (44% success rate)
- LibreWolf patches updated from upstream: 17 patches synced, 5 deleted, 2 auto-fixed
-
2025-12-19 05:58:30 +00:00
Nirupam Bhowmick cd77ea7bd5 feat: remove webrtc ipv6 func and update diff command in developer script 2025-08-24 01:36:16 +01:00
Nirupam Bhowmick e1a28778db feat: add WebRTC IP spoofing with per-context isolation support 2025-08-23 23:53:07 +01:00
Nirupam Bhowmick 15719fe9b1 feat: implement user context-based font spacing 2025-08-19 19:02:22 +01:00
Serhii Maltsev cc852b424a Minor dev UI improvements: add patch statuses directly to lists for improved usability 2025-02-13 17:52:53 +01:00
Serhii Maltsev 8dc1f6b039 fix broken f-string formatting and broken python make edits call 2025-02-11 12:41:05 +01:00
daijro 9f6d55f39b Extract inner tar in packager 2025-02-05 19:18:17 -06:00
daijro 2f2af937a1 Update packager to search for tar.xz 2025-02-05 12:13:30 -06:00
daijro 33085c90f3 Merge with Playwright a121f85
Merges patches with the latest commit: https://github.com/microsoft/playwright/commit/a121f85ce91b67aeb1191e2fcca0939ad5b38671
2025-01-24 18:20:07 -06:00
daijro bbe1cbe2b2 Memory benchmark scripts via podman #87 2024-11-30 21:15:43 -06:00
daijro 4f15447e04 Deprecate old launcher & locales 2024-11-21 18:51:27 -06:00
daijro 85eb40aee4 Leak fixes #90 2024-11-21 01:59:01 -06:00
daijro e126cf379c Update uBlock Origin assets & updater 2024-11-04 03:13:23 -06:00
daijro ad3b3f04fe Add extra parameters to test site
Added the following parameters to the WebGL testing site:
TIMESTAMP_EXT, GPU_DISJOINT_EXT, MAX_VIEWS_OVR
2024-10-15 05:37:59 -05:00
daijro 5bfc3ee026 Further improved WebGL spoofing beta.12
- Added ability to spoof webgl2 supported extensions
- Added ability to block parameters that aren't defined in config
- Passing null in config will block the value
- Added more parameters to the demo site
2024-10-14 20:31:58 -05:00
daijro 02bc15161a feat: WebGL fingerprint spoofing
Experimental WebGL fingerprint injection.
- Allows the ability to set all WebGL parameters, supported extension list, shader precision formats, & context attributes.
- Added a demo website under scripts/examples/webgl.html that can be used to generate Camoufox config data
2024-10-14 02:12:13 -05:00
daijro 8a9b062d05 Update test script to output debug.log 2024-09-30 00:41:47 -05:00
daijro ea84f792df Developer UI: Keep clean build files on reset 2024-09-09 18:48:36 -05:00
daijro a2cb02df8a Add config type validator
- Validates property types passed in --config.
- Types are stored in properties.json.
2024-08-18 05:14:20 -05:00
daijro a766940363 Makefile: Fix build resetting workspace when editing patch 2024-08-17 00:25:34 -05:00
daijro 1d31bad14e Merge gh-actions branch into main
main..gh-actions:
- CI/CD: Fix release permissions
- Fix macos packaging on debian
- CI/CD: Remove unwanted tools
- CI/CD: Attempt to fix OOM killing GH runner during LTO
- CI/CD: Fix glibc errors
- CI/CD: Downgrade to ubuntu-20.04
- CI/CD: Use target os matrix & fix release
- CI/CD: Remove Windows (temporarily)
- CI/CD: Move to AdityaGarg8/remove-unwanted-software@v4.1
- CI/CD: Limit CPU as well
- CI/CD: Create cgroup with 80% mem limit
- CI/CD: Revert "Remove .mozbuild caching"
- CI/CD: Expand root & swap build space
- CI/CD: Remove .mozbuild caching
- CI/CD: Check disk space after checkout
- CI/CD: Use easimon/maximize-build-space
- CI/CD: Add workflow dispatch trigger
- CI/CD: Experimental fix for clang, add swap space
- CI/CD: Save .mozbuid cache after Build
2024-08-16 07:34:54 -05:00
daijro 80a657268e Packaging & macos exec fixes
- Use "open -a" to launch Camoufox.app
- Fix fonts not copying correctly
- Find & move asset files to dist/ correctly
2024-08-14 05:22:01 -05:00
daijro a891914b9a Makefile: Remove revert from dir command
Removes git reset when running `make dir`. This avoids errors when using `make setup-minimal`.
2024-08-14 00:41:35 -05:00
daijro 2ac5351fd5 Fix developer UI not finding source folder 2024-08-13 22:14:59 -05:00
daijro ad87cec317 Makefile: run-pw with launcher
Build and copy the launcher when testing Playwright
2024-08-13 21:20:19 -05:00
daijro eeb9cb3b60 Makefile: Add run-pw to test Playwright 2024-08-13 06:32:13 -05:00
daijro 0b650d8dfd Developer UI: Add break option in "Find broken Patches"
Adds a option in "Find broken patches" to break after one reject file was found.
2024-08-11 01:51:05 -05:00
daijro a58428b534 Hotfix Windows launcher packaging
Fixes an issue with the launcher not copying correctly during the packaging process for Windows.
2024-08-06 04:21:08 -05:00