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 existingbase64AsBinary()helper, which returns a properUint8Array - Update all test fixtures from
Uint32ArraytoUint8Arrayto match - Add a new test that explicitly asserts
event.datais aUint8Arraywith correctbuffer.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