Skip to content

Commit 93f565f

Browse files
committed
fix!: decode data_base64 as Uint8Array instead of Uint32Array
1 parent bf5d53f commit 93f565f

4 files changed

Lines changed: 27 additions & 16 deletions

File tree

src/message/http/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import {
1616
v1binaryParsers,
1717
v1structuredParsers,
1818
} from "./headers";
19-
import { isStringOrObjectOrThrow, ValidationError } from "../../event/validation";
19+
import { base64AsBinary, isStringOrObjectOrThrow, ValidationError } from "../../event/validation";
2020
import { JSONParser, MappedParser, Parser, parserByContentType } from "../../parsers";
2121

2222
/**
@@ -248,7 +248,7 @@ function parseStructured<T>(message: Message, version: string): CloudEvent<T> {
248248
// itself will be encoded as base64
249249
if (eventObj.data_base64 || eventObj.datacontentencoding === CONSTANTS.ENCODING_BASE64) {
250250
const data = eventObj.data_base64 || eventObj.data;
251-
eventObj.data = new Uint32Array(Buffer.from(data as string, "base64"));
251+
eventObj.data = base64AsBinary(data as string);
252252
delete eventObj.data_base64;
253253
delete eventObj.datacontentencoding;
254254
}

test/integration/cloud_event_test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ const fixture = Object.freeze({
2222
data: `"some data"`
2323
});
2424

25-
const imageData = new Uint32Array(fs.readFileSync(path.join(process.cwd(), "test", "integration", "ce.png")));
25+
const imageData = new Uint8Array(fs.readFileSync(path.join(process.cwd(), "test", "integration", "ce.png")));
2626
const image_base64 = asBase64(imageData);
2727

2828
// Do not replace this with the assignment of a class instance

test/integration/kafka_tests.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,12 @@ const ext2Name = "extension2";
3434
const ext2Value = "acme";
3535

3636
// Binary data as base64
37-
const dataBinary = Uint32Array.from(JSON.stringify(data), (c) => c.codePointAt(0) as number);
37+
const dataBinary = Uint8Array.from(JSON.stringify(data), (c) => c.codePointAt(0) as number);
3838
const data_base64 = asBase64(dataBinary);
3939

4040
// Since the above is a special case (string as binary), let's test
4141
// with a real binary file one is likely to encounter in the wild
42-
const imageData = new Uint32Array(fs.readFileSync(path.join(process.cwd(), "test", "integration", "ce.png")));
42+
const imageData = new Uint8Array(fs.readFileSync(path.join(process.cwd(), "test", "integration", "ce.png")));
4343
const image_base64 = asBase64(imageData);
4444

4545
const fixture = new CloudEvent({
@@ -289,14 +289,14 @@ describe("Kafka transport", () => {
289289

290290
it.skip("Converts base64 encoded data to binary when deserializing structured messages", () => {
291291
const message = Kafka.structured(fixture.cloneWith({ data: imageData, datacontenttype: "image/png" }));
292-
const eventDeserialized = Kafka.toEvent(message) as CloudEvent<Uint32Array>;
292+
const eventDeserialized = Kafka.toEvent(message) as CloudEvent<Uint8Array>;
293293
expect(eventDeserialized.data).to.deep.equal(imageData);
294294
expect(eventDeserialized.data_base64).to.equal(image_base64);
295295
});
296296

297297
it("Converts base64 encoded data to binary when deserializing binary messages", () => {
298298
const message = Kafka.binary(fixture.cloneWith({ data: imageData, datacontenttype: "image/png" }));
299-
const eventDeserialized = Kafka.toEvent(message) as CloudEvent<Uint32Array>;
299+
const eventDeserialized = Kafka.toEvent(message) as CloudEvent<Uint8Array>;
300300
expect(eventDeserialized.data).to.deep.equal(imageData);
301301
expect(eventDeserialized.data_base64).to.equal(image_base64);
302302
});
@@ -310,7 +310,7 @@ describe("Kafka transport", () => {
310310

311311
it("Does not parse binary data from binary messages with content type application/json", () => {
312312
const message = Kafka.binary(fixture.cloneWith({ data: dataBinary }));
313-
const eventDeserialized = Kafka.toEvent(message) as CloudEvent<Uint32Array>;
313+
const eventDeserialized = Kafka.toEvent(message) as CloudEvent<Uint8Array>;
314314
expect(eventDeserialized.data).to.deep.equal(dataBinary);
315315
expect(eventDeserialized.data_base64).to.equal(data_base64);
316316
});

test/integration/message_test.ts

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,12 @@ const ext2Name = "extension2";
3232
const ext2Value = "acme";
3333

3434
// Binary data as base64
35-
const dataBinary = Uint32Array.from(JSON.stringify(data), (c) => c.codePointAt(0) as number);
35+
const dataBinary = Uint8Array.from(JSON.stringify(data), (c) => c.codePointAt(0) as number);
3636
const data_base64 = asBase64(dataBinary);
3737

3838
// Since the above is a special case (string as binary), let's test
3939
// with a real binary file one is likely to encounter in the wild
40-
const imageData = new Uint32Array(fs.readFileSync(path.join(process.cwd(), "test", "integration", "ce.png")));
40+
const imageData = new Uint8Array(fs.readFileSync(path.join(process.cwd(), "test", "integration", "ce.png")));
4141
const image_base64 = asBase64(imageData);
4242

4343
describe("HTTP transport", () => {
@@ -317,21 +317,32 @@ describe("HTTP transport", () => {
317317

318318
it("Converts base64 encoded data to binary when deserializing structured messages", () => {
319319
const message = HTTP.structured(fixture.cloneWith({ data: imageData, datacontenttype: "image/png" }));
320-
const eventDeserialized = HTTP.toEvent(message) as CloudEvent<Uint32Array>;
320+
const eventDeserialized = HTTP.toEvent(message) as CloudEvent<Uint8Array>;
321321
expect(eventDeserialized.data).to.deep.equal(imageData);
322322
expect(eventDeserialized.data_base64).to.equal(image_base64);
323323
});
324324

325325
it("Does not parse binary data from structured messages with content type application/json", () => {
326326
const message = HTTP.structured(fixture.cloneWith({ data: dataBinary }));
327-
const eventDeserialized = HTTP.toEvent(message) as CloudEvent<Uint32Array>;
327+
const eventDeserialized = HTTP.toEvent(message) as CloudEvent<Uint8Array>;
328328
expect(eventDeserialized.data).to.deep.equal(dataBinary);
329329
expect(eventDeserialized.data_base64).to.equal(data_base64);
330330
});
331331

332+
it("Deserializes data_base64 as Uint8Array with correct byte length", () => {
333+
const original = new Uint8Array([0x00, 0x01, 0x02, 0xff]);
334+
const event = fixture.cloneWith({ data: original, datacontenttype: "application/octet-stream" });
335+
const message = HTTP.structured(event);
336+
const deserialized = HTTP.toEvent(message) as CloudEvent<Uint8Array>;
337+
expect(deserialized.data).to.be.instanceOf(Uint8Array);
338+
expect(deserialized.data!.length).to.equal(4);
339+
expect(deserialized.data!.buffer.byteLength).to.equal(4);
340+
expect(Array.from(deserialized.data!)).to.deep.equal([0x00, 0x01, 0x02, 0xff]);
341+
});
342+
332343
it("Converts base64 encoded data to binary when deserializing binary messages", () => {
333344
const message = HTTP.binary(fixture.cloneWith({ data: imageData, datacontenttype: "image/png" }));
334-
const eventDeserialized = HTTP.toEvent(message) as CloudEvent<Uint32Array>;
345+
const eventDeserialized = HTTP.toEvent(message) as CloudEvent<Uint8Array>;
335346
expect(eventDeserialized.data).to.deep.equal(imageData);
336347
expect(eventDeserialized.data_base64).to.equal(image_base64);
337348
});
@@ -345,7 +356,7 @@ describe("HTTP transport", () => {
345356

346357
it("Does not parse binary data from binary messages with content type application/json", () => {
347358
const message = HTTP.binary(fixture.cloneWith({ data: dataBinary }));
348-
const eventDeserialized = HTTP.toEvent(message) as CloudEvent<Uint32Array>;
359+
const eventDeserialized = HTTP.toEvent(message) as CloudEvent<Uint8Array>;
349360
expect(eventDeserialized.data).to.deep.equal(dataBinary);
350361
expect(eventDeserialized.data_base64).to.equal(data_base64);
351362
});
@@ -422,14 +433,14 @@ describe("HTTP transport", () => {
422433
// Creating an event with binary data automatically produces base64 encoded data
423434
// which is then set as the 'data' attribute on the message body
424435
const message = HTTP.structured(fixture.cloneWith({ data: imageData, datacontenttype: "image/png" }));
425-
const eventDeserialized = HTTP.toEvent(message) as CloudEvent<Uint32Array>;
436+
const eventDeserialized = HTTP.toEvent(message) as CloudEvent<Uint8Array>;
426437
expect(eventDeserialized.data).to.deep.equal(imageData);
427438
expect(eventDeserialized.data_base64).to.equal(image_base64);
428439
});
429440

430441
it("Converts base64 encoded data to binary when deserializing binary messages", () => {
431442
const message = HTTP.binary(fixture.cloneWith({ data: imageData, datacontenttype: "image/png" }));
432-
const eventDeserialized = HTTP.toEvent(message) as CloudEvent<Uint32Array>;
443+
const eventDeserialized = HTTP.toEvent(message) as CloudEvent<Uint8Array>;
433444
expect(eventDeserialized.data).to.deep.equal(imageData);
434445
expect(eventDeserialized.data_base64).to.equal(image_base64);
435446
});

0 commit comments

Comments
 (0)