Skip to content

typeof Uint8Array.prototype.toBase64 / Uint8Array.fromBase64 reads 'undefined' though the methods dispatch on call (breaks feature-detection → fallback paths) #6674

Description

@proggeramlug

Summary

A method that exists on Uint8Array (and its prototype) reads as undefined under typeof when accessed as a property value, even though it dispatches correctly when called:

typeof Uint8Array.prototype.toBase64   // node: "function"   perry: "undefined"
typeof Uint8Array.fromBase64           // node: "function"   perry: "undefined"

const b = new Uint8Array([0,1,2]);
b.toBase64({ alphabet: "base64url", omitPadding: true });   // works on perry
Uint8Array.fromBase64("AAEC", { alphabet: "base64url" });   // works on perry

So the property-read form (X.prototype.m / X.staticM) returns undefined while the call form (obj.m(...)) dispatches to the real implementation. Feature-detection code that gates on typeof X.prototype.m === "function" (or truthiness of X.staticM) therefore picks its fallback path on Perry even though the native method is present.

Impact

This is the reason jose/Auth.js took its atob/btoa base64 fallback instead of the native Uint8Array.toBase64/fromBase64 path (surfaced while fixing #6673): jose does Uint8Array.prototype.toBase64 ? native : fallback and Uint8Array.fromBase64 ? native : fallback, both of which read falsy on Perry. The fallback then hit the separate atob bug (#6673). Fixing this typeof-visibility gap would also route such libraries onto their native fast path.

Likely related to how the modern Uint8Array base64/hex methods (toBase64/fromBase64/toHex/fromHex/setFromBase64) are registered — dispatchable but not materialized as readable prototype/static property values (typeof, in, hasOwnProperty, destructuring, Object.getOwnPropertyNames would all likely disagree with Node).

Repro: the snippet above; observed on main @ ad91f35, macOS arm64. /tmp/gsct/bcrepro/b64.cjs in the finding session.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions