| ... | ... | @@ -374,13 +374,11 @@ pub fn fmt(uri: *const Uri, flags: Format.Flags) std.fmt.Alt(Format, Format.defa |
| 374 | 374 | /// The return value will contain strings pointing into the original `text`. |
| 375 | 375 | /// Each component that is provided will be non-`null`. |
| 376 | 376 | pub fn parse(text: []const u8) ParseError!Uri { |
| 377 | | const end = for (text, 0..) |byte, i| { |
| 378 | | if (!isSchemeChar(byte)) break i; |
| 379 | | } else text.len; |
| 380 | | // After the scheme, a ':' must appear. |
| 381 | | if (end >= text.len) return error.InvalidFormat; |
| 382 | | if (text[end] != ':') return error.UnexpectedCharacter; |
| 383 | | return parseAfterScheme(text[0..end], text[end + 1 ..]); |
| 377 | const scheme, const rest = std.mem.cutScalar(u8, text, ':') orelse |
| 378 | return error.InvalidFormat; |
| 379 | if (!isValidScheme(scheme)) |
| 380 | return error.UnexpectedCharacter; |
| 381 | return parseAfterScheme(scheme, rest); |
| 384 | 382 | } |
| 385 | 383 | |
| 386 | 384 | pub const ResolveInPlaceError = ParseError || error{NoSpaceLeft}; |
| ... | ... | @@ -522,11 +520,16 @@ fn merge_paths(base: Component, new: []u8, aux_buf: *[]u8) error{NoSpaceLeft}!Co |
| 522 | 520 | } |
| 523 | 521 | |
| 524 | 522 | /// scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) |
| 525 | | fn isSchemeChar(c: u8) bool { |
| 526 | | return switch (c) { |
| 527 | | 'A'...'Z', 'a'...'z', '0'...'9', '+', '-', '.' => true, |
| 528 | | else => false, |
| 529 | | }; |
| 523 | fn isValidScheme(scheme: []const u8) bool { |
| 524 | if (scheme.len == 0) return false; |
| 525 | if (!std.ascii.isAlphabetic(scheme[0])) return false; |
| 526 | for (scheme[1..]) |byte| { |
| 527 | switch (byte) { |
| 528 | 'A'...'Z', 'a'...'z', '0'...'9', '+', '-', '.' => continue, |
| 529 | else => return false, |
| 530 | } |
| 531 | } |
| 532 | return true; |
| 530 | 533 | } |
| 531 | 534 | |
| 532 | 535 | /// sub-delims = "!" / "$" / "&" / "'" / "(" / ")" |
| ... | ... | @@ -620,6 +623,13 @@ test "scheme" { |
| 620 | 623 | try std.testing.expectEqualStrings("ab+", (try parse("ab+:_")).scheme); |
| 621 | 624 | try std.testing.expectEqualStrings("X+++", (try parse("X+++:_")).scheme); |
| 622 | 625 | try std.testing.expectEqualStrings("Y+-.", (try parse("Y+-.:_")).scheme); |
| 626 | |
| 627 | try std.testing.expectError(error.InvalidFormat, parse("")); |
| 628 | try std.testing.expectError(error.UnexpectedCharacter, parse(":")); |
| 629 | try std.testing.expectError(error.UnexpectedCharacter, parse("-:")); |
| 630 | try std.testing.expectError(error.UnexpectedCharacter, parse("+hTTp:")); |
| 631 | try std.testing.expectError(error.UnexpectedCharacter, parse("$:")); |
| 632 | try std.testing.expectError(error.UnexpectedCharacter, parse("h$:")); |
| 623 | 633 | } |
| 624 | 634 | |
| 625 | 635 | test "authority" { |