Skip to content

Commit

Permalink
fix: remove null characters from user-specified strings when storing …
Browse files Browse the repository at this point in the history
…nft metadata

also add a new chain sync data set in util-dev
  • Loading branch information
mkazlauskas committed May 22, 2024
1 parent 39a8c2b commit 29a0014
Show file tree
Hide file tree
Showing 5 changed files with 7,686 additions and 6 deletions.
10 changes: 5 additions & 5 deletions packages/projection-typeorm/src/entity/NftMetadata.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { AssetEntity } from './Asset.entity';
import { BlockEntity } from './Block.entity';
import { Column, Entity, JoinColumn, ManyToOne, PrimaryGeneratedColumn } from 'typeorm';
import { OnDeleteCascadeRelationOptions, OnDeleteSetNullRelationOptions } from './util';
import { serializableObj } from './transformers';
import { sanitizeString, serializableObj } from './transformers';

export enum NftMetadataType {
CIP25 = 'CIP-0025',
Expand All @@ -14,13 +14,13 @@ export enum NftMetadataType {
export class NftMetadataEntity {
@PrimaryGeneratedColumn()
id?: number;
@Column()
@Column({ transformer: sanitizeString })
name?: string;
@Column({ nullable: true, type: 'varchar' })
@Column({ nullable: true, transformer: sanitizeString, type: 'varchar' })
description?: string | null;
@Column()
@Column({ transformer: sanitizeString })
image?: Asset.Uri;
@Column({ nullable: true, type: 'varchar' })
@Column({ nullable: true, transformer: sanitizeString, type: 'varchar' })
mediaType?: string | null;
@Column({ nullable: true, type: 'jsonb' })
files?: Asset.NftMetadataFile[] | null;
Expand Down
10 changes: 10 additions & 0 deletions packages/projection-typeorm/src/entity/transformers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,16 @@ export const serializableObj: ValueTransformer = {
}
};

export const sanitizeString: ValueTransformer = {
from(obj: any) {
return obj;
},
to(obj: any) {
if (typeof obj !== 'string') return obj;
return obj.replace(/\0/g, '');
}
};

export const parseBigInt: ValueTransformer = {
from(obj: unknown) {
return typeof obj === 'string' ? BigInt(obj) : obj;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {
import { Bootstrap, Mappers, ProjectionEvent, requestNext } from '@cardano-sdk/projection';
import { CIP67Asset, ProjectedNftMetadata } from '@cardano-sdk/projection/dist/cjs/operators/Mappers';
import { ChainSyncDataSet, chainSyncData, generateRandomHexString, logger } from '@cardano-sdk/util-dev';
import { Observable, firstValueFrom, lastValueFrom, toArray } from 'rxjs';
import { Observable, firstValueFrom, lastValueFrom, map, toArray } from 'rxjs';
import { QueryRunner, Repository } from 'typeorm';
import { connectionConfig$, initializeDataSource } from '../util';
import {
Expand Down Expand Up @@ -321,6 +321,60 @@ describe('storeNftMetadata', () => {
}),
NftMetadataType.CIP25
);

it('does not throw when name has null characters', async () => {
const events = chainSyncData(ChainSyncDataSet.AssetNameUtf8Problem);
await expect(
lastValueFrom(
project$({
...events,
cardanoNode: {
...events.cardanoNode,
findIntersect: (points) =>
events.cardanoNode.findIntersect(points).pipe(
map((observableChainSync) => ({
...observableChainSync,
chainSync$: observableChainSync.chainSync$.pipe(
// filter out Tokens that don't exist in the database with this dataset
map((e) => ({
...e,
...(e.eventType === ChainSyncEventType.RollForward
? {
block: {
...e.block,
body: e.block.body.map((tx) => ({
...tx,
body: {
...tx.body,
outputs: tx.body.outputs.map((output) => ({
...output,
value: {
...output.value,
assets: new Map(
[...(output.value.assets?.entries() || [])].filter(
([assetId]) =>
assetId ===
'00740069006e0079002000640069006e006f0073002000230035003600350032'
)
)
}
}))
}
}))
}
}
: {})
}))
)
}))
)
}
})
)
// throws 'invalid byte sequence for encoding "UTF8": 0x00'
// when asset name is not sanitized
).resolves.not.toThrow();
});
});

describe('cip68', () => {
Expand Down
Loading

0 comments on commit 29a0014

Please sign in to comment.