fix!: decode data_base64 as Uint8Array instead of Uint32Array by saschabratton · Pull Request #644 · cloudevents/sdk-javascript

parseStructured() decodes data_base64 into a Uint32Array instead of Uint8Array, producing binary data with a corrupted underlying ArrayBuffer.

The existing code:

eventObj.data = new Uint32Array(Buffer.from(data, "base64"));

This stores each byte value (0–255) in a 32-bit element. The numeric values are correct, so consumers using Buffer.from(typedArray) (which copies values element-by-element) happen to get the right bytes. But any consumer that reads the underlying ArrayBuffer directly (such as protobuf libraries) sees 4 bytes per element with null-byte padding, resulting in silently corrupted data.

Uint32Array was introduced as the SDK's internal binary representation around #491 / #494, which fixed the encoding direction (creating CloudEvents with binary data). The decoding path in parseStructured was never updated. Notably, the SDK's own base64AsBinary() in event/validation.ts already correctly uses Uint8Array.

Proposed Changes

  • Replace the inline new Uint32Array(Buffer.from(...)) with a call to the existing base64AsBinary() helper, which returns a proper Uint8Array
  • Update all test fixtures from Uint32Array to Uint8Array to match
  • Add a new test that explicitly asserts event.data is a Uint8Array with correct buffer.byteLength

Breaking change note

I have flagged this PR as a breaking change because it changes the runtime type of event.data from Uint32Array to Uint8Array for structured-mode CloudEvents with data_base64. Code that checks instanceof Uint32Array or relies on BYTES_PER_ELEMENT === 4 would break.

However, the current Uint32Array behavior is a bug and Uint8Array is the correct type for binary data. It's unlikely any consumer intentionally depends on Uint32Array. So this could potentially be safe as a patch/minor fix rather than requiring a major version bump.

Fixes: #643