diff --git a/src/main/java/build/buf/protovalidate/CustomOverload.java b/src/main/java/build/buf/protovalidate/CustomOverload.java index 94cc4819..fa244fbe 100644 --- a/src/main/java/build/buf/protovalidate/CustomOverload.java +++ b/src/main/java/build/buf/protovalidate/CustomOverload.java @@ -16,7 +16,6 @@ import com.google.common.primitives.Bytes; import java.util.HashSet; -import java.util.Locale; import java.util.Set; import java.util.regex.Pattern; import org.projectnessie.cel.common.types.BoolT; @@ -463,6 +462,10 @@ private static boolean isPort(String str) { return false; } + if (str.length() > 1 && str.charAt(0) == '0') { + return false; + } + for (int i = 0; i < str.length(); i++) { char c = str.charAt(i); if ('0' <= c && c <= '9') { @@ -557,7 +560,7 @@ private static boolean isHostname(String val) { boolean allDigits = false; - String[] parts = str.toLowerCase(Locale.getDefault()).split("\\.", -1); + String[] parts = str.split("\\.", -1); // split hostname on '.' and validate each part for (String part : parts) { @@ -572,8 +575,8 @@ private static boolean isHostname(String val) { // for each character in part for (int i = 0; i < part.length(); i++) { char c = part.charAt(i); - // if the character is not a-z, 0-9, or '-', it is invalid - if ((c < 'a' || c > 'z') && (c < '0' || c > '9') && c != '-') { + // if the character is not a-z, A-Z, 0-9, or '-', it is invalid + if ((c < 'a' || c > 'z') && (c < 'A' || c > 'Z') && (c < '0' || c > '9') && c != '-') { return false; } diff --git a/src/main/java/build/buf/protovalidate/Uri.java b/src/main/java/build/buf/protovalidate/Uri.java index 65fd63ed..60a127e2 100644 --- a/src/main/java/build/buf/protovalidate/Uri.java +++ b/src/main/java/build/buf/protovalidate/Uri.java @@ -167,7 +167,7 @@ private boolean scheme() { if (this.alpha()) { while (this.alpha() || this.digit() || this.take('+') || this.take('-') || this.take('.')) {} - if (this.str.charAt(this.index) == ':') { + if (this.peek(':')) { return true; } } @@ -253,10 +253,8 @@ private boolean userinfo() { continue; } - if (this.index < this.str.length()) { - if (this.str.charAt(this.index) == '@') { - return true; - } + if (this.peek('@')) { + return true; } this.index = start; @@ -335,15 +333,11 @@ private boolean checkHostPctEncoded(String str) { *
host = IP-literal / IPv4address / reg-name.
*/
private boolean host() {
- if (this.index >= this.str.length()) {
- return true;
- }
-
int start = this.index;
this.pctEncodedFound = false;
// Note: IPv4address is a subset of reg-name
- if ((this.str.charAt(this.index) == '[' && this.ipLiteral()) || this.regName()) {
+ if ((this.peek('[') && this.ipLiteral()) || this.regName()) {
if (this.pctEncodedFound) {
String rawHost = this.str.substring(start, this.index);
// RFC 3986:
@@ -446,7 +440,7 @@ private boolean ipv6Address() {
/**
* Determines whether the current position is a valid IPv6addrz.
*
- * Parses the rule:
+ * Parses the rule:
*
*
IPv6addrz = IPv6address "%25" ZoneID
*/
@@ -465,7 +459,7 @@ private boolean ipv6Addrz() {
/**
* Determines whether the current position is a valid zone ID.
*
- * Parses the rule:
+ * Parses the rule:
*
*
ZoneID = 1*( unreserved / pct-encoded )
*/
@@ -486,7 +480,7 @@ private boolean zoneID() {
/**
* Determines whether the current position is a valid IPvFuture.
*
- * Parses the rule:
+ * Parses the rule:
*
*
IPvFuture = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
*/
@@ -517,7 +511,7 @@ private boolean ipvFuture() {
/**
* Determines whether the current position is a valid reg-name.
*
- * Parses the rule:
+ * Parses the rule:
*
*
reg-name = *( unreserved / pct-encoded / sub-delims )
*
@@ -536,7 +530,7 @@ private boolean regName() {
return true;
}
- if (this.str.charAt(this.index) == ':') {
+ if (this.peek(':')) {
return true;
}
@@ -570,7 +564,7 @@ private boolean isPathEnd() {
/**
* Determines whether the current position is a valid path-abempty.
*
- * Parses the rule:
+ * Parses the rule:
*
*
path-abempty = *( "/" segment )
*
@@ -593,7 +587,7 @@ private boolean pathAbempty() {
/**
* Determines whether the current position is a valid path-absolute.
*
- * Parses the rule:
+ * Parses the rule:
*
*
path-absolute = "/" [ segment-nz *( "/" segment ) ]
*
@@ -620,7 +614,7 @@ private boolean pathAbsolute() {
/**
* Determines whether the current position is a valid path-noscheme.
*
- * Parses the rule:
+ * Parses the rule:
*
*
path-noscheme = segment-nz-nc *( "/" segment )
*
@@ -645,7 +639,7 @@ private boolean pathNoscheme() {
/**
* Determines whether the current position is a valid path-rootless.
*
- * Parses the rule:
+ * Parses the rule:
*
*
path-rootless = segment-nz *( "/" segment )
*
@@ -670,7 +664,7 @@ private boolean pathRootless() {
/**
* Determines whether the current position is a valid path-empty.
*
- * Parses the rule:
+ * Parses the rule:
*
*
path-empty = 0
*
@@ -683,7 +677,7 @@ private boolean pathEmpty() {
/**
* Determines whether the current position is a valid segment.
*
- * Parses the rule:
+ * Parses the rule:
*
*
segment = *pchar
*/
@@ -696,7 +690,7 @@ private boolean segment() {
/**
* Determines whether the current position is a valid segment-nz.
*
- * Parses the rule:
+ * Parses the rule:
*
*
segment-nz = 1*pchar
*/
@@ -716,7 +710,7 @@ private boolean segmentNz() {
/**
* Determines whether the current position is a valid segment-nz-nc.
*
- * Parses the rule:
+ * Parses the rule:
*
*
segment-nz-nc = 1*( unreserved / pct-encoded / sub-delims / "@" )
* ; non-zero-length segment without any colon ":"
@@ -738,7 +732,7 @@ private boolean segmentNzNc() {
/**
* Determines whether the current position is a valid pchar.
*
- * Parses the rule:
+ * Parses the rule:
*
*
pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
*/
@@ -753,7 +747,7 @@ private boolean pchar() {
/**
* Determines whether the current position is a valid query.
*
- * Parses the rule:
+ * Parses the rule:
*
*
query = *( pchar / "/" / "?" )
*
@@ -767,7 +761,7 @@ private boolean query() {
continue;
}
- if (this.index == this.str.length() || this.str.charAt(this.index) == '#') {
+ if (this.peek('#') || this.index == this.str.length()) {
return true;
}
@@ -780,7 +774,7 @@ private boolean query() {
/**
* Determines whether the current position is a valid fragment.
*
- * Parses the rule:
+ * Parses the rule:
*
*
fragment = *( pchar / "/" / "?" )
*
@@ -807,7 +801,7 @@ private boolean fragment() {
/**
* Determines whether the current position is a valid pct-encoded.
*
- * Parses the rule:
+ * Parses the rule:
*
*
pct-encoded = "%"+HEXDIG+HEXDIG
*
@@ -830,7 +824,7 @@ private boolean pctEncoded() {
/**
* Determines whether the current position is an unreserved character.
*
- * Parses the rule:
+ * Parses the rule:
*
*
unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
*/
@@ -846,7 +840,7 @@ private boolean unreserved() {
/**
* Determines whether the current position is a sub-delim.
*
- * Parses the rule:
+ * Parses the rule:
*
*
sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
* / "*" / "+" / "," / ";" / "="
@@ -868,7 +862,7 @@ private boolean subDelims() {
/**
* Determines whether the current position is an alpha character.
*
- * Parses the rule:
+ * Parses the rule:
*
*
ALPHA = %x41-5A / %x61-7A ; A-Z / a-z
*/
@@ -942,4 +936,8 @@ private boolean take(char c) {
return false;
}
+
+ private boolean peek(char c) {
+ return this.index < this.str.length() && this.str.charAt(this.index) == c;
+ }
}