undefect. CWE-407 — 63 sites patched across 27 ecosystems
Authors: russell@unturf.com · brackishbert@gmail.com · foxhop.net · TimeHexOn.com Patches, unit tests, benchmarks, whitepaper, and outreach briefs. Public domain — no copyright claimed. Use freely.
This commit is contained in:
commit
0a580b313d
70422 changed files with 17213626 additions and 0 deletions
406
test/jdk/java/lang/Integer/Unsigned.java
Normal file
406
test/jdk/java/lang/Integer/Unsigned.java
Normal file
|
|
@ -0,0 +1,406 @@
|
|||
/*
|
||||
* Copyright (c) 2009, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4504839 4215269 6322074
|
||||
* @summary Basic tests for unsigned operations.
|
||||
*/
|
||||
public class Unsigned {
|
||||
public static void main(String... args) {
|
||||
int errors = 0;
|
||||
|
||||
errors += testRoundtrip();
|
||||
errors += testByteToUnsignedInt();
|
||||
errors += testShortToUnsignedInt();
|
||||
errors += testUnsignedCompare();
|
||||
errors += testToUnsignedLong();
|
||||
errors += testToStringUnsigned();
|
||||
errors += testParseUnsignedInt();
|
||||
errors += testDivideAndRemainder();
|
||||
|
||||
if (errors > 0) {
|
||||
throw new RuntimeException(errors + " errors found in unsigned operations.");
|
||||
}
|
||||
}
|
||||
|
||||
private static int testRoundtrip() {
|
||||
int errors = 0;
|
||||
|
||||
int[] data = {-1, 0, 1};
|
||||
|
||||
for(int datum : data) {
|
||||
if (Integer.parseUnsignedInt(Integer.toBinaryString(datum), 2) != datum) {
|
||||
errors++;
|
||||
System.err.println("Bad binary roundtrip conversion of " + datum);
|
||||
}
|
||||
|
||||
if (Integer.parseUnsignedInt(Integer.toOctalString(datum), 8) != datum) {
|
||||
errors++;
|
||||
System.err.println("Bad octal roundtrip conversion of " + datum);
|
||||
}
|
||||
|
||||
if (Integer.parseUnsignedInt(Integer.toHexString(datum), 16) != datum) {
|
||||
errors++;
|
||||
System.err.println("Bad hex roundtrip conversion of " + datum);
|
||||
}
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
private static int testByteToUnsignedInt() {
|
||||
int errors = 0;
|
||||
|
||||
for(int i = Byte.MIN_VALUE; i <= Byte.MAX_VALUE; i++) {
|
||||
byte datum = (byte) i;
|
||||
int ui = Byte.toUnsignedInt(datum);
|
||||
|
||||
if ( (ui & (~0xff)) != 0 ||
|
||||
((byte)ui != datum )) {
|
||||
errors++;
|
||||
System.err.printf("Bad conversion of byte %d to unsigned int %d%n",
|
||||
datum, ui);
|
||||
}
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
private static int testShortToUnsignedInt() {
|
||||
int errors = 0;
|
||||
|
||||
for(int i = Short.MIN_VALUE; i <= Short.MAX_VALUE; i++) {
|
||||
short datum = (short) i;
|
||||
int ui = Short.toUnsignedInt(datum);
|
||||
|
||||
if ( (ui & (~0xffff)) != 0 ||
|
||||
((short)ui != datum )) {
|
||||
errors++;
|
||||
System.err.printf("Bad conversion of short %d to unsigned int %d%n",
|
||||
datum, ui);
|
||||
}
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
private static int testUnsignedCompare() {
|
||||
int errors = 0;
|
||||
|
||||
int[] data = {
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
0x8000_0000,
|
||||
0x8000_0001,
|
||||
0x8000_0002,
|
||||
0x8000_0003,
|
||||
0xFFFF_FFFE,
|
||||
0xFFFF_FFFF,
|
||||
};
|
||||
|
||||
for(int i : data) {
|
||||
for(int j : data) {
|
||||
int libraryResult = Integer.compareUnsigned(i, j);
|
||||
int libraryResultRev = Integer.compareUnsigned(j, i);
|
||||
int localResult = compUnsigned(i, j);
|
||||
|
||||
if (i == j) {
|
||||
if (libraryResult != 0) {
|
||||
errors++;
|
||||
System.err.printf("Value 0x%x did not compare as " +
|
||||
"an unsigned value equal to itself; got %d%n",
|
||||
i, libraryResult);
|
||||
}
|
||||
}
|
||||
|
||||
if (Integer.signum(libraryResult) != Integer.signum(localResult)) {
|
||||
errors++;
|
||||
System.err.printf("Unsigned compare of 0x%x to 0x%x%n:" +
|
||||
"\texpected sign of %d, got %d%n",
|
||||
i, j, localResult, libraryResult);
|
||||
}
|
||||
|
||||
if (Integer.signum(libraryResult) !=
|
||||
-Integer.signum(libraryResultRev)) {
|
||||
errors++;
|
||||
System.err.printf("signum(compareUnsigned(x, y)) != -signum(compareUnsigned(y,x))" +
|
||||
" for \t0x%x and 0x%x, computed %d and %d%n",
|
||||
i, j, libraryResult, libraryResultRev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Straightforward compare unsigned algorithm.
|
||||
*/
|
||||
private static int compUnsigned(int x, int y) {
|
||||
int sign_x = x & Integer.MIN_VALUE;
|
||||
int sign_y = y & Integer.MIN_VALUE;
|
||||
|
||||
int mant_x = x & (~Integer.MIN_VALUE);
|
||||
int mant_y = y & (~Integer.MIN_VALUE);
|
||||
|
||||
if (sign_x == sign_y)
|
||||
return Integer.compare(mant_x, mant_y);
|
||||
else {
|
||||
if (sign_x == 0)
|
||||
return -1; // sign x is 0, sign y is 1 => (x < y)
|
||||
else
|
||||
return 1; // sign x is 1, sign y is 0 => (x > y)
|
||||
}
|
||||
}
|
||||
|
||||
private static int testToUnsignedLong() {
|
||||
int errors = 0;
|
||||
|
||||
int[] data = {
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
0x1234_5678,
|
||||
0x8000_0000,
|
||||
0x8000_0001,
|
||||
0x8000_0002,
|
||||
0x8000_0003,
|
||||
0x8765_4321,
|
||||
0xFFFF_FFFE,
|
||||
0xFFFF_FFFF,
|
||||
};
|
||||
|
||||
for(int datum : data) {
|
||||
long result = Integer.toUnsignedLong(datum);
|
||||
|
||||
// High-order bits should be zero
|
||||
if ((result & 0xffff_ffff_0000_0000L) != 0L) {
|
||||
errors++;
|
||||
System.err.printf("High bits set converting 0x%x to 0x%x%n",
|
||||
datum, result);
|
||||
}
|
||||
|
||||
// Lower-order bits should be equal to datum.
|
||||
int lowOrder = (int)(result & 0x0000_0000_ffff_ffffL);
|
||||
if (lowOrder != datum ) {
|
||||
errors++;
|
||||
System.err.printf("Low bits not preserved converting 0x%x to 0x%x%n",
|
||||
datum, result);
|
||||
}
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
private static int testToStringUnsigned() {
|
||||
int errors = 0;
|
||||
|
||||
int[] data = {
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
99999,
|
||||
100000,
|
||||
999999,
|
||||
100000,
|
||||
999999999,
|
||||
1000000000,
|
||||
0x1234_5678,
|
||||
0x8000_0000,
|
||||
0x8000_0001,
|
||||
0x8000_0002,
|
||||
0x8000_0003,
|
||||
0x8765_4321,
|
||||
0xFFFF_FFFE,
|
||||
0xFFFF_FFFF,
|
||||
};
|
||||
|
||||
for(int radix = Character.MIN_RADIX; radix <= Character.MAX_RADIX; radix++) {
|
||||
for(int datum : data) {
|
||||
String result1 = Integer.toUnsignedString(datum, radix);
|
||||
String result2 = Long.toString(Integer.toUnsignedLong(datum), radix);
|
||||
|
||||
if (!result1.equals(result2)) {
|
||||
errors++;
|
||||
System.err.printf("Unexpected string difference converting 0x%x:" +
|
||||
"\t%s %s%n",
|
||||
datum, result1, result2);
|
||||
}
|
||||
|
||||
if (radix == 10) {
|
||||
String result3 = Integer.toUnsignedString(datum);
|
||||
if (!result2.equals(result3)) {
|
||||
errors++;
|
||||
System.err.printf("Unexpected string difference converting 0x%x:" +
|
||||
"\t%s %s%n",
|
||||
datum, result3, result2);
|
||||
}
|
||||
}
|
||||
|
||||
int parseResult = Integer.parseUnsignedInt(result1, radix);
|
||||
|
||||
if (parseResult != datum) {
|
||||
errors++;
|
||||
System.err.printf("Bad roundtrip conversion of %d in base %d" +
|
||||
"\tconverting back ''%s'' resulted in %d%n",
|
||||
datum, radix, result1, parseResult);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
private static final long MAX_UNSIGNED_INT = Integer.toUnsignedLong(0xffff_ffff);
|
||||
|
||||
private static int testParseUnsignedInt() {
|
||||
int errors = 0;
|
||||
|
||||
// Values include those between signed Integer.MAX_VALUE and
|
||||
// unsignted int MAX_VALUE.
|
||||
long[] inRange = {
|
||||
0L,
|
||||
1L,
|
||||
10L,
|
||||
2147483646L, // MAX_VALUE - 1
|
||||
2147483647L, // MAX_VALUE
|
||||
2147483648L, // MAX_VALUE + 1
|
||||
|
||||
MAX_UNSIGNED_INT - 1L,
|
||||
MAX_UNSIGNED_INT,
|
||||
};
|
||||
|
||||
for(long value : inRange) {
|
||||
for(int radix = Character.MIN_RADIX; radix <= Character.MAX_RADIX; radix++) {
|
||||
String longString = Long.toString(value, radix);
|
||||
int intResult = Integer.parseUnsignedInt(longString, radix);
|
||||
|
||||
if (Integer.toUnsignedLong(intResult) != value) {
|
||||
errors++;
|
||||
System.err.printf("Bad roundtrip conversion of %d in base %d" +
|
||||
"\tconverting back ''%s'' resulted in %d%n",
|
||||
value, radix, longString, intResult);
|
||||
}
|
||||
|
||||
// test offset based parse method
|
||||
intResult = Integer.parseUnsignedInt("prefix" + longString + "suffix",
|
||||
"prefix".length(), "prefix".length() + longString.length(), radix);
|
||||
|
||||
if (Integer.toUnsignedLong(intResult) != value) {
|
||||
errors++;
|
||||
System.err.printf("Bad roundtrip conversion of %d in base %d" +
|
||||
"\tconverting back ''%s'' resulted in %d%n",
|
||||
value, radix, longString, intResult);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String[] outOfRange = {
|
||||
null,
|
||||
"",
|
||||
"-1",
|
||||
Long.toString(MAX_UNSIGNED_INT + 1L),
|
||||
Long.toString(Long.MAX_VALUE)
|
||||
};
|
||||
|
||||
for(String s : outOfRange) {
|
||||
try {
|
||||
int result = Integer.parseUnsignedInt(s);
|
||||
errors++; // Should not reach here
|
||||
System.err.printf("Unexpected got %d from an unsigned conversion of %s",
|
||||
result, s);
|
||||
} catch(NumberFormatException nfe) {
|
||||
; // Correct result
|
||||
}
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
private static int testDivideAndRemainder() {
|
||||
int errors = 0;
|
||||
|
||||
long[] inRange = {
|
||||
0L,
|
||||
1L,
|
||||
2L,
|
||||
2147483646L, // MAX_VALUE - 1
|
||||
2147483647L, // MAX_VALUE
|
||||
2147483648L, // MAX_VALUE + 1
|
||||
|
||||
MAX_UNSIGNED_INT - 1L,
|
||||
MAX_UNSIGNED_INT,
|
||||
};
|
||||
|
||||
for(long dividend : inRange) {
|
||||
for(long divisor : inRange) {
|
||||
int quotient;
|
||||
long longQuotient;
|
||||
|
||||
int remainder;
|
||||
long longRemainder;
|
||||
|
||||
if (divisor == 0) {
|
||||
try {
|
||||
quotient = Integer.divideUnsigned((int) dividend, (int) divisor);
|
||||
errors++;
|
||||
} catch(ArithmeticException ea) {
|
||||
; // Expected
|
||||
}
|
||||
|
||||
try {
|
||||
remainder = Integer.remainderUnsigned((int) dividend, (int) divisor);
|
||||
errors++;
|
||||
} catch(ArithmeticException ea) {
|
||||
; // Expected
|
||||
}
|
||||
} else {
|
||||
quotient = Integer.divideUnsigned((int) dividend, (int) divisor);
|
||||
longQuotient = dividend / divisor;
|
||||
|
||||
if (quotient != (int)longQuotient) {
|
||||
errors++;
|
||||
System.err.printf("Unexpected unsigned divide result %s on %s/%s%n",
|
||||
Integer.toUnsignedString(quotient),
|
||||
Integer.toUnsignedString((int) dividend),
|
||||
Integer.toUnsignedString((int) divisor));
|
||||
}
|
||||
|
||||
remainder = Integer.remainderUnsigned((int) dividend, (int) divisor);
|
||||
longRemainder = dividend % divisor;
|
||||
|
||||
if (remainder != (int)longRemainder) {
|
||||
errors++;
|
||||
System.err.printf("Unexpected unsigned remainder result %s on %s%%%s%n",
|
||||
Integer.toUnsignedString(remainder),
|
||||
Integer.toUnsignedString((int) dividend),
|
||||
Integer.toUnsignedString((int) divisor));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue