On Thu, 11 Apr 2024 15:27:55 GMT, Sergey Chernyshev <schernys...@openjdk.org> 
wrote:

>> There are two distinct approaches to parsing IPv4 literal addresses. One is 
>> the Java baseline "strict" syntax (all-decimal d.d.d.d form family), another 
>> one is the "loose" syntax of RFC 6943 section 3.1.1 [1] (POSIX `inet_addr` 
>> allowing octal and hexadecimal forms [2]). The goal of this PR is to provide 
>> interface to construct InetAddress objects from literal addresses in POSIX 
>> form, to applications that need to mimic the behavior of `inet_addr` used by 
>> standard network utilities such as netcat/curl/wget and the majority of web 
>> browsers. At present time, there's no way to construct `InetAddress` object 
>> from such literal addresses because the existing APIs such as 
>> `InetAddress.getByName()`, `InetAddress#ofLiteral()` and 
>> `Inet4Address#ofLiteral()` will consume an address and successfully parse it 
>> as decimal, regardless of the octal prefix. Hence, the resulting object will 
>> point to a different IP address.
>> 
>> Historically `InetAddress.getByName()/.getAllByName()` were the only way to 
>> convert a literal address into an InetAddress object. `getAllByName()` API 
>> relies on POSIX `getaddrinfo` / `inet_addr` which parses IP address segments 
>> with `strtoul` (accepts octal and hexadecimal bases).
>> 
>> The fallback to `getaddrinfo` is undesirable as it may end up with network 
>> queries (blocking mode), if `inet_addr` rejects the input literal address. 
>> The Java standard explicitly says that
>> 
>> "If a literal IP address is supplied, only the validity of the address 
>> format is checked."
>> 
>> @AlekseiEfimov contributed JDK-8272215 [3] that adds new factory methods 
>> `.ofLiteral()` to `InetAddress` classes. Although the new API is not 
>> affected by the `getaddrinfo` fallback issue, it is not sufficient for an 
>> application that needs to interoperate with external tooling that follows 
>> POSIX standard. In the current state, `InetAddress#ofLiteral()` and 
>> `Inet4Address#ofLiteral()` will consume the input literal address and 
>> (regardless of the octal prefix) parse it as decimal numbers. Hence, it's 
>> not possible to reliably construct an `InetAddress` object from a literal 
>> address in POSIX form that would point to the desired host.
>> 
>> It is proposed to extend the factory methods with 
>> `Inet4Address#ofPosixLiteral()` that allows parsing literal IP(v4) addresses 
>> in "loose" syntax, compatible with `inet_addr` POSIX api. The implementation 
>> is based on `.isBsdParsableV4()` method added along with JDK-8277608 [4]. 
>> The changes in the original algorithm are as follows:
>> 
>> - `IPAddressUtil#parseB...
>
> Sergey Chernyshev has updated the pull request incrementally with two 
> additional commits since the last revision:
> 
>  - Update src/java.base/share/classes/java/net/Inet4Address.java
>    
>    Co-authored-by: Daniel Fuchs <67001856+df...@users.noreply.github.com>
>  - Update src/java.base/share/classes/java/net/Inet4Address.java
>    
>    Co-authored-by: Daniel Fuchs <67001856+df...@users.noreply.github.com>

The parsing code and the test changes look good to me with a couple of minor 
suggestions.

src/java.base/share/classes/java/net/Inet4Address.java line 321:

> 319:      * cannot be parsed as an IPv4 address literal and {@code throwIAE} 
> is {@code true}.
> 320:      */
> 321:     static Inet4Address parseAddressStringPosix(String addressLiteral, 
> boolean throwIAE) {

This method can be made `private` since it's only used in the `Inet4Address` 
class.
`throwIAE`  is always `true` and therefore can be removed.

src/java.base/share/classes/sun/net/util/IPAddressUtil.java line 711:

> 709:                 fieldValue = parseV4FieldBsd(radix, charBuffer, 
> fieldNumber);
> 710:                 if (fieldValue >= 0) {
> 711:                     if (fieldValue < 256) {

Maybe this check can be acccompanied with a comment to clarify the following, 
ie if a field value is greater than `255` then it can only be the last field. 
If it is not the last one then `parseV4FieldBsd` enforces this limit and will 
return `null`.
That would help future code maintainers :)

src/java.base/share/classes/sun/net/util/IPAddressUtil.java line 730:

> 728:             return null;
> 729:         }
> 730:         // If the last fieldValue is greater than 255 (fieldNumer < 4),

typo:
Suggestion:

        // If the last fieldValue is greater than 255 (fieldNumber < 4),

test/jdk/java/net/InetAddress/OfLiteralTest.java line 26:

> 24: /* @test
> 25:  * @bug 8272215 8315767
> 26:  * @summary Test for ofLiteral API in InetAddress classes

The test summary can mention that `ofLiteralPosix` is also tested here

test/jdk/java/net/InetAddress/OfLiteralTest.java line 126:

> 124:         byte[] ipv4_0_0_0_34 = new byte[]{0, 0, 0, 34};
> 125: 
> 126:         // 127.0.1.1 address bytes

Update comment to match the code:
Suggestion:

        // 127.0.1.2 address bytes

test/jdk/java/net/InetAddress/OfLiteralTest.java line 129:

> 127:         byte[] ipv4_127_0_1_2 = new byte[]{127, 0, 1, 2};
> 128: 
> 129:         // 127.1.1.1 address bytes

Update comment to match the code:
Suggestion:

        // 127.1.2.3 address bytes

-------------

PR Review: https://git.openjdk.org/jdk/pull/18493#pullrequestreview-2004651764
PR Review Comment: https://git.openjdk.org/jdk/pull/18493#discussion_r1567975404
PR Review Comment: https://git.openjdk.org/jdk/pull/18493#discussion_r1567996061
PR Review Comment: https://git.openjdk.org/jdk/pull/18493#discussion_r1567984828
PR Review Comment: https://git.openjdk.org/jdk/pull/18493#discussion_r1568000966
PR Review Comment: https://git.openjdk.org/jdk/pull/18493#discussion_r1567998369
PR Review Comment: https://git.openjdk.org/jdk/pull/18493#discussion_r1567998873

Reply via email to