Name: jl125535 Date: 01/27/2003
FULL PRODUCT VERSION :
java version "1.4.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-b92)
Java HotSpot(TM) Client VM (build 1.4.0-b92, mixed mode)
A DESCRIPTION OF THE PROBLEM :
java.sql.Time valueOf() is written making extensive use of
String's subString and indexOf to parse a JDBC Escaped Time
string into a java.sql.Time instance. Suggested enhancement
removes dependence on String and Integer.parseInt() and
makes one pass through a char buffer extracted from String
and directly parses the characters into an int array.
Previous code did little validation of the parsed values,
suggested enhancement code does quick but complete
validateion of the parsed values. Previous code had a bug
in it that a string of the form "-12:00:00" or "12:-34:45"
or "12:34:-23" would be accepted and yield unpredictable
results.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
Current source code:
public static Time valueOf(String s) {
int hour;
int minute;
int second;
int firstColon;
int secondColon;
if (s == null) throw new java.lang.IllegalArgumentException();
firstColon = s.indexOf(':');
secondColon = s.indexOf(':', firstColon+1);
if ((firstColon > 0) & (secondColon > 0) &
(secondColon < s.length()-1)) {
hour = Integer.parseInt(s.substring(0, firstColon));
minute =
Integer.parseInt(s.substring(firstColon+1, secondColon));
second = Integer.parseInt(s.substring(secondColon+1));
} else {
throw new java.lang.IllegalArgumentException();
}
return new Time(hour, minute, second);
}
Suggested enhancement:
public static Time valueOf(String s) {
if (s == null) {
throw new java.lang.IllegalArgumentException();
}
char buf[] = s.toCharArray();
int results[] = {0,0,0};
int r = 0; // results index to 0
int i=0; // buf index to 0
while (i < buf.length) {
char c = buf[i++];
if (c == ':') {
if (r++ >= results.length) {
throw new java.lang.IllegalArgumentException();
}
} else {
int digit = Character.digit(c, 10);
if (digit < 0) {
throw new NumberFormatException(s);
}
results[r] = (results[r] * 10) + digit;
if (results[r] > 59) {
// None of the fields should exceed 59
throw new NumberFormatException(s);
}
}
}
// Validate results
if (
// Didn't reach end of buffer
(i != buf.length) ||
// Didn't parse all of our int's
(r != results.length - 1) ||
// Hours too large
(results[0] > 23)
// No need to check minutes, done above
// No need to check seconds, done above
) {
throw new NumberFormatException(s);
}
// Create and return new Time
return new Time(results[0], results[1], results[2]);
}
---------- END SOURCE ----------
(Review ID: 153581)
======================================================================
- relates to
-
JDK-8055055 Improve numeric parsing in java.sql
-
- Resolved
-