Skip to content

Implement Uint8Array base64/hex encoding methods (fromBase64, fromHex, toBase64, toHex, setFromBase64, setFromHex) #5170

Description

@Nakshatra480

Description

Boa is missing the Uint8Array base64 and hex encoding/decoding methods specified in ECMAScript 2025 (Section 23.3). These methods provide native, efficient conversion between Uint8Array byte data and base64/hex string representations — functionality that is extremely common in real-world JavaScript (handling binary data, cryptographic digests, network protocols, etc.).

Methods to implement

Method Spec Section Type
Uint8Array.fromBase64(string [, options]) §23.3.1.1 Static
Uint8Array.fromHex(string) §23.3.1.2 Static
Uint8Array.prototype.toBase64([options]) §23.3.2.3 Instance
Uint8Array.prototype.toHex() §23.3.2.4 Instance
Uint8Array.prototype.setFromBase64(string [, options]) §23.3.2.1 Instance
Uint8Array.prototype.setFromHex(string) §23.3.2.2 Instance

Helper abstract operations (§23.3.3)

  • ValidateUint8Array(ta) — §23.3.3.1
  • GetUint8ArrayBytes(ta) — §23.3.3.2
  • SetUint8ArrayBytes(into, bytes) — §23.3.3.3
  • SkipAsciiWhitespace(string, index) — §23.3.3.4
  • DecodeFinalBase64Chunk(chunk, throwOnExtraBits) — §23.3.3.5
  • DecodeFullLengthBase64Chunk(chunk) — §23.3.3.6
  • FromBase64(string, alphabet, lastChunkHandling [, maxLength]) — §23.3.3.7
  • FromHex(string [, maxLength]) — §23.3.3.8

Expected Behavior

// Encoding
const bytes = new Uint8Array([72, 101, 108, 108, 111]);
bytes.toBase64();  // "SGVsbG8="
bytes.toHex();     // "48656c6c6f"

// Decoding
Uint8Array.fromBase64("SGVsbG8=");        // Uint8Array [72, 101, 108, 108, 111]
Uint8Array.fromHex("48656c6c6f");         // Uint8Array [72, 101, 108, 108, 111]

// Options: base64url alphabet
bytes.toBase64({ alphabet: "base64url" });
Uint8Array.fromBase64("SGVsbG8", { alphabet: "base64url", lastChunkHandling: "loose" });

// In-place set operations
const target = new Uint8Array(10);
target.setFromBase64("SGVsbG8=");   // returns { read: 8, written: 5 }
target.setFromHex("48656c6c6f");    // returns { read: 10, written: 5 }

Implementation Hints

  • Location: core/engine/src/builtins/typed_array/ — either extend the existing Uint8Array builtin or add a new uint8array_extras.rs module
  • Rust ecosystem: The base64 and hex crates can accelerate implementation, but the spec algorithms should be followed precisely for edge cases (whitespace handling, lastChunkHandling option, alphabet selection)
  • Test262 coverage: The test262 suite includes tests under test/built-ins/Uint8Array/fromBase64/, test/built-ins/Uint8Array/fromHex/, test/built-ins/Uint8Array/prototype/toBase64/, test/built-ins/Uint8Array/prototype/toHex/, etc.
  • Other engines: V8, SpiderMonkey, and JavaScriptCore all ship these methods

Why this matters

Base64/hex encoding is ubiquitous in JavaScript — from fetch response handling to WebCrypto to working with binary protocols. Until these methods existed, JS developers had to rely on atob/btoa (which work on strings, not bytes) or third-party libraries. These spec-mandated methods are the correct, type-safe, standards-compliant way to do it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels
    No fields configured for Feature.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions