New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@dao-xyz/borsh

Package Overview
Dependencies
Maintainers
1
Versions
51
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@dao-xyz/borsh - npm Package Compare versions

Comparing version 5.1.3 to 5.1.4

4

lib/cjs/binary.d.ts

@@ -64,4 +64,6 @@ import { PrimitiveType, SmallIntegerType } from './types.js';

static string(reader: BinaryReader): string;
static bufferString(reader: BinaryReader): string;
static bufferStringCustom(reader: BinaryReader, length: (reader: BinaryReader) => number): string;
static stringCustom(reader: BinaryReader, length: (reader: BinaryReader) => number): string;
static read(encoding: PrimitiveType): ((reader: BinaryReader) => number) | ((reader: BinaryReader) => bigint) | ((reader: BinaryReader) => boolean) | ((reader: BinaryReader) => string);
static read(encoding: PrimitiveType, fromBuffer?: boolean): ((reader: BinaryReader) => number) | ((reader: BinaryReader) => bigint) | ((reader: BinaryReader) => boolean) | ((reader: BinaryReader) => string);
buffer(len: number): Uint8Array;

@@ -68,0 +70,0 @@ uint8Array(): Uint8Array;

@@ -18,6 +18,23 @@ "use strict";

const allocUnsafe = allocUnsafeFn();
const writeStringBufferFnFn = () => {
if (globalThis.Buffer) {
return (length) => {
if (length < 48)
return utf8_1.default.write;
return (string, buf, offset) => buf.write(string, offset);
};
}
return () => utf8_1.default.write;
};
const writeStringBufferFn = writeStringBufferFnFn();
const stringLengthFn = () => {
if (globalThis.Buffer) {
return (globalThis.Buffer).byteLength;
}
return utf8_1.default.length;
};
class BinaryWriter {
constructor() {
this.totalSize = 0;
this._writes = () => { };
this._writes = () => { this._buf = allocUnsafe(this.totalSize); };
}

@@ -128,3 +145,3 @@ bool(value) {

static string(str, writer) {
const len = utf8_1.default.length(str);
const len = stringLengthFn()(str);
let offset = writer.totalSize;

@@ -135,3 +152,3 @@ const last = writer._writes;

(0, bigint_js_1.writeUInt32LE)(len, writer._buf, offset);
utf8_1.default.write(str, writer._buf, offset + 4);
writeStringBufferFn(len)(str, writer._buf, offset + 4);
};

@@ -147,3 +164,3 @@ writer.totalSize += 4 + len;

lengthWriter(len, writer._buf, offset);
utf8_1.default.write(str, writer._buf, offset + lengthSize);
writeStringBufferFn(len)(str, writer._buf, offset + lengthSize);
};

@@ -237,3 +254,2 @@ writer.totalSize += lengthSize + len;

finalize() {
this._buf = allocUnsafe(this.totalSize);
this._writes();

@@ -349,2 +365,21 @@ return this._buf;

}
static bufferString(reader) {
const len = reader.u32();
const end = reader._offset + len;
const string = reader._buf.toString(undefined, reader._offset, end);
reader._offset = end;
return string;
}
static bufferStringCustom(reader, length) {
const len = length(reader);
try {
const end = reader._offset + len;
const string = reader._buf.toString(undefined, reader._offset, end);
reader._offset = end;
return string;
}
catch (e) {
throw new error_js_1.BorshError(`Error decoding UTF-8 string: ${e}`);
}
}
static stringCustom(reader, length) {

@@ -362,3 +397,3 @@ const len = length(reader);

}
static read(encoding) {
static read(encoding, fromBuffer) {
if (encoding === 'u8') {

@@ -386,3 +421,3 @@ return BinaryReader.u8;

else if (encoding === 'string') {
return BinaryReader.string;
return fromBuffer ? BinaryReader.bufferString : BinaryReader.string;
}

@@ -389,0 +424,0 @@ else if (encoding === 'bool') {

@@ -30,2 +30,3 @@ import { StructKind, SimpleField, CustomField, Constructor, AbstractType } from "./types.js";

export declare const getSchema: (ctor: Function, offset?: number) => StructKind;
export declare const getSchemasBottomUp: (ctor: Function) => StructKind[];
/**

@@ -32,0 +33,0 @@ *

@@ -17,3 +17,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.getDiscriminator = exports.validate = exports.field = exports.variant = exports.getSchema = exports.deserialize = exports.serialize = void 0;
exports.getDiscriminator = exports.validate = exports.field = exports.variant = exports.getSchemasBottomUp = exports.getSchema = exports.deserialize = exports.serialize = void 0;
const types_js_1 = require("./types.js");

@@ -30,6 +30,8 @@ __exportStar(require("./binary.js"), exports);

*/
const MAX_PROTOTYPE_SEARCH = 500;
// we will store some metadata about the schemas on the prototype. Prototype set get is faster if we use numbers (so we are going to use that here)
const MAX_PROTOTYPE_SEARCH = 250;
const PROTOTYPE_POLLUTION_CONTEXT_RANGE = 500;
const PROTOTYPE_DESERIALIZATION_HANDLER_OFFSET = 500;
const PROTOTYPE_DEPENDENCY_HANDLER_OFFSET = PROTOTYPE_DESERIALIZATION_HANDLER_OFFSET + MAX_PROTOTYPE_SEARCH;
const PROTOTYPE_SCHEMA_OFFSET = PROTOTYPE_DESERIALIZATION_HANDLER_OFFSET + MAX_PROTOTYPE_SEARCH * 2;
const PROTOTYPE_DEPENDENCY_HANDLER_OFFSET = PROTOTYPE_DESERIALIZATION_HANDLER_OFFSET + PROTOTYPE_POLLUTION_CONTEXT_RANGE;
const PROTOTYPE_SCHEMA_OFFSET = PROTOTYPE_DESERIALIZATION_HANDLER_OFFSET + PROTOTYPE_POLLUTION_CONTEXT_RANGE * 2;
/**

@@ -49,3 +51,4 @@ * Serialize an object with @field(...) or @variant(...) decorators

const reader = new binary_js_1.BinaryReader(buffer);
const result = deserializeStruct(classType)(reader, options);
let fromBuffer = buffer.constructor !== Uint8Array;
const result = deserializeStruct(classType, fromBuffer)(reader, options);
if (!options?.unchecked && reader._offset !== buffer.length) {

@@ -215,6 +218,6 @@ throw new error_js_1.BorshError(`Unexpected ${buffer.length - reader._offset} bytes after deserialized data`);

}
function deserializeField(fieldName, fieldType) {
function deserializeField(fieldName, fieldType, fromBuffer) {
try {
if (typeof fieldType === "string") {
return binary_js_1.BinaryReader.read(fieldType);
return binary_js_1.BinaryReader.read(fieldType, fromBuffer);
}

@@ -230,3 +233,3 @@ if (fieldType === Uint8Array) {

else {
const sizeHandle = binary_js_1.BinaryReader.read(fieldType.sizeEncoding);
const sizeHandle = binary_js_1.BinaryReader.read(fieldType.sizeEncoding, fromBuffer);
return (reader) => binary_js_1.BinaryReader.uint8Array(reader, sizeHandle(reader));

@@ -236,4 +239,4 @@ }

else {
let sizeHandle = fieldType instanceof types_js_1.VecKind ? binary_js_1.BinaryReader.read(fieldType.sizeEncoding) : (() => fieldType.length);
const fieldHandle = deserializeField(null, fieldType.elementType);
let sizeHandle = fieldType instanceof types_js_1.VecKind ? binary_js_1.BinaryReader.read(fieldType.sizeEncoding, fromBuffer) : (() => fieldType.length);
const fieldHandle = deserializeField(null, fieldType.elementType, fromBuffer);
return (reader, options) => {

@@ -250,3 +253,4 @@ const len = sizeHandle(reader);

if (fieldType instanceof types_js_1.StringType) {
return (reader) => binary_js_1.BinaryReader.stringCustom(reader, binary_js_1.BinaryReader.read(fieldType.sizeEncoding));
const sizeReader = binary_js_1.BinaryReader.read(fieldType.sizeEncoding, fromBuffer);
return fromBuffer ? (reader) => binary_js_1.BinaryReader.bufferStringCustom(reader, sizeReader) : (reader) => binary_js_1.BinaryReader.stringCustom(reader, sizeReader);
}

@@ -257,3 +261,3 @@ if (typeof fieldType["deserialize"] == "function") {

if (fieldType instanceof types_js_1.OptionKind) {
const fieldHandle = deserializeField(fieldName, fieldType.elementType);
const fieldHandle = deserializeField(fieldName, fieldType.elementType, fromBuffer);
return (reader, options) => {

@@ -263,3 +267,3 @@ return reader.u8() ? fieldHandle(reader, options) : undefined;

}
return deserializeStruct(fieldType);
return deserializeStruct(fieldType, fromBuffer);
}

@@ -273,4 +277,4 @@ catch (error) {

}
function deserializeStruct(targetClazz) {
const handle = getCreateDeserializationHandle(targetClazz, 0);
function deserializeStruct(targetClazz, fromBuffer) {
const handle = getCreateDeserializationHandle(targetClazz, 0, fromBuffer); // "compile time"
return (reader, options) => {

@@ -284,6 +288,6 @@ const result = handle({}, reader, options);

}
const getCreateDeserializationHandle = (clazz, offset) => getDeserializationHandle(clazz, offset) || setDeserializationHandle(clazz, offset, createDeserializeStructHandle(clazz, offset));
const getDeserializationHandle = (clazz, offset) => clazz.prototype[PROTOTYPE_DESERIALIZATION_HANDLER_OFFSET + offset];
const setDeserializationHandle = (clazz, offset, handle) => clazz.prototype[PROTOTYPE_DESERIALIZATION_HANDLER_OFFSET + offset] = handle;
const createDeserializeStructHandle = (currClazz, offset) => {
const getCreateDeserializationHandle = (clazz, offset, fromBuffer) => getDeserializationHandle(clazz, offset, fromBuffer) || setDeserializationHandle(clazz, offset, fromBuffer, createDeserializeStructHandle(clazz, offset, fromBuffer));
const getDeserializationHandle = (clazz, offset, fromBuffer) => clazz.prototype[PROTOTYPE_DESERIALIZATION_HANDLER_OFFSET + offset + (fromBuffer ? MAX_PROTOTYPE_SEARCH : 0)];
const setDeserializationHandle = (clazz, offset, fromBuffer, handle) => clazz.prototype[PROTOTYPE_DESERIALIZATION_HANDLER_OFFSET + offset + (fromBuffer ? MAX_PROTOTYPE_SEARCH : 0)] = handle;
const createDeserializeStructHandle = (currClazz, offset, fromBuffer) => {
let handle = undefined;

@@ -322,3 +326,3 @@ let endHandle = (result, reader, options) => {

const prev = handle;
const fieldHandle = deserializeField(field.key, field.type);
const fieldHandle = deserializeField(field.key, field.type, fromBuffer);
if (prev) {

@@ -357,7 +361,7 @@ handle = (result, reader, options) => {

handle && handle(result, reader, options);
return getCreateDeserializationHandle(dep[1], dep[2].offset)(result, reader, options);
return getCreateDeserializationHandle(dep[1], dep[2].offset, fromBuffer)(result, reader, options);
};
}
else
throw new error_js_1.BorshError(`Multiple deserialization paths from ${currClazz.name} found: but no variants are used which makes deserialization undetermenistic`);
throw new error_js_1.BorshError(`Failed to find class to deserialize to from ${currClazz.name}: but no variants are used which makes deserialization undeterministic`);
}

@@ -372,3 +376,3 @@ return (result, reader, options) => {

if (agg === dep[0]) {
return getCreateDeserializationHandle(dep[1], dep[2].offset)(result, reader, options);
return getCreateDeserializationHandle(dep[1], dep[2].offset, fromBuffer)(result, reader, options);
}

@@ -381,3 +385,3 @@ }

if (variant === dep[0]) {
return getCreateDeserializationHandle(dep[1], dep[2].offset)(result, reader, options);
return getCreateDeserializationHandle(dep[1], dep[2].offset, fromBuffer)(result, reader, options);
}

@@ -396,3 +400,3 @@ }

currentVariant.every((value, index) => value === agg[index])) {
return getCreateDeserializationHandle(dep[1], dep[2].offset)(result, reader, options);
return getCreateDeserializationHandle(dep[1], dep[2].offset, fromBuffer)(result, reader, options);
}

@@ -413,7 +417,7 @@ }

const classes = [...dependencies.entries()].map(([c]) => c.name).join(', ');
throw new error_js_1.BorshError(`Multiple deserialization paths from ${currClazz.name} found: ${classes} but no matches the variant read from the buffer.`);
throw new error_js_1.BorshError(`Failed to find class to deserialize to from ${currClazz.name} found: ${classes} but no variant matches bytes read from the buffer.`);
}
}
if (next != null) {
getCreateDeserializationHandle(next, nextOffset)(result, reader, options);
getCreateDeserializationHandle(next, nextOffset, fromBuffer)(result, reader, options);
}

@@ -546,2 +550,3 @@ else {

};
exports.getSchemasBottomUp = getSchemasBottomUp;
/**

@@ -702,3 +707,3 @@ *

const getDiscriminator = (constructor) => {
const schemas = getSchemasBottomUp(constructor);
const schemas = (0, exports.getSchemasBottomUp)(constructor);
const writer = new binary_js_1.BinaryWriter();

@@ -705,0 +710,0 @@ for (let i = 0; i < schemas.length; i++) {

@@ -64,4 +64,6 @@ import { PrimitiveType, SmallIntegerType } from './types.js';

static string(reader: BinaryReader): string;
static bufferString(reader: BinaryReader): string;
static bufferStringCustom(reader: BinaryReader, length: (reader: BinaryReader) => number): string;
static stringCustom(reader: BinaryReader, length: (reader: BinaryReader) => number): string;
static read(encoding: PrimitiveType): ((reader: BinaryReader) => number) | ((reader: BinaryReader) => bigint) | ((reader: BinaryReader) => boolean) | ((reader: BinaryReader) => string);
static read(encoding: PrimitiveType, fromBuffer?: boolean): ((reader: BinaryReader) => number) | ((reader: BinaryReader) => bigint) | ((reader: BinaryReader) => boolean) | ((reader: BinaryReader) => string);
buffer(len: number): Uint8Array;

@@ -68,0 +70,0 @@ uint8Array(): Uint8Array;

@@ -12,6 +12,23 @@ import { toBigIntLE, writeBufferLEBigInt, writeUInt32LE, readUInt32LE, readUInt16LE, writeUInt16LE, readBigUInt64LE, readUIntLE, checkInt, writeBigUint64Le } from './bigint.js';

const allocUnsafe = allocUnsafeFn();
const writeStringBufferFnFn = () => {
if (globalThis.Buffer) {
return (length) => {
if (length < 48)
return utf8.write;
return (string, buf, offset) => buf.write(string, offset);
};
}
return () => utf8.write;
};
const writeStringBufferFn = writeStringBufferFnFn();
const stringLengthFn = () => {
if (globalThis.Buffer) {
return (globalThis.Buffer).byteLength;
}
return utf8.length;
};
export class BinaryWriter {
constructor() {
this.totalSize = 0;
this._writes = () => { };
this._writes = () => { this._buf = allocUnsafe(this.totalSize); };
}

@@ -122,3 +139,3 @@ bool(value) {

static string(str, writer) {
const len = utf8.length(str);
const len = stringLengthFn()(str);
let offset = writer.totalSize;

@@ -129,3 +146,3 @@ const last = writer._writes;

writeUInt32LE(len, writer._buf, offset);
utf8.write(str, writer._buf, offset + 4);
writeStringBufferFn(len)(str, writer._buf, offset + 4);
};

@@ -141,3 +158,3 @@ writer.totalSize += 4 + len;

lengthWriter(len, writer._buf, offset);
utf8.write(str, writer._buf, offset + lengthSize);
writeStringBufferFn(len)(str, writer._buf, offset + lengthSize);
};

@@ -231,3 +248,2 @@ writer.totalSize += lengthSize + len;

finalize() {
this._buf = allocUnsafe(this.totalSize);
this._writes();

@@ -342,2 +358,21 @@ return this._buf;

}
static bufferString(reader) {
const len = reader.u32();
const end = reader._offset + len;
const string = reader._buf.toString(undefined, reader._offset, end);
reader._offset = end;
return string;
}
static bufferStringCustom(reader, length) {
const len = length(reader);
try {
const end = reader._offset + len;
const string = reader._buf.toString(undefined, reader._offset, end);
reader._offset = end;
return string;
}
catch (e) {
throw new BorshError(`Error decoding UTF-8 string: ${e}`);
}
}
static stringCustom(reader, length) {

@@ -355,3 +390,3 @@ const len = length(reader);

}
static read(encoding) {
static read(encoding, fromBuffer) {
if (encoding === 'u8') {

@@ -379,3 +414,3 @@ return BinaryReader.u8;

else if (encoding === 'string') {
return BinaryReader.string;
return fromBuffer ? BinaryReader.bufferString : BinaryReader.string;
}

@@ -382,0 +417,0 @@ else if (encoding === 'bool') {

@@ -30,2 +30,3 @@ import { StructKind, SimpleField, CustomField, Constructor, AbstractType } from "./types.js";

export declare const getSchema: (ctor: Function, offset?: number) => StructKind;
export declare const getSchemasBottomUp: (ctor: Function) => StructKind[];
/**

@@ -32,0 +33,0 @@ *

@@ -12,6 +12,8 @@ import { FixedArrayKind, OptionKind, StructKind, VecKind, getOffset, StringType, } from "./types.js";

*/
const MAX_PROTOTYPE_SEARCH = 500;
// we will store some metadata about the schemas on the prototype. Prototype set get is faster if we use numbers (so we are going to use that here)
const MAX_PROTOTYPE_SEARCH = 250;
const PROTOTYPE_POLLUTION_CONTEXT_RANGE = 500;
const PROTOTYPE_DESERIALIZATION_HANDLER_OFFSET = 500;
const PROTOTYPE_DEPENDENCY_HANDLER_OFFSET = PROTOTYPE_DESERIALIZATION_HANDLER_OFFSET + MAX_PROTOTYPE_SEARCH;
const PROTOTYPE_SCHEMA_OFFSET = PROTOTYPE_DESERIALIZATION_HANDLER_OFFSET + MAX_PROTOTYPE_SEARCH * 2;
const PROTOTYPE_DEPENDENCY_HANDLER_OFFSET = PROTOTYPE_DESERIALIZATION_HANDLER_OFFSET + PROTOTYPE_POLLUTION_CONTEXT_RANGE;
const PROTOTYPE_SCHEMA_OFFSET = PROTOTYPE_DESERIALIZATION_HANDLER_OFFSET + PROTOTYPE_POLLUTION_CONTEXT_RANGE * 2;
/**

@@ -30,3 +32,4 @@ * Serialize an object with @field(...) or @variant(...) decorators

const reader = new BinaryReader(buffer);
const result = deserializeStruct(classType)(reader, options);
let fromBuffer = buffer.constructor !== Uint8Array;
const result = deserializeStruct(classType, fromBuffer)(reader, options);
if (!options?.unchecked && reader._offset !== buffer.length) {

@@ -195,6 +198,6 @@ throw new BorshError(`Unexpected ${buffer.length - reader._offset} bytes after deserialized data`);

}
function deserializeField(fieldName, fieldType) {
function deserializeField(fieldName, fieldType, fromBuffer) {
try {
if (typeof fieldType === "string") {
return BinaryReader.read(fieldType);
return BinaryReader.read(fieldType, fromBuffer);
}

@@ -210,3 +213,3 @@ if (fieldType === Uint8Array) {

else {
const sizeHandle = BinaryReader.read(fieldType.sizeEncoding);
const sizeHandle = BinaryReader.read(fieldType.sizeEncoding, fromBuffer);
return (reader) => BinaryReader.uint8Array(reader, sizeHandle(reader));

@@ -216,4 +219,4 @@ }

else {
let sizeHandle = fieldType instanceof VecKind ? BinaryReader.read(fieldType.sizeEncoding) : (() => fieldType.length);
const fieldHandle = deserializeField(null, fieldType.elementType);
let sizeHandle = fieldType instanceof VecKind ? BinaryReader.read(fieldType.sizeEncoding, fromBuffer) : (() => fieldType.length);
const fieldHandle = deserializeField(null, fieldType.elementType, fromBuffer);
return (reader, options) => {

@@ -230,3 +233,4 @@ const len = sizeHandle(reader);

if (fieldType instanceof StringType) {
return (reader) => BinaryReader.stringCustom(reader, BinaryReader.read(fieldType.sizeEncoding));
const sizeReader = BinaryReader.read(fieldType.sizeEncoding, fromBuffer);
return fromBuffer ? (reader) => BinaryReader.bufferStringCustom(reader, sizeReader) : (reader) => BinaryReader.stringCustom(reader, sizeReader);
}

@@ -237,3 +241,3 @@ if (typeof fieldType["deserialize"] == "function") {

if (fieldType instanceof OptionKind) {
const fieldHandle = deserializeField(fieldName, fieldType.elementType);
const fieldHandle = deserializeField(fieldName, fieldType.elementType, fromBuffer);
return (reader, options) => {

@@ -243,3 +247,3 @@ return reader.u8() ? fieldHandle(reader, options) : undefined;

}
return deserializeStruct(fieldType);
return deserializeStruct(fieldType, fromBuffer);
}

@@ -253,4 +257,4 @@ catch (error) {

}
function deserializeStruct(targetClazz) {
const handle = getCreateDeserializationHandle(targetClazz, 0);
function deserializeStruct(targetClazz, fromBuffer) {
const handle = getCreateDeserializationHandle(targetClazz, 0, fromBuffer); // "compile time"
return (reader, options) => {

@@ -264,6 +268,6 @@ const result = handle({}, reader, options);

}
const getCreateDeserializationHandle = (clazz, offset) => getDeserializationHandle(clazz, offset) || setDeserializationHandle(clazz, offset, createDeserializeStructHandle(clazz, offset));
const getDeserializationHandle = (clazz, offset) => clazz.prototype[PROTOTYPE_DESERIALIZATION_HANDLER_OFFSET + offset];
const setDeserializationHandle = (clazz, offset, handle) => clazz.prototype[PROTOTYPE_DESERIALIZATION_HANDLER_OFFSET + offset] = handle;
const createDeserializeStructHandle = (currClazz, offset) => {
const getCreateDeserializationHandle = (clazz, offset, fromBuffer) => getDeserializationHandle(clazz, offset, fromBuffer) || setDeserializationHandle(clazz, offset, fromBuffer, createDeserializeStructHandle(clazz, offset, fromBuffer));
const getDeserializationHandle = (clazz, offset, fromBuffer) => clazz.prototype[PROTOTYPE_DESERIALIZATION_HANDLER_OFFSET + offset + (fromBuffer ? MAX_PROTOTYPE_SEARCH : 0)];
const setDeserializationHandle = (clazz, offset, fromBuffer, handle) => clazz.prototype[PROTOTYPE_DESERIALIZATION_HANDLER_OFFSET + offset + (fromBuffer ? MAX_PROTOTYPE_SEARCH : 0)] = handle;
const createDeserializeStructHandle = (currClazz, offset, fromBuffer) => {
let handle = undefined;

@@ -302,3 +306,3 @@ let endHandle = (result, reader, options) => {

const prev = handle;
const fieldHandle = deserializeField(field.key, field.type);
const fieldHandle = deserializeField(field.key, field.type, fromBuffer);
if (prev) {

@@ -337,7 +341,7 @@ handle = (result, reader, options) => {

handle && handle(result, reader, options);
return getCreateDeserializationHandle(dep[1], dep[2].offset)(result, reader, options);
return getCreateDeserializationHandle(dep[1], dep[2].offset, fromBuffer)(result, reader, options);
};
}
else
throw new BorshError(`Multiple deserialization paths from ${currClazz.name} found: but no variants are used which makes deserialization undetermenistic`);
throw new BorshError(`Failed to find class to deserialize to from ${currClazz.name}: but no variants are used which makes deserialization undeterministic`);
}

@@ -352,3 +356,3 @@ return (result, reader, options) => {

if (agg === dep[0]) {
return getCreateDeserializationHandle(dep[1], dep[2].offset)(result, reader, options);
return getCreateDeserializationHandle(dep[1], dep[2].offset, fromBuffer)(result, reader, options);
}

@@ -361,3 +365,3 @@ }

if (variant === dep[0]) {
return getCreateDeserializationHandle(dep[1], dep[2].offset)(result, reader, options);
return getCreateDeserializationHandle(dep[1], dep[2].offset, fromBuffer)(result, reader, options);
}

@@ -376,3 +380,3 @@ }

currentVariant.every((value, index) => value === agg[index])) {
return getCreateDeserializationHandle(dep[1], dep[2].offset)(result, reader, options);
return getCreateDeserializationHandle(dep[1], dep[2].offset, fromBuffer)(result, reader, options);
}

@@ -393,7 +397,7 @@ }

const classes = [...dependencies.entries()].map(([c]) => c.name).join(', ');
throw new BorshError(`Multiple deserialization paths from ${currClazz.name} found: ${classes} but no matches the variant read from the buffer.`);
throw new BorshError(`Failed to find class to deserialize to from ${currClazz.name} found: ${classes} but no variant matches bytes read from the buffer.`);
}
}
if (next != null) {
getCreateDeserializationHandle(next, nextOffset)(result, reader, options);
getCreateDeserializationHandle(next, nextOffset, fromBuffer)(result, reader, options);
}

@@ -508,3 +512,3 @@ else {

};
const getSchemasBottomUp = (ctor) => {
export const getSchemasBottomUp = (ctor) => {
let last = undefined;

@@ -511,0 +515,0 @@ let ret = [];

{
"name": "@dao-xyz/borsh",
"version": "5.1.3",
"version": "5.1.4",
"readme": "README.md",

@@ -5,0 +5,0 @@ "homepage": "https://github.com/dao-xyz/borsh-ts#README",

@@ -191,3 +191,3 @@ # Borsh TS

class TestStruct {
@field({ type: vec('32') })
@field({ type: vec('u32') })
public vec: number[];

@@ -194,0 +194,0 @@ }

@@ -17,2 +17,3 @@ import { BinaryReader, BinaryWriter } from "../binary.js";

} from "../index.js";
import crypto from "crypto";

@@ -637,3 +638,3 @@ describe("struct", () => {

test("u512 with 8int8array", () => {
test("u512 with Uint8array", () => {
class Struct {

@@ -780,3 +781,3 @@ @field({ type: "u512" })

@variant(1)
class TestEnum {}
class TestEnum { }
const instance = new TestEnum();

@@ -811,3 +812,3 @@ validate(TestEnum);

test("enum field serialization/deserialization", () => {
class Super {}
class Super { }

@@ -860,3 +861,3 @@ @variant(0)

test("extended enum top variants", () => {
class SuperSuper {}
class SuperSuper { }

@@ -916,3 +917,3 @@ class Super extends SuperSuper {

@variant(1)
class SuperSuper {}
class SuperSuper { }

@@ -1015,3 +1016,3 @@ @variant(2)

@variant(1)
class Super {}
class Super { }

@@ -1032,3 +1033,3 @@ @variant(2)

@variant(0)
class Super {}
class Super { }

@@ -1051,3 +1052,3 @@ @variant(0)

property: ClazzA;
constructor() {}
constructor() { }
}

@@ -1063,3 +1064,3 @@

@variant(0)
class Super {}
class Super { }

@@ -1082,3 +1083,3 @@ @variant(0)

property: ClazzB;
constructor() {}
constructor() { }
}

@@ -1093,3 +1094,3 @@ // we try to deserializ [0,0] into Struct, which shouldnot be possible since property is instance of ClazzB

@variant(1)
class Super {}
class Super { }

@@ -1117,3 +1118,3 @@ @variant(2)

}
class AA extends A {}
class AA extends A { }
abstract class B {

@@ -1126,3 +1127,3 @@ @field({ type: A })

}
class BB extends B {}
class BB extends B { }
const b = new BB(new AA(123));

@@ -1134,3 +1135,3 @@

test("inheritance without variant", () => {
class Super {}
class Super { }
class A extends Super {

@@ -1161,3 +1162,3 @@ @field({ type: "u8" })

@variant(1)
class C2 extends B {}
class C2 extends B { }

@@ -1176,3 +1177,3 @@ validate(Super);

test("wrapped enum", () => {
class Super {}
class Super { }

@@ -1210,3 +1211,3 @@ @variant(2)

test("enum variant array", () => {
class Super {}
class Super { }

@@ -1265,6 +1266,6 @@ @variant([1, 2, 3])

@variant("🦍")
class Gorilla extends Ape {}
class Gorilla extends Ape { }
@variant("🦧")
class Orangutan extends Ape {}
class Orangutan extends Ape { }

@@ -1357,24 +1358,51 @@ class HighCouncil {

});
});
describe("string", () => {
test("field string", () => {
test("empty string option", () => {
class TestStruct {
@field({ type: "string" })
public a: string;
@field({ type: option("string") })
string: string;
@field({ type: "u8" })
public b: number;
constructor(string: string) {
this.string = string;
}
}
expect(
deserialize(serialize(new TestStruct("")), TestStruct).string
).toEqual("");
});
@field({ type: "string" })
public c: string;
test("0 number option", () => {
class TestStruct {
@field({ type: option("u8") })
number: number;
constructor(a: string, b: number, c: string) {
this.a = a;
this.b = b;
this.c = c;
constructor(number: number) {
this.number = number;
}
}
expect(
deserialize(serialize(new TestStruct(0)), TestStruct).number
).toEqual(0);
});
});
describe("string", () => {
class TestStruct {
@field({ type: "string" })
public a: string;
@field({ type: "u8" })
public b: number;
@field({ type: "string" })
public c: string;
constructor(a: string, b: number, c: string) {
this.a = a;
this.b = b;
this.c = c;
}
}
test("field string", () => {
validate(TestStruct);
const bufSome = serialize(new TestStruct("a string 😊", 123, "that ends"));

@@ -1387,3 +1415,8 @@ expect(new Uint8Array(bufSome)).toEqual(

);
const deserializedSome = deserialize(new Uint8Array(bufSome), TestStruct);
const deserializedSome = deserialize(bufSome, TestStruct);
const deserializedSomeUint8Array = deserialize(
new Uint8Array(bufSome),
TestStruct
);
expect(deserializedSome).toMatchObject(deserializedSomeUint8Array);
expect(deserializedSome.a).toEqual("a string 😊");

@@ -1394,4 +1427,19 @@ expect(deserializedSome.b).toEqual(123);

test("large string", () => {
let first = Buffer.from(crypto.randomBytes(10000)).toString("hex");
const bufSome = serialize(new TestStruct(first, 123, "that ends"));
const deserializedSome = deserialize(bufSome, TestStruct);
const deserializedSomeFromUint8Array = deserialize(
new Uint8Array(bufSome),
TestStruct
);
expect(deserializedSome).toMatchObject(deserializedSomeFromUint8Array);
expect(deserializedSome.a).toEqual(first);
expect(deserializedSome.b).toEqual(123);
expect(deserializedSome.c).toEqual("that ends");
});
test("custom length", () => {
class TestStruct {
class TestStructCustom {
@field({ type: string("u8") })

@@ -1416,6 +1464,6 @@ public a: string;

}
validate(TestStruct);
validate(TestStructCustom);
const bufSome = serialize(
new TestStruct("a string 😊", 123, "that ends", "somewhere")
new TestStructCustom("a string 😊", 123, "that ends", "somewhere")
);

@@ -1429,3 +1477,8 @@ expect(new Uint8Array(bufSome)).toEqual(

);
const deserializedSome = deserialize(new Uint8Array(bufSome), TestStruct);
const deserializedSome = deserialize(bufSome, TestStructCustom);
const deserializedSomeUint8Array = deserialize(
new Uint8Array(bufSome),
TestStructCustom
);
expect(deserializedSome).toMatchObject(deserializedSomeUint8Array);
expect(deserializedSome.a).toEqual("a string 😊");

@@ -1663,6 +1716,6 @@ expect(deserializedSome.b).toEqual(123);

@variant([1, 2])
class A {}
class B extends A {}
class A { }
class B extends A { }
@variant(3)
class C extends B {}
class C extends B { }

@@ -1687,3 +1740,3 @@ @variant("abc")

@variant(3)
class B extends A {}
class B extends A { }
expect(() => getDiscriminator(B)).toThrowError(BorshError);

@@ -1698,3 +1751,3 @@ });

@variant(3)
class B extends A {}
class B extends A { }
expect(() => getDiscriminator(B)).toThrowError(BorshError);

@@ -1726,3 +1779,3 @@ });

class Value {
constructor() {}
constructor() { }
}

@@ -1754,3 +1807,3 @@

class Super {
constructor() {}
constructor() { }
}

@@ -1792,10 +1845,10 @@

class Super {
constructor() {}
constructor() { }
}
@variant(0)
class A extends Super {}
class A extends Super { }
@variant(1)
class B extends A {}
class B extends A { }

@@ -1819,10 +1872,10 @@ class Clazz {

class Super {
constructor() {}
constructor() { }
}
@variant(0)
class A extends Super {}
class A extends Super { }
@variant(1)
class Other {}
class Other { }

@@ -1845,3 +1898,3 @@ class Clazz {

class TestStruct {
constructor() {}
constructor() { }
}

@@ -1866,3 +1919,3 @@

class TestStruct {
constructor() {}
constructor() { }
}

@@ -1890,3 +1943,3 @@ @variant([0, 1, 2]) // Same as B

class TestStruct {
constructor() {}
constructor() { }
}

@@ -1914,3 +1967,3 @@ @variant([0, 1]) // Same as B

class TestStructSuper {
constructor() {}
constructor() { }
}

@@ -1943,3 +1996,3 @@ class TestStruct extends TestStructSuper {

class TestStruct {
constructor() {}
constructor() { }
}

@@ -2044,2 +2097,26 @@ @variant(0) // Same as B

});
test("can alternate between", () => {
class Clazz {
@field({ type: option('string') })
string?: string;
constructor(string?: string) {
this.string = string;
}
}
const string = 'abc'
const ser = serialize(new Clazz(string));
const der = deserialize(ser, Clazz);
const der2 = deserialize(new Uint8Array(ser), Clazz);
const der3 = deserialize(ser, Clazz);
const der4 = deserialize(new Uint8Array(ser), Clazz);
expect(der.string).toEqual(string);
expect(der2.string).toEqual(string);
expect(der3.string).toEqual(string);
expect(der4.string).toEqual(string);
});
});

@@ -15,3 +15,22 @@ import { toBigIntLE, writeBufferLEBigInt, writeUInt32LE, readUInt32LE, readUInt16LE, writeUInt16LE, readBigUInt64LE, readUIntLE, checkInt, writeBigUint64Le } from './bigint.js';

const writeStringBufferFnFn: () => ((len: number) => (string: string, buf: Uint8Array, offset: number) => void) = () => {
if ((globalThis as any).Buffer) {
return (length: number) => {
if (length < 48)
return utf8.write
return (string: string, buf: Uint8Array, offset: number) => (buf as any).write(string, offset)
}
}
return () => utf8.write
}
const writeStringBufferFn = writeStringBufferFnFn()
const stringLengthFn: () => ((str: string) => number) = () => {
if ((globalThis as any).Buffer) {
return ((globalThis as any).Buffer).byteLength
}
return utf8.length
}
export class BinaryWriter {

@@ -24,3 +43,3 @@ _buf: Uint8Array;

this.totalSize = 0;
this._writes = () => { };
this._writes = () => { this._buf = allocUnsafe(this.totalSize) };
}

@@ -160,3 +179,3 @@

public static string(str: string, writer: BinaryWriter) {
const len = utf8.length(str);
const len = stringLengthFn()(str);
let offset = writer.totalSize;

@@ -166,4 +185,4 @@ const last = writer._writes;

last();
writeUInt32LE(len, writer._buf, offset)
utf8.write(str, writer._buf, offset + 4);
writeUInt32LE(len, writer._buf, offset);
writeStringBufferFn(len)(str, writer._buf, offset + 4);
}

@@ -180,3 +199,3 @@ writer.totalSize += 4 + len;

lengthWriter(len, writer._buf, offset)
utf8.write(str, writer._buf, offset + lengthSize);
writeStringBufferFn(len)(str, writer._buf, offset + lengthSize);
}

@@ -266,3 +285,2 @@ writer.totalSize += lengthSize + len;

return BinaryWriter.bool
}

@@ -284,3 +302,2 @@ else if (encoding === 'f32') {

public finalize(): Uint8Array {
this._buf = allocUnsafe(this.totalSize);
this._writes()

@@ -424,2 +441,23 @@ return this._buf;

static bufferString(reader: BinaryReader): string {
const len = reader.u32();
const end = reader._offset + len;
const string = (reader._buf as Buffer).toString(undefined, reader._offset, end);
reader._offset = end;
return string;
}
static bufferStringCustom(reader: BinaryReader, length: (reader: BinaryReader) => number): string {
const len = length(reader);
try {
const end = reader._offset + len;
const string = (reader._buf as Buffer).toString(undefined, reader._offset, end);
reader._offset = end;
return string;
} catch (e) {
throw new BorshError(`Error decoding UTF-8 string: ${e}`);
}
}
static stringCustom(reader: BinaryReader, length: (reader: BinaryReader) => number): string {

@@ -437,3 +475,3 @@ const len = length(reader);

public static read(encoding: PrimitiveType): ((reader: BinaryReader) => number) | ((reader: BinaryReader) => bigint) | ((reader: BinaryReader) => boolean) | ((reader: BinaryReader) => string) {
public static read(encoding: PrimitiveType, fromBuffer?: boolean): ((reader: BinaryReader) => number) | ((reader: BinaryReader) => bigint) | ((reader: BinaryReader) => boolean) | ((reader: BinaryReader) => string) {
if (encoding === 'u8') {

@@ -461,3 +499,3 @@ return BinaryReader.u8

else if (encoding === 'string') {
return BinaryReader.string
return fromBuffer ? BinaryReader.bufferString : BinaryReader.string
}

@@ -464,0 +502,0 @@ else if (encoding === 'bool') {

@@ -27,6 +27,8 @@ import {

const MAX_PROTOTYPE_SEARCH = 500;
// we will store some metadata about the schemas on the prototype. Prototype set get is faster if we use numbers (so we are going to use that here)
const MAX_PROTOTYPE_SEARCH = 250;
const PROTOTYPE_POLLUTION_CONTEXT_RANGE = 500;
const PROTOTYPE_DESERIALIZATION_HANDLER_OFFSET = 500;
const PROTOTYPE_DEPENDENCY_HANDLER_OFFSET = PROTOTYPE_DESERIALIZATION_HANDLER_OFFSET + MAX_PROTOTYPE_SEARCH;
const PROTOTYPE_SCHEMA_OFFSET = PROTOTYPE_DESERIALIZATION_HANDLER_OFFSET + MAX_PROTOTYPE_SEARCH * 2;
const PROTOTYPE_DEPENDENCY_HANDLER_OFFSET = PROTOTYPE_DESERIALIZATION_HANDLER_OFFSET + PROTOTYPE_POLLUTION_CONTEXT_RANGE;
const PROTOTYPE_SCHEMA_OFFSET = PROTOTYPE_DESERIALIZATION_HANDLER_OFFSET + PROTOTYPE_POLLUTION_CONTEXT_RANGE * 2;

@@ -68,3 +70,4 @@ /**

const reader = new BinaryReader(buffer);
const result = deserializeStruct(classType)(reader, options);
let fromBuffer = buffer.constructor !== Uint8Array
const result = deserializeStruct(classType, fromBuffer)(reader, options);
if (!options?.unchecked && reader._offset !== buffer.length) {

@@ -268,6 +271,7 @@ throw new BorshError(

fieldType: any,
fromBuffer: boolean
): (reader: BinaryReader, options: DeserializeStructOptions) => any {
try {
if (typeof fieldType === "string") {
return BinaryReader.read(fieldType as IntegerType)
return BinaryReader.read(fieldType as IntegerType, fromBuffer)
}

@@ -285,3 +289,3 @@

else {
const sizeHandle = BinaryReader.read(fieldType.sizeEncoding) as (reader: BinaryReader) => number;
const sizeHandle = BinaryReader.read(fieldType.sizeEncoding, fromBuffer) as (reader: BinaryReader) => number;
return (reader) => BinaryReader.uint8Array(reader, sizeHandle(reader))

@@ -291,4 +295,4 @@ }

else {
let sizeHandle = fieldType instanceof VecKind ? BinaryReader.read(fieldType.sizeEncoding) as (reader: BinaryReader) => number : (() => fieldType.length);
const fieldHandle = deserializeField(null, fieldType.elementType);
let sizeHandle = fieldType instanceof VecKind ? BinaryReader.read(fieldType.sizeEncoding, fromBuffer) as (reader: BinaryReader) => number : (() => fieldType.length);
const fieldHandle = deserializeField(null, fieldType.elementType, fromBuffer);
return (reader, options) => {

@@ -306,3 +310,5 @@ const len = sizeHandle(reader);

if (fieldType instanceof StringType) {
return (reader) => BinaryReader.stringCustom(reader, BinaryReader.read(fieldType.sizeEncoding) as (reader: BinaryReader) => number)
const sizeReader = BinaryReader.read(fieldType.sizeEncoding, fromBuffer) as (reader: BinaryReader) => number;
return fromBuffer ? (reader) => BinaryReader.bufferStringCustom(reader, sizeReader) : (reader) => BinaryReader.stringCustom(reader, sizeReader)
}

@@ -317,3 +323,5 @@

fieldName,
fieldType.elementType);
fieldType.elementType,
fromBuffer
);
return (reader, options) => {

@@ -326,3 +334,3 @@ return reader.u8() ? fieldHandle(

}
return deserializeStruct(fieldType)
return deserializeStruct(fieldType, fromBuffer)

@@ -336,6 +344,6 @@ } catch (error) {

}
function deserializeStruct(targetClazz: any): (reader: BinaryReader, options?: DeserializeStructOptions) => any {
function deserializeStruct(targetClazz: any, fromBuffer: boolean): (reader: BinaryReader, options?: DeserializeStructOptions) => any {
const handle = getCreateDeserializationHandle(targetClazz, 0);
return (reader: BinaryReader, options?: DeserializeStructOptions) => {
const handle = getCreateDeserializationHandle(targetClazz, 0, fromBuffer); // "compile time"
return (reader: BinaryReader, options?: DeserializeStructOptions) => { // runtime
const result = handle({}, reader, options)

@@ -351,7 +359,7 @@ if (!options?.unchecked && !(options as any)?.object && !checkClazzesCompatible(result.constructor, targetClazz)) {

const getCreateDeserializationHandle = (clazz: any, offset: number): (result: any, reader: BinaryReader, options?: DeserializeStructOptions) => any => getDeserializationHandle(clazz, offset) || setDeserializationHandle(clazz, offset, createDeserializeStructHandle(clazz, offset))
const getDeserializationHandle = (clazz: any, offset: number) => clazz.prototype[PROTOTYPE_DESERIALIZATION_HANDLER_OFFSET + offset]
const setDeserializationHandle = (clazz: any, offset: number, handle: (result: any, reader: BinaryReader, options?: DeserializeStructOptions) => any) => clazz.prototype[PROTOTYPE_DESERIALIZATION_HANDLER_OFFSET + offset] = handle;
const getCreateDeserializationHandle = (clazz: any, offset: number, fromBuffer: boolean): (result: any, reader: BinaryReader, options?: DeserializeStructOptions) => any => getDeserializationHandle(clazz, offset, fromBuffer) || setDeserializationHandle(clazz, offset, fromBuffer, createDeserializeStructHandle(clazz, offset, fromBuffer))
const getDeserializationHandle = (clazz: any, offset: number, fromBuffer: boolean) => clazz.prototype[PROTOTYPE_DESERIALIZATION_HANDLER_OFFSET + offset + (fromBuffer ? MAX_PROTOTYPE_SEARCH : 0)]
const setDeserializationHandle = (clazz: any, offset: number, fromBuffer: boolean, handle: (result: any, reader: BinaryReader, options?: DeserializeStructOptions) => any) => clazz.prototype[PROTOTYPE_DESERIALIZATION_HANDLER_OFFSET + offset + (fromBuffer ? MAX_PROTOTYPE_SEARCH : 0)] = handle;
const createDeserializeStructHandle = (currClazz: Constructor<any>, offset: number): ((result: any, reader: BinaryReader, options?: DeserializeStructOptions) => any) => {
const createDeserializeStructHandle = (currClazz: Constructor<any>, offset: number, fromBuffer: boolean): ((result: any, reader: BinaryReader, options?: DeserializeStructOptions) => any) => {
let handle: (result: any, reader: BinaryReader, options?: DeserializeStructOptions) => any | undefined = undefined;

@@ -393,2 +401,3 @@ let endHandle = (result: any, reader: BinaryReader, options: DeserializeStructOptions) => {

field.type,
fromBuffer
);

@@ -435,6 +444,6 @@ if (prev) {

handle && handle(result, reader, options)
return getCreateDeserializationHandle(dep[1], dep[2].offset)(result, reader, options)
return getCreateDeserializationHandle(dep[1], dep[2].offset, fromBuffer)(result, reader, options)
}
}
else throw new BorshError(`Multiple deserialization paths from ${currClazz.name} found: but no variants are used which makes deserialization undetermenistic`)
else throw new BorshError(`Failed to find class to deserialize to from ${currClazz.name}: but no variants are used which makes deserialization undeterministic`)

@@ -452,3 +461,3 @@ }

if (agg === dep[0]) {
return getCreateDeserializationHandle(dep[1], dep[2].offset)(result, reader, options)
return getCreateDeserializationHandle(dep[1], dep[2].offset, fromBuffer)(result, reader, options)
}

@@ -461,3 +470,3 @@ }

if (variant === dep[0]) {
return getCreateDeserializationHandle(dep[1], dep[2].offset)(result, reader, options)
return getCreateDeserializationHandle(dep[1], dep[2].offset, fromBuffer)(result, reader, options)
}

@@ -477,3 +486,3 @@ }

return getCreateDeserializationHandle(dep[1], dep[2].offset)(result, reader, options)
return getCreateDeserializationHandle(dep[1], dep[2].offset, fromBuffer)(result, reader, options)
}

@@ -495,7 +504,7 @@ }

const classes = [...dependencies.entries()].map(([c]) => c.name).join(', ')
throw new BorshError(`Multiple deserialization paths from ${currClazz.name} found: ${classes} but no matches the variant read from the buffer.`)
throw new BorshError(`Failed to find class to deserialize to from ${currClazz.name} found: ${classes} but no variant matches bytes read from the buffer.`)
}
}
if (next != null) {
getCreateDeserializationHandle(next, nextOffset)(result, reader, options)
getCreateDeserializationHandle(next, nextOffset, fromBuffer)(result, reader, options)

@@ -632,3 +641,3 @@ }

const getSchemasBottomUp = (ctor: Function): StructKind[] => {
export const getSchemasBottomUp = (ctor: Function): StructKind[] => {

@@ -635,0 +644,0 @@ let last = undefined;

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc