Skip to content

Commit

Permalink
add checks for more parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
derwehr committed Apr 5, 2024
1 parent d4a3888 commit 1d86750
Show file tree
Hide file tree
Showing 2 changed files with 135 additions and 14 deletions.
77 changes: 63 additions & 14 deletions packages/core/src/codecs/octetstream-codec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,14 +59,41 @@ export default class OctetstreamCodec implements ContentCodec {
debug("OctetstreamCodec parsing", bytes);
debug("Parameters", parameters);

const bigEndian = !(parameters.byteSeq?.includes(Endianness.LITTLE_ENDIAN) === true); // default to big endian
let signed = parameters.signed !== "false"; // default to signed
const length =
parameters.length != null
? parseInt(parameters.length)
: (warn("Missing 'length' parameter necessary for write. I'll do my best"), undefined);

if (length !== undefined) {
if (isNaN(length) || length < 0) {
throw new Error("'length' parameter must be a non-negative number");
}
if (length !== bytes.length) {
throw new Error(`Lengths do not match, required: ${length} provided: ${bytes.length}`);
}

Check warning on line 73 in packages/core/src/codecs/octetstream-codec.ts

View check run for this annotation

Codecov / codecov/patch

packages/core/src/codecs/octetstream-codec.ts#L72-L73

Added lines #L72 - L73 were not covered by tests
}

let signed = true; // default to signed
if (parameters.signed !== undefined) {
if (parameters.signed !== "true" && parameters.signed !== "false") {
throw new Error("'signed' parameter must be 'true' or 'false'");
}
signed = parameters.signed === "true";
}

let bitLength = schema?.["ex:bitLength"] !== undefined ? parseInt(schema["ex:bitLength"]) : bytes.length * 8;

if (isNaN(bitLength) || bitLength < 0) {
throw new Error("'ex:bitLength' must be a non-negative number");
}

const offset = schema?.["ex:bitOffset"] !== undefined ? parseInt(schema["ex:bitOffset"]) : 0;
if (parameters.length != null && parseInt(parameters.length) !== bytes.length) {
throw new Error("Lengths do not match, required: " + parameters.length + " provided: " + bytes.length);

if (isNaN(offset) || offset < 0) {
throw new Error("'ex:bitOffset' must be a non-negative number");
}
let bitLength: number =
schema?.["ex:bitLength"] !== undefined ? parseInt(schema["ex:bitLength"]) : bytes.length * 8;

const bigEndian = !(parameters.byteSeq?.includes(Endianness.LITTLE_ENDIAN) === true); // default to big endian
let dataType: string = schema?.type;

if (!dataType) {
Expand Down Expand Up @@ -223,16 +250,38 @@ export default class OctetstreamCodec implements ContentCodec {
valueToBytes(value: unknown, schema?: DataSchema, parameters: { [key: string]: string | undefined } = {}): Buffer {
debug(`OctetstreamCodec serializing '${value}'`);

if (parameters.length == null) {
warn("Missing 'length' parameter necessary for write. I'll do my best");
const bigEndian = !(parameters.byteSeq?.includes(Endianness.LITTLE_ENDIAN) === true); // default to big endian

let signed = true; // default to true

if (parameters.signed !== undefined) {
if (parameters.signed !== "true" && parameters.signed !== "false") {
throw new Error("'signed' parameter must be 'true' or 'false'");
}
signed = parameters.signed === "true";
}

let length =
parameters.length != null
? parseInt(parameters.length)
: (warn("Missing 'length' parameter necessary for write. I'll do my best"), undefined);

if (length !== undefined && (isNaN(length) || length < 0)) {
throw new Error("'length' parameter must be a non-negative number");
}

const bigEndian = !(parameters.byteSeq?.includes(Endianness.LITTLE_ENDIAN) === true); // default to big endian
let signed = parameters.signed !== "false"; // default to signed
// byte length of the buffer to be returned
let length = parameters.length != null ? parseInt(parameters.length) : undefined;
let bitLength = schema?.["ex:bitLength"] !== undefined ? parseInt(schema["ex:bitLength"]) : undefined;

if (bitLength !== undefined && (isNaN(bitLength) || bitLength < 0)) {
throw new Error("'ex:bitLength' must be a non-negative number");
}

const offset = schema?.["ex:bitOffset"] !== undefined ? parseInt(schema["ex:bitOffset"]) : 0;

if (isNaN(offset) || offset < 0) {
throw new Error("'ex:bitOffset' must be a non-negative number");
}

let dataType: string = schema?.type ?? undefined;

if (value === undefined) {
Expand Down Expand Up @@ -547,11 +596,11 @@ export default class OctetstreamCodec implements ContentCodec {
const offset = schema["ex:bitOffset"] !== undefined ? parseInt(schema["ex:bitOffset"]) : 0;

if (isNaN(offset) || offset < 0) {
throw new Error("ex:bitOffset must be a non-negative number");
throw new Error("'ex:bitOffset' must be a non-negative number");
}

Check warning on line 600 in packages/core/src/codecs/octetstream-codec.ts

View check run for this annotation

Codecov / codecov/patch

packages/core/src/codecs/octetstream-codec.ts#L599-L600

Added lines #L599 - L600 were not covered by tests

if (offset > length * 8) {
throw new Error(`ex:bitOffset ${offset} exceeds length ${length}`);
throw new Error(`'ex:bitOffset' ${offset} exceeds 'length' ${length}`);
}

Check warning on line 604 in packages/core/src/codecs/octetstream-codec.ts

View check run for this annotation

Codecov / codecov/patch

packages/core/src/codecs/octetstream-codec.ts#L603-L604

Added lines #L603 - L604 were not covered by tests

result = result ?? Buffer.alloc(length);
Expand Down
72 changes: 72 additions & 0 deletions packages/core/test/ContentSerdesTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,55 @@ class SerdesOctetTests {
{ type: "uint8" }
)
).to.throw(Error, "Type is unsigned but 'signed' is true");

expect(() =>
ContentSerdes.contentToValue(
{ type: `application/octet-stream;length=test`, body: Buffer.from([0x36]) },
{ type: "integer" }
)
).to.throw(Error, "'length' parameter must be a non-negative number");

expect(() =>
ContentSerdes.contentToValue(
{ type: `application/octet-stream;length=-1`, body: Buffer.from([0x36]) },
{ type: "integer" }
)
).to.throw(Error, "'length' parameter must be a non-negative number");

expect(() =>
ContentSerdes.contentToValue(
{ type: `application/octet-stream;signed=invalid`, body: Buffer.from([0x36]) },
{ type: "integer" }
)
).to.throw(Error, "'signed' parameter must be 'true' or 'false'");

expect(() =>
ContentSerdes.contentToValue(
{ type: `application/octet-stream`, body: Buffer.from([0x36]) },
{ type: "integer", "ex:bitOffset": "invalid" }
)
).to.throw(Error, "'ex:bitOffset' must be a non-negative number");

expect(() =>
ContentSerdes.contentToValue(
{ type: `application/octet-stream`, body: Buffer.from([0x36]) },
{ type: "integer", "ex:bitOffset": -1 }
)
).to.throw(Error, "'ex:bitOffset' must be a non-negative number");

expect(() =>
ContentSerdes.contentToValue(
{ type: `application/octet-stream`, body: Buffer.from([0x36]) },
{ type: "integer", "ex:bitLength": "invalid" }
)
).to.throw(Error, "'ex:bitLength' must be a non-negative number");

expect(() =>
ContentSerdes.contentToValue(
{ type: `application/octet-stream`, body: Buffer.from([0x36]) },
{ type: "integer", "ex:bitLength": -1 }
)
).to.throw(Error, "'ex:bitLength' must be a non-negative number");
}

@test async "value to OctetStream"() {
Expand Down Expand Up @@ -937,6 +986,29 @@ class SerdesOctetTests {
Error,
"Missing 'type' property in schema"
);
expect(() => ContentSerdes.valueToContent(10, { type: "int8" }, "application/octet-stream;signed=8")).to.throw(
Error,
"'signed' parameter must be 'true' or 'false'"
);
expect(() =>
ContentSerdes.valueToContent(10, { type: "int8" }, "application/octet-stream;length=-1;")
).to.throw(Error, "'length' parameter must be a non-negative number");
expect(() => ContentSerdes.valueToContent(10, { type: "int8" }, "application/octet-stream;length=x;")).to.throw(
Error,
"'length' parameter must be a non-negative number"
);
expect(() =>
ContentSerdes.valueToContent(10, { type: "integer", "ex:bitOffset": -16 }, "application/octet-stream")
).to.throw(Error, "'ex:bitOffset' must be a non-negative number");
expect(() =>
ContentSerdes.valueToContent(10, { type: "integer", "ex:bitOffset": "foo" }, "application/octet-stream")
).to.throw(Error, "'ex:bitOffset' must be a non-negative number");
expect(() =>
ContentSerdes.valueToContent(10, { type: "integer", "ex:bitLength": -8 }, "application/octet-stream")
).to.throw(Error, "'ex:bitLength' must be a non-negative number");
expect(() =>
ContentSerdes.valueToContent(10, { type: "integer", "ex:bitLength": "foo" }, "application/octet-stream")
).to.throw(Error, "'ex:bitLength' must be a non-negative number");
}
}

Expand Down

0 comments on commit 1d86750

Please sign in to comment.