# HG changeset patch # User claes.redestad@oracle.com # Date 1407948016 -7200 # Wed Aug 13 18:40:16 2014 +0200 # Node ID 4c313c301a7e05f57853c1ccc62502a398686f7f # Parent fc0ddfe492a674271ede290f8cc3cfb1383b0ce4 8055055: Improve numeric parsing in java.sql diff --git a/src/share/classes/java/sql/Time.java b/src/share/classes/java/sql/Time.java --- a/src/share/classes/java/sql/Time.java +++ b/src/share/classes/java/sql/Time.java @@ -100,12 +100,11 @@ 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)); + if (firstColon > 0 && secondColon > 0 && + secondColon < s.length() - 1) { + hour = Integer.parseInt(s, 10, 0, firstColon); + minute = Integer.parseInt(s, 10, firstColon + 1, secondColon); + second = Integer.parseInt(s, 10, secondColon + 1); } else { throw new java.lang.IllegalArgumentException(); } diff --git a/src/share/classes/java/sql/Timestamp.java b/src/share/classes/java/sql/Timestamp.java --- a/src/share/classes/java/sql/Timestamp.java +++ b/src/share/classes/java/sql/Timestamp.java @@ -171,9 +171,6 @@ 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 @@ 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 >= 2 && secondDash - firstDash - 1 <= MONTH_LENGTH) && + (dividingSpace - secondDash >= 2 && dividingSpace - secondDash - 1 <= DAY_LENGTH)) { + year = Integer.parseInt(s, 10, 0, firstDash); + month = Integer.parseInt(s, 10, firstDash + 1, secondDash); + day = Integer.parseInt(s, 10, secondDash + 1, dividingSpace); if ((month >= 1 && month <= MAX_MONTH) && (day >= 1 && day <= MAX_DAY)) { parsedDate = true; @@ -238,25 +224,26 @@ } // 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) + if (firstColon > 0 && secondColon > 0 && secondColon < s.length() - 1) { + hour = Integer.parseInt(s, 10, dividingSpace + 1, firstColon); + minute = Integer.parseInt(s, 10, firstColon + 1, secondColon); + if (period > 0 && period < s.length() - 1) { + second = Integer.parseInt(s, 10, secondColon + 1, period); + int nanoPrecision = s.length() - (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, 10, period + 1); + 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, 10, secondColon + 1); } } else { throw new java.lang.IllegalArgumentException(formatError);