diff --git a/nostrdb/src/bolt11/bech32.c b/nostrdb/src/bolt11/bech32.c index 84c74bf2..00c94414 100644 --- a/nostrdb/src/bolt11/bech32.c +++ b/nostrdb/src/bolt11/bech32.c @@ -157,13 +157,21 @@ bech32_encoding bech32_decode_len(char* hrp, uint8_t *data, size_t *data_len, co } } +/** + * Decode a bech32 string. + * + * IMPORTANT: Caller must allocate hrp buffer of at least (strlen(input) - 6) bytes + * to hold the maximum possible HRP for the given input. This matches bolt11.c usage. + */ bech32_encoding bech32_decode(char* hrp, uint8_t *data, size_t *data_len, const char *input, size_t max_input_len) { size_t len = strlen(input); if (len > max_input_len) { return BECH32_ENCODING_NONE; } - static const int MAX_PREFIX = 10; // 9 bytes for the text, 1 byte for the null terminator - return bech32_decode_len(hrp, data, data_len, input, len, MAX_PREFIX); + // Derive max HRP length from input: input = hrp + '1' + data + checksum(6) + // Caller must allocate hrp buffer of at least len-6 bytes (see bolt11.c:386) + int max_hrp_len = (len > 6) ? (int)(len - 6) : 1; + return bech32_decode_len(hrp, data, data_len, input, len, max_hrp_len); } int bech32_convert_bits(uint8_t* out, size_t* outlen, int outbits, const uint8_t* in, size_t inlen, int inbits, int pad) { diff --git a/nostrdb/src/bolt11/bolt11.c b/nostrdb/src/bolt11/bolt11.c index d79eb66e..80477c98 100644 --- a/nostrdb/src/bolt11/bolt11.c +++ b/nostrdb/src/bolt11/bolt11.c @@ -376,8 +376,15 @@ static bool bech32_decode_alloc(const tal_t *ctx, size_t *data_len, const char *str) { - char *hrp = tal_arr(ctx, char, strlen(str) - 6); - u5 *data = tal_arr(ctx, u5, strlen(str) - 8); + size_t len = strlen(str); + + /* Minimum: 1 HRP + '1' separator + 6 checksum = 8 chars. + * Guard prevents underflow in (len - 6) and (len - 8) below. */ + if (len < 8) + return false; + + char *hrp = tal_arr(ctx, char, len - 6); + u5 *data = tal_arr(ctx, u5, len - 8); if (bech32_decode(hrp, data, data_len, str, (size_t)-1) != BECH32_ENCODING_BECH32) { diff --git a/nostrdb/src/content_parser.c b/nostrdb/src/content_parser.c index a8352db1..1e5aa7b2 100644 --- a/nostrdb/src/content_parser.c +++ b/nostrdb/src/content_parser.c @@ -180,7 +180,15 @@ static int push_invoice_str(struct ndb_content_parser *p, struct ndb_str_block * struct bolt11 *bolt11; char *fail; - if (!(bolt11 = bolt11_decode_minimal(NULL, str->str, &fail))) + // Create null-terminated copy since str->str points into content buffer + char *invoice_str = strndup(str->str, str->len); + if (!invoice_str) + return 0; + + bolt11 = bolt11_decode_minimal(NULL, invoice_str, &fail); + free(invoice_str); + + if (!bolt11) return 0; start = p->buffer.p;