Affects: 5.2.0-Release, current master (2020-01-22)

Line numbers from 5.2.0. spring-web/src/main/java/org/springframework/web/util/HierarchicalUriComponents.java:330

        for (byte b : bytes) {
            if (b < 0) {
                b += 256;
            }
            if (type.isAllowed(b)) {
                bos.write(b);
            }
        [...]

The b += 256 is a no-op as b is a byte (and so everything is modulo 256). type.isAllowed(b) expects an int as argument --> a negative b is widened to a negative int value.

Proposed fix: change the data type of b from byte to int.

Comment From: rstoyanchev

Yes this is for non-ASCII characters where the sign bit makes them appear as negative. We should change that to int c = b & 0xff, effectively Byte.toUnsignedInt. Note that the current behavior ends up in the same outcome because isAllowed will return false just the same.

Comment From: Andy-2639

I didn't know Byte.toUnsignedInt. Why not just using it?

Comment From: rstoyanchev

I opted to remove the code in the end. It was a no-op after all and whether it's negative or over 128, it makes no difference and isAllowed will return false for both.