From 18e9ddd16ad73b263c565280dff580ce657678f4 Mon Sep 17 00:00:00 2001 From: Shusui MOYATANI Date: Fri, 5 May 2023 17:13:19 +0900 Subject: [PATCH] fix: bech32 duplication bug in parseTextNote --- src/nostr/parseTextNote.test.ts | 10 ++++++++++ src/nostr/parseTextNote.ts | 22 ++++++++++++++-------- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/nostr/parseTextNote.test.ts b/src/nostr/parseTextNote.test.ts index 7e5692f..fad7edc 100644 --- a/src/nostr/parseTextNote.test.ts +++ b/src/nostr/parseTextNote.test.ts @@ -173,6 +173,16 @@ describe('parseTextNote', () => { assert.deepStrictEqual(parsed, expected); }); + + it('should parse text note which includes invalid npub string', () => { + const parsed = parseTextNote('this is pubkey\nnpub1srf6g8\nhello'); + + const expected: ParsedTextNoteNode[] = [ + { type: 'PlainText', content: 'this is pubkey\nnpub1srf6g8\nhello' }, + ]; + + assert.deepStrictEqual(parsed, expected); + }); }); describe('resolveTagReference', () => { diff --git a/src/nostr/parseTextNote.ts b/src/nostr/parseTextNote.ts index b10ad6f..404aedd 100644 --- a/src/nostr/parseTextNote.ts +++ b/src/nostr/parseTextNote.ts @@ -78,10 +78,19 @@ const parseTextNote = (textNoteContent: string) => { const result: ParsedTextNote = []; const pushPlainText = (index: number | undefined) => { - if (index != null && pos !== index) { + if (index != null && index > pos) { const content = textNoteContent.slice(pos, index); - const plainText: PlainText = { type: 'PlainText', content }; - result.push(plainText); + + // combine plaintext node when failed to decode (e.g. bech32) + const lastNode = result[result.length - 1]; + if (lastNode?.type === 'PlainText') { + lastNode.content += content; + } else { + const plainText: PlainText = { type: 'PlainText', content }; + result.push(plainText); + } + + pos = index; } }; @@ -118,7 +127,6 @@ const parseTextNote = (textNoteContent: string) => { } catch (e) { console.warn(`failed to parse Bech32 entity (NIP-19): ${match[0]}`); pushPlainText(index + match[0].length); - return; } } else if (match.groups?.hashtag) { pushPlainText(index); @@ -133,10 +141,8 @@ const parseTextNote = (textNoteContent: string) => { pos = index + match[0].length; }); - if (pos !== textNoteContent.length) { - const content = textNoteContent.slice(pos); - const plainText: PlainText = { type: 'PlainText', content }; - result.push(plainText); + if (pos < textNoteContent.length) { + pushPlainText(textNoteContent.length); } return result;