8055055: Improve numeric parsing in java.sql

Reviewed-by: lancea
This commit is contained in:
Claes Redestad 2014-08-13 18:40:16 +02:00
parent 2daf96018c
commit 85cc6b9fde
3 changed files with 55 additions and 74 deletions

View File

@ -108,31 +108,27 @@ public class Date extends java.util.Date {
* JDBC date escape format (yyyy-[m]m-[d]d)
*/
public static Date valueOf(String s) {
if (s == null) {
throw new java.lang.IllegalArgumentException();
}
final int YEAR_LENGTH = 4;
final int MONTH_LENGTH = 2;
final int DAY_LENGTH = 2;
final int MAX_MONTH = 12;
final int MAX_DAY = 31;
int firstDash;
int secondDash;
Date d = null;
if (s == null) {
throw new java.lang.IllegalArgumentException();
}
firstDash = s.indexOf('-');
secondDash = s.indexOf('-', firstDash + 1);
int firstDash = s.indexOf('-');
int secondDash = s.indexOf('-', firstDash + 1);
int len = s.length();
if ((firstDash > 0) && (secondDash > 0) && (secondDash < s.length() - 1)) {
String yyyy = s.substring(0, firstDash);
String mm = s.substring(firstDash + 1, secondDash);
String dd = s.substring(secondDash + 1);
if (yyyy.length() == YEAR_LENGTH &&
(mm.length() >= 1 && mm.length() <= MONTH_LENGTH) &&
(dd.length() >= 1 && dd.length() <= DAY_LENGTH)) {
int year = Integer.parseInt(yyyy);
int month = Integer.parseInt(mm);
int day = Integer.parseInt(dd);
if ((firstDash > 0) && (secondDash > 0) && (secondDash < len - 1)) {
if (firstDash == YEAR_LENGTH &&
(secondDash - firstDash > 1 && secondDash - firstDash <= MONTH_LENGTH + 1) &&
(len - secondDash > 1 && len - secondDash <= DAY_LENGTH + 1)) {
int year = Integer.parseInt(s, 0, firstDash, 10);
int month = Integer.parseInt(s, firstDash + 1, secondDash, 10);
int day = Integer.parseInt(s, secondDash + 1, len, 10);
if ((month >= 1 && month <= MAX_MONTH) && (day >= 1 && day <= MAX_DAY)) {
d = new Date(year - 1900, month - 1, day);

View File

@ -90,22 +90,19 @@ public class Time extends java.util.Date {
* @return a corresponding <code>Time</code> object
*/
public static Time valueOf(String s) {
if (s == null) throw new java.lang.IllegalArgumentException();
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));
int firstColon = s.indexOf(':');
int secondColon = s.indexOf(':', firstColon + 1);
int len = s.length();
if (firstColon > 0 && secondColon > 0 &&
secondColon < len - 1) {
hour = Integer.parseInt(s, 0, firstColon, 10);
minute = Integer.parseInt(s, firstColon + 1, secondColon, 10);
second = Integer.parseInt(s, secondColon + 1, len, 10);
} else {
throw new java.lang.IllegalArgumentException();
}

View File

@ -171,9 +171,6 @@ public class Timestamp extends java.util.Date {
final int DAY_LENGTH = 2;
final int MAX_MONTH = 12;
final int MAX_DAY = 31;
String date_s;
String time_s;
String nanos_s;
int year = 0;
int month = 0;
int day = 0;
@ -184,49 +181,38 @@ public class Timestamp extends java.util.Date {
int firstDash;
int secondDash;
int dividingSpace;
int firstColon = 0;
int secondColon = 0;
int period = 0;
int firstColon;
int secondColon;
int period;
String formatError = "Timestamp format must be yyyy-mm-dd hh:mm:ss[.fffffffff]";
String zeros = "000000000";
String delimiterDate = "-";
String delimiterTime = ":";
if (s == null) throw new java.lang.IllegalArgumentException("null string");
// Split the string into date and time components
s = s.trim();
dividingSpace = s.indexOf(' ');
if (dividingSpace > 0) {
date_s = s.substring(0,dividingSpace);
time_s = s.substring(dividingSpace+1);
} else {
if (dividingSpace < 0) {
throw new java.lang.IllegalArgumentException(formatError);
}
// Parse the date
firstDash = date_s.indexOf('-');
secondDash = date_s.indexOf('-', firstDash+1);
firstDash = s.indexOf('-');
secondDash = s.indexOf('-', firstDash+1);
// Parse the time
if (time_s == null)
throw new java.lang.IllegalArgumentException(formatError);
firstColon = time_s.indexOf(':');
secondColon = time_s.indexOf(':', firstColon+1);
period = time_s.indexOf('.', secondColon+1);
firstColon = s.indexOf(':', dividingSpace + 1);
secondColon = s.indexOf(':', firstColon + 1);
period = s.indexOf('.', secondColon + 1);
// Convert the date
boolean parsedDate = false;
if ((firstDash > 0) && (secondDash > 0) && (secondDash < date_s.length() - 1)) {
String yyyy = date_s.substring(0, firstDash);
String mm = date_s.substring(firstDash + 1, secondDash);
String dd = date_s.substring(secondDash + 1);
if (yyyy.length() == YEAR_LENGTH &&
(mm.length() >= 1 && mm.length() <= MONTH_LENGTH) &&
(dd.length() >= 1 && dd.length() <= DAY_LENGTH)) {
year = Integer.parseInt(yyyy);
month = Integer.parseInt(mm);
day = Integer.parseInt(dd);
if (firstDash > 0 && secondDash > 0 && secondDash < dividingSpace - 1) {
if (firstDash == YEAR_LENGTH &&
(secondDash - firstDash > 1 && secondDash - firstDash <= MONTH_LENGTH + 1) &&
(dividingSpace - secondDash > 1 && dividingSpace - secondDash <= DAY_LENGTH + 1)) {
year = Integer.parseInt(s, 0, firstDash, 10);
month = Integer.parseInt(s, firstDash + 1, secondDash, 10);
day = Integer.parseInt(s, secondDash + 1, dividingSpace, 10);
if ((month >= 1 && month <= MAX_MONTH) && (day >= 1 && day <= MAX_DAY)) {
parsedDate = true;
@ -238,25 +224,27 @@ public class Timestamp extends java.util.Date {
}
// Convert the time; default missing nanos
if ((firstColon > 0) & (secondColon > 0) &
(secondColon < time_s.length()-1)) {
hour = Integer.parseInt(time_s.substring(0, firstColon));
minute =
Integer.parseInt(time_s.substring(firstColon+1, secondColon));
if ((period > 0) & (period < time_s.length()-1)) {
second =
Integer.parseInt(time_s.substring(secondColon+1, period));
nanos_s = time_s.substring(period+1);
if (nanos_s.length() > 9)
int len = s.length();
if (firstColon > 0 && secondColon > 0 && secondColon < len - 1) {
hour = Integer.parseInt(s, dividingSpace + 1, firstColon, 10);
minute = Integer.parseInt(s, firstColon + 1, secondColon, 10);
if (period > 0 && period < len - 1) {
second = Integer.parseInt(s, secondColon + 1, period, 10);
int nanoPrecision = len - (period + 1);
if (nanoPrecision > 9)
throw new java.lang.IllegalArgumentException(formatError);
if (!Character.isDigit(nanos_s.charAt(0)))
if (!Character.isDigit(s.charAt(period + 1)))
throw new java.lang.IllegalArgumentException(formatError);
nanos_s = nanos_s + zeros.substring(0,9-nanos_s.length());
a_nanos = Integer.parseInt(nanos_s);
int tmpNanos = Integer.parseInt(s, period + 1, len, 10);
while (nanoPrecision < 9) {
tmpNanos *= 10;
nanoPrecision++;
}
a_nanos = tmpNanos;
} else if (period > 0) {
throw new java.lang.IllegalArgumentException(formatError);
} else {
second = Integer.parseInt(time_s.substring(secondColon+1));
second = Integer.parseInt(s, secondColon + 1, len, 10);
}
} else {
throw new java.lang.IllegalArgumentException(formatError);