Skip to content

Commit

Permalink
bech32: use utf8 it and last index
Browse files Browse the repository at this point in the history
  • Loading branch information
StringNick committed Sep 14, 2024
1 parent 6ef9a1f commit 1b8e7c2
Showing 1 changed file with 21 additions and 5 deletions.
26 changes: 21 additions & 5 deletions src/bech32/bech32.zig
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ pub const Variant = enum {
fn splitAndDecode(allocator: std.mem.Allocator, s: []const u8) Error!struct { std.ArrayList(u8), std.ArrayList(u5) } {
// Split at separator and check for two pieces

const raw_hrp, const raw_data = if (std.mem.indexOfScalar(u8, s, SEP)) |sep| .{
const raw_hrp, const raw_data = if (std.mem.lastIndexOfScalar(u8, s, SEP)) |sep| .{
s[0..sep], s[sep + 1 ..],
} else return Error.MissingSeparator;

Expand All @@ -177,20 +177,27 @@ fn splitAndDecode(allocator: std.mem.Allocator, s: []const u8) Error!struct { st
var data = std.ArrayList(u5).init(allocator);
errdefer data.deinit();

var it = std.unicode.Utf8View.initUnchecked(raw_data).iterator();
// Check data payload
for (raw_data) |c| {
while (it.nextCodepoint()) |c| {
// Only check if c is in the ASCII range, all invalid ASCII
// characters have the value -1 in CHARSET_REV (which covers
// the whole ASCII range) and will be filtered out later.
if (!std.ascii.isAscii(c)) return error.InvalidChar;
if (c >= 128) return error.InvalidChar;

if (std.ascii.isLower(c)) {
if (switch (c) {
'a'...'z' => true,
else => false,
}) {
switch (case) {
.upper => return Error.MixedCase,
.none => case = .lower,
.lower => {},
}
} else if (std.ascii.isUpper(c)) {
} else if (switch (c) {
'A'...'Z' => true,
else => false,
}) {
switch (case) {
.lower => return Error.MixedCase,
.none => case = .upper,
Expand Down Expand Up @@ -531,6 +538,15 @@ test "roundtrip_without_checksum" {
try std.testing.expectEqualSlices(u5, data.items, decoded_data.items);
}

test "decode ln" {
const str = "lnbc10n1pnw2hkzdqqpp5ve584t0cv27hwmy0cx9ca8uwyqyfw9y9dm3r8vus9fv36r2l9yjssp59g4z52329g4z52329g4z52329g4z52329g4z52329g4z52329g4qcqzysc39n3w6zq50y3775yc66mmvt2fe5aa9mzzdnvq5palgyw6j9uu04qnm0g4ftm5ehtm5aulwtuy0hfrtqcdaxcl2r7wz2x4503levlacqswkkem";

const h, const d, const v = try decode(std.testing.allocator, str);
_ = v; // autofix
defer h.deinit();
defer d.deinit();
}

test "test_hrp_case_decode" {
const hrp, const data, const variant = try decode(std.testing.allocator, "hrp1qqqq40atq3");
defer hrp.deinit();
Expand Down

0 comments on commit 1b8e7c2

Please sign in to comment.