-
Notifications
You must be signed in to change notification settings - Fork 16
Enhance IP validation #256
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
@pkwarren reverted back to JDK 8. |
| return !portRequired && isIP(str.substring(1, end), 6); | ||
| } else if (endPlus == splitIdx) { // port | ||
| return isIP(str.substring(1, end), 6) && isPort(str.substring(splitIdx + 1)); | ||
| } else { // malformed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: General code style but would prefer we remove the else here and just return as before.
| private static boolean validatePort(String value) { | ||
| // Returns true if the string is a valid port for isHostAndPort. | ||
| private static boolean isPort(String str) { | ||
| if (str.length() == 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| if (str.length() == 0) { | |
| if (str.isEmpty()) { |
| int portNum = Integer.parseInt(value); | ||
| return portNum >= 0 && portNum <= 65535; | ||
| int val = Integer.parseInt(str); | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Can remove the extra space here and below before the return.
| return val <= 65535; | ||
|
|
||
| } catch (NumberFormatException nfe) { | ||
| // Error converting to number |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can remove this comment.
| return true; | ||
| private static boolean isIP(String addr, long ver) { | ||
| if (ver == 6L) { | ||
| return new Ipv6(addr).address(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not very idiomatic Java here - having to create an empty object then calling a method on it to determine if it is valid.
I think we should make these functions like isIPv4 and isIPv6 that minimize allocations and state if possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, this is where the nuance of trying to stay consistent comes into play. This allocation is done across impls, so should we refactor those also? cc @timostamm
| private boolean prefixLength() { | ||
| int start = this.index; | ||
|
|
||
| while (true) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The condition on line 756 should be moved into the while here.
| } | ||
|
|
||
| String str = this.str.substring(start, this.index); | ||
| if (str.length() == 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| if (str.length() == 0) { | |
| if (str.isEmpty()) { |
| return true; | ||
|
|
||
| } catch (NumberFormatException nfe) { | ||
| // Error converting to number |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can remove this.
| addr = str.toAddress(); | ||
| } catch (Exception e) { | ||
| int val = Integer.parseInt(str); | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lots of extra whitespace in here that isn't improving readability - I'd remove the majority of this.
| */ | ||
| private boolean digit() { | ||
| char c = this.str.charAt(this.index); | ||
| if ('0' <= c && c <= '9') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We've got lots of places in here that could benefit from a static boolean isDigit(char c) helper to simplify code.
| return BoolT.False; | ||
| } | ||
| return Types.boolOf(validateIP(address, rhs.intValue())); | ||
| return Types.boolOf(isIP(address, rhs.intValue())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the check for address.isEmpty() still necessary?
Same for other places.
| * <p>The host can be one of: - An IPv4 address in dotted decimal format, for example | ||
| * "192.168.0.1". - An IPv6 address enclosed in square brackets, for example "[::1]". - A | ||
| * hostname, for example "example.com". |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should use <ul> for the list:
| * <p>The host can be one of: - An IPv4 address in dotted decimal format, for example | |
| * "192.168.0.1". - An IPv6 address enclosed in square brackets, for example "[::1]". - A | |
| * hostname, for example "example.com". | |
| * <p>The host can be one of: | |
| * <ul> | |
| * <li>An IPv4 address in dotted decimal format, for example "192.168.0.1".</li> | |
| * <li>An IPv6 address enclosed in square brackets, for example "[::1]".</li> | |
| * <li>A hostname, for example "example.com".</li> | |
| * </ul> |
| * | ||
| * @param host The input string to validate as a hostname. | ||
| * @return {@code true} if the input string is a valid hostname, {@code false} otherwise. | ||
| * <p>A valid hostname follows the rules below: - The name consists of one or more labels, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs a <ul>
| * <p>Returns 0 if no address was parsed successfully. | ||
| */ | ||
| int getBits() { | ||
| if (this.octets.size() != 4) { | ||
| return -1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Documented to return 0, but returns -1.
| * | ||
| * <p>Method parses the rule: | ||
| * | ||
| * <p>DIGIT = %x30-39 ; 0-9 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we use <pre> for ABNF rules?
| * <p>DIGIT = %x30-39 ; 0-9 | |
| * <pre>DIGIT = %x30-39 ; 0-9</pre> |
| // dotted notation successfully parsed as IPv4 | ||
| @Nullable private Ipv4 dottedAddr; | ||
| private boolean zoneIDFound; | ||
| // 0 -128 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| // 0 -128 | |
| // 0 - 128 |
| @Nullable private Ipv4 dottedAddr; | ||
| private boolean zoneIDFound; | ||
| // 0 -128 | ||
| private long prefixLen; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why a long if we're only ever assign values between 0 and 128?
| * <p>The same principle applies to IPv4 addresses. "192.168.1.0/24" designates the first 24 bits | ||
| * of the 32-bit IPv4 as the network prefix. | ||
| */ | ||
| static boolean isIPPrefix(String str, long version, boolean strict) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be private like the other members.
| * <p>Note Java does not support unsigned numeric types, so to handle unsigned 32-bit values, we | ||
| * need to use a 64-bit long type instead of the 32-bit (signed) Integer type. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Documented to use long, but returns an int.
| api(libs.protobuf.java) | ||
| implementation(enforcedPlatform(libs.cel)) | ||
| implementation(libs.cel.core) | ||
| implementation(libs.guava) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We actually can't remove Guava. It's used in a bunch of places after looking more in-depth.
|
@timostamm @pkwarren think i addressed most comments. lmk if I missed anything. |
This beefs up the validation for the following:
IP address (v4 and v6)
IP prefix (v4 and v6)
Hostname / Port