damus

nostr ios client
git clone git://jb55.com/damus
Log | Files | Refs | README | LICENSE

commit 9b7057de363aaa3fdf35651f71f5622dc8670a9d
parent c6ab1de63926ff7f6e29a260e3e7f2473855c9c7
Author: William Casarin <jb55@jb55.com>
Date:   Wed, 19 Oct 2022 09:51:25 -0700

make url and invoice parsing case-insensitive

Signed-off-by: William Casarin <jb55@jb55.com>

Diffstat:
Mdamus-c/damus.c | 32++++++++++++++++++++++----------
MdamusTests/InvoiceTests.swift | 25++++++++++++++++++++-----
MdamusTests/damusTests.swift | 15+++++++++++----
3 files changed, 53 insertions(+), 19 deletions(-)

diff --git a/damus-c/damus.c b/damus-c/damus.c @@ -79,17 +79,26 @@ static int parse_digit(struct cursor *cur, int *digit) { } static int parse_str(struct cursor *cur, const char *str) { - unsigned long len = strlen(str); + int i; + char c, cs; + unsigned long len; + + len = strlen(str); if (cur->p + len >= cur->end) return 0; - if (!memcmp(cur->p, str, len)) { - cur->p += len; - return 1; + for (i = 0; i < len; i++) { + c = tolower(cur->p[i]); + cs = tolower(str[i]); + + if (c != cs) + return 0; } - return 0; + cur->p += len; + + return 1; } static int parse_mention(struct cursor *cur, struct block *block) { @@ -158,6 +167,9 @@ static int add_text_block(struct blocks *blocks, const u8 *start, const u8 *end) { struct block b; + if (start == end) + return 1; + b.type = BLOCK_TEXT; b.block.str.start = (const char*)start; b.block.str.end = (const char*)end; @@ -171,7 +183,7 @@ static int parse_url(struct cursor *cur, struct block *block) { if (!parse_str(cur, "http")) return 0; - if (parse_char(cur, 's')) { + if (parse_char(cur, 's') || parse_char(cur, 'S')) { if (!parse_str(cur, "://")) { cur->p = start; return 0; @@ -231,7 +243,7 @@ static int parse_invoice(struct cursor *cur, struct block *block) { return 1; } -static int add_text_then_block(struct cursor *cur, struct blocks *blocks, struct block block, u8 **start, u8 *pre_mention) +static int add_text_then_block(struct cursor *cur, struct blocks *blocks, struct block block, const u8 **start, const u8 *pre_mention) { if (!add_text_block(blocks, *start, pre_mention)) return 0; @@ -248,7 +260,7 @@ int damus_parse_content(struct blocks *blocks, const char *content) { int cp, c; struct cursor cur; struct block block; - u8 *start, *pre_mention; + const u8 *start, *pre_mention; blocks->num_blocks = 0; make_cursor(&cur, (const u8*)content, strlen(content)); @@ -264,11 +276,11 @@ int damus_parse_content(struct blocks *blocks, const char *content) { if (!add_text_then_block(&cur, blocks, block, &start, pre_mention)) return 0; continue; - } else if (c == 'h' && parse_url(&cur, &block)) { + } else if ((c == 'h' || c == 'H') && parse_url(&cur, &block)) { if (!add_text_then_block(&cur, blocks, block, &start, pre_mention)) return 0; continue; - } else if (c == 'l' && parse_invoice(&cur, &block)) { + } else if ((c == 'l' || c == 'L') && parse_invoice(&cur, &block)) { if (!add_text_then_block(&cur, blocks, block, &start, pre_mention)) return 0; continue; diff --git a/damusTests/InvoiceTests.swift b/damusTests/InvoiceTests.swift @@ -17,16 +17,31 @@ final class InvoiceTests: XCTestCase { override func tearDownWithError() throws { // Put teardown code here. This method is called after the invocation of each test method in the class. } - + + func testParseInvoiceUpper() throws { + let invstr = "LNBC100N1P357SL0SP5T9N56WDZTUN39LGDQLR30XQWKSG3K69Q4Q2RKR52APLUJW0ESN0QPP5MRQGLJK62Z20Q4NVGR6LZCYN6FHYLZCCWDVU4K77APG3ZMRKUJJQDPZW35XJUEQD9EJQCFQV3JHXCMJD9C8G6T0DCXQYJW5QCQPJRZJQT56H4GVP5YX36U2UZQA6QWCSK3E2DUUNFXPPZJ9VHYPC3WFE2WSWZ607UQQ3XQQQSQQQQQQQQQQQLQQYG9QYYSGQAGX5H20AEULJ3GDWX3KXS8U9F4MCAKDKWUAKASAMM9562FFYR9EN8YG20LG0YGNR9ZPWP68524KMDA0T5XP2WYTEX35PU8HAPYJAJXQPSQL29R" + let parsed = parse_mentions(content: invstr, tags: []) + + XCTAssertNotNil(parsed) + XCTAssertEqual(parsed.count, 1) + XCTAssertNotNil(parsed[0].is_invoice) + guard let invoice = parsed[0].is_invoice else { + return + } + XCTAssertEqual(invoice.amount, 10000) + XCTAssertEqual(invoice.expiry, 604800) + XCTAssertEqual(invoice.created_at, 1666139119) + XCTAssertEqual(invoice.string, invstr) + } + func testParseInvoice() throws { let invstr = "lnbc100n1p357sl0sp5t9n56wdztun39lgdqlr30xqwksg3k69q4q2rkr52aplujw0esn0qpp5mrqgljk62z20q4nvgr6lzcyn6fhylzccwdvu4k77apg3zmrkujjqdpzw35xjueqd9ejqcfqv3jhxcmjd9c8g6t0dcxqyjw5qcqpjrzjqt56h4gvp5yx36u2uzqa6qwcsk3e2duunfxppzj9vhypc3wfe2wswz607uqq3xqqqsqqqqqqqqqqqlqqyg9qyysgqagx5h20aeulj3gdwx3kxs8u9f4mcakdkwuakasamm9562ffyr9en8yg20lg0ygnr9zpwp68524kmda0t5xp2wytex35pu8hapyjajxqpsql29r" let parsed = parse_mentions(content: invstr, tags: []) XCTAssertNotNil(parsed) - XCTAssertEqual(parsed.count, 2) - XCTAssertEqual(parsed[0].is_text, "") - XCTAssertNotNil(parsed[1].is_invoice) - guard let invoice = parsed[1].is_invoice else { + XCTAssertEqual(parsed.count, 1) + XCTAssertNotNil(parsed[0].is_invoice) + guard let invoice = parsed[0].is_invoice else { return } XCTAssertEqual(invoice.amount, 10000) diff --git a/damusTests/damusTests.swift b/damusTests/damusTests.swift @@ -64,6 +64,14 @@ class damusTests: XCTestCase { XCTAssertNotNil(parsed[0].is_text) } + func testParseUrlUpper() { + let parsed = parse_mentions(content: "a HTTPS://jb55.COM b", tags: []) + + XCTAssertNotNil(parsed) + XCTAssertEqual(parsed.count, 3) + XCTAssertEqual(parsed[1].is_url?.absoluteString, "HTTPS://jb55.COM") + } + func testParseUrl() { let parsed = parse_mentions(content: "a https://jb55.com b", tags: []) @@ -85,10 +93,9 @@ class damusTests: XCTestCase { let parsed = parse_mentions(content: "https://jb55.com br", tags: []) XCTAssertNotNil(parsed) - XCTAssertEqual(parsed.count, 3) - XCTAssertEqual(parsed[0].is_text, "") - XCTAssertEqual(parsed[1].is_url?.absoluteString, "https://jb55.com") - XCTAssertEqual(parsed[2].is_text, " br") + XCTAssertEqual(parsed.count, 2) + XCTAssertEqual(parsed[0].is_url?.absoluteString, "https://jb55.com") + XCTAssertEqual(parsed[1].is_text, " br") } func testParseMentionBlank() {