fix(fingerprints): a NewContext Linux identity is Linux in platform and oscpu too

fpgen's Linux pool now and then pairs a Linux user agent with
navigator.platform Win32 and a Windows oscpu. launch_options() corrects
that with fix_navigator_arch(); generate_context_fingerprint() never
called it, so 24 of 1,500 Linux NewContext identities (1.6%) said Win32
under a Linux UA -- and because that path reads the OS for fonts and
voices from the platform, they drew Windows fonts and voices as well.

It now applies the same fix right after the fpgen draw, in pythonlib and
in the TypeScript twin. The fix draws nothing, so the parity goldens are
unchanged.

The new tests feed the context path a real Linux draw with the Windows
platform and oscpu, and fail without the fix ('Win32' != 'Linux x86_64')
in both ports. After it: 0 of 1,500 sampled contexts mismatch.
pythonlib 412 passed; typescript 585 passed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Jake Writer
2026-09-27 20:09:03 +00:00
co-authored by Claude Opus 5.5
parent 8081061156
commit 12a1bb4fc6
4 changed files with 60 additions and 1 deletions
+6
View File
@@ -1619,6 +1619,12 @@ def generate_context_fingerprint(
# Fall back to synthetic generation
fp = generate_fingerprint(os=os)
config = from_fpgen(fp, ff_version)
# fpgen's Linux pool now and then pairs the Linux UA with a Windows
# platform and oscpu. launch_options() corrects that; this path did
# not, so ~1.6% of Linux contexts said Win32 -- and, since the OS below
# is read from the platform, drew Windows fonts and voices as well.
if 'Linux' in str(config.get('navigator.userAgent', '')):
fix_navigator_arch(config, 'lin')
# A fresh identity: every seeded draw below gets its own salt.
_salt = identity_salt()
+22
View File
@@ -199,3 +199,25 @@ def test_is_mobile_warns_that_camoufox_is_desktop_only():
with pytest.warns(LeakWarning, match="built for desktops"):
launch(is_mobile=True, i_know_what_im_doing=False)
def test_a_context_with_a_linux_ua_is_linux_throughout(monkeypatch):
"""fpgen's Linux pool now and then pairs the Linux UA with platform Win32 and
a Windows oscpu (~1.6% of NewContext Linux identities). launch_options()
fixed that and generate_context_fingerprint() did not -- and it reads the OS
for fonts and voices from the platform, so those came out Windows too."""
real = fp.generate_fingerprint
def mismatched(**kwargs):
drawn = real(**kwargs)
drawn["navigator"]["platform"] = "Win32"
drawn["navigator"]["oscpu"] = "Windows NT 10.0; Win64; x64"
return drawn
monkeypatch.setattr(fp, "generate_fingerprint", mismatched)
config = fp.generate_context_fingerprint(os="linux")["config"]
assert "Linux x86_64" in config["navigator.userAgent"]
assert config["navigator.platform"] == "Linux x86_64"
assert config["navigator.oscpu"] == "Linux x86_64"
assert "Segoe UI" not in config["fonts"]