Skip to content

Commit

Permalink
fix(core): throw serialization error for invalid metadata fields
Browse files Browse the repository at this point in the history
  • Loading branch information
James Browning authored and mkazlauskas committed Feb 18, 2022
1 parent 8af0787 commit d67debb
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 7 deletions.
16 changes: 16 additions & 0 deletions packages/core/src/CSL/coreToCsl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,26 @@ export const txOut = (core: Cardano.TxOut): TransactionOutput =>
export const utxo = (core: Cardano.Utxo[]): TransactionUnspentOutput[] =>
core.map((item) => TransactionUnspentOutput.new(txIn(item[0]), txOut(item[1])));

const check64Length = (metadatum: string | Uint8Array): void => {
const len = typeof metadatum === 'string' ? Buffer.from(metadatum, 'utf8').length : metadatum.length;
if (len >= 64)
throw new SerializationError(
SerializationFailure.MaxLengthLimit,
`Metadatum value '${metadatum}' is too long. Length is ${len}. Max length is 64 bytes`
);
};

export const txMetadatum = (metadatum: Cardano.Metadatum): TransactionMetadatum => {
if (metadatum === null) throw new SerializationError(SerializationFailure.InvalidType);
switch (typeof metadatum) {
case 'number':
case 'boolean':
case 'undefined':
throw new SerializationError(SerializationFailure.InvalidType);
case 'bigint':
return TransactionMetadatum.new_int(Int.new(BigNum.from_str(metadatum.toString())));
case 'string':
check64Length(metadatum);
return TransactionMetadatum.new_text(metadatum);
default: {
if (Array.isArray(metadatum)) {
Expand All @@ -84,6 +99,7 @@ export const txMetadatum = (metadatum: Cardano.Metadatum): TransactionMetadatum
}
return TransactionMetadatum.new_list(metadataList);
} else if (ArrayBuffer.isView(metadatum)) {
check64Length(metadatum);
return TransactionMetadatum.new_bytes(metadatum);
}
const metadataMap = MetadataMap.new();
Expand Down
3 changes: 2 additions & 1 deletion packages/core/src/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ export class ProviderError extends CustomError {
export enum SerializationFailure {
InvalidType = 'INVALID_TYPE',
Overflow = 'OVERFLOW',
InvalidAddress = 'INVALID_ADDRESS'
InvalidAddress = 'INVALID_ADDRESS',
MaxLengthLimit = 'MAX_LENGTH_LIMIT'
}

export class SerializationError extends CustomError {
Expand Down
19 changes: 13 additions & 6 deletions packages/core/test/CSL/coreToCsl.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* eslint-disable max-len */
import { Asset, CSL, Cardano, coreToCsl } from '../../src';
import { Asset, CSL, Cardano, coreToCsl, SerializationFailure } from '../../src';
import { BigNum } from '@emurgo/cardano-serialization-lib-nodejs';

const txIn: Cardano.TxIn = {
Expand Down Expand Up @@ -180,17 +180,24 @@ describe('coreToCsl', () => {

test('bytes too long throws error', () => {
const bytes = Buffer.from(str65Len, 'utf8');
expect(() => convertMetadatum(bytes)).toThrowError('too long');
expect(() => convertMetadatum(bytes)).toThrow(SerializationFailure.MaxLengthLimit);
});

it('text too long throws error', () => {
const str = str65Len;
expect(() => convertMetadatum(str)).toThrowError('too long');
expect(() => convertMetadatum(str65Len)).toThrow(SerializationFailure.MaxLengthLimit);
});

it('bool throws error', () => {
const bool = true;
expect(() => convertMetadatum(bool)).toThrow(TypeError);
expect(() => convertMetadatum(true)).toThrowError(SerializationFailure.InvalidType);
});

it('undefined throws error', () => {
// eslint-disable-next-line unicorn/no-useless-undefined
expect(() => convertMetadatum(undefined)).toThrowError(SerializationFailure.InvalidType);
});

it('null throws error', () => {
expect(() => convertMetadatum(null)).toThrowError(SerializationFailure.InvalidType);
});
});

Expand Down

0 comments on commit d67debb

Please sign in to comment.