| ... | ... | @@ -191,7 +191,11 @@ pub fn parseAfterScheme(scheme: []const u8, text: []const u8) ParseError!Uri { |
| 191 | 191 | } |
| 192 | 192 | |
| 193 | 193 | var start_of_host: usize = 0; |
| 194 | | if (std.mem.find(u8, authority, "@")) |index| { |
| 194 | // Use findLast to handle unencoded @ in userinfo gracefully, |
| 195 | // e.g. scheme://user:p@ssword@hostname. This deviates from RFC3986 |
| 196 | // (which requires @ to be percent-encoded as %40 in userinfo) but |
| 197 | // is more robust against URIs in the wild. |
| 198 | if (std.mem.findLast(u8, authority, "@")) |index| { |
| 195 | 199 | start_of_host = index + 1; |
| 196 | 200 | const user_info = authority[0..index]; |
| 197 | 201 | |
| ... | ... | @@ -621,6 +625,23 @@ test "authority" { |
| 621 | 625 | try std.testing.expectEqual(@as(u16, 1234), (try parse("scheme://user:password@hostname:1234")).port.?); |
| 622 | 626 | try std.testing.expectEqualStrings("user", (try parse("scheme://user:password@hostname:1234")).user.?.percent_encoded); |
| 623 | 627 | try std.testing.expectEqualStrings("password", (try parse("scheme://user:password@hostname:1234")).password.?.percent_encoded); |
| 628 | |
| 629 | try std.testing.expectEqualStrings("user", (try parse("scheme://user:p@ssword@hostname:1234")).user.?.percent_encoded); |
| 630 | try std.testing.expectEqualStrings("p@ssword", (try parse("scheme://user:p@ssword@hostname:1234")).password.?.percent_encoded); |
| 631 | try std.testing.expectEqualStrings("hostname", (try parse("scheme://user:p@ssword@hostname:1234")).host.?.percent_encoded); |
| 632 | |
| 633 | try std.testing.expectEqualStrings("user", (try parse("scheme://user:p@@@word@hostname:1234")).user.?.percent_encoded); |
| 634 | try std.testing.expectEqualStrings("p@@@word", (try parse("scheme://user:p@@@word@hostname:1234")).password.?.percent_encoded); |
| 635 | try std.testing.expectEqualStrings("hostname", (try parse("scheme://user:p@@@word@hostname:1234")).host.?.percent_encoded); |
| 636 | |
| 637 | try std.testing.expectEqualStrings("user@name", (try parse("scheme://user@name@hostname")).user.?.percent_encoded); |
| 638 | try std.testing.expectEqual(@as(?Component, null), (try parse("scheme://user@name@hostname")).password); |
| 639 | try std.testing.expectEqualStrings("hostname", (try parse("scheme://user@name@hostname")).host.?.percent_encoded); |
| 640 | |
| 641 | try std.testing.expectEqualStrings("user@name", (try parse("scheme://user@name@hostname:1234")).user.?.percent_encoded); |
| 642 | try std.testing.expectEqual(@as(?Component, null), (try parse("scheme://user@name@hostname:1234")).password); |
| 643 | try std.testing.expectEqualStrings("hostname", (try parse("scheme://user@name@hostname:1234")).host.?.percent_encoded); |
| 644 | try std.testing.expectEqual(@as(u16, 1234), (try parse("scheme://user@name@hostname:1234")).port.?); |
| 624 | 645 | } |
| 625 | 646 | |
| 626 | 647 | test "authority.password" { |