# HG changeset patch # User robm # Date 1355412520 0 # Node ID 54eb3f0909349a2d0a8d18e38de9da413fa67f70 # Parent a9f61e0cbe61e9f45d97d710e0a3d4060558fdef 8000525: Java.net.httpcookie api does not support 2-digit year format Reviewed-by: chegar diff -r a9f61e0cbe61 -r 54eb3f090934 jdk/src/share/classes/java/net/HttpCookie.java --- a/jdk/src/share/classes/java/net/HttpCookie.java Thu Dec 13 14:47:35 2012 +0000 +++ b/jdk/src/share/classes/java/net/HttpCookie.java Thu Dec 13 15:28:40 2012 +0000 @@ -30,6 +30,8 @@ import java.util.NoSuchElementException; import java.text.SimpleDateFormat; import java.util.TimeZone; +import java.util.Calendar; +import java.util.GregorianCalendar; import java.util.Date; import java.util.Locale; import java.util.Objects; @@ -89,7 +91,10 @@ private final static String[] COOKIE_DATE_FORMATS = { "EEE',' dd-MMM-yyyy HH:mm:ss 'GMT'", "EEE',' dd MMM yyyy HH:mm:ss 'GMT'", - "EEE MMM dd yyyy HH:mm:ss 'GMT'Z" + "EEE MMM dd yyyy HH:mm:ss 'GMT'Z", + "EEE',' dd-MMM-yy HH:mm:ss 'GMT'", + "EEE',' dd MMM yy HH:mm:ss 'GMT'", + "EEE MMM dd yy HH:mm:ss 'GMT'Z" }; // constant strings represent set-cookie header token @@ -1025,13 +1030,29 @@ * specified by dateString */ private long expiryDate2DeltaSeconds(String dateString) { + Calendar cal = new GregorianCalendar(GMT); for (int i = 0; i < COOKIE_DATE_FORMATS.length; i++) { SimpleDateFormat df = new SimpleDateFormat(COOKIE_DATE_FORMATS[i], Locale.US); + cal.set(1970, 0, 1, 0, 0, 0); df.setTimeZone(GMT); + df.setLenient(false); + df.set2DigitYearStart(cal.getTime()); try { - Date date = df.parse(dateString); - return (date.getTime() - whenCreated) / 1000; + cal.setTime(df.parse(dateString)); + if (!COOKIE_DATE_FORMATS[i].contains("yyyy")) { + // 2-digit years following the standard set + // out it rfc 6265 + int year = cal.get(Calendar.YEAR); + year %= 100; + if (year < 70) { + year += 2000; + } else { + year += 1900; + } + cal.set(Calendar.YEAR, year); + } + return (cal.getTimeInMillis() - whenCreated) / 1000; } catch (Exception e) { // Ignore, try the next date format } diff -r a9f61e0cbe61 -r 54eb3f090934 jdk/test/java/net/CookieHandler/B6791927.java --- a/jdk/test/java/net/CookieHandler/B6791927.java Thu Dec 13 14:47:35 2012 +0000 +++ b/jdk/test/java/net/CookieHandler/B6791927.java Thu Dec 13 15:28:40 2012 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2012, 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 @@ -37,7 +37,7 @@ try { // Forces a non US locale Locale.setDefault(Locale.FRANCE); - List cookies = HttpCookie.parse("set-cookie: CUSTOMER=WILE_E_COYOTE; expires=Wednesday, 09-Nov-2019 23:12:40 GMT"); + List cookies = HttpCookie.parse("set-cookie: CUSTOMER=WILE_E_COYOTE; expires=Sat, 09-Nov-2019 23:12:40 GMT"); if (cookies == null || cookies.isEmpty()) { throw new RuntimeException("No cookie found"); } diff -r a9f61e0cbe61 -r 54eb3f090934 jdk/test/java/net/CookieHandler/CookieManagerTest.java --- a/jdk/test/java/net/CookieHandler/CookieManagerTest.java Thu Dec 13 14:47:35 2012 +0000 +++ b/jdk/test/java/net/CookieHandler/CookieManagerTest.java Thu Dec 13 15:28:40 2012 +0000 @@ -126,7 +126,7 @@ testPolicies[count] = CookiePolicy.ACCEPT_ORIGINAL_SERVER; testCases[count++] = new CookieTestCase[]{ new CookieTestCase("Set-Cookie", - "CUSTOMER=WILE:BOB; path=/; expires=Wednesday, 09-Nov-2030 23:12:40 GMT;" + "domain=." + localHostAddr, + "CUSTOMER=WILE:BOB; path=/; expires=Sat, 09-Nov-2030 23:12:40 GMT;" + "domain=." + localHostAddr, "CUSTOMER=WILE:BOB", "/" ), diff -r a9f61e0cbe61 -r 54eb3f090934 jdk/test/java/net/HttpCookie/ExpiredCookieTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/net/HttpCookie/ExpiredCookieTest.java Thu Dec 13 15:28:40 2012 +0000 @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2012, 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 8000525 + */ + +import java.net.*; +import java.util.*; +import java.io.*; +import java.text.*; + +public class ExpiredCookieTest { + // lifted from HttpCookie.java + private final static String[] COOKIE_DATE_FORMATS = { + "EEE',' dd-MMM-yy HH:mm:ss 'GMT'", + "EEE',' dd MMM yy HH:mm:ss 'GMT'", + "EEE MMM dd yy HH:mm:ss 'GMT'Z", + "EEE',' dd-MMM-yyyy HH:mm:ss 'GMT'", + "EEE',' dd MMM yyyy HH:mm:ss 'GMT'", + "EEE MMM dd yyyy HH:mm:ss 'GMT'Z" + }; + static final TimeZone GMT = TimeZone.getTimeZone("GMT"); + + public static void main(String[] args) throws Exception { + Calendar cal = Calendar.getInstance(GMT); + + for (int i = 0; i < COOKIE_DATE_FORMATS.length; i++) { + SimpleDateFormat df = new SimpleDateFormat(COOKIE_DATE_FORMATS[i], + Locale.US); + cal.set(1970, 0, 1, 0, 0, 0); + df.setTimeZone(GMT); + df.setLenient(false); + df.set2DigitYearStart(cal.getTime()); + CookieManager cm = new CookieManager( + null, CookiePolicy.ACCEPT_ALL); + CookieHandler.setDefault(cm); + Map> header = new HashMap<>(); + List values = new ArrayList<>(); + + cal.set(1970, 6, 9, 10, 10, 1); + StringBuilder datestring = + new StringBuilder(df.format(cal.getTime())); + values.add( + "TEST1=TEST1; Path=/; Expires=" + datestring.toString()); + + cal.set(1969, 6, 9, 10, 10, 2); + datestring = new StringBuilder(df.format(cal.getTime())); + values.add( + "TEST2=TEST2; Path=/; Expires=" + datestring.toString()); + + cal.set(2070, 6, 9, 10, 10, 3); + datestring = new StringBuilder(df.format(cal.getTime())); + values.add( + "TEST3=TEST3; Path=/; Expires=" + datestring.toString()); + + cal.set(2069, 6, 9, 10, 10, 4); + datestring = new StringBuilder(df.format(cal.getTime())); + values.add( + "TEST4=TEST4; Path=/; Expires=" + datestring.toString()); + + header.put("Set-Cookie", values); + cm.put(new URI("http://127.0.0.1/"), header); + + CookieStore cookieJar = cm.getCookieStore(); + List cookies = cookieJar.getCookies(); + if (COOKIE_DATE_FORMATS[i].contains("yyyy")) { + if (cookies.size() != 2) + throw new RuntimeException( + "Incorrectly parsing a bad date"); + } else if (cookies.size() != 1) { + throw new RuntimeException( + "Incorrectly parsing a bad date"); + } + } + } +}