Skip to content

Commit

Permalink
Add strict checks for deserialization and serialization property targets
Browse files Browse the repository at this point in the history
  • Loading branch information
marcus-pousette committed Jul 13, 2022
1 parent 2b70fb6 commit f294fc0
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 6 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@dao-xyz/borsh",
"version": "2.1.3",
"version": "2.1.4",
"readme": "README.md",
"homepage": "https://github.com/dao-xyz/borsh-ts#README",
"description": "Binary Object Representation Serializer for Hashing simplified with decorators",
Expand Down
57 changes: 57 additions & 0 deletions src/__tests__/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,63 @@ describe("enum", () => {
);
});

test("extended enum inheritance variants, serialization target does matter for fields", () => {
@variant(0)
class Super {}

@variant(0)
class ClazzA extends Super {
constructor() {
super();
}
}
@variant(1)
class ClazzB extends Super {
constructor() {
super();
}
}

class Struct {
@field({ type: ClazzA })
property: ClazzA;
constructor() {}
}

const s = new Struct();
s.property = new ClazzB();

expect(() => serialize(s)).toThrowError();
});

test("extended enum inheritance variants, deserialization target does matter for fields", () => {
@variant(0)
class Super {}

@variant(0)
class ClazzA extends Super {
constructor() {
super();
}
}
@variant(1)
class ClazzB extends Super {
constructor() {
super();
}
}

class Struct {
@field({ type: ClazzB })
property: ClazzB;
constructor() {}
}
// we try to deserializ [0,0] into Struct, which shouldnot be possible since property is instance of ClazzB
expect(() =>
deserialize(Buffer.from(Uint8Array.from([0, 0])), Struct)
).toThrowError();
});

test("extended enum inheritance and field value conflict is resolved", () => {
@variant(1)
class Super {}
Expand Down
14 changes: 9 additions & 5 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,14 +191,14 @@ function deserializeField(
}
}

function deserializeStruct(clazz: any, reader: BinaryReader) {
if (typeof clazz.borshDeserialize === "function") {
return clazz.borshDeserialize(reader);
function deserializeStruct(targetClazz: any, reader: BinaryReader) {
if (typeof targetClazz.borshDeserialize === "function") {
return targetClazz.borshDeserialize(reader);
}

const result: { [key: string]: any } = {};

clazz = getSuperMostClass(clazz);
const clazz = getSuperMostClass(targetClazz);

// assume clazz is super class
if (getVariantIndex(clazz) !== undefined) {
Expand Down Expand Up @@ -295,7 +295,7 @@ function deserializeStruct(clazz: any, reader: BinaryReader) {
nextClazz = dependencies.values().next().value;
else if (dependencies.size > 1) {
const classes = [...dependencies.values()].map((f) => f.name).join(', ')
throw new BorshError(`Multiple ambigious deserialization paths from ${currClazz.name} found: ${classes}. This is not allowed, and would not be performant if allowed`)
throw new BorshError(`Multiple deserialization paths from ${currClazz.name} found: ${classes} but no matches the variant read from the buffer.`)
}
}

Expand All @@ -307,6 +307,10 @@ function deserializeStruct(clazz: any, reader: BinaryReader) {
if (!once) {
throw new BorshError(`Unexpected schema ${clazz.constructor.name}`);
}
if (!checkClazzesCompatible(currClazz, targetClazz)) {
throw new BorshError(`Deserialization of ${targetClazz} yielded another Class: ${clazz} which are not compatible`);

}
return Object.assign(new currClazz(), result);

}
Expand Down

0 comments on commit f294fc0

Please sign in to comment.