fix: improve validation on extension attribute (#502)
* fix: improve validation on extension attribute Fixes: https://github.com/cloudevents/sdk-javascript/issues/500 Adds a regular expression check to the attribute name validation code to ensure that attribute names only use a-z0-9 (except for `data_base64`, which apparently is an exception to the rule. Signed-off-by: Lance Ball <lball@redhat.com>
This commit is contained in:
parent
847f6bfcc7
commit
ea94a4d779
|
@ -18,10 +18,11 @@ export function validateCloudEvent<T>(event: CloudEventV1<T>): boolean {
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// attribute names must all be lowercase
|
// attribute names must all be [a-z|0-9]
|
||||||
|
const validation = /^[a-z0-9]+$/;
|
||||||
for (const key in event) {
|
for (const key in event) {
|
||||||
if (key !== key.toLowerCase()) {
|
if (validation.test(key) === false && key !== "data_base64") {
|
||||||
throw new ValidationError(`invalid attribute name: ${key}`);
|
throw new ValidationError(`invalid attribute name: "${key}"`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -131,7 +131,7 @@ describe("Kafka transport", () => {
|
||||||
expect(event.LUNCH).to.equal("tacos");
|
expect(event.LUNCH).to.equal("tacos");
|
||||||
expect(function () {
|
expect(function () {
|
||||||
event.validate();
|
event.validate();
|
||||||
}).to.throw("invalid attribute name: LUNCH");
|
}).to.throw("invalid attribute name: \"LUNCH\"");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Can detect CloudEvent binary Messages with weird versions", () => {
|
it("Can detect CloudEvent binary Messages with weird versions", () => {
|
||||||
|
|
|
@ -41,7 +41,21 @@ const imageData = new Uint32Array(fs.readFileSync(path.join(process.cwd(), "test
|
||||||
const image_base64 = asBase64(imageData);
|
const image_base64 = asBase64(imageData);
|
||||||
|
|
||||||
describe("HTTP transport", () => {
|
describe("HTTP transport", () => {
|
||||||
|
it("validates extension attribute names for incoming messages", () => {
|
||||||
|
// create a new Message
|
||||||
|
const msg: Message = {
|
||||||
|
headers: {
|
||||||
|
"ce-id": "213",
|
||||||
|
"ce-source": "test",
|
||||||
|
"ce-type": "test",
|
||||||
|
"ce-bad-extension": "value"
|
||||||
|
},
|
||||||
|
body: undefined
|
||||||
|
};
|
||||||
|
const evt = HTTP.toEvent(msg) as CloudEvent;
|
||||||
|
expect(() => evt.validate()).to.throw(TypeError);
|
||||||
|
});
|
||||||
|
|
||||||
it("Includes extensions in binary mode when type is 'boolean' with a false value", () => {
|
it("Includes extensions in binary mode when type is 'boolean' with a false value", () => {
|
||||||
const evt = new CloudEvent({ source: "test", type: "test", extboolean: false });
|
const evt = new CloudEvent({ source: "test", type: "test", extboolean: false });
|
||||||
expect(evt.hasOwnProperty("extboolean")).to.equal(true);
|
expect(evt.hasOwnProperty("extboolean")).to.equal(true);
|
||||||
|
@ -129,7 +143,7 @@ describe("HTTP transport", () => {
|
||||||
expect(event.LUNCH).to.equal("tacos");
|
expect(event.LUNCH).to.equal("tacos");
|
||||||
expect(function () {
|
expect(function () {
|
||||||
event.validate();
|
event.validate();
|
||||||
}).to.throw("invalid attribute name: LUNCH");
|
}).to.throw("invalid attribute name: \"LUNCH\"");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Can detect CloudEvent binary Messages with weird versions", () => {
|
it("Can detect CloudEvent binary Messages with weird versions", () => {
|
||||||
|
|
|
@ -134,7 +134,7 @@ describe("MQTT transport", () => {
|
||||||
expect(event.LUNCH).to.equal("tacos");
|
expect(event.LUNCH).to.equal("tacos");
|
||||||
expect(function () {
|
expect(function () {
|
||||||
event.validate();
|
event.validate();
|
||||||
}).to.throw("invalid attribute name: LUNCH");
|
}).to.throw("invalid attribute name: \"LUNCH\"");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Can detect CloudEvent binary Messages with weird versions", () => {
|
it("Can detect CloudEvent binary Messages with weird versions", () => {
|
||||||
|
|
|
@ -99,6 +99,16 @@ describe("CloudEvents Spec v1.0", () => {
|
||||||
it("should be ok when the type is an string converted from an object", () => {
|
it("should be ok when the type is an string converted from an object", () => {
|
||||||
expect(cloudevent.cloneWith({ objectextension: JSON.stringify({ some: "object" }) }).validate()).to.equal(true);
|
expect(cloudevent.cloneWith({ objectextension: JSON.stringify({ some: "object" }) }).validate()).to.equal(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should only allow a-z|0-9 in the attribute names", () => {
|
||||||
|
const testCases = [
|
||||||
|
"an extension", "an_extension", "an-extension", "an.extension", "an+extension"
|
||||||
|
];
|
||||||
|
testCases.forEach((testCase) => {
|
||||||
|
const evt = cloudevent.cloneWith({ [testCase]: "a value"}, false);
|
||||||
|
expect(() => evt.validate()).to.throw(ValidationError);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("The Constraints check", () => {
|
describe("The Constraints check", () => {
|
||||||
|
|
Loading…
Reference in New Issue