On Fri, 1 Nov 2024 19:24:05 GMT, Chen Liang <li...@openjdk.org> wrote:

>> In the patch for [JDK-8338544](https://bugs.openjdk.org/browse/JDK-8338544) 
>> #20665, the validation methods `validateBinaryClassName` and 
>> `validateInternalClassName` only checks if a separator char is the initial 
>> or final char, or if it immediately follows another chars.  This omitted the 
>> case of empty strings, and allowed creation of invalid ClassDesc with empty 
>> binary name, which is otherwise rejected by `ofDescriptor`.
>> 
>> To better check for the separator char, the tracking mechanism is updated to 
>> indicate a position where a separator char shouldn't appear, or where the 
>> name string should not terminate.  This is initially set to the initial 
>> position 0, and upon each time of encountering a separator, this is updated 
>> to the next char.
>> 
>> This logic is similar to the existing one in `skipOverFieldSignature`, which 
>> uses a boolean `legal` variable.  Both reject empty strings, leading and 
>> trailing separators, or consecutive separators.  The new logic, however, 
>> does not require repeated updates to the new `afterSeparator` variable upon 
>> scanning each character.
>> 
>> In addition, I noted the package name validation erroneously does not 
>> prohibit leading, trailing, or consecutive separator chars.  (Package names 
>> are derived from class or interface names, so the same restrictions shall 
>> apply)  This patch also makes package name validation reuse class or 
>> interface name validation in non-empty (unnamed package) cases, and added 
>> those cases to the test suite.
>
> Chen Liang has updated the pull request incrementally with one additional 
> commit since the last revision:
> 
>   Comments to clarify, also align skipOverFieldSignature

src/java.base/share/classes/jdk/internal/constant/ConstantUtils.java line 258:

> 256:         if (name.isEmpty())
> 257:             return name;
> 258:         return validateBinaryClassName(name);

Perhaps have a utility method to specify if empty name is allowed.   
`validateBinaryClassName` and `validateInternalClassName` only differ in the 
separator charactor.   They can be refactored to call one single name 
validation method something like this:


    private static String validateName(String name, boolean internalName, 
boolean allowEmptyName) {
        if (!allowEmptyName && name.isEmpty())
              throw invalidClassName(name);
              
        // state variable for detection of illegal states, such as:
        // empty unqualified name, consecutive, leading, or trailing separators
        int afterSeparator = 0;
        int len = name.length();
        for (int i = 0; i < len; i++) {
            char ch = name.charAt(i);
            // reject ';' or '[' or other form's separator
            if (ch == ';' || ch == '[' || (internalName && ch == '.') || 
(!internalName && ch == '/'))
                throw invalidClassName(name);
            if ((internalName && ch == '/') || (!internalName && ch == '.')) {
                // illegal state when received separator indicates consecutive
                // or leading separators
                if (i == afterSeparator)
                    throw invalidClassName(name);
                afterSeparator = i + 1;
            }
        }
        // reject empty unqualified name or trailing separators
        if (len == afterSeparator)
            throw invalidClassName(name);
        return name;
    }

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

PR Review Comment: https://git.openjdk.org/jdk/pull/21830#discussion_r1826315242

Reply via email to