-
Notifications
You must be signed in to change notification settings - Fork 76
Description
Describe the Bug
When deserializing a structured-mode CloudEvent that contains data_base64, the parseStructured function in src/message/http/index.ts decodes the binary data into a Uint32Array instead of a Uint8Array:
eventObj.data = new Uint32Array(Buffer.from(data, "base64"));This produces an object where each byte value (0–255) occupies a 32-bit element. While Buffer.from(uint32Array) happens to copy values correctly (element-by-element), any consumer that reads the underlying ArrayBuffer directly (such as protobuf libraries) sees 4 bytes per element with null-byte padding, resulting in corrupted data.
Related: #491 explains how Uint32Array ended up as the SDK's internal binary representation. That issue and PR #494 fixed the encoding direction (creating CloudEvents with binary data), but the decoding path in parseStructured was never updated.
Steps to Reproduce
const { HTTP } = require("cloudevents");
const originalBytes = Buffer.from([0x0a, 0x0d, 0x6f, 0x70]);
const envelope = JSON.stringify({
specversion: "1.0",
id: "test-123",
type: "test",
source: "test",
data_base64: originalBytes.toString("base64"),
});
const event = HTTP.toEvent({
headers: { "content-type": "application/cloudevents+json" },
body: envelope,
});
console.log(event.data.constructor.name); // "Uint32Array" — should be "Uint8Array"
console.log(event.data.buffer.byteLength); // 16 (4 elements × 4 bytes) — should be 4
// Reading the underlying ArrayBuffer gives corrupted data:
const raw = Buffer.from(event.data.buffer, event.data.byteOffset, event.data.byteLength);
console.log(raw); // <Buffer 0a 00 00 00 0d 00 00 00 6f 00 00 00 70 00 00 00>Expected Behavior
event.data should be a Uint8Array so that both value-based access and raw ArrayBuffer access produce the correct bytes.
This would also be consistent with the SDK's own base64AsBinary() in event/validation.ts, which already uses Uint8Array.