Skip to content

Commit c1e8e82

Browse files
authored
Fix several issues in isHostAndPort, isHostname, and isUri (#264)
1 parent 38be4e6 commit c1e8e82

File tree

2 files changed

+36
-35
lines changed

2 files changed

+36
-35
lines changed

src/main/java/build/buf/protovalidate/CustomOverload.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
import com.google.common.primitives.Bytes;
1818
import java.util.HashSet;
19-
import java.util.Locale;
2019
import java.util.Set;
2120
import java.util.regex.Pattern;
2221
import org.projectnessie.cel.common.types.BoolT;
@@ -463,6 +462,10 @@ private static boolean isPort(String str) {
463462
return false;
464463
}
465464

465+
if (str.length() > 1 && str.charAt(0) == '0') {
466+
return false;
467+
}
468+
466469
for (int i = 0; i < str.length(); i++) {
467470
char c = str.charAt(i);
468471
if ('0' <= c && c <= '9') {
@@ -557,7 +560,7 @@ private static boolean isHostname(String val) {
557560

558561
boolean allDigits = false;
559562

560-
String[] parts = str.toLowerCase(Locale.getDefault()).split("\\.", -1);
563+
String[] parts = str.split("\\.", -1);
561564

562565
// split hostname on '.' and validate each part
563566
for (String part : parts) {
@@ -572,8 +575,8 @@ private static boolean isHostname(String val) {
572575
// for each character in part
573576
for (int i = 0; i < part.length(); i++) {
574577
char c = part.charAt(i);
575-
// if the character is not a-z, 0-9, or '-', it is invalid
576-
if ((c < 'a' || c > 'z') && (c < '0' || c > '9') && c != '-') {
578+
// if the character is not a-z, A-Z, 0-9, or '-', it is invalid
579+
if ((c < 'a' || c > 'z') && (c < 'A' || c > 'Z') && (c < '0' || c > '9') && c != '-') {
577580
return false;
578581
}
579582

src/main/java/build/buf/protovalidate/Uri.java

Lines changed: 29 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ private boolean scheme() {
167167
if (this.alpha()) {
168168
while (this.alpha() || this.digit() || this.take('+') || this.take('-') || this.take('.')) {}
169169

170-
if (this.str.charAt(this.index) == ':') {
170+
if (this.peek(':')) {
171171
return true;
172172
}
173173
}
@@ -253,10 +253,8 @@ private boolean userinfo() {
253253
continue;
254254
}
255255

256-
if (this.index < this.str.length()) {
257-
if (this.str.charAt(this.index) == '@') {
258-
return true;
259-
}
256+
if (this.peek('@')) {
257+
return true;
260258
}
261259

262260
this.index = start;
@@ -335,15 +333,11 @@ private boolean checkHostPctEncoded(String str) {
335333
* <pre>host = IP-literal / IPv4address / reg-name.
336334
*/
337335
private boolean host() {
338-
if (this.index >= this.str.length()) {
339-
return true;
340-
}
341-
342336
int start = this.index;
343337
this.pctEncodedFound = false;
344338

345339
// Note: IPv4address is a subset of reg-name
346-
if ((this.str.charAt(this.index) == '[' && this.ipLiteral()) || this.regName()) {
340+
if ((this.peek('[') && this.ipLiteral()) || this.regName()) {
347341
if (this.pctEncodedFound) {
348342
String rawHost = this.str.substring(start, this.index);
349343
// RFC 3986:
@@ -446,7 +440,7 @@ private boolean ipv6Address() {
446440
/**
447441
* Determines whether the current position is a valid IPv6addrz.
448442
*
449-
* Parses the rule:
443+
* <p>Parses the rule:
450444
*
451445
* <pre>IPv6addrz = IPv6address "%25" ZoneID
452446
*/
@@ -465,7 +459,7 @@ private boolean ipv6Addrz() {
465459
/**
466460
* Determines whether the current position is a valid zone ID.
467461
*
468-
* Parses the rule:
462+
* <p>Parses the rule:
469463
*
470464
* <pre>ZoneID = 1*( unreserved / pct-encoded )
471465
*/
@@ -486,7 +480,7 @@ private boolean zoneID() {
486480
/**
487481
* Determines whether the current position is a valid IPvFuture.
488482
*
489-
* Parses the rule:
483+
* <p>Parses the rule:
490484
*
491485
* <pre>IPvFuture = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
492486
*/
@@ -517,7 +511,7 @@ private boolean ipvFuture() {
517511
/**
518512
* Determines whether the current position is a valid reg-name.
519513
*
520-
* Parses the rule:
514+
* <p>Parses the rule:
521515
*
522516
* <pre>reg-name = *( unreserved / pct-encoded / sub-delims )
523517
*
@@ -536,7 +530,7 @@ private boolean regName() {
536530
return true;
537531
}
538532

539-
if (this.str.charAt(this.index) == ':') {
533+
if (this.peek(':')) {
540534
return true;
541535
}
542536

@@ -570,7 +564,7 @@ private boolean isPathEnd() {
570564
/**
571565
* Determines whether the current position is a valid path-abempty.
572566
*
573-
* Parses the rule:
567+
* <p>Parses the rule:
574568
*
575569
* <pre>path-abempty = *( "/" segment )
576570
*
@@ -593,7 +587,7 @@ private boolean pathAbempty() {
593587
/**
594588
* Determines whether the current position is a valid path-absolute.
595589
*
596-
* Parses the rule:
590+
* <p>Parses the rule:
597591
*
598592
* <pre>path-absolute = "/" [ segment-nz *( "/" segment ) ]
599593
*
@@ -620,7 +614,7 @@ private boolean pathAbsolute() {
620614
/**
621615
* Determines whether the current position is a valid path-noscheme.
622616
*
623-
* Parses the rule:
617+
* <p>Parses the rule:
624618
*
625619
* <pre>path-noscheme = segment-nz-nc *( "/" segment )
626620
*
@@ -645,7 +639,7 @@ private boolean pathNoscheme() {
645639
/**
646640
* Determines whether the current position is a valid path-rootless.
647641
*
648-
* Parses the rule:
642+
* <p>Parses the rule:
649643
*
650644
* <pre>path-rootless = segment-nz *( "/" segment )
651645
*
@@ -670,7 +664,7 @@ private boolean pathRootless() {
670664
/**
671665
* Determines whether the current position is a valid path-empty.
672666
*
673-
* Parses the rule:
667+
* <p>Parses the rule:
674668
*
675669
* <pre>path-empty = 0<pchar>
676670
*
@@ -683,7 +677,7 @@ private boolean pathEmpty() {
683677
/**
684678
* Determines whether the current position is a valid segment.
685679
*
686-
* Parses the rule:
680+
* <p>Parses the rule:
687681
*
688682
* <pre>segment = *pchar
689683
*/
@@ -696,7 +690,7 @@ private boolean segment() {
696690
/**
697691
* Determines whether the current position is a valid segment-nz.
698692
*
699-
* Parses the rule:
693+
* <p>Parses the rule:
700694
*
701695
* <pre>segment-nz = 1*pchar
702696
*/
@@ -716,7 +710,7 @@ private boolean segmentNz() {
716710
/**
717711
* Determines whether the current position is a valid segment-nz-nc.
718712
*
719-
* Parses the rule:
713+
* <p>Parses the rule:
720714
*
721715
* <pre>segment-nz-nc = 1*( unreserved / pct-encoded / sub-delims / "@" )
722716
* ; non-zero-length segment without any colon ":"
@@ -738,7 +732,7 @@ private boolean segmentNzNc() {
738732
/**
739733
* Determines whether the current position is a valid pchar.
740734
*
741-
* Parses the rule:
735+
* <p>Parses the rule:
742736
*
743737
* <pre>pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
744738
*/
@@ -753,7 +747,7 @@ private boolean pchar() {
753747
/**
754748
* Determines whether the current position is a valid query.
755749
*
756-
* Parses the rule:
750+
* <p>Parses the rule:
757751
*
758752
* <pre>query = *( pchar / "/" / "?" )
759753
*
@@ -767,7 +761,7 @@ private boolean query() {
767761
continue;
768762
}
769763

770-
if (this.index == this.str.length() || this.str.charAt(this.index) == '#') {
764+
if (this.peek('#') || this.index == this.str.length()) {
771765
return true;
772766
}
773767

@@ -780,7 +774,7 @@ private boolean query() {
780774
/**
781775
* Determines whether the current position is a valid fragment.
782776
*
783-
* Parses the rule:
777+
* <p>Parses the rule:
784778
*
785779
* <pre>fragment = *( pchar / "/" / "?" )
786780
*
@@ -807,7 +801,7 @@ private boolean fragment() {
807801
/**
808802
* Determines whether the current position is a valid pct-encoded.
809803
*
810-
* Parses the rule:
804+
* <p>Parses the rule:
811805
*
812806
* <pre>pct-encoded = "%"+HEXDIG+HEXDIG
813807
*
@@ -830,7 +824,7 @@ private boolean pctEncoded() {
830824
/**
831825
* Determines whether the current position is an unreserved character.
832826
*
833-
* Parses the rule:
827+
* <p>Parses the rule:
834828
*
835829
* <pre>unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
836830
*/
@@ -846,7 +840,7 @@ private boolean unreserved() {
846840
/**
847841
* Determines whether the current position is a sub-delim.
848842
*
849-
* Parses the rule:
843+
* <p>Parses the rule:
850844
*
851845
* <pre>sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
852846
* / "*" / "+" / "," / ";" / "="
@@ -868,7 +862,7 @@ private boolean subDelims() {
868862
/**
869863
* Determines whether the current position is an alpha character.
870864
*
871-
* Parses the rule:
865+
* <p>Parses the rule:
872866
*
873867
* <pre>ALPHA = %x41-5A / %x61-7A ; A-Z / a-z
874868
*/
@@ -942,4 +936,8 @@ private boolean take(char c) {
942936

943937
return false;
944938
}
939+
940+
private boolean peek(char c) {
941+
return this.index < this.str.length() && this.str.charAt(this.index) == c;
942+
}
945943
}

0 commit comments

Comments
 (0)