From 7507943253d20f1fb98fc84f29ba4874649b7c80 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Thu, 29 Jun 2023 13:18:09 -0500 Subject: [PATCH] Fix nip27.matchAll crash on invalid nip19 --- nip27.test.ts | 19 +++++++++++++++++++ nip27.ts | 23 +++++++++++++---------- 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/nip27.test.ts b/nip27.test.ts index d6bc024..dd40f19 100644 --- a/nip27.test.ts +++ b/nip27.test.ts @@ -29,6 +29,25 @@ test('matchAll', () => { ]) }) +test('matchAll with an invalid nip19', () => { + const result = matchAll( + 'Hello npub129tvj896hqqkljerxkccpj9flshwnw999v9uwn9lfmwlj8vnzwgq9y5llnpub1rujdpkd8mwezrvpqd2rx2zphfaztqrtsfg6w3vdnlj!\n\nnostr:note1gmtnz6q2m55epmlpe3semjdcq987av3jvx4emmjsa8g3s9x7tg4sclreky' + ) + + expect([...result]).toEqual([ + { + decoded: { + data: '46d731680add2990efe1cc619dc9b8014feeb23261ab9dee50e9d11814de5a2b', + type: 'note' + }, + end: 187, + start: 118, + uri: 'nostr:note1gmtnz6q2m55epmlpe3semjdcq987av3jvx4emmjsa8g3s9x7tg4sclreky', + value: 'note1gmtnz6q2m55epmlpe3semjdcq987av3jvx4emmjsa8g3s9x7tg4sclreky' + } + ]) +}) + test('replaceAll', () => { const content = 'Hello nostr:npub108pv4cg5ag52nq082kd5leu9ffrn2gdg6g4xdwatn73y36uzplmq9uyev6!\n\nnostr:note1gmtnz6q2m55epmlpe3semjdcq987av3jvx4emmjsa8g3s9x7tg4sclreky' diff --git a/nip27.ts b/nip27.ts index 9c3598f..abededc 100644 --- a/nip27.ts +++ b/nip27.ts @@ -2,8 +2,7 @@ import {decode} from './nip19.ts' import {NOSTR_URI_REGEX, type NostrURI} from './nip21.ts' /** Regex to find NIP-21 URIs inside event content. */ -export const regex = () => - new RegExp(`\\b${NOSTR_URI_REGEX.source}\\b`, 'g') +export const regex = () => new RegExp(`\\b${NOSTR_URI_REGEX.source}\\b`, 'g') /** Match result for a Nostr URI in event content. */ export interface NostrURIMatch extends NostrURI { @@ -14,18 +13,22 @@ export interface NostrURIMatch extends NostrURI { } /** Find and decode all NIP-21 URIs. */ -export function * matchAll(content: string): Iterable { +export function* matchAll(content: string): Iterable { const matches = content.matchAll(regex()) for (const match of matches) { - const [uri, value] = match + try { + const [uri, value] = match - yield { - uri: uri as `nostr:${string}`, - value, - decoded: decode(value), - start: match.index!, - end: match.index! + uri.length + yield { + uri: uri as `nostr:${string}`, + value, + decoded: decode(value), + start: match.index!, + end: match.index! + uri.length + } + } catch (_e) { + // do nothing } } }