Skip to content

Commit 921e273

Browse files
authored
fix: allow TypedArray for binary data (cloudevents#494)
* fix: allow `Uint16|8Array` for binary data Previously we only considered `Uint32Array` binary data. This was an oversight. This fixes that issue. Fixes: cloudevents#491 Signed-off-by: Lance Ball <lball@redhat.com>
1 parent a62eb44 commit 921e273

File tree

3 files changed

+64
-13
lines changed

3 files changed

+64
-13
lines changed

Diff for: src/event/cloudevent.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ See: https://github.com/cloudevents/spec/blob/v1.0/spec.md#type-system`);
133133

134134
set data(value: T | undefined) {
135135
if (isBinary(value)) {
136-
this.data_base64 = asBase64(value);
136+
this.data_base64 = asBase64(value as unknown as Buffer);
137137
}
138138
this.#_data = value;
139139
}

Diff for: src/event/validation.ts

+9-4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55

66
import { ErrorObject } from "ajv";
77

8+
export type TypeArray = Int8Array | Uint8Array | Int16Array | Uint16Array |
9+
Int32Array | Uint32Array | Uint8ClampedArray | Float32Array | Float64Array;
10+
11+
812
/**
913
* An Error class that will be thrown when a CloudEvent
1014
* cannot be properly validated against a specification.
@@ -36,7 +40,7 @@ export const isDefined = (v: unknown): boolean => v !== null && typeof v !== "un
3640
export const isBoolean = (v: unknown): boolean => typeof v === "boolean";
3741
export const isInteger = (v: unknown): boolean => Number.isInteger(v as number);
3842
export const isDate = (v: unknown): v is Date => v instanceof Date;
39-
export const isBinary = (v: unknown): v is Uint32Array => v instanceof Uint32Array;
43+
export const isBinary = (v: unknown): boolean => ArrayBuffer.isView(v);
4044

4145
export const isStringOrThrow = (v: unknown, t: Error): boolean =>
4246
isString(v)
@@ -73,7 +77,7 @@ export const isBase64 = (value: unknown): boolean =>
7377

7478
export const isBuffer = (value: unknown): boolean => value instanceof Buffer;
7579

76-
export const asBuffer = (value: string | Buffer | Uint32Array): Buffer =>
80+
export const asBuffer = (value: string | Buffer | TypeArray): Buffer =>
7781
isBinary(value)
7882
? Buffer.from((value as unknown) as string)
7983
: isBuffer(value)
@@ -82,7 +86,8 @@ export const asBuffer = (value: string | Buffer | Uint32Array): Buffer =>
8286
throw new TypeError("is not buffer or a valid binary");
8387
})();
8488

85-
export const asBase64 = (value: string | Buffer | Uint32Array): string => asBuffer(value).toString("base64");
89+
export const asBase64 =
90+
(value: string | Buffer | TypeArray): string => asBuffer(value).toString("base64");
8691

8792
export const clone = (o: Record<string, unknown>): Record<string, unknown> => JSON.parse(JSON.stringify(o));
8893

@@ -97,5 +102,5 @@ export const asData = (data: unknown, contentType: string): string => {
97102
return isBinary(maybeJson) ? asBase64(maybeJson) : maybeJson;
98103
};
99104

100-
export const isValidType = (v: boolean | number | string | Date | Uint32Array | unknown): boolean =>
105+
export const isValidType = (v: boolean | number | string | Date | TypeArray | unknown): boolean =>
101106
isBoolean(v) || isInteger(v) || isString(v) || isDate(v) || isBinary(v) || isObject(v);

Diff for: test/integration/spec_1_tests.ts

+54-8
Original file line numberDiff line numberDiff line change
@@ -173,14 +173,60 @@ describe("CloudEvents Spec v1.0", () => {
173173
expect(typeof ce.data).to.equal("string");
174174
});
175175

176-
it("should be ok when type is 'Uint32Array' for 'Binary'", () => {
177-
const dataString = ")(*~^my data for ce#@#$%";
178-
179-
const dataBinary = Uint32Array.from(dataString, (c) => c.codePointAt(0) as number);
180-
const expected = asBase64(dataBinary);
181-
182-
const ce = cloudevent.cloneWith({ datacontenttype: "text/plain", data: dataBinary });
183-
expect(ce.data_base64).to.equal(expected);
176+
const dataString = ")(*~^my data for ce#@#$%";
177+
const testCases = [
178+
{
179+
type: Int8Array,
180+
data: Int8Array.from(dataString, (c) => c.codePointAt(0) as number),
181+
expected: asBase64(Int8Array.from(dataString, (c) => c.codePointAt(0) as number))
182+
},
183+
{
184+
type: Uint8Array,
185+
data: Uint8Array.from(dataString, (c) => c.codePointAt(0) as number),
186+
expected: asBase64(Uint8Array.from(dataString, (c) => c.codePointAt(0) as number))
187+
},
188+
{
189+
type: Int16Array,
190+
data: Int16Array.from(dataString, (c) => c.codePointAt(0) as number),
191+
expected: asBase64(Int16Array.from(dataString, (c) => c.codePointAt(0) as number))
192+
},
193+
{
194+
type: Uint16Array,
195+
data: Uint16Array.from(dataString, (c) => c.codePointAt(0) as number),
196+
expected: asBase64(Uint16Array.from(dataString, (c) => c.codePointAt(0) as number))
197+
},
198+
{
199+
type: Int32Array,
200+
data: Int32Array.from(dataString, (c) => c.codePointAt(0) as number),
201+
expected: asBase64(Int32Array.from(dataString, (c) => c.codePointAt(0) as number))
202+
},
203+
{
204+
type: Uint32Array,
205+
data: Uint32Array.from(dataString, (c) => c.codePointAt(0) as number),
206+
expected: asBase64(Uint32Array.from(dataString, (c) => c.codePointAt(0) as number))
207+
},
208+
{
209+
type: Uint8ClampedArray,
210+
data: Uint8ClampedArray.from(dataString, (c) => c.codePointAt(0) as number),
211+
expected: asBase64(Uint8ClampedArray.from(dataString, (c) => c.codePointAt(0) as number))
212+
},
213+
{
214+
type: Float32Array,
215+
data: Float32Array.from(dataString, (c) => c.codePointAt(0) as number),
216+
expected: asBase64(Float32Array.from(dataString, (c) => c.codePointAt(0) as number))
217+
},
218+
{
219+
type: Float64Array,
220+
data: Float64Array.from(dataString, (c) => c.codePointAt(0) as number),
221+
expected: asBase64(Float64Array.from(dataString, (c) => c.codePointAt(0) as number))
222+
},
223+
];
224+
225+
testCases.forEach((test) => {
226+
it(`should be ok when type is '${test.type.name}' for 'Binary'`, () => {
227+
const ce = cloudevent.cloneWith({ datacontenttype: "text/plain", data: test.data });
228+
expect(ce.data_base64).to.equal(test.expected);
229+
});
184230
});
185231
});
186232
});

0 commit comments

Comments
 (0)