Merge
diff --git a/.hgtags b/.hgtags
index 8dba41a..24c7341 100644
--- a/.hgtags
+++ b/.hgtags
@@ -251,6 +251,9 @@
fbf251b8ef8a4a2aa1fd58efc8d0d5c8e2fd582b jdk8-b127
f644211c59fd7c1d0c81239c55b31e1d377d7650 jdk8-b128
80568a19aab7300bc92baf2dc225be929f5b03ed jdk8-b129
+43386cc9a017a9f9e704760050086bb18b778ae0 jdk8-b130
+e291ac47c9a90366c3c0787a6f7ce547a2bda308 jdk8-b131
+43cb25339b5500871f41388a5197f1b01c4b57b8 jdk8-b132
fa2d5a06308f3f36fb09662fa58070a02352f023 jdk8u5-b01
343f4f8ba0982b3516e33c859b01634d919243c4 jdk8u5-b02
c35571198602a5856280d5c7c10bda4e7b769104 jdk8u5-b03
@@ -261,3 +264,8 @@
469c2c1a4885ddedc114e17902bb2f7f7326a4b7 jdk8u5-b07
e48a0e01e6e19846533ec2cf3df15a6699d7ea8b jdk8u5-b08
cd9a093d0f63375dc323f8af59a3f7e77bc5d3e9 jdk8u5-b09
+7f905cc47d4951628d956c436c8aa95aeb8bd014 jdk8u5-b10
+f4f3b7ccd2801a0a87dd4677332f5b93191d08f2 jdk8u5-b11
+9ff7f7909e122bb54f7df80efd0fc7a03ce7efff jdk8u5-b12
+c6836440c427800a9f48168af29759b79857781d jdk8u5-b13
+5eff6b1060758eae51125156a6f9c7725905e64e jdk8u11-b01
diff --git a/make/data/tzdata/VERSION b/make/data/tzdata/VERSION
index 2f162e0..8ab96a7 100644
--- a/make/data/tzdata/VERSION
+++ b/make/data/tzdata/VERSION
@@ -21,4 +21,4 @@
# or visit www.oracle.com if you need additional information or have any
# questions.
#
-tzdata2013i
+tzdata2014a
diff --git a/make/data/tzdata/asia b/make/data/tzdata/asia
index 1a8f83d..dc3c94b 100644
--- a/make/data/tzdata/asia
+++ b/make/data/tzdata/asia
@@ -1113,8 +1113,13 @@
Rule Zion 1986 only - Sep 7 0:00 0 S
Rule Zion 1987 only - Apr 15 0:00 1:00 D
Rule Zion 1987 only - Sep 13 0:00 0 S
-Rule Zion 1988 only - Apr 9 0:00 1:00 D
-Rule Zion 1988 only - Sep 3 0:00 0 S
+
+# From Avigdor Finkelstein (2014-03-05):
+# I check the Parliament (Knesset) records and there it's stated that the
+# [1988] transition should take place on Saturday night, when the Sabbath
+# ends and changes to Sunday.
+Rule Zion 1988 only - Apr 10 0:00 1:00 D
+Rule Zion 1988 only - Sep 4 0:00 0 S
# From Ephraim Silverberg
# (1997-03-04, 1998-03-16, 1998-12-28, 2000-01-17, 2000-07-25, 2004-12-22,
diff --git a/make/data/tzdata/australasia b/make/data/tzdata/australasia
index cd6b724..a0e8b5a 100644
--- a/make/data/tzdata/australasia
+++ b/make/data/tzdata/australasia
@@ -377,16 +377,18 @@
# http://www.fiji.gov.fj/index.php?option=com_content&view=article&id=6702&catid=71&Itemid=155
# From the Fijian Government Media Center (2013-08-30) via David Wheeler:
-# Fiji will start daylight savings on Sunday 27th October, 2013 and end at 3am
-# on Sunday 19th January, 2014.... move clocks forward by one hour from 2am
+# Fiji will start daylight savings on Sunday 27th October, 2013 ...
+# move clocks forward by one hour from 2am
# http://www.fiji.gov.fj/Media-Center/Press-Releases/DAYLIGHT-SAVING-STARTS-ON-SUNDAY,-27th-OCTOBER-201.aspx
-#
-# From Paul Eggert (2013-09-09):
+
+# From Steffen Thorsen (2013-01-10):
+# Fiji will end DST on 2014-01-19 02:00:
+# http://www.fiji.gov.fj/Media-Center/Press-Releases/DAYLIGHT-SAVINGS-TO-END-THIS-MONTH-%281%29.aspx
+
+# From Paul Eggert (2014-01-10):
# For now, guess that Fiji springs forward the Sunday before the fourth
-# Monday in October. This matches both recent practice and
-# timeanddate.com's current spring-forward prediction.
-# For the January 2014 transition we guessed right while timeanddate.com
-# guessed wrong, so leave the fall-back prediction alone.
+# Monday in October, and springs back the penultimate Sunday in January.
+# This is ad hoc, but matches recent practice.
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule Fiji 1998 1999 - Nov Sun>=1 2:00 1:00 S
@@ -395,7 +397,8 @@
Rule Fiji 2010 only - Mar lastSun 3:00 0 -
Rule Fiji 2010 max - Oct Sun>=21 2:00 1:00 S
Rule Fiji 2011 only - Mar Sun>=1 3:00 0 -
-Rule Fiji 2012 max - Jan Sun>=18 3:00 0 -
+Rule Fiji 2012 2013 - Jan Sun>=18 3:00 0 -
+Rule Fiji 2014 max - Jan Sun>=18 2:00 0 -
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Pacific/Fiji 11:55:44 - LMT 1915 Oct 26 # Suva
12:00 Fiji FJ%sT # Fiji Time
diff --git a/make/data/tzdata/europe b/make/data/tzdata/europe
index 9f574a3..585e64d 100644
--- a/make/data/tzdata/europe
+++ b/make/data/tzdata/europe
@@ -2768,14 +2768,18 @@
# According to the articles linked below, Turkey will change into summer
# time zone (GMT+3) on March 28, 2011 at 3:00 a.m. instead of March 27.
# This change is due to a nationwide exam on 27th.
-#
-# <a href="http://www.worldbulletin.net/?aType=haber&ArticleID=70872">
# http://www.worldbulletin.net/?aType=haber&ArticleID=70872
-# </a>
# Turkish:
-# <a href="http://www.hurriyet.com.tr/ekonomi/17230464.asp?gid=373">
# http://www.hurriyet.com.tr/ekonomi/17230464.asp?gid=373
-# </a>
+
+# From Faruk Pasin (2014-02-14):
+# The DST for Turkey has been changed for this year because of the
+# Turkish Local election....
+# http://www.sabah.com.tr/Ekonomi/2014/02/12/yaz-saatinde-onemli-degisiklik
+# ... so Turkey will move clocks forward one hour on March 31 at 3:00 a.m.
+# From Paul Eggert (2014-02-17):
+# Here is an English-language source:
+# http://www.worldbulletin.net/turkey/129016/turkey-switches-to-daylight-saving-time-march-31
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule Turkey 1916 only - May 1 0:00 1:00 S
@@ -2844,6 +2848,8 @@
2:00 Turkey EE%sT 2007
2:00 EU EE%sT 2011 Mar 27 1:00u
2:00 - EET 2011 Mar 28 1:00u
+ 2:00 EU EE%sT 2014 Mar 30 1:00u
+ 2:00 - EET 2014 Mar 31 1:00u
2:00 EU EE%sT
Link Europe/Istanbul Asia/Istanbul # Istanbul is in both continents.
@@ -2865,19 +2871,13 @@
# approval from 266 deputies.
#
# Ukraine abolishes transter back to the winter time (in Russian)
-# <a href="http://news.mail.ru/politics/6861560/">
# http://news.mail.ru/politics/6861560/
-# </a>
#
# The Ukrainians will no longer change the clock (in Russian)
-# <a href="http://www.segodnya.ua/news/14290482.html">
# http://www.segodnya.ua/news/14290482.html
-# </a>
#
# Deputies cancelled the winter time (in Russian)
-# <a href="http://www.pravda.com.ua/rus/news/2011/09/20/6600616/">
# http://www.pravda.com.ua/rus/news/2011/09/20/6600616/
-# </a>
#
# From Philip Pizzey (2011-10-18):
# Today my Ukrainian colleagues have informed me that the
@@ -2888,18 +2888,39 @@
# As far as I understand, the recent change to the Ukrainian time zone
# (Europe/Kiev) to introduce permanent daylight saving time (similar
# to Russia) was reverted today:
-#
-# <a href="http://portal.rada.gov.ua/rada/control/en/publish/article/info_left?art_id=287324&cat_id=105995">
# http://portal.rada.gov.ua/rada/control/en/publish/article/info_left?art_id=287324&cat_id=105995
-# </a>
#
# Also reported by Alexander Bokovoy (2011-10-18) who also noted:
# The law documents themselves are at
-#
-# <a href="http://w1.c1.rada.gov.ua/pls/zweb_n/webproc4_1?id=&pf3511=41484">
# http://w1.c1.rada.gov.ua/pls/zweb_n/webproc4_1?id=&pf3511=41484
-# </a>
+# From Vladimir in Moscow via Alois Treindl re Kiev time 1991/2 (2014-02-28):
+# First in Ukraine they changed Time zone from UTC+3 to UTC+2 with DST:
+# 03 25 1990 02:00 -03.00 1 Time Zone 3 with DST
+# 07 01 1990 02:00 -02.00 1 Time Zone 2 with DST
+# * Ukrainian Government's Resolution of 18.06.1990, No. 134.
+# http://search.ligazakon.ua/l_doc2.nsf/link1/T001500.html
+#
+# They did not end DST in September, 1990 (according to the law,
+# "summer time" was still in action):
+# 09 30 1990 03:00 -02.00 1 Time Zone 2 with DST
+# * Ukrainian Government's Resolution of 21.09.1990, No. 272.
+# http://search.ligazakon.ua/l_doc2.nsf/link1/KP900272.html
+#
+# Again no change in March, 1991 ("summer time" in action):
+# 03 31 1991 02:00 -02.00 1 Time Zone 2 with DST
+#
+# DST ended in September 1991 ("summer time" ended):
+# 09 29 1991 03:00 -02.00 0 Time Zone 2, no DST
+# * Ukrainian Government's Resolution of 25.09.1991, No. 225.
+# http://www.uazakon.com/documents/date_21/pg_iwgdoc.htm
+# This is an answer.
+#
+# Since 1992 they had normal DST procedure:
+# 03 29 1992 02:00 -02.00 1 DST started
+# 09 27 1992 03:00 -02.00 0 DST ended
+# * Ukrainian Government's Resolution of 20.03.1992, No. 139.
+# http://www.uazakon.com/documents/date_8u/pg_grcasa.htm
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
# Most of Ukraine since 1970 has been like Kiev.
@@ -2910,9 +2931,8 @@
2:00 - EET 1930 Jun 21
3:00 - MSK 1941 Sep 20
1:00 C-Eur CE%sT 1943 Nov 6
- 3:00 Russia MSK/MSD 1990
- 3:00 - MSK 1990 Jul 1 2:00
- 2:00 - EET 1992
+ 3:00 Russia MSK/MSD 1990 Jul 1 2:00
+ 2:00 1:00 EEST 1991 Sep 29 3:00
2:00 E-Eur EE%sT 1995
2:00 EU EE%sT
# Ruthenia used CET 1990/1991.
diff --git a/make/data/tzdata/northamerica b/make/data/tzdata/northamerica
index 9e551bb..dc0c2e9 100644
--- a/make/data/tzdata/northamerica
+++ b/make/data/tzdata/northamerica
@@ -414,9 +414,10 @@
# US Pacific time, represented by Los Angeles
#
# California, northern Idaho (Benewah, Bonner, Boundary, Clearwater,
-# Idaho, Kootenai, Latah, Lewis, Nez Perce, and Shoshone counties,
-# and the northern three-quarters of Idaho county),
-# most of Nevada, most of Oregon, and Washington
+# Kootenai, Latah, Lewis, Nez Perce, and Shoshone counties, Idaho county
+# north of the Salmon River, and the towns of Burgdorf and Warren),
+# Nevada (except West Wendover), Oregon (except the northern 3/4 of
+# Malheur county), and Washington
#
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER
Rule CA 1948 only - Mar 14 2:00 1:00 D
diff --git a/make/data/tzdata/southamerica b/make/data/tzdata/southamerica
index 071f890..02bf3bb 100644
--- a/make/data/tzdata/southamerica
+++ b/make/data/tzdata/southamerica
@@ -1298,6 +1298,13 @@
# start date is 2013-09-08 00:00....
# http://www.gob.cl/informa/2013/02/15/gobierno-anuncia-fechas-de-cambio-de-hora-para-el-ano-2013.htm
+# From Jose Miguel Garrido (2014-02-19):
+# Today appeared in the Diario Oficial a decree amending the time change
+# dates to 2014.
+# DST End: last Saturday of April 2014 (Sun 27 Apr 2014 03:00 UTC)
+# DST Start: first Saturday of September 2014 (Sun 07 Sep 2014 04:00 UTC)
+# http://www.diariooficial.interior.gob.cl//media/2014/02/19/do-20140219.pdf
+
# NOTE: ChileAQ rules for Antarctic bases are stored separately in the
# 'antarctica' file.
@@ -1631,6 +1638,9 @@
# From Carlos Raul Perasso (2013-03-15):
# The change in Paraguay is now final. Decree number 10780
# http://www.presidencia.gov.py/uploads/pdf/presidencia-3b86ff4b691c79d4f5927ca964922ec74772ce857c02ca054a52a37b49afc7fb.pdf
+# From Carlos Raul Perasso (2014-02-28):
+# Decree 1264 can be found at:
+# http://www.presidencia.gov.py/archivos/documentos/DECRETO1264_ey9r8zai.pdf
Rule Para 2013 max - Mar Sun>=22 0:00 0 -
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
@@ -1689,18 +1699,19 @@
Zone America/Port_of_Spain -4:06:04 - LMT 1912 Mar 2
-4:00 - AST
+# These all agree with Trinidad and Tobago since 1970.
Link America/Port_of_Spain America/Anguilla
Link America/Port_of_Spain America/Dominica
Link America/Port_of_Spain America/Grenada
Link America/Port_of_Spain America/Guadeloupe
-Link America/Port_of_Spain America/Marigot
+Link America/Port_of_Spain America/Marigot # St Martin (French part)
Link America/Port_of_Spain America/Montserrat
Link America/Port_of_Spain America/St_Barthelemy
-Link America/Port_of_Spain America/St_Kitts
+Link America/Port_of_Spain America/St_Kitts # St Kitts & Nevis
Link America/Port_of_Spain America/St_Lucia
-Link America/Port_of_Spain America/St_Thomas
+Link America/Port_of_Spain America/St_Thomas # Virgin Islands (US)
Link America/Port_of_Spain America/St_Vincent
-Link America/Port_of_Spain America/Tortola
+Link America/Port_of_Spain America/Tortola # Virgin Islands (UK)
# Uruguay
# From Paul Eggert (1993-11-18):
diff --git a/make/mapfiles/libsunec/mapfile-vers b/make/mapfiles/libsunec/mapfile-vers
index a1da80c..3295322 100644
--- a/make/mapfiles/libsunec/mapfile-vers
+++ b/make/mapfiles/libsunec/mapfile-vers
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2009, 2014, 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
@@ -28,10 +28,9 @@
SUNWprivate_1.1 {
global:
Java_sun_security_ec_ECKeyPairGenerator_generateECKeyPair;
- Java_sun_security_ec_ECKeyPairGenerator_getEncodedBytes;
- Java_sun_security_ec_ECDSASignature_signDigest;
- Java_sun_security_ec_ECDSASignature_verifySignedDigest;
- Java_sun_security_ec_ECDHKeyAgreement_deriveKey;
+ Java_sun_security_ec_ECDSASignature_signDigest;
+ Java_sun_security_ec_ECDSASignature_verifySignedDigest;
+ Java_sun_security_ec_ECDHKeyAgreement_deriveKey;
local:
*;
};
diff --git a/src/share/classes/com/sun/jmx/remote/security/SubjectDelegator.java b/src/share/classes/com/sun/jmx/remote/security/SubjectDelegator.java
index a69c501..536e231 100644
--- a/src/share/classes/com/sun/jmx/remote/security/SubjectDelegator.java
+++ b/src/share/classes/com/sun/jmx/remote/security/SubjectDelegator.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2014, 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
@@ -34,22 +34,14 @@
import javax.management.remote.SubjectDelegationPermission;
-import com.sun.jmx.remote.util.CacheMap;
-import java.util.ArrayList;
-import java.util.Collection;
+import java.util.*;
public class SubjectDelegator {
- private static final int PRINCIPALS_CACHE_SIZE = 10;
- private static final int ACC_CACHE_SIZE = 10;
-
- private CacheMap<Subject, Principal[]> principalsCache;
- private CacheMap<Subject, AccessControlContext> accCache;
-
/* Return the AccessControlContext appropriate to execute an
operation on behalf of the delegatedSubject. If the
authenticatedAccessControlContext does not have permission to
delegate to that subject, throw SecurityException. */
- public synchronized AccessControlContext
+ public AccessControlContext
delegatedContext(AccessControlContext authenticatedACC,
Subject delegatedSubject,
boolean removeCallerContext)
@@ -58,56 +50,14 @@
if (System.getSecurityManager() != null && authenticatedACC == null) {
throw new SecurityException("Illegal AccessControlContext: null");
}
- if (principalsCache == null || accCache == null) {
- principalsCache =
- new CacheMap<>(PRINCIPALS_CACHE_SIZE);
- accCache =
- new CacheMap<>(ACC_CACHE_SIZE);
- }
-
- // Retrieve the principals for the given
- // delegated subject from the cache
- //
- Principal[] delegatedPrincipals = principalsCache.get(delegatedSubject);
-
- // Convert the set of principals stored in the
- // delegated subject into an array of principals
- // and store it in the cache
- //
- if (delegatedPrincipals == null) {
- delegatedPrincipals =
- delegatedSubject.getPrincipals().toArray(new Principal[0]);
- principalsCache.put(delegatedSubject, delegatedPrincipals);
- }
-
- // Retrieve the access control context for the
- // given delegated subject from the cache
- //
- AccessControlContext delegatedACC = accCache.get(delegatedSubject);
-
- // Build the access control context to be used
- // when executing code as the delegated subject
- // and store it in the cache
- //
- if (delegatedACC == null) {
- if (removeCallerContext) {
- delegatedACC =
- JMXSubjectDomainCombiner.getDomainCombinerContext(
- delegatedSubject);
- } else {
- delegatedACC =
- JMXSubjectDomainCombiner.getContext(delegatedSubject);
- }
- accCache.put(delegatedSubject, delegatedACC);
- }
// Check if the subject delegation permission allows the
// authenticated subject to assume the identity of each
// principal in the delegated subject
//
- final Principal[] dp = delegatedPrincipals;
- final Collection<Permission> permissions = new ArrayList<>(dp.length);
- for(Principal p : dp) {
+ Collection<Principal> ps = getSubjectPrincipals(delegatedSubject);
+ final Collection<Permission> permissions = new ArrayList<>(ps.size());
+ for(Principal p : ps) {
final String pname = p.getClass().getName() + "." + p.getName();
permissions.add(new SubjectDelegationPermission(pname));
}
@@ -122,7 +72,15 @@
};
AccessController.doPrivileged(action, authenticatedACC);
- return delegatedACC;
+ return getDelegatedAcc(delegatedSubject, removeCallerContext);
+ }
+
+ private AccessControlContext getDelegatedAcc(Subject delegatedSubject, boolean removeCallerContext) {
+ if (removeCallerContext) {
+ return JMXSubjectDomainCombiner.getDomainCombinerContext(delegatedSubject);
+ } else {
+ return JMXSubjectDomainCombiner.getContext(delegatedSubject);
+ }
}
/**
@@ -137,11 +95,9 @@
public static synchronized boolean
checkRemoveCallerContext(Subject subject) {
try {
- final Principal[] dp =
- subject.getPrincipals().toArray(new Principal[0]);
- for (int i = 0 ; i < dp.length ; i++) {
+ for (Principal p : getSubjectPrincipals(subject)) {
final String pname =
- dp[i].getClass().getName() + "." + dp[i].getName();
+ p.getClass().getName() + "." + p.getName();
final Permission sdp =
new SubjectDelegationPermission(pname);
AccessController.checkPermission(sdp);
@@ -151,4 +107,19 @@
}
return true;
}
+
+ /**
+ * Retrieves the {@linkplain Subject} principals
+ * @param subject The subject
+ * @return If the {@code Subject} is immutable it will return the principals directly.
+ * If the {@code Subject} is mutable it will create an unmodifiable copy.
+ */
+ private static Collection<Principal> getSubjectPrincipals(Subject subject) {
+ if (subject.isReadOnly()) {
+ return subject.getPrincipals();
+ }
+
+ List<Principal> principals = Arrays.asList(subject.getPrincipals().toArray(new Principal[0]));
+ return Collections.unmodifiableList(principals);
+ }
}
diff --git a/src/share/classes/com/sun/jmx/remote/util/CacheMap.java b/src/share/classes/com/sun/jmx/remote/util/CacheMap.java
deleted file mode 100644
index ae21d07..0000000
--- a/src/share/classes/com/sun/jmx/remote/util/CacheMap.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (c) 2003, 2006, 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. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package com.sun.jmx.remote.util;
-
-import java.lang.ref.SoftReference;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.WeakHashMap;
-
-import com.sun.jmx.mbeanserver.Util;
-
-/**
- * <p>Like WeakHashMap, except that the keys of the <em>n</em> most
- * recently-accessed entries are kept as {@link SoftReference soft
- * references}. Accessing an element means creating it, or retrieving
- * it with {@link #get(Object) get}. Because these entries are kept
- * with soft references, they will tend to remain even if their keys
- * are not referenced elsewhere. But if memory is short, they will
- * be removed.</p>
- */
-public class CacheMap<K, V> extends WeakHashMap<K, V> {
- /**
- * <p>Create a <code>CacheMap</code> that can keep up to
- * <code>nSoftReferences</code> as soft references.</p>
- *
- * @param nSoftReferences Maximum number of keys to keep as soft
- * references. Access times for {@link #get(Object) get} and
- * {@link #put(Object, Object) put} have a component that scales
- * linearly with <code>nSoftReferences</code>, so this value
- * should not be too great.
- *
- * @throws IllegalArgumentException if
- * <code>nSoftReferences</code> is negative.
- */
- public CacheMap(int nSoftReferences) {
- if (nSoftReferences < 0) {
- throw new IllegalArgumentException("nSoftReferences = " +
- nSoftReferences);
- }
- this.nSoftReferences = nSoftReferences;
- }
-
- public V put(K key, V value) {
- cache(key);
- return super.put(key, value);
- }
-
- public V get(Object key) {
- cache(Util.<K>cast(key));
- return super.get(key);
- }
-
- /* We don't override remove(Object) or try to do something with
- the map's iterators to detect removal. So we may keep useless
- entries in the soft reference list for keys that have since
- been removed. The assumption is that entries are added to the
- cache but never removed. But the behavior is not wrong if
- they are in fact removed -- the caching is just less
- performant. */
-
- private void cache(K key) {
- Iterator<SoftReference<K>> it = cache.iterator();
- while (it.hasNext()) {
- SoftReference<K> sref = it.next();
- K key1 = sref.get();
- if (key1 == null)
- it.remove();
- else if (key.equals(key1)) {
- // Move this element to the head of the LRU list
- it.remove();
- cache.add(0, sref);
- return;
- }
- }
-
- int size = cache.size();
- if (size == nSoftReferences) {
- if (size == 0)
- return; // degenerate case, equivalent to WeakHashMap
- it.remove();
- }
-
- cache.add(0, new SoftReference<K>(key));
- }
-
- /* List of soft references for the most-recently referenced keys.
- The list is in most-recently-used order, i.e. the first element
- is the most-recently referenced key. There are never more than
- nSoftReferences elements of this list.
-
- If we didn't care about J2SE 1.3 compatibility, we could use
- LinkedHashSet in conjunction with a subclass of SoftReference
- whose equals and hashCode reflect the referent. */
- private final LinkedList<SoftReference<K>> cache =
- new LinkedList<SoftReference<K>>();
- private final int nSoftReferences;
-}
diff --git a/src/share/classes/com/sun/security/sasl/CramMD5Base.java b/src/share/classes/com/sun/security/sasl/CramMD5Base.java
index 5d0309c..559b0bc 100644
--- a/src/share/classes/com/sun/security/sasl/CramMD5Base.java
+++ b/src/share/classes/com/sun/security/sasl/CramMD5Base.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2014, 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
@@ -32,6 +32,7 @@
import java.security.NoSuchAlgorithmException;
import java.security.MessageDigest;
+import java.util.Arrays;
import java.util.logging.Logger;
/**
@@ -159,7 +160,7 @@
MessageDigest md5 = MessageDigest.getInstance("MD5");
/* digest the key if longer than 64 bytes */
- if (key.length > 64) {
+ if (key.length > MD5_BLOCKSIZE) {
key = md5.digest(key);
}
@@ -169,13 +170,9 @@
int i;
/* store key in pads */
- for (i = 0; i < MD5_BLOCKSIZE; i++) {
- for ( ; i < key.length; i++) {
- ipad[i] = key[i];
- opad[i] = key[i];
- }
- ipad[i] = 0x00;
- opad[i] = 0x00;
+ for (i = 0; i < key.length; i++) {
+ ipad[i] = key[i];
+ opad[i] = key[i];
}
/* XOR key with pads */
@@ -207,6 +204,11 @@
}
}
+ Arrays.fill(ipad, (byte)0);
+ Arrays.fill(opad, (byte)0);
+ ipad = null;
+ opad = null;
+
return (digestString.toString());
}
diff --git a/src/share/classes/java/awt/Toolkit.java b/src/share/classes/java/awt/Toolkit.java
index e1f86f2..c32b081 100644
--- a/src/share/classes/java/awt/Toolkit.java
+++ b/src/share/classes/java/awt/Toolkit.java
@@ -2557,30 +2557,23 @@
public void firePropertyChange(final PropertyChangeEvent evt) {
Object oldValue = evt.getOldValue();
Object newValue = evt.getNewValue();
- String propertyName = evt.getPropertyName();
if (oldValue != null && newValue != null && oldValue.equals(newValue)) {
return;
}
- Runnable updater = new Runnable() {
- public void run() {
- PropertyChangeSupport pcs = (PropertyChangeSupport)
- AppContext.getAppContext().get(PROP_CHANGE_SUPPORT_KEY);
- if (null != pcs) {
- pcs.firePropertyChange(evt);
- }
- }
- };
- final AppContext currentAppContext = AppContext.getAppContext();
for (AppContext appContext : AppContext.getAppContexts()) {
if (null == appContext || appContext.isDisposed()) {
continue;
}
- if (currentAppContext == appContext) {
- updater.run();
- } else {
- final PeerEvent e = new PeerEvent(source, updater, PeerEvent.ULTIMATE_PRIORITY_EVENT);
- SunToolkit.postEvent(appContext, e);
- }
+ final PeerEvent e = new PeerEvent(source,
+ () -> {
+ PropertyChangeSupport pcs = (PropertyChangeSupport)
+ AppContext.getAppContext().get(PROP_CHANGE_SUPPORT_KEY);
+ if (null != pcs) {
+ pcs.firePropertyChange(evt);
+ }
+ },
+ PeerEvent.ULTIMATE_PRIORITY_EVENT);
+ SunToolkit.postEvent(appContext, e);
}
}
}
diff --git a/src/share/classes/java/lang/ProcessBuilder.java b/src/share/classes/java/lang/ProcessBuilder.java
index efa30fd..fc58abc 100644
--- a/src/share/classes/java/lang/ProcessBuilder.java
+++ b/src/share/classes/java/lang/ProcessBuilder.java
@@ -1019,6 +1019,12 @@
String dir = directory == null ? null : directory.toString();
+ for (int i = 1; i < cmdarray.length; i++) {
+ if (cmdarray[i].indexOf('\u0000') >= 0) {
+ throw new IOException("invalid null character in command");
+ }
+ }
+
try {
return ProcessImpl.start(cmdarray,
environment,
diff --git a/src/share/classes/java/lang/invoke/AbstractValidatingLambdaMetafactory.java b/src/share/classes/java/lang/invoke/AbstractValidatingLambdaMetafactory.java
index 10c3ed1..3f91060 100644
--- a/src/share/classes/java/lang/invoke/AbstractValidatingLambdaMetafactory.java
+++ b/src/share/classes/java/lang/invoke/AbstractValidatingLambdaMetafactory.java
@@ -200,6 +200,13 @@
implIsInstanceMethod ? "instance" : "static", implInfo,
instantiatedArity, samArity));
}
+ for (MethodType bridgeMT : additionalBridges) {
+ if (bridgeMT.parameterCount() != samArity) {
+ throw new LambdaConversionException(
+ String.format("Incorrect number of parameters for bridge signature %s; incompatible with %s",
+ bridgeMT, samMethodType));
+ }
+ }
// If instance: first captured arg (receiver) must be subtype of class where impl method is defined
final int capturedStart;
@@ -232,7 +239,7 @@
throw new LambdaConversionException(
String.format("Invalid receiver type %s; not a subtype of implementation receiver type %s",
receiverClass, implReceiverClass));
- }
+ }
} else {
// no receiver
capturedStart = 0;
@@ -274,11 +281,18 @@
String.format("Type mismatch for lambda return: %s is not convertible to %s",
actualReturnType, expectedType));
}
- if (!isAdaptableToAsReturn(expectedType, samReturnType)) {
+ if (!isAdaptableToAsReturnStrict(expectedType, samReturnType)) {
throw new LambdaConversionException(
String.format("Type mismatch for lambda expected return: %s is not convertible to %s",
expectedType, samReturnType));
}
+ for (MethodType bridgeMT : additionalBridges) {
+ if (!isAdaptableToAsReturnStrict(expectedType, bridgeMT.returnType())) {
+ throw new LambdaConversionException(
+ String.format("Type mismatch for lambda expected return: %s is not convertible to %s",
+ expectedType, bridgeMT.returnType()));
+ }
+ }
}
/**
@@ -330,6 +344,10 @@
return toType.equals(void.class)
|| !fromType.equals(void.class) && isAdaptableTo(fromType, toType, false);
}
+ private boolean isAdaptableToAsReturnStrict(Class<?> fromType, Class<?> toType) {
+ if (fromType.equals(void.class)) return toType.equals(void.class);
+ return isAdaptableTo(fromType, toType, true);
+ }
/*********** Logging support -- for debugging only, uncomment as needed
diff --git a/src/share/classes/java/lang/invoke/MethodHandles.java b/src/share/classes/java/lang/invoke/MethodHandles.java
index eeb9a4a..f3b904e 100644
--- a/src/share/classes/java/lang/invoke/MethodHandles.java
+++ b/src/share/classes/java/lang/invoke/MethodHandles.java
@@ -39,7 +39,9 @@
import sun.security.util.SecurityConstants;
import static java.lang.invoke.MethodHandleStatics.*;
import static java.lang.invoke.MethodHandleNatives.Constants.*;
+
import java.util.concurrent.ConcurrentHashMap;
+
import sun.security.util.SecurityConstants;
/**
@@ -1504,6 +1506,10 @@
// that is *not* the bytecode behavior.
mods ^= Modifier.PROTECTED | Modifier.PUBLIC;
}
+ if (Modifier.isProtected(mods) && refKind == REF_newInvokeSpecial) {
+ // cannot "new" a protected ctor in a different package
+ mods ^= Modifier.PROTECTED;
+ }
if (Modifier.isFinal(mods) &&
MethodHandleNatives.refKindIsSetter(refKind))
throw m.makeAccessException("unexpected set of a final field", this);
diff --git a/src/share/classes/java/lang/invoke/TypeConvertingMethodAdapter.java b/src/share/classes/java/lang/invoke/TypeConvertingMethodAdapter.java
index 5d8e1bf..aecbeb6 100644
--- a/src/share/classes/java/lang/invoke/TypeConvertingMethodAdapter.java
+++ b/src/share/classes/java/lang/invoke/TypeConvertingMethodAdapter.java
@@ -212,7 +212,7 @@
* @param functional
*/
void convertType(Class<?> arg, Class<?> target, Class<?> functional) {
- if (arg.equals(target)) {
+ if (arg.equals(target) && arg.equals(functional)) {
return;
}
if (arg == Void.TYPE || target == Void.TYPE) {
diff --git a/src/share/classes/java/lang/reflect/Proxy.java b/src/share/classes/java/lang/reflect/Proxy.java
index 20e62b6..7b80e45 100644
--- a/src/share/classes/java/lang/reflect/Proxy.java
+++ b/src/share/classes/java/lang/reflect/Proxy.java
@@ -362,12 +362,13 @@
Class<?>... interfaces)
throws IllegalArgumentException
{
- SecurityManager sm = System.getSecurityManager();
+ final Class<?>[] intfs = interfaces.clone();
+ final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
- checkProxyAccess(Reflection.getCallerClass(), loader, interfaces);
+ checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
}
- return getProxyClass0(loader, interfaces);
+ return getProxyClass0(loader, intfs);
}
/*
@@ -706,15 +707,16 @@
{
Objects.requireNonNull(h);
+ final Class<?>[] intfs = interfaces.clone();
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
- checkProxyAccess(Reflection.getCallerClass(), loader, interfaces);
+ checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
}
/*
* Look up or generate the designated proxy class.
*/
- Class<?> cl = getProxyClass0(loader, interfaces);
+ Class<?> cl = getProxyClass0(loader, intfs);
/*
* Invoke its constructor with the designated invocation handler.
diff --git a/src/share/classes/java/util/TreeMap.java b/src/share/classes/java/util/TreeMap.java
index 6a3ecc0..e014fb5 100644
--- a/src/share/classes/java/util/TreeMap.java
+++ b/src/share/classes/java/util/TreeMap.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2014, 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
@@ -1338,6 +1338,7 @@
*/
abstract static class NavigableSubMap<K,V> extends AbstractMap<K,V>
implements NavigableMap<K,V>, java.io.Serializable {
+ private static final long serialVersionUID = -2102997345730753016L;
/**
* The backing map.
*/
diff --git a/src/share/classes/javax/script/ScriptEngineManager.java b/src/share/classes/javax/script/ScriptEngineManager.java
index 83cb9f0..b2af53e 100644
--- a/src/share/classes/javax/script/ScriptEngineManager.java
+++ b/src/share/classes/javax/script/ScriptEngineManager.java
@@ -81,23 +81,28 @@
nameAssociations = new HashMap<String, ScriptEngineFactory>();
extensionAssociations = new HashMap<String, ScriptEngineFactory>();
mimeTypeAssociations = new HashMap<String, ScriptEngineFactory>();
- AccessController.doPrivileged(new PrivilegedAction<Object>() {
- public Object run() {
- initEngines(loader);
- return null;
- }
- });
+ initEngines(loader);
+ }
+
+ private ServiceLoader<ScriptEngineFactory> getServiceLoader(final ClassLoader loader) {
+ if (loader != null) {
+ return ServiceLoader.load(ScriptEngineFactory.class, loader);
+ } else {
+ return ServiceLoader.loadInstalled(ScriptEngineFactory.class);
+ }
}
private void initEngines(final ClassLoader loader) {
Iterator<ScriptEngineFactory> itr = null;
try {
- ServiceLoader<ScriptEngineFactory> sl;
- if (loader != null) {
- sl = ServiceLoader.load(ScriptEngineFactory.class, loader);
- } else {
- sl = ServiceLoader.loadInstalled(ScriptEngineFactory.class);
- }
+ ServiceLoader<ScriptEngineFactory> sl = AccessController.doPrivileged(
+ new PrivilegedAction<ServiceLoader<ScriptEngineFactory>>() {
+ @Override
+ public ServiceLoader<ScriptEngineFactory> run() {
+ return getServiceLoader(loader);
+ }
+ });
+
itr = sl.iterator();
} catch (ServiceConfigurationError err) {
System.err.println("Can't find ScriptEngineFactory providers: " +
diff --git a/src/share/classes/javax/swing/filechooser/FileSystemView.java b/src/share/classes/javax/swing/filechooser/FileSystemView.java
index f62d69c..b1d9d1f 100644
--- a/src/share/classes/javax/swing/filechooser/FileSystemView.java
+++ b/src/share/classes/javax/swing/filechooser/FileSystemView.java
@@ -718,7 +718,8 @@
* @return the Desktop folder.
*/
public File getHomeDirectory() {
- return getRoots()[0];
+ File[] roots = getRoots();
+ return (roots.length == 0) ? null : roots[0];
}
/**
diff --git a/src/share/classes/sun/awt/AppContext.java b/src/share/classes/sun/awt/AppContext.java
index c7f46ef..e638164 100644
--- a/src/share/classes/sun/awt/AppContext.java
+++ b/src/share/classes/sun/awt/AppContext.java
@@ -329,6 +329,20 @@
while (context == null) {
threadGroup = threadGroup.getParent();
if (threadGroup == null) {
+ // We've got up to the root thread group and did not find an AppContext
+ // Try to get it from the security manager
+ SecurityManager securityManager = System.getSecurityManager();
+ if (securityManager != null) {
+ ThreadGroup smThreadGroup = securityManager.getThreadGroup();
+ if (smThreadGroup != null) {
+ /*
+ * If we get this far then it's likely that
+ * the ThreadGroup does not actually belong
+ * to the applet, so do not cache it.
+ */
+ return threadGroup2appContext.get(smThreadGroup);
+ }
+ }
return null;
}
context = threadGroup2appContext.get(threadGroup);
diff --git a/src/share/classes/sun/security/ec/ECKeyPairGenerator.java b/src/share/classes/sun/security/ec/ECKeyPairGenerator.java
index 5bfb6a7..bd97248 100644
--- a/src/share/classes/sun/security/ec/ECKeyPairGenerator.java
+++ b/src/share/classes/sun/security/ec/ECKeyPairGenerator.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2014, 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
@@ -125,19 +125,18 @@
try {
- long[] handles = generateECKeyPair(keySize, encodedParams, seed);
+ Object[] keyBytes = generateECKeyPair(keySize, encodedParams, seed);
// The 'params' object supplied above is equivalent to the native
// one so there is no need to fetch it.
-
- // handles[0] points to the native private key
- BigInteger s = new BigInteger(1, getEncodedBytes(handles[0]));
+ // keyBytes[0] is the encoding of the native private key
+ BigInteger s = new BigInteger(1, (byte[])keyBytes[0]);
PrivateKey privateKey =
new ECPrivateKeyImpl(s, (ECParameterSpec)params);
- // handles[1] points to the native public key
- ECPoint w = ECUtil.decodePoint(getEncodedBytes(handles[1]),
+ // keyBytes[1] is the encoding of the native public key
+ ECPoint w = ECUtil.decodePoint((byte[])keyBytes[1],
((ECParameterSpec)params).getCurve());
PublicKey publicKey =
new ECPublicKeyImpl(w, (ECParameterSpec)params);
@@ -162,14 +161,9 @@
}
/*
- * Generates the keypair and returns a 2-element array of handles.
- * The first handle points to the private key, the second to the public key.
+ * Generates the keypair and returns a 2-element array of encoding bytes.
+ * The first one is for the private key, the second for the public key.
*/
- private static native long[] generateECKeyPair(int keySize,
+ private static native Object[] generateECKeyPair(int keySize,
byte[] encodedParams, byte[] seed) throws GeneralSecurityException;
-
- /*
- * Extracts the encoded key data using the supplied handle.
- */
- private static native byte[] getEncodedBytes(long handle);
}
diff --git a/src/share/classes/sun/security/provider/SeedGenerator.java b/src/share/classes/sun/security/provider/SeedGenerator.java
index 4856662..c4438da 100644
--- a/src/share/classes/sun/security/provider/SeedGenerator.java
+++ b/src/share/classes/sun/security/provider/SeedGenerator.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2014, 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
@@ -179,8 +179,8 @@
md.update(p.getProperty(s).getBytes());
}
- md.update
- (InetAddress.getLocalHost().toString().getBytes());
+ // Include network adapter names (and a Mac address)
+ addNetworkAdapterInfo(md);
// The temporary dir
File f = new File(p.getProperty("java.io.tmpdir"));
@@ -221,6 +221,31 @@
return md.digest();
}
+ /*
+ * Include network adapter names and, if available, a Mac address
+ *
+ * See also java.util.concurrent.ThreadLocalRandom.initialSeed()
+ */
+ private static void addNetworkAdapterInfo(MessageDigest md) {
+
+ try {
+ Enumeration<NetworkInterface> ifcs =
+ NetworkInterface.getNetworkInterfaces();
+ while (ifcs.hasMoreElements()) {
+ NetworkInterface ifc = ifcs.nextElement();
+ md.update(ifc.toString().getBytes());
+ if (!ifc.isVirtual()) { // skip fake addresses
+ byte[] bs = ifc.getHardwareAddress();
+ if (bs != null) {
+ md.update(bs);
+ break;
+ }
+ }
+ }
+ } catch (Exception ignore) {
+ }
+ }
+
/**
* Helper function to convert a long into a byte array (least significant
* byte first).
diff --git a/src/share/classes/sun/security/rsa/RSACore.java b/src/share/classes/sun/security/rsa/RSACore.java
index c34f6a4..81b4e3f 100644
--- a/src/share/classes/sun/security/rsa/RSACore.java
+++ b/src/share/classes/sun/security/rsa/RSACore.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2014, 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
@@ -50,6 +50,15 @@
*/
public final class RSACore {
+ // globally enable/disable use of blinding
+ private final static boolean ENABLE_BLINDING = true;
+
+ // cache for blinding parameters. Map<BigInteger, BlindingParameters>
+ // use a weak hashmap so that cached values are automatically cleared
+ // when the modulus is GC'ed
+ private final static Map<BigInteger, BlindingParameters>
+ blindingCache = new WeakHashMap<>();
+
private RSACore() {
// empty
}
@@ -100,12 +109,12 @@
if (key instanceof RSAPrivateCrtKey) {
return crtCrypt(msg, (RSAPrivateCrtKey)key);
} else {
- return crypt(msg, key.getModulus(), key.getPrivateExponent());
+ return priCrypt(msg, key.getModulus(), key.getPrivateExponent());
}
}
/**
- * RSA public key ops and non-CRT private key ops. Simple modPow().
+ * RSA public key ops. Simple modPow().
*/
private static byte[] crypt(byte[] msg, BigInteger n, BigInteger exp)
throws BadPaddingException {
@@ -115,22 +124,29 @@
}
/**
+ * RSA non-CRT private key operations.
+ */
+ private static byte[] priCrypt(byte[] msg, BigInteger n, BigInteger exp)
+ throws BadPaddingException {
+
+ BigInteger c = parseMsg(msg, n);
+ BlindingRandomPair brp = null;
+ BigInteger m;
+ if (ENABLE_BLINDING) {
+ brp = getBlindingRandomPair(null, exp, n);
+ c = c.multiply(brp.u).mod(n);
+ m = c.modPow(exp, n);
+ m = m.multiply(brp.v).mod(n);
+ } else {
+ m = c.modPow(exp, n);
+ }
+
+ return toByteArray(m, getByteLength(n));
+ }
+
+ /**
* RSA private key operations with CRT. Algorithm and variable naming
* are taken from PKCS#1 v2.1, section 5.1.2.
- *
- * The only difference is the addition of blinding to twart timing attacks.
- * This is described in the RSA Bulletin#2 (Jan 96) among other places.
- * This means instead of implementing RSA as
- * m = c ^ d mod n (or RSA in CRT variant)
- * we do
- * r = random(0, n-1)
- * c' = c * r^e mod n
- * m' = c' ^ d mod n (or RSA in CRT variant)
- * m = m' * r^-1 mod n (where r^-1 is the modular inverse of r mod n)
- * This works because r^(e*d) * r^-1 = r * r^-1 = 1 (all mod n)
- *
- * We do not generate new blinding parameters for each operation but reuse
- * them BLINDING_MAX_REUSE times (see definition below).
*/
private static byte[] crtCrypt(byte[] msg, RSAPrivateCrtKey key)
throws BadPaddingException {
@@ -141,13 +157,13 @@
BigInteger dP = key.getPrimeExponentP();
BigInteger dQ = key.getPrimeExponentQ();
BigInteger qInv = key.getCrtCoefficient();
+ BigInteger e = key.getPublicExponent();
+ BigInteger d = key.getPrivateExponent();
- BlindingParameters params;
+ BlindingRandomPair brp;
if (ENABLE_BLINDING) {
- params = getBlindingParameters(key);
- c = c.multiply(params.re).mod(n);
- } else {
- params = null;
+ brp = getBlindingRandomPair(e, d, n);
+ c = c.multiply(brp.u).mod(n);
}
// m1 = c ^ dP mod p
@@ -165,8 +181,8 @@
// m = m2 + q * h
BigInteger m = h.multiply(q).add(m2);
- if (params != null) {
- m = m.multiply(params.rInv).mod(n);
+ if (ENABLE_BLINDING) {
+ m = m.multiply(brp.v).mod(n);
}
return toByteArray(m, getByteLength(n));
@@ -208,82 +224,217 @@
return t;
}
- // globally enable/disable use of blinding
- private final static boolean ENABLE_BLINDING = true;
+ /**
+ * Parameters (u,v) for RSA Blinding. This is described in the RSA
+ * Bulletin#2 (Jan 96) and other places:
+ *
+ * ftp://ftp.rsa.com/pub/pdfs/bull-2.pdf
+ *
+ * The standard RSA Blinding decryption requires the public key exponent
+ * (e) and modulus (n), and converts ciphertext (c) to plaintext (p).
+ *
+ * Before the modular exponentiation operation, the input message should
+ * be multiplied by (u (mod n)), and afterward the result is corrected
+ * by multiplying with (v (mod n)). The system should reject messages
+ * equal to (0 (mod n)). That is:
+ *
+ * 1. Generate r between 0 and n-1, relatively prime to n.
+ * 2. Compute x = (c*u) mod n
+ * 3. Compute y = (x^d) mod n
+ * 4. Compute p = (y*v) mod n
+ *
+ * The Java APIs allows for either standard RSAPrivateKey or
+ * RSAPrivateCrtKey RSA keys.
+ *
+ * If the public exponent is available to us (e.g. RSAPrivateCrtKey),
+ * choose a random r, then let (u, v):
+ *
+ * u = r ^ e mod n
+ * v = r ^ (-1) mod n
+ *
+ * The proof follows:
+ *
+ * p = (((c * u) ^ d mod n) * v) mod n
+ * = ((c ^ d) * (u ^ d) * v) mod n
+ * = ((c ^ d) * (r ^ e) ^ d) * (r ^ (-1))) mod n
+ * = ((c ^ d) * (r ^ (e * d)) * (r ^ (-1))) mod n
+ * = ((c ^ d) * (r ^ 1) * (r ^ (-1))) mod n (see below)
+ * = (c ^ d) mod n
+ *
+ * because in RSA cryptosystem, d is the multiplicative inverse of e:
+ *
+ * (r^(e * d)) mod n
+ * = (r ^ 1) mod n
+ * = r mod n
+ *
+ * However, if the public exponent is not available (e.g. RSAPrivateKey),
+ * we mitigate the timing issue by using a similar random number blinding
+ * approach using the private key:
+ *
+ * u = r
+ * v = ((r ^ (-1)) ^ d) mod n
+ *
+ * This returns the same plaintext because:
+ *
+ * p = (((c * u) ^ d mod n) * v) mod n
+ * = ((c ^ d) * (u ^ d) * v) mod n
+ * = ((c ^ d) * (u ^ d) * ((u ^ (-1)) ^d)) mod n
+ * = (c ^ d) mod n
+ *
+ * Computing inverses mod n and random number generation is slow, so
+ * it is often not practical to generate a new random (u, v) pair for
+ * each new exponentiation. The calculation of parameters might even be
+ * subject to timing attacks. However, (u, v) pairs should not be
+ * reused since they themselves might be compromised by timing attacks,
+ * leaving the private exponent vulnerable. An efficient solution to
+ * this problem is update u and v before each modular exponentiation
+ * step by computing:
+ *
+ * u = u ^ 2
+ * v = v ^ 2
+ *
+ * The total performance cost is small.
+ */
+ private final static class BlindingRandomPair {
+ final BigInteger u;
+ final BigInteger v;
- // maximum number of times that we will use a set of blinding parameters
- // value suggested by Paul Kocher (quoted by NSS)
- private final static int BLINDING_MAX_REUSE = 50;
-
- // cache for blinding parameters. Map<BigInteger, BlindingParameters>
- // use a weak hashmap so that cached values are automatically cleared
- // when the modulus is GC'ed
- private final static Map<BigInteger, BlindingParameters> blindingCache =
- new WeakHashMap<>();
+ BlindingRandomPair(BigInteger u, BigInteger v) {
+ this.u = u;
+ this.v = v;
+ }
+ }
/**
* Set of blinding parameters for a given RSA key.
*
* The RSA modulus is usually unique, so we index by modulus in
- * blindingCache. However, to protect against the unlikely case of two
- * keys sharing the same modulus, we also store the public exponent.
- * This means we cannot cache blinding parameters for multiple keys that
- * share the same modulus, but since sharing moduli is fundamentally broken
- * an insecure, this does not matter.
+ * {@code blindingCache}. However, to protect against the unlikely
+ * case of two keys sharing the same modulus, we also store the public
+ * or the private exponent. This means we cannot cache blinding
+ * parameters for multiple keys that share the same modulus, but
+ * since sharing moduli is fundamentally broken and insecure, this
+ * does not matter.
*/
- private static final class BlindingParameters {
- // e (RSA public exponent)
- final BigInteger e;
- // r ^ e mod n
- final BigInteger re;
- // inverse of r mod n
- final BigInteger rInv;
- // how many more times this parameter object can be used
- private volatile int remainingUses;
- BlindingParameters(BigInteger e, BigInteger re, BigInteger rInv) {
+ private final static class BlindingParameters {
+ private final static BigInteger BIG_TWO = BigInteger.valueOf(2L);
+
+ // RSA public exponent
+ private final BigInteger e;
+
+ // hash code of RSA private exponent
+ private final BigInteger d;
+
+ // r ^ e mod n (CRT), or r mod n (Non-CRT)
+ private BigInteger u;
+
+ // r ^ (-1) mod n (CRT) , or ((r ^ (-1)) ^ d) mod n (Non-CRT)
+ private BigInteger v;
+
+ // e: the public exponent
+ // d: the private exponent
+ // n: the modulus
+ BlindingParameters(BigInteger e, BigInteger d, BigInteger n) {
+ this.u = null;
+ this.v = null;
this.e = e;
- this.re = re;
- this.rInv = rInv;
- // initialize remaining uses, subtract current use now
- remainingUses = BLINDING_MAX_REUSE - 1;
+ this.d = d;
+
+ int len = n.bitLength();
+ SecureRandom random = JCAUtil.getSecureRandom();
+ u = new BigInteger(len, random).mod(n);
+ // Although the possibility is very much limited that u is zero
+ // or is not relatively prime to n, we still want to be careful
+ // about the special value.
+ //
+ // Secure random generation is expensive, try to use BigInteger.ONE
+ // this time if this new generated random number is zero or is not
+ // relatively prime to n. Next time, new generated secure random
+ // number will be used instead.
+ if (u.equals(BigInteger.ZERO)) {
+ u = BigInteger.ONE; // use 1 this time
+ }
+
+ try {
+ // The call to BigInteger.modInverse() checks that u is
+ // relatively prime to n. Otherwise, ArithmeticException is
+ // thrown.
+ v = u.modInverse(n);
+ } catch (ArithmeticException ae) {
+ // if u is not relatively prime to n, use 1 this time
+ u = BigInteger.ONE;
+ v = BigInteger.ONE;
+ }
+
+ if (e != null) {
+ u = u.modPow(e, n); // e: the public exponent
+ // u: random ^ e
+ // v: random ^ (-1)
+ } else {
+ v = v.modPow(d, n); // d: the private exponent
+ // u: random
+ // v: random ^ (-d)
+ }
}
- boolean valid(BigInteger e) {
- int k = remainingUses--;
- return (k > 0) && this.e.equals(e);
+
+ // return null if need to reset the parameters
+ BlindingRandomPair getBlindingRandomPair(
+ BigInteger e, BigInteger d, BigInteger n) {
+
+ if ((this.e != null && this.e.equals(e)) ||
+ (this.d != null && this.d.equals(d))) {
+
+ BlindingRandomPair brp = null;
+ synchronized (this) {
+ if (!u.equals(BigInteger.ZERO) &&
+ !v.equals(BigInteger.ZERO)) {
+
+ brp = new BlindingRandomPair(u, v);
+ if (u.compareTo(BigInteger.ONE) <= 0 ||
+ v.compareTo(BigInteger.ONE) <= 0) {
+
+ // need to reset the random pair next time
+ u = BigInteger.ZERO;
+ v = BigInteger.ZERO;
+ } else {
+ u = u.modPow(BIG_TWO, n);
+ v = v.modPow(BIG_TWO, n);
+ }
+ } // Otherwise, need to reset the random pair.
+ }
+ return brp;
+ }
+
+ return null;
}
}
- /**
- * Return valid RSA blinding parameters for the given private key.
- * Use cached parameters if available. If not, generate new parameters
- * and cache.
- */
- private static BlindingParameters getBlindingParameters
- (RSAPrivateCrtKey key) {
- BigInteger modulus = key.getModulus();
- BigInteger e = key.getPublicExponent();
- BlindingParameters params;
- // we release the lock between get() and put()
- // that means threads might concurrently generate new blinding
- // parameters for the same modulus. this is only a slight waste
- // of cycles and seems preferable in terms of scalability
- // to locking out all threads while generating new parameters
+ private static BlindingRandomPair getBlindingRandomPair(
+ BigInteger e, BigInteger d, BigInteger n) {
+
+ BlindingParameters bps = null;
synchronized (blindingCache) {
- params = blindingCache.get(modulus);
+ bps = blindingCache.get(n);
}
- if ((params != null) && params.valid(e)) {
- return params;
+
+ if (bps == null) {
+ bps = new BlindingParameters(e, d, n);
+ synchronized (blindingCache) {
+ blindingCache.putIfAbsent(n, bps);
+ }
}
- int len = modulus.bitLength();
- SecureRandom random = JCAUtil.getSecureRandom();
- BigInteger r = new BigInteger(len, random).mod(modulus);
- BigInteger re = r.modPow(e, modulus);
- BigInteger rInv = r.modInverse(modulus);
- params = new BlindingParameters(e, re, rInv);
- synchronized (blindingCache) {
- blindingCache.put(modulus, params);
+
+ BlindingRandomPair brp = bps.getBlindingRandomPair(e, d, n);
+ if (brp == null) {
+ // need to reset the blinding parameters
+ bps = new BlindingParameters(e, d, n);
+ synchronized (blindingCache) {
+ blindingCache.replace(n, bps);
+ }
+ brp = bps.getBlindingRandomPair(e, d, n);
}
- return params;
+
+ return brp;
}
}
diff --git a/src/share/classes/sun/security/util/KeyUtil.java b/src/share/classes/sun/security/util/KeyUtil.java
index cbaa8a5..df7055a 100644
--- a/src/share/classes/sun/security/util/KeyUtil.java
+++ b/src/share/classes/sun/security/util/KeyUtil.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, 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
@@ -198,7 +198,16 @@
"Diffie-Hellman public key is too large");
}
- // Don't bother to check against the y^q mod p if safe primes are used.
+ // y^q mod p == 1?
+ // Unable to perform this check as q is unknown in this circumstance.
+
+ // p is expected to be prime. However, it is too expensive to check
+ // that p is prime. Instead, in order to mitigate the impact of
+ // non-prime values, we check that y is not a factor of p.
+ BigInteger r = p.remainder(y);
+ if (r.equals(BigInteger.ZERO)) {
+ throw new InvalidKeyException("Invalid Diffie-Hellman parameters");
+ }
}
/**
diff --git a/src/share/native/sun/awt/medialib/awt_ImagingLib.c b/src/share/native/sun/awt/medialib/awt_ImagingLib.c
index 0b34229..30089f1 100644
--- a/src/share/native/sun/awt/medialib/awt_ImagingLib.c
+++ b/src/share/native/sun/awt/medialib/awt_ImagingLib.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2014, 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
@@ -373,14 +373,14 @@
/* Parse the source image */
- if ((status = awt_parseImage(env, jsrc, &srcImageP, FALSE)) <= 0) {
+ if (awt_parseImage(env, jsrc, &srcImageP, FALSE) <= 0) {
/* Can't handle any custom images */
free(dkern);
return 0;
}
/* Parse the destination image */
- if ((status = awt_parseImage(env, jdst, &dstImageP, FALSE)) <= 0) {
+ if (awt_parseImage(env, jdst, &dstImageP, FALSE) <= 0) {
/* Can't handle any custom images */
awt_freeParsedImage(srcImageP, TRUE);
free(dkern);
@@ -627,7 +627,7 @@
}
/* Parse the source raster */
- if ((status = awt_parseRaster(env, jsrc, srcRasterP)) <= 0) {
+ if (awt_parseRaster(env, jsrc, srcRasterP) <= 0) {
/* Can't handle any custom rasters */
free(srcRasterP);
free(dstRasterP);
@@ -636,7 +636,7 @@
}
/* Parse the destination raster */
- if ((status = awt_parseRaster(env, jdst, dstRasterP)) <= 0) {
+ if (awt_parseRaster(env, jdst, dstRasterP) <= 0) {
/* Can't handle any custom images */
awt_freeParsedRaster(srcRasterP, TRUE);
free(dstRasterP);
@@ -839,13 +839,13 @@
(*env)->ReleasePrimitiveArrayCritical(env, jmatrix, matrix, JNI_ABORT);
/* Parse the source image */
- if ((status = awt_parseImage(env, jsrc, &srcImageP, FALSE)) <= 0) {
+ if (awt_parseImage(env, jsrc, &srcImageP, FALSE) <= 0) {
/* Can't handle any custom images */
return 0;
}
/* Parse the destination image */
- if ((status = awt_parseImage(env, jdst, &dstImageP, FALSE)) <= 0) {
+ if (awt_parseImage(env, jdst, &dstImageP, FALSE) <= 0) {
/* Can't handle any custom images */
awt_freeParsedImage(srcImageP, TRUE);
return 0;
@@ -1059,7 +1059,7 @@
(*env)->ReleasePrimitiveArrayCritical(env, jmatrix, matrix, JNI_ABORT);
/* Parse the source raster */
- if ((status = awt_parseRaster(env, jsrc, srcRasterP)) <= 0) {
+ if (awt_parseRaster(env, jsrc, srcRasterP) <= 0) {
/* Can't handle any custom rasters */
free(srcRasterP);
free(dstRasterP);
@@ -1067,7 +1067,7 @@
}
/* Parse the destination raster */
- if ((status = awt_parseRaster(env, jdst, dstRasterP)) <= 0) {
+ if (awt_parseRaster(env, jdst, dstRasterP) <= 0) {
/* Can't handle any custom images */
awt_freeParsedRaster(srcRasterP, TRUE);
free(dstRasterP);
@@ -1305,13 +1305,13 @@
if (s_timeIt) (*start_timer)(3600);
/* Parse the source image */
- if ((status = awt_parseImage(env, jsrc, &srcImageP, FALSE)) <= 0) {
+ if (awt_parseImage(env, jsrc, &srcImageP, FALSE) <= 0) {
/* Can't handle any custom images */
return 0;
}
/* Parse the destination image */
- if ((status = awt_parseImage(env, jdst, &dstImageP, FALSE)) <= 0) {
+ if (awt_parseImage(env, jdst, &dstImageP, FALSE) <= 0) {
/* Can't handle any custom images */
awt_freeParsedImage(srcImageP, TRUE);
return 0;
@@ -1553,14 +1553,14 @@
}
/* Parse the source raster - reject custom images */
- if ((status = awt_parseRaster(env, jsrc, srcRasterP)) <= 0) {
+ if (awt_parseRaster(env, jsrc, srcRasterP) <= 0) {
free(srcRasterP);
free(dstRasterP);
return 0;
}
/* Parse the destination image - reject custom images */
- if ((status = awt_parseRaster(env, jdst, dstRasterP)) <= 0) {
+ if (awt_parseRaster(env, jdst, dstRasterP) <= 0) {
awt_freeParsedRaster(srcRasterP, TRUE);
free(dstRasterP);
return 0;
diff --git a/src/share/native/sun/font/freetypeScaler.c b/src/share/native/sun/font/freetypeScaler.c
index e4b37fd..55ca4eb 100644
--- a/src/share/native/sun/font/freetypeScaler.c
+++ b/src/share/native/sun/font/freetypeScaler.c
@@ -177,18 +177,10 @@
if (numBytes > FILEDATACACHESIZE) {
bBuffer = (*env)->NewDirectByteBuffer(env, destBuffer, numBytes);
if (bBuffer != NULL) {
- /* Loop until the read succeeds (or EOF).
- * This should improve robustness in the event of a problem in
- * the I/O system. If we find that we ever end up spinning here
- * we are going to have to do some serious work to recover.
- * Just returning without reading the data will cause a crash.
- */
- while (bread == 0) {
- bread = (*env)->CallIntMethod(env,
- scalerInfo->font2D,
- sunFontIDs.ttReadBlockMID,
- bBuffer, offset, numBytes);
- }
+ bread = (*env)->CallIntMethod(env,
+ scalerInfo->font2D,
+ sunFontIDs.ttReadBlockMID,
+ bBuffer, offset, numBytes);
return bread;
} else {
/* We probably hit bug bug 4845371. For reasons that
@@ -224,19 +216,10 @@
(offset + FILEDATACACHESIZE > scalerInfo->fileSize) ?
scalerInfo->fileSize - offset : FILEDATACACHESIZE;
bBuffer = scalerInfo->directBuffer;
- /* Loop until all the read succeeds (or EOF).
- * This should improve robustness in the event of a problem in
- * the I/O system. If we find that we ever end up spinning here
- * we are going to have to do some serious work to recover.
- * Just returning without reading the data will cause a crash.
- */
- while (bread == 0) {
- bread = (*env)->CallIntMethod(env, scalerInfo->font2D,
- sunFontIDs.ttReadBlockMID,
- bBuffer, offset,
- scalerInfo->fontDataLength);
- }
-
+ bread = (*env)->CallIntMethod(env, scalerInfo->font2D,
+ sunFontIDs.ttReadBlockMID,
+ bBuffer, offset,
+ scalerInfo->fontDataLength);
memcpy(destBuffer, scalerInfo->fontData, numBytes);
return numBytes;
}
diff --git a/src/share/native/sun/security/ec/ECC_JNI.cpp b/src/share/native/sun/security/ec/ECC_JNI.cpp
index dff675f..f2612ad 100644
--- a/src/share/native/sun/security/ec/ECC_JNI.cpp
+++ b/src/share/native/sun/security/ec/ECC_JNI.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2014, 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
@@ -64,22 +64,40 @@
free(ecparams);
}
+jbyteArray getEncodedBytes(JNIEnv *env, SECItem *hSECItem)
+{
+ SECItem *s = (SECItem *)hSECItem;
+
+ jbyteArray jEncodedBytes = env->NewByteArray(s->len);
+ if (jEncodedBytes == NULL) {
+ return NULL;
+ }
+ // Copy bytes from a native SECItem buffer to Java byte array
+ env->SetByteArrayRegion(jEncodedBytes, 0, s->len, (jbyte *)s->data);
+ if (env->ExceptionCheck()) { // should never happen
+ return NULL;
+ }
+ return jEncodedBytes;
+}
+
+
/*
* Class: sun_security_ec_ECKeyPairGenerator
* Method: generateECKeyPair
- * Signature: (I[B[B)[J
+ * Signature: (I[B[B)[[B
*/
-JNIEXPORT jlongArray
+JNIEXPORT jobjectArray
JNICALL Java_sun_security_ec_ECKeyPairGenerator_generateECKeyPair
(JNIEnv *env, jclass clazz, jint keySize, jbyteArray encodedParams, jbyteArray seed)
{
- ECPrivateKey *privKey; /* contains both public and private values */
+ ECPrivateKey *privKey = NULL; // contains both public and private values
ECParams *ecparams = NULL;
SECKEYECParams params_item;
jint jSeedLength;
jbyte* pSeedBuffer = NULL;
- jlongArray result = NULL;
- jlong* resultElements = NULL;
+ jobjectArray result = NULL;
+ jclass baCls = NULL;
+ jbyteArray jba;
// Initialize the ECParams struct
params_item.len = env->GetArrayLength(encodedParams);
@@ -106,61 +124,61 @@
}
jboolean isCopy;
- result = env->NewLongArray(2);
- resultElements = env->GetLongArrayElements(result, &isCopy);
+ baCls = env->FindClass("[B");
+ if (baCls == NULL) {
+ goto cleanup;
+ }
+ result = env->NewObjectArray(2, baCls, NULL);
+ if (result == NULL) {
+ goto cleanup;
+ }
+ jba = getEncodedBytes(env, &(privKey->privateValue));
+ if (jba == NULL) {
+ result = NULL;
+ goto cleanup;
+ }
+ env->SetObjectArrayElement(result, 0, jba); // big integer
+ if (env->ExceptionCheck()) { // should never happen
+ result = NULL;
+ goto cleanup;
+ }
- resultElements[0] = (jlong) &(privKey->privateValue); // private big integer
- resultElements[1] = (jlong) &(privKey->publicValue); // encoded ec point
-
- // If the array is a copy then we must write back our changes
- if (isCopy == JNI_TRUE) {
- env->ReleaseLongArrayElements(result, resultElements, 0);
+ jba = getEncodedBytes(env, &(privKey->publicValue));
+ if (jba == NULL) {
+ result = NULL;
+ goto cleanup;
+ }
+ env->SetObjectArrayElement(result, 1, jba); // encoded ec point
+ if (env->ExceptionCheck()) { // should never happen
+ result = NULL;
+ goto cleanup;
}
cleanup:
{
- if (params_item.data)
+ if (params_item.data) {
env->ReleaseByteArrayElements(encodedParams,
(jbyte *) params_item.data, JNI_ABORT);
-
- if (ecparams)
+ }
+ if (ecparams) {
FreeECParams(ecparams, true);
-
+ }
if (privKey) {
FreeECParams(&privKey->ecParams, false);
SECITEM_FreeItem(&privKey->version, B_FALSE);
- // Don't free privKey->privateValue and privKey->publicValue
+ SECITEM_FreeItem(&privKey->privateValue, B_FALSE);
+ SECITEM_FreeItem(&privKey->publicValue, B_FALSE);
+ free(privKey);
}
-
- if (pSeedBuffer)
+ if (pSeedBuffer) {
delete [] pSeedBuffer;
+ }
}
return result;
}
/*
- * Class: sun_security_ec_ECKeyPairGenerator
- * Method: getEncodedBytes
- * Signature: (J)[B
- */
-JNIEXPORT jbyteArray
-JNICALL Java_sun_security_ec_ECKeyPairGenerator_getEncodedBytes
- (JNIEnv *env, jclass clazz, jlong hSECItem)
-{
- SECItem *s = (SECItem *)hSECItem;
- jbyteArray jEncodedBytes = env->NewByteArray(s->len);
-
- // Copy bytes from a native SECItem buffer to Java byte array
- env->SetByteArrayRegion(jEncodedBytes, 0, s->len, (jbyte *)s->data);
-
- // Use B_FALSE to free only the SECItem->data
- SECITEM_FreeItem(s, B_FALSE);
-
- return jEncodedBytes;
-}
-
-/*
* Class: sun_security_ec_ECDSASignature
* Method: signDigest
* Signature: ([B[B[B[B)[B
@@ -234,21 +252,26 @@
cleanup:
{
- if (params_item.data)
+ if (params_item.data) {
env->ReleaseByteArrayElements(encodedParams,
(jbyte *) params_item.data, JNI_ABORT);
-
- if (pDigestBuffer)
+ }
+ if (privKey.privateValue.data) {
+ env->ReleaseByteArrayElements(privateKey,
+ (jbyte *) privKey.privateValue.data, JNI_ABORT);
+ }
+ if (pDigestBuffer) {
delete [] pDigestBuffer;
-
- if (pSignedDigestBuffer)
+ }
+ if (pSignedDigestBuffer) {
delete [] pSignedDigestBuffer;
-
- if (pSeedBuffer)
+ }
+ if (pSeedBuffer) {
delete [] pSeedBuffer;
-
- if (ecparams)
+ }
+ if (ecparams) {
FreeECParams(ecparams, true);
+ }
}
return jSignedDigest;
diff --git a/src/windows/bin/java_md.c b/src/windows/bin/java_md.c
index 4078ecc..d517e92 100644
--- a/src/windows/bin/java_md.c
+++ b/src/windows/bin/java_md.c
@@ -1301,6 +1301,14 @@
/* save path length */
jrePathLen = JLI_StrLen(libraryPath);
+ if (jrePathLen + JLI_StrLen("\\bin\\verify.dll") >= MAXPATHLEN) {
+ /* jre path is too long, the library path will not fit there;
+ * report and abort preloading
+ */
+ JLI_ReportErrorMessage(JRE_ERROR11);
+ break;
+ }
+
/* load msvcrt 1st */
LoadMSVCRT();
diff --git a/src/windows/classes/sun/awt/shell/Win32ShellFolder2.java b/src/windows/classes/sun/awt/shell/Win32ShellFolder2.java
index 765a9b4..0070bd4 100644
--- a/src/windows/classes/sun/awt/shell/Win32ShellFolder2.java
+++ b/src/windows/classes/sun/awt/shell/Win32ShellFolder2.java
@@ -583,11 +583,18 @@
// Needs to be accessible to Win32ShellFolderManager2
static String getFileSystemPath(final int csidl) throws IOException, InterruptedException {
- return invoke(new Callable<String>() {
+ String path = invoke(new Callable<String>() {
public String call() throws IOException {
return getFileSystemPath0(csidl);
}
}, IOException.class);
+ if (path != null) {
+ SecurityManager security = System.getSecurityManager();
+ if (security != null) {
+ security.checkRead(path);
+ }
+ }
+ return path;
}
// NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
diff --git a/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java b/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java
index c89eccd..7514454 100644
--- a/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java
+++ b/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java
@@ -142,6 +142,8 @@
if (desktop == null) {
try {
desktop = new Win32ShellFolder2(DESKTOP);
+ } catch (SecurityException e) {
+ // Ignore error
} catch (IOException e) {
// Ignore error
} catch (InterruptedException e) {
@@ -155,6 +157,8 @@
if (drives == null) {
try {
drives = new Win32ShellFolder2(DRIVES);
+ } catch (SecurityException e) {
+ // Ignore error
} catch (IOException e) {
// Ignore error
} catch (InterruptedException e) {
@@ -171,6 +175,8 @@
if (path != null) {
recent = createShellFolder(getDesktop(), new File(path));
}
+ } catch (SecurityException e) {
+ // Ignore error
} catch (InterruptedException e) {
// Ignore error
} catch (IOException e) {
@@ -184,6 +190,8 @@
if (network == null) {
try {
network = new Win32ShellFolder2(NETWORK);
+ } catch (SecurityException e) {
+ // Ignore error
} catch (IOException e) {
// Ignore error
} catch (InterruptedException e) {
@@ -207,6 +215,8 @@
personal.setIsPersonal();
}
}
+ } catch (SecurityException e) {
+ // Ignore error
} catch (InterruptedException e) {
// Ignore error
} catch (IOException e) {
diff --git a/src/windows/classes/sun/awt/windows/WToolkit.java b/src/windows/classes/sun/awt/windows/WToolkit.java
index 188c60c..7d9392a 100644
--- a/src/windows/classes/sun/awt/windows/WToolkit.java
+++ b/src/windows/classes/sun/awt/windows/WToolkit.java
@@ -866,11 +866,7 @@
* Windows doesn't always send WM_SETTINGCHANGE when it should.
*/
private void windowsSettingChange() {
- EventQueue.invokeLater(new Runnable() {
- public void run() {
- updateProperties();
- }
- });
+ updateProperties();
}
private synchronized void updateProperties() {
diff --git a/test/java/awt/DataFlavor/MissedHtmlAndRtfBug/InterprocessMessages.java b/test/java/awt/DataFlavor/MissedHtmlAndRtfBug/InterprocessMessages.java
index d66982d..587db43 100644
--- a/test/java/awt/DataFlavor/MissedHtmlAndRtfBug/InterprocessMessages.java
+++ b/test/java/awt/DataFlavor/MissedHtmlAndRtfBug/InterprocessMessages.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, 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
@@ -24,5 +24,6 @@
interface InterprocessMessages {
final static int EXECUTION_IS_SUCCESSFULL = 0;
final static int DATA_IS_CORRUPTED = 212;
+ final static int NO_DROP_HAPPENED = 112;
}
diff --git a/test/java/awt/DataFlavor/MissedHtmlAndRtfBug/MissedHtmlAndRtfBug.html b/test/java/awt/DataFlavor/MissedHtmlAndRtfBug/MissedHtmlAndRtfBug.html
index af168b4..7f2a48d 100644
--- a/test/java/awt/DataFlavor/MissedHtmlAndRtfBug/MissedHtmlAndRtfBug.html
+++ b/test/java/awt/DataFlavor/MissedHtmlAndRtfBug/MissedHtmlAndRtfBug.html
@@ -1,5 +1,5 @@
<!--
- Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2013, 2014, 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
@@ -24,7 +24,7 @@
<html>
<!--
@test
- @bug 8005932
+ @bug 8005932 8017456
@summary Java 7 on mac os x only provides text clipboard formats
@author mikhail.cherkasov@oracle.com
@library ../../regtesthelpers
diff --git a/test/java/awt/DataFlavor/MissedHtmlAndRtfBug/MissedHtmlAndRtfBug.java b/test/java/awt/DataFlavor/MissedHtmlAndRtfBug/MissedHtmlAndRtfBug.java
index 598426f..4c303cc 100644
--- a/test/java/awt/DataFlavor/MissedHtmlAndRtfBug/MissedHtmlAndRtfBug.java
+++ b/test/java/awt/DataFlavor/MissedHtmlAndRtfBug/MissedHtmlAndRtfBug.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, 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
@@ -21,17 +21,6 @@
* questions.
*/
-/*
- @bug 8005932
- @summary Java 7 on mac os x only provides text clipboard formats
- @author mikhail.cherkasov@oracle.com
- @library ../../regtesthelpers
- @library ../../regtesthelpers/process
- @build Util
- @build ProcessResults ProcessCommunicator
- @run applet/othervm MissedHtmlAndRtfBug.html
-*/
-
import java.awt.*;
import java.awt.datatransfer.DataFlavor;
import java.awt.event.*;
@@ -47,6 +36,7 @@
import static java.lang.Thread.sleep;
public class MissedHtmlAndRtfBug extends Applet {
+
public void init() {
setLayout(new BorderLayout());
}//End init()
@@ -82,9 +72,6 @@
args.add(concatStrings(DataFlavorSearcher.RICH_TEXT_NAMES));
ProcessResults processResults =
-// ProcessCommunicator.executeChildProcess(this.getClass(), "/Users/mcherkasov/ws/clipboard/DataFlover/out/production/DataFlover" +
-// " -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005 ",
-// args.toArray(new String[0]));
ProcessCommunicator.executeChildProcess(this.getClass(),
"." + File.separator + System.getProperty("java.class.path"), args.toArray(new String[]{}));
@@ -117,6 +104,13 @@
throw new RuntimeException("TEST IS FAILED: Target has received" +
" corrupted data.");
}
+ if (InterprocessMessages.NO_DROP_HAPPENED ==
+ processResults.getExitValue()) {
+ processResults.printProcessErrorOutput(System.err);
+ throw new RuntimeException("Error. Drop did not happen." +
+ " Target frame is possibly covered by a window of other application." +
+ " Please, rerun the test with all windows minimized.");
+ }
processResults.verifyStdErr(System.err);
processResults.verifyProcessExitValue(System.err);
processResults.printProcessStandartOutput(System.out);
@@ -184,7 +178,7 @@
}
}
- public static void main(String[] args) {
+ public static void main(String[] args) throws InterruptedException {
Point dragSourcePoint = new Point(InterprocessArguments.DRAG_SOURCE_POINT_X_ARGUMENT.extractInt(args),
InterprocessArguments.DRAG_SOURCE_POINT_Y_ARGUMENT.extractInt(args));
Point targetFrameLocation = new Point(InterprocessArguments.TARGET_FRAME_X_POSITION_ARGUMENT.extractInt(args),
@@ -197,6 +191,8 @@
} catch (InterruptedException e) {
e.printStackTrace();
}
+ sleep(5000);
+ System.exit(InterprocessMessages.NO_DROP_HAPPENED);
}
diff --git a/test/java/awt/Toolkit/ToolkitPropertyTest/NoAppContextTest.java b/test/java/awt/Toolkit/ToolkitPropertyTest/NoAppContextTest.java
new file mode 100644
index 0000000..f5956e1
--- /dev/null
+++ b/test/java/awt/Toolkit/ToolkitPropertyTest/NoAppContextTest.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2014, 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 8032960
+ * @summary checks that desktop properties work if Toolkit thread has no AppContext
+ * @author Petr Pchelko
+ */
+
+import sun.awt.OSInfo;
+import sun.awt.SunToolkit;
+
+import javax.swing.*;
+import java.awt.*;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
+
+public class NoAppContextTest {
+
+ private static final ThreadGroup stubGroup = new ThreadGroup("stub");
+ private static final ThreadGroup awtGroup = new ThreadGroup("AWT");
+ private static final AtomicBoolean propertyChangeFired = new AtomicBoolean(false);
+ private static Frame frame;
+
+ private static final Object LOCK = new Object();
+
+ public static void main(String[] args) throws Exception {
+
+ if (OSInfo.getOSType() != OSInfo.OSType.WINDOWS) {
+ // The test is for Windows platform only
+ return;
+ }
+
+ createStubContext();
+
+ Thread awtThread = new Thread(awtGroup, () -> {
+ SunToolkit.createNewAppContext();
+ SwingUtilities.invokeLater(() -> {
+ synchronized (LOCK) {
+ frame = new Frame();
+ frame.setBounds(100, 100, 100, 100);
+ frame.setVisible(true);
+ Toolkit.getDefaultToolkit().addPropertyChangeListener("win.propNames", ev -> {
+ propertyChangeFired.set(true);
+ });
+ }
+ });
+ });
+ awtThread.start();
+ awtThread.join();
+ sync();
+
+ final GraphicsDevice device = GraphicsEnvironment.getLocalGraphicsEnvironment()
+ .getDefaultScreenDevice();
+
+ AtomicReference<DisplayMode> originalRef = new AtomicReference<>();
+ try {
+ AtomicBoolean isSupported = new AtomicBoolean(true);
+ invokeInAWT(() -> {
+ if (device.isFullScreenSupported()) {
+ device.setFullScreenWindow(frame);
+ } else {
+ isSupported.set(false);
+ }
+ });
+ if (!isSupported.get()) {
+ return;
+ }
+ invokeInAWT(() -> {
+ if (device.isDisplayChangeSupported()) {
+ DisplayMode original = device.getDisplayMode();
+ originalRef.set(original);
+ try {
+ DisplayMode[] modes = device.getDisplayModes();
+ for (DisplayMode mode : modes) {
+ if (!mode.equals(original)) {
+ device.setDisplayMode(mode);
+ break;
+ }
+ }
+ } finally {
+ device.setDisplayMode(original);
+ }
+ } else {
+ isSupported.set(false);
+ }
+ });
+ if (!isSupported.get()) {
+ return;
+ }
+ } finally {
+ invokeInAWT(() -> {
+ device.setDisplayMode(originalRef.get());
+ frame.dispose();
+ });
+ }
+
+ if (!propertyChangeFired.get()) {
+ throw new RuntimeException("Failed: PropertyChange did not fire");
+ }
+ }
+
+ private static void invokeInAWT(Runnable r) throws InterruptedException {
+ Thread awtThread = new Thread(awtGroup, () -> {
+ SwingUtilities.invokeLater(() -> {
+ synchronized (LOCK) {
+ r.run();
+ }
+ });
+ });
+ awtThread.start();
+ awtThread.join();
+ sync();
+ }
+
+ private static void createStubContext() throws InterruptedException {
+ Thread stub = new Thread(stubGroup, SunToolkit::createNewAppContext);
+ stub.start();
+ stub.join();
+ }
+
+ /**
+ * Runs realSync on a thread with an AppContext and waits for it to finish
+ */
+ private static void sync() throws InterruptedException {
+ final AtomicReference<InterruptedException> exc = new AtomicReference<>(null);
+
+ Thread syncThread = new Thread(awtGroup, () -> {
+ try {
+ ((SunToolkit) Toolkit.getDefaultToolkit()).realSync();
+ Thread.sleep(2000);
+ } catch (InterruptedException e) {
+ exc.set(e);
+ }
+ });
+ syncThread.start();
+ syncThread.join();
+ if (exc.get() != null) {
+ throw exc.get();
+ }
+ }
+}
+
diff --git a/test/java/lang/invoke/lambda/LambdaReceiver.java b/test/java/lang/invoke/lambda/LambdaReceiver.java
new file mode 100644
index 0000000..8e24379
--- /dev/null
+++ b/test/java/lang/invoke/lambda/LambdaReceiver.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2014, 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 8035776
+ * @summary Consistent Lambda construction
+ */
+
+import java.lang.invoke.CallSite;
+import java.lang.invoke.LambdaMetafactory;
+import java.lang.invoke.LambdaConversionException;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.ArrayList;
+import java.util.List;
+
+import LambdaReceiver_anotherpkg.LambdaReceiver_A;
+
+public class LambdaReceiver extends LambdaReceiver_A {
+
+ interface IA {
+ int m(LambdaReceiver_A x);
+ }
+
+ static MethodHandles.Lookup l;
+ static MethodHandle h;
+ private static MethodType mt(Class<?> k) { return MethodType.methodType(k); }
+ private static MethodType mt(Class<?> k, Class<?> k2) { return MethodType.methodType(k, k2); }
+ private static void mf(List<String> errs, MethodType mts, MethodType mtf, boolean shouldWork) {
+ }
+
+ public static void main(String[] args) throws Throwable {
+ l = MethodHandles.lookup();
+ h = l.findVirtual(LambdaReceiver_A.class, "f", mt(int.class));
+ MethodType X = mt(int.class, LambdaReceiver.class);
+ MethodType A = mt(int.class, LambdaReceiver_A.class);
+ MethodType mti = mt(IA.class);
+ CallSite cs = LambdaMetafactory.metafactory(l, "m", mti,A,h,X);
+ IA p = (IA)cs.dynamicInvoker().invoke();
+ LambdaReceiver_A lra = new LambdaReceiver_A();
+ try {
+ p.m(lra);
+ } catch (ClassCastException cce) {
+ return;
+ }
+ throw new AssertionError("CCE expected");
+ }
+}
diff --git a/test/java/lang/invoke/lambda/LambdaReceiverBridge.java b/test/java/lang/invoke/lambda/LambdaReceiverBridge.java
new file mode 100644
index 0000000..b1f3b85
--- /dev/null
+++ b/test/java/lang/invoke/lambda/LambdaReceiverBridge.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2014, 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 8035776
+ * @summary Consistent Lambda construction
+ */
+
+import java.lang.invoke.CallSite;
+import java.lang.invoke.LambdaMetafactory;
+import java.lang.invoke.LambdaConversionException;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.ArrayList;
+import java.util.List;
+
+import LambdaReceiver_anotherpkg.LambdaReceiver_A;
+
+public class LambdaReceiverBridge extends LambdaReceiver_A {
+
+ interface IA {
+ int m(LambdaReceiver_A x);
+ }
+
+ static MethodHandles.Lookup l;
+ static MethodHandle h;
+ private static MethodType mt(Class<?> k) { return MethodType.methodType(k); }
+ private static MethodType mt(Class<?> k, Class<?> k2) { return MethodType.methodType(k, k2); }
+ private static void mf(List<String> errs, MethodType mts, MethodType mtf, boolean shouldWork) {
+ }
+
+ public static void main(String[] args) throws Throwable {
+ l = MethodHandles.lookup();
+ h = l.findVirtual(LambdaReceiver_A.class, "f", mt(int.class));
+ MethodType X = mt(int.class, LambdaReceiverBridge.class);
+ MethodType A = mt(int.class, LambdaReceiver_A.class);
+ MethodType mti = mt(IA.class);
+ CallSite cs = LambdaMetafactory.altMetafactory(l, "m", mti,X,h,X,
+ LambdaMetafactory.FLAG_BRIDGES, 1, A);
+ IA p = (IA)cs.dynamicInvoker().invoke();
+ LambdaReceiver_A lra = new LambdaReceiver_A();
+ try {
+ p.m(lra);
+ } catch (ClassCastException cce) {
+ return;
+ }
+ throw new AssertionError("CCE expected");
+ }
+}
diff --git a/test/java/lang/invoke/lambda/LambdaReceiver_anotherpkg/LambdaReceiver_A.java b/test/java/lang/invoke/lambda/LambdaReceiver_anotherpkg/LambdaReceiver_A.java
new file mode 100644
index 0000000..e4d1c98
--- /dev/null
+++ b/test/java/lang/invoke/lambda/LambdaReceiver_anotherpkg/LambdaReceiver_A.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2014, 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.
+ */
+
+package LambdaReceiver_anotherpkg;
+
+public class LambdaReceiver_A {
+ protected final int f() { return 2; }
+}
diff --git a/test/java/lang/invoke/lambda/LambdaReturn.java b/test/java/lang/invoke/lambda/LambdaReturn.java
new file mode 100644
index 0000000..27a02f0
--- /dev/null
+++ b/test/java/lang/invoke/lambda/LambdaReturn.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2014, 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 8035776
+ * @summary Consistent Lambda construction
+ */
+
+import java.lang.invoke.LambdaMetafactory;
+import java.lang.invoke.LambdaConversionException;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.ArrayList;
+import java.util.List;
+
+public class LambdaReturn {
+
+ interface I {
+ void m();
+ }
+
+ static void hereV() {}
+ static String hereS() { return "hi"; }
+ static MethodHandles.Lookup l;
+ private static MethodType mt(Class<?> k) { return MethodType.methodType(k); }
+ private static MethodType mt(Class<?> k, Class<?> k2) { return MethodType.methodType(k, k2); }
+ private static void amf(List<String> errs, MethodHandle h, MethodType mts, MethodType mtf, MethodType mtb, boolean shouldWork) {
+ MethodType mti = mt(I.class);
+ try {
+ LambdaMetafactory.altMetafactory(l, "m", mti, mts,h,mtf,
+ LambdaMetafactory.FLAG_BRIDGES, 1, mtb);
+ } catch(LambdaConversionException e) {
+ if (shouldWork) errs.add("Error: Should work h=" + h + " s=" + mts + " -- f=" + mtf + " / b=" + mtb + " got: " + e);
+ return;
+ }
+ if (!shouldWork) errs.add("Error: Should fail h=" + h + " s=" + mts + " -- f=" + mtf + " / b=" + mtb);
+ }
+
+ public static void main(String[] args) throws Throwable {
+ l = MethodHandles.lookup();
+ MethodHandle hV = l.findStatic(LambdaReturn.class, "hereV", mt(void.class));
+ MethodHandle hS = l.findStatic(LambdaReturn.class, "hereS", mt(String.class));
+ List<String> errs = new ArrayList<>();
+ MethodType V = mt(void.class);
+ MethodType S = mt(String.class);
+ MethodType O = mt(Object.class);
+ MethodType I = mt(int.class);
+ amf(errs, hS, S, S, O, true);
+ amf(errs, hS, S, S, V, false);
+ amf(errs, hS, S, S, I, false);
+ amf(errs, hS, O, S, S, true);
+ amf(errs, hS, V, S, S, false);
+ amf(errs, hS, I, S, S, false);
+ amf(errs, hS, O, O, S, false);
+ amf(errs, hS, S, O, O, false);
+ amf(errs, hV, V, V, O, false);
+ amf(errs, hV, V, V, I, false);
+ amf(errs, hV, V, V, S, false);
+ amf(errs, hV, O, V, V, false);
+ amf(errs, hV, I, V, V, false);
+ amf(errs, hV, S, V, V, false);
+
+ if (errs.size() > 0) {
+ for (String err : errs) {
+ System.err.println(err);
+ }
+ throw new AssertionError("Errors: " + errs.size());
+ }
+ }
+}
diff --git a/test/java/lang/invoke/lambda/MetafactoryArityTest.java b/test/java/lang/invoke/lambda/MetafactoryArityTest.java
new file mode 100644
index 0000000..568abba
--- /dev/null
+++ b/test/java/lang/invoke/lambda/MetafactoryArityTest.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2014, 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 8035776
+ * @summary metafactory should fail if arities are mismatched
+ */
+import java.lang.invoke.*;
+import java.util.Arrays;
+import static java.lang.invoke.MethodType.methodType;
+
+public class MetafactoryArityTest {
+
+ public interface I {}
+ public static class C { public static String m(int arg) { return ""; } }
+
+ static final MethodHandles.Lookup lookup = MethodHandles.lookup();
+ static final Class<?>[] capInt = { int.class };
+ static final MethodHandle C_m;
+ static {
+ try { C_m = lookup.findStatic(C.class, "m", methodType(String.class, int.class)); }
+ catch (NoSuchMethodException | IllegalAccessException e) { throw new RuntimeException(e); }
+ }
+
+ public static void main(String... args) {
+ MethodType unary = methodType(String.class, int.class);
+ MethodType nullary = methodType(String.class);
+ MethodType binary = methodType(String.class, int.class, int.class);
+ MethodType unaryCS = methodType(CharSequence.class, int.class);
+ MethodType nullaryCS = methodType(CharSequence.class);
+ MethodType binaryCS = methodType(CharSequence.class, int.class, int.class);
+ MethodType unaryObj = methodType(Object.class, int.class);
+ MethodType nullaryObj = methodType(Object.class);
+ MethodType binaryObj = methodType(Object.class, int.class, int.class);
+
+ test(true, C_m, unary, unary);
+ test(false, C_m, unary, nullary);
+ test(false, C_m, nullary, unary);
+ test(false, C_m, unary, binary);
+ test(false, C_m, binary, unary);
+
+ testBridge(true, C_m, unary, unary, unaryCS);
+ testBridge(false, C_m, unary, unary, nullaryCS);
+ testBridge(false, C_m, unary, unary, binaryCS);
+
+ testBridge(true, C_m, unary, unary, unaryCS, unaryObj);
+ testBridge(false, C_m, unary, unary, unaryCS, nullaryObj);
+ testBridge(false, C_m, unary, unary, unaryCS, binaryObj);
+
+ testCapture(true, C_m, capInt, nullary, nullary);
+ testCapture(false, C_m, capInt, binary, binary);
+ testCapture(false, C_m, capInt, nullary, unary);
+ testCapture(false, C_m, capInt, nullary, binary);
+ testCapture(false, C_m, capInt, unary, nullary);
+ testCapture(false, C_m, capInt, unary, binary);
+
+ testCaptureBridge(true, C_m, capInt, nullary, nullary, nullaryCS);
+ testCaptureBridge(false, C_m, capInt, unary, unary, unaryCS);
+ testCaptureBridge(false, C_m, capInt, nullary, nullary, unaryCS);
+ testCaptureBridge(false, C_m, capInt, nullary, nullary, binaryCS);
+
+ testCaptureBridge(true, C_m, capInt, nullary, nullary, nullaryCS, nullaryObj);
+ testCaptureBridge(false, C_m, capInt, unary, unary, unaryCS, unaryObj);
+ testCaptureBridge(false, C_m, capInt, nullary, nullary, nullaryCS, unaryObj);
+ testCaptureBridge(false, C_m, capInt, nullary, nullary, nullaryCS, binaryObj);
+ }
+
+ static void test(boolean correct, MethodHandle mh, MethodType instMT, MethodType samMT) {
+ tryMetafactory(correct, mh, new Class<?>[]{}, instMT, samMT);
+ tryAltMetafactory(correct, mh, new Class<?>[]{}, instMT, samMT);
+ }
+
+ static void testBridge(boolean correct, MethodHandle mh, MethodType instMT, MethodType samMT, MethodType... bridgeMTs) {
+ tryAltMetafactory(correct, mh, new Class<?>[]{}, instMT, samMT, bridgeMTs);
+ }
+
+ static void testCapture(boolean correct, MethodHandle mh, Class<?>[] captured, MethodType instMT, MethodType samMT) {
+ tryMetafactory(correct, mh, captured, instMT, samMT);
+ tryAltMetafactory(correct, mh, captured, instMT, samMT);
+ }
+
+ static void testCaptureBridge(boolean correct, MethodHandle mh, Class<?>[] captured,
+ MethodType instMT, MethodType samMT, MethodType... bridgeMTs) {
+ tryAltMetafactory(correct, mh, captured, instMT, samMT, bridgeMTs);
+ }
+
+ static void tryMetafactory(boolean correct, MethodHandle mh, Class<?>[] captured,
+ MethodType instMT, MethodType samMT) {
+ try {
+ LambdaMetafactory.metafactory(lookup, "run", methodType(I.class, captured),
+ samMT, mh, instMT);
+ if (!correct) {
+ throw new AssertionError("Uncaught linkage error:" +
+ " impl=" + mh +
+ ", captured=" + Arrays.toString(captured) +
+ ", inst=" + instMT +
+ ", sam=" + samMT);
+ }
+ }
+ catch (LambdaConversionException e) {
+ if (correct) {
+ throw new AssertionError("Unexpected linkage error:" +
+ " e=" + e +
+ ", impl=" + mh +
+ ", captured=" + Arrays.toString(captured) +
+ ", inst=" + instMT +
+ ", sam=" + samMT);
+ }
+ }
+ }
+
+ static void tryAltMetafactory(boolean correct, MethodHandle mh, Class<?>[] captured,
+ MethodType instMT, MethodType samMT, MethodType... bridgeMTs) {
+ boolean bridge = bridgeMTs.length > 0;
+ Object[] args = new Object[bridge ? 5+bridgeMTs.length : 4];
+ args[0] = samMT;
+ args[1] = mh;
+ args[2] = instMT;
+ args[3] = bridge ? LambdaMetafactory.FLAG_BRIDGES : 0;
+ if (bridge) {
+ args[4] = bridgeMTs.length;
+ for (int i = 0; i < bridgeMTs.length; i++) args[5+i] = bridgeMTs[i];
+ }
+ try {
+ LambdaMetafactory.altMetafactory(lookup, "run", methodType(I.class, captured), args);
+ if (!correct) {
+ throw new AssertionError("Uncaught linkage error:" +
+ " impl=" + mh +
+ ", captured=" + Arrays.toString(captured) +
+ ", inst=" + instMT +
+ ", sam=" + samMT +
+ ", bridges=" + Arrays.toString(bridgeMTs));
+ }
+ }
+ catch (LambdaConversionException e) {
+ if (correct) {
+ throw new AssertionError("Unexpected linkage error:" +
+ " e=" + e +
+ ", impl=" + mh +
+ ", captured=" + Arrays.toString(captured) +
+ ", inst=" + instMT +
+ ", sam=" + samMT +
+ ", bridges=" + Arrays.toString(bridgeMTs));
+ }
+ }
+ }
+
+}
diff --git a/test/java/lang/invoke/lambda/MetafactoryParameterCastTest.java b/test/java/lang/invoke/lambda/MetafactoryParameterCastTest.java
new file mode 100644
index 0000000..70a65e5
--- /dev/null
+++ b/test/java/lang/invoke/lambda/MetafactoryParameterCastTest.java
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2014, 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 8035776
+ * @summary Ensure that invocation parameters are always cast to the instantiatedMethodType
+ */
+import java.lang.invoke.*;
+import java.util.Arrays;
+import static java.lang.invoke.MethodType.methodType;
+
+public class MetafactoryParameterCastTest {
+
+ static final MethodHandles.Lookup lookup = MethodHandles.lookup();
+
+ public static class A {
+ }
+
+ public static class B extends A {
+ void instance0() {}
+ void instance1(B arg) {}
+ static void static1(B arg) {}
+ static void static2(B arg1, B arg2) {}
+ }
+
+ public static class C extends B {}
+ public static class NotC extends B {}
+
+ public interface ASink { void take(A arg); }
+ public interface BSink { void take(B arg); }
+
+ public static void main(String... args) throws Throwable {
+ new MetafactoryParameterCastTest().test();
+ }
+
+ void test() throws Throwable {
+ MethodType takeA = methodType(void.class, A.class);
+ MethodType takeB = methodType(void.class, B.class);
+ MethodType takeC = methodType(void.class, C.class);
+
+ Class<?>[] noCapture = {};
+ Class<?>[] captureB = { B.class };
+
+ MethodHandle[] oneBParam = { lookup.findVirtual(B.class, "instance0", methodType(void.class)),
+ lookup.findStatic(B.class, "static1", methodType(void.class, B.class)) };
+ MethodHandle[] twoBParams = { lookup.findVirtual(B.class, "instance1", methodType(void.class, B.class)),
+ lookup.findStatic(B.class, "static2", methodType(void.class, B.class, B.class)) };
+
+ for (MethodHandle mh : oneBParam) {
+ // sam
+ tryASink(invokeMetafactory(mh, ASink.class, "take", noCapture, takeC, takeA));
+ tryBSink(invokeMetafactory(mh, BSink.class, "take", noCapture, takeC, takeB));
+ tryASink(invokeAltMetafactory(mh, ASink.class, "take", noCapture, takeC, takeA));
+ tryBSink(invokeAltMetafactory(mh, BSink.class, "take", noCapture, takeC, takeB));
+
+ // bridge
+ tryASink(invokeAltMetafactory(mh, ASink.class, "take", noCapture, takeC, takeC, takeA));
+ tryBSink(invokeAltMetafactory(mh, BSink.class, "take", noCapture, takeC, takeC, takeB));
+ }
+
+ for (MethodHandle mh : twoBParams) {
+ // sam
+ tryCapASink(invokeMetafactory(mh, ASink.class, "take", captureB, takeC, takeA));
+ tryCapBSink(invokeMetafactory(mh, BSink.class, "take", captureB, takeC, takeB));
+ tryCapASink(invokeAltMetafactory(mh, ASink.class, "take", captureB, takeC, takeA));
+ tryCapBSink(invokeAltMetafactory(mh, BSink.class, "take", captureB, takeC, takeB));
+
+ // bridge
+ tryCapASink(invokeAltMetafactory(mh, ASink.class, "take", captureB, takeC, takeC, takeA));
+ tryCapBSink(invokeAltMetafactory(mh, BSink.class, "take", captureB, takeC, takeC, takeB));
+ }
+ }
+
+ void tryASink(CallSite cs) throws Throwable {
+ ASink sink = (ASink) cs.dynamicInvoker().invoke();
+ tryASink(sink);
+ }
+
+ void tryCapASink(CallSite cs) throws Throwable {
+ ASink sink = (ASink) cs.dynamicInvoker().invoke(new B());
+ tryASink(sink);
+ }
+
+ void tryBSink(CallSite cs) throws Throwable {
+ BSink sink = (BSink) cs.dynamicInvoker().invoke();
+ tryBSink(sink);
+ }
+
+ void tryCapBSink(CallSite cs) throws Throwable {
+ BSink sink = (BSink) cs.dynamicInvoker().invoke(new B());
+ tryBSink(sink);
+ }
+
+ void tryASink(ASink sink) {
+ try { sink.take(new C()); }
+ catch (ClassCastException e) {
+ throw new AssertionError("Unexpected cast failure: " + e + " " + lastMFParams());
+ }
+
+ try {
+ sink.take(new B());
+ throw new AssertionError("Missing cast from A to C: " + lastMFParams());
+ }
+ catch (ClassCastException e) { /* expected */ }
+
+ try {
+ sink.take(new NotC());
+ throw new AssertionError("Missing cast from A to C: " + lastMFParams());
+ }
+ catch (ClassCastException e) { /* expected */ }
+ }
+
+ void tryBSink(BSink sink) {
+ try { sink.take(new C()); }
+ catch (ClassCastException e) {
+ throw new AssertionError("Unexpected cast failure: " + e + " " + lastMFParams());
+ }
+
+ try {
+ sink.take(new B());
+ throw new AssertionError("Missing cast from B to C: " + lastMFParams());
+ }
+ catch (ClassCastException e) { /* expected */ }
+
+ try {
+ sink.take(new NotC());
+ throw new AssertionError("Missing cast from B to C: " + lastMFParams());
+ }
+ catch (ClassCastException e) { /* expected */ }
+ }
+
+ MethodHandle lastMH;
+ Class<?>[] lastCaptured;
+ MethodType lastInstMT;
+ MethodType lastSamMT;
+ MethodType[] lastBridgeMTs;
+
+ String lastMFParams() {
+ return "mh=" + lastMH +
+ ", captured=" + Arrays.toString(lastCaptured) +
+ ", instMT=" + lastInstMT +
+ ", samMT=" + lastSamMT +
+ ", bridgeMTs=" + Arrays.toString(lastBridgeMTs);
+ }
+
+ CallSite invokeMetafactory(MethodHandle mh, Class<?> sam, String methodName,
+ Class<?>[] captured, MethodType instMT, MethodType samMT) {
+ lastMH = mh;
+ lastCaptured = captured;
+ lastInstMT = instMT;
+ lastSamMT = samMT;
+ lastBridgeMTs = new MethodType[]{};
+ try {
+ return LambdaMetafactory.metafactory(lookup, methodName, methodType(sam, captured),
+ samMT, mh, instMT);
+ }
+ catch (LambdaConversionException e) {
+ // unexpected linkage error
+ throw new RuntimeException(e);
+ }
+ }
+
+ CallSite invokeAltMetafactory(MethodHandle mh, Class<?> sam, String methodName,
+ Class<?>[] captured, MethodType instMT,
+ MethodType samMT, MethodType... bridgeMTs) {
+ lastMH = mh;
+ lastCaptured = captured;
+ lastInstMT = instMT;
+ lastSamMT = samMT;
+ lastBridgeMTs = bridgeMTs;
+ try {
+ boolean bridge = bridgeMTs.length > 0;
+ Object[] args = new Object[bridge ? 5+bridgeMTs.length : 4];
+ args[0] = samMT;
+ args[1] = mh;
+ args[2] = instMT;
+ args[3] = bridge ? LambdaMetafactory.FLAG_BRIDGES : 0;
+ if (bridge) {
+ args[4] = bridgeMTs.length;
+ for (int i = 0; i < bridgeMTs.length; i++) args[5+i] = bridgeMTs[i];
+ }
+ return LambdaMetafactory.altMetafactory(lookup, methodName, methodType(sam, captured), args);
+ }
+ catch (LambdaConversionException e) {
+ // unexpected linkage error
+ throw new RuntimeException(e);
+ }
+ }
+
+}
diff --git a/test/java/lang/invoke/lambda/MetafactorySamReturnTest.java b/test/java/lang/invoke/lambda/MetafactorySamReturnTest.java
new file mode 100644
index 0000000..4caf262
--- /dev/null
+++ b/test/java/lang/invoke/lambda/MetafactorySamReturnTest.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2014, 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 8035776
+ * @summary metafactory should fail if impl return does not match sam/bridge returns
+ */
+import java.lang.invoke.*;
+import java.util.Arrays;
+import static java.lang.invoke.MethodType.methodType;
+
+public class MetafactorySamReturnTest {
+
+ static final MethodHandles.Lookup lookup = MethodHandles.lookup();
+
+ public interface I {}
+
+ public static class C {
+ public static void m_void(String arg) {}
+ public static boolean m_boolean(String arg) { return true; }
+ public static char m_char(String arg) { return 'x'; }
+ public static byte m_byte(String arg) { return 12; }
+ public static short m_short(String arg) { return 12; }
+ public static int m_int(String arg) { return 12; }
+ public static long m_long(String arg) { return 12; }
+ public static float m_float(String arg) { return 12; }
+ public static double m_double(String arg) { return 12; }
+ public static String m_String(String arg) { return ""; }
+ public static Integer m_Integer(String arg) { return 23; }
+ public static Object m_Object(String arg) { return new Object(); }
+
+ public static MethodHandle getMH(Class<?> c) {
+ try {
+ return lookup.findStatic(C.class, "m_" + c.getSimpleName(), methodType(c, String.class));
+ }
+ catch (NoSuchMethodException | IllegalAccessException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ public static void main(String... args) {
+ Class<?>[] t = { void.class, boolean.class, char.class,
+ byte.class, short.class, int.class, long.class, float.class, double.class,
+ String.class, Integer.class, Object.class };
+
+ for (int i = 0; i < t.length; i++) {
+ MethodHandle mh = C.getMH(t[i]);
+ for (int j = 0; j < t.length; j++) {
+ // TEMPORARY EXCEPTIONS
+ if (t[j] == void.class) continue;
+ if (t[i].isPrimitive() && t[j] == Object.class) continue;
+ if (t[i] == char.class && (t[j] == int.class || t[j] == long.class || t[j] == float.class || t[j] == double.class)) continue;
+ if (t[i] == byte.class && (t[j] == short.class || t[j] == int.class || t[j] == long.class || t[j] == float.class || t[j] == double.class)) continue;
+ if (t[i] == short.class && (t[j] == int.class || t[j] == long.class || t[j] == float.class || t[j] == double.class)) continue;
+ if (t[i] == int.class && (t[j] == long.class || t[j] == float.class || t[j] == double.class)) continue;
+ if (t[i] == long.class && (t[j] == float.class || t[j] == double.class)) continue;
+ if (t[i] == float.class && t[j] == double.class) continue;
+ if (t[i] == int.class && t[j] == Integer.class) continue;
+ if (t[i] == Integer.class && (t[j] == int.class || t[j] == long.class || t[j] == float.class || t[j] == double.class)) continue;
+ // END TEMPORARY EXCEPTIONS
+ boolean correct = (t[i].isPrimitive() || t[j].isPrimitive())
+ ? t[i] == t[j]
+ : t[j].isAssignableFrom(t[i]);
+ MethodType mti = methodType(t[i], String.class);
+ MethodType mtiCS = methodType(t[i], CharSequence.class);
+ MethodType mtj = methodType(t[j], String.class);
+ MethodType mtjObj = methodType(t[j], Object.class);
+ test(correct, mh, mti, mtj);
+ testBridge(correct, mh, mti, mti, mtjObj);
+ testBridge(correct, mh, mti, mti, mtiCS, mtjObj);
+ }
+ }
+ }
+
+ static void test(boolean correct, MethodHandle mh, MethodType instMT, MethodType samMT) {
+ tryMetafactory(correct, mh, new Class<?>[]{}, instMT, samMT);
+ tryAltMetafactory(correct, mh, new Class<?>[]{}, instMT, samMT);
+ }
+
+ static void testBridge(boolean correct, MethodHandle mh, MethodType instMT, MethodType samMT, MethodType... bridgeMTs) {
+ tryAltMetafactory(correct, mh, new Class<?>[]{}, instMT, samMT, bridgeMTs);
+ }
+
+ static void tryMetafactory(boolean correct, MethodHandle mh, Class<?>[] captured,
+ MethodType instMT, MethodType samMT) {
+ try {
+ LambdaMetafactory.metafactory(lookup, "run", methodType(I.class, captured),
+ samMT, mh, instMT);
+ if (!correct) {
+ throw new AssertionError("Uncaught linkage error:" +
+ " impl=" + mh +
+ ", captured=" + Arrays.toString(captured) +
+ ", inst=" + instMT +
+ ", sam=" + samMT);
+ }
+ }
+ catch (LambdaConversionException e) {
+ if (correct) {
+ throw new AssertionError("Unexpected linkage error:" +
+ " e=" + e +
+ ", impl=" + mh +
+ ", captured=" + Arrays.toString(captured) +
+ ", inst=" + instMT +
+ ", sam=" + samMT);
+ }
+ }
+ }
+
+ static void tryAltMetafactory(boolean correct, MethodHandle mh, Class<?>[] captured,
+ MethodType instMT, MethodType samMT, MethodType... bridgeMTs) {
+ boolean bridge = bridgeMTs.length > 0;
+ Object[] args = new Object[bridge ? 5+bridgeMTs.length : 4];
+ args[0] = samMT;
+ args[1] = mh;
+ args[2] = instMT;
+ args[3] = bridge ? LambdaMetafactory.FLAG_BRIDGES : 0;
+ if (bridge) {
+ args[4] = bridgeMTs.length;
+ for (int i = 0; i < bridgeMTs.length; i++) args[5+i] = bridgeMTs[i];
+ }
+ try {
+ LambdaMetafactory.altMetafactory(lookup, "run", methodType(I.class, captured), args);
+ if (!correct) {
+ throw new AssertionError("Uncaught linkage error:" +
+ " impl=" + mh +
+ ", captured=" + Arrays.toString(captured) +
+ ", inst=" + instMT +
+ ", sam=" + samMT +
+ ", bridges=" + Arrays.toString(bridgeMTs));
+ }
+ }
+ catch (LambdaConversionException e) {
+ if (correct) {
+ throw new AssertionError("Unexpected linkage error:" +
+ " e=" + e +
+ ", impl=" + mh +
+ ", captured=" + Arrays.toString(captured) +
+ ", inst=" + instMT +
+ ", sam=" + samMT +
+ ", bridges=" + Arrays.toString(bridgeMTs));
+ }
+ }
+ }
+
+}
diff --git a/test/java/nio/channels/Selector/ByteServer.java b/test/java/nio/channels/Selector/ByteServer.java
index eefd1fb..40d8adf 100644
--- a/test/java/nio/channels/Selector/ByteServer.java
+++ b/test/java/nio/channels/Selector/ByteServer.java
@@ -22,52 +22,54 @@
*/
/**
- *
- * Utility class for tests. A simple server, which waits for a connection,
- * writes out n bytes and waits.
+ * Utility class for tests. A simple "in-thread" server to accept connections
+ * and write bytes.
* @author kladko
*/
import java.net.Socket;
import java.net.ServerSocket;
+import java.net.SocketAddress;
+import java.net.InetSocketAddress;
+import java.io.IOException;
+import java.io.Closeable;
-public class ByteServer {
+public class ByteServer implements Closeable {
- public static final String LOCALHOST = "localhost";
- private int bytecount;
- private Socket socket;
- private ServerSocket serversocket;
- private Thread serverthread;
- volatile Exception savedException;
+ private final ServerSocket ss;
+ private Socket s;
- public ByteServer(int bytecount) throws Exception{
- this.bytecount = bytecount;
- serversocket = new ServerSocket(0);
+ ByteServer() throws IOException {
+ this.ss = new ServerSocket(0);
}
- public int port() {
- return serversocket.getLocalPort();
+ SocketAddress address() {
+ return new InetSocketAddress(ss.getInetAddress(), ss.getLocalPort());
}
- public void start() {
- serverthread = new Thread() {
- public void run() {
- try {
- socket = serversocket.accept();
- socket.getOutputStream().write(new byte[bytecount]);
- socket.getOutputStream().flush();
- } catch (Exception e) {
- System.err.println("Exception in ByteServer: " + e);
- System.exit(1);
- }
- }
- };
- serverthread.start();
+ void acceptConnection() throws IOException {
+ if (s != null)
+ throw new IllegalStateException("already connected");
+ this.s = ss.accept();
}
- public void exit() throws Exception {
- serverthread.join();
- socket.close();
- serversocket.close();
+ void closeConnection() throws IOException {
+ Socket s = this.s;
+ if (s != null) {
+ this.s = null;
+ s.close();
+ }
+ }
+
+ void write(int count) throws IOException {
+ if (s == null)
+ throw new IllegalStateException("no connection");
+ s.getOutputStream().write(new byte[count]);
+ }
+
+ public void close() throws IOException {
+ if (s != null)
+ s.close();
+ ss.close();
}
}
diff --git a/test/java/nio/channels/Selector/ReadAfterConnect.java b/test/java/nio/channels/Selector/ReadAfterConnect.java
index e5d0b09..93318fb 100644
--- a/test/java/nio/channels/Selector/ReadAfterConnect.java
+++ b/test/java/nio/channels/Selector/ReadAfterConnect.java
@@ -27,27 +27,25 @@
* @author kladko
*/
-import java.net.*;
-import java.nio.*;
-import java.nio.channels.*;
+import java.nio.channels.Selector;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.SocketChannel;
public class ReadAfterConnect {
-
public static void main(String[] argv) throws Exception {
- ByteServer server = new ByteServer(0); // server: accept connection and do nothing
- server.start();
- InetSocketAddress isa = new InetSocketAddress(
- InetAddress.getByName(ByteServer.LOCALHOST), server.port());
- Selector sel = Selector.open();
- SocketChannel sc = SocketChannel.open();
- sc.connect(isa);
- sc.configureBlocking(false);
- sc.register(sel, SelectionKey.OP_READ);
- // Previously channel would get selected here, although there is nothing to read
- if (sel.selectNow() != 0)
- throw new Exception("Select returned nonzero value");
- sc.close();
- server.exit();
+ try (ByteServer server = new ByteServer();
+ SocketChannel sc = SocketChannel.open(server.address())) {
+
+ server.acceptConnection();
+
+ try (Selector sel = Selector.open()) {
+ sc.configureBlocking(false);
+ sc.register(sel, SelectionKey.OP_READ);
+ // Previously channel would get selected here, although there is nothing to read
+ if (sel.selectNow() != 0)
+ throw new Exception("Select returned nonzero value");
+ }
+ }
}
}
diff --git a/test/java/nio/channels/Selector/SelectAfterRead.java b/test/java/nio/channels/Selector/SelectAfterRead.java
index fccd9dd..3563146 100644
--- a/test/java/nio/channels/Selector/SelectAfterRead.java
+++ b/test/java/nio/channels/Selector/SelectAfterRead.java
@@ -28,60 +28,62 @@
* @author kladko
*/
-import java.net.*;
-import java.nio.*;
-import java.nio.channels.*;
+import java.nio.ByteBuffer;
+import java.nio.channels.Selector;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.SocketChannel;
public class SelectAfterRead {
- final static int TIMEOUT = 1000;
+ private static final int TIMEOUT = 1000;
public static void main(String[] argv) throws Exception {
- InetAddress lh = InetAddress.getByName(ByteServer.LOCALHOST);
// server: accept connection and write one byte
- ByteServer server = new ByteServer(1);
- server.start();
- Selector sel = Selector.open();
- SocketChannel sc = SocketChannel.open();
- sc.connect(new InetSocketAddress(lh, server.port()));
- sc.read(ByteBuffer.allocate(1));
- sc.configureBlocking(false);
- sc.register(sel, SelectionKey.OP_READ);
- // previously on Windows select would select channel here, although there was
- // nothing to read
- if (sel.selectNow() != 0)
- throw new Exception("Select returned nonzero value");
- sc.close();
- sel.close();
- server.exit();
+ try (ByteServer server = new ByteServer();
+ SocketChannel sc = SocketChannel.open(server.address())) {
+
+ server.acceptConnection();
+ server.write(1);
+
+ try (Selector sel = Selector.open()) {
+ sc.read(ByteBuffer.allocate(1));
+ sc.configureBlocking(false);
+ sc.register(sel, SelectionKey.OP_READ);
+ // previously on Windows select would select channel here, although there was
+ // nothing to read
+ if (sel.selectNow() != 0)
+ throw new Exception("Select returned nonzero value");
+ }
+ }
// Now we will test a two reads combination
// server: accept connection and write two bytes
- server = new ByteServer(2);
- server.start();
- sc = SocketChannel.open();
- sc.connect(new InetSocketAddress(lh, server.port()));
- sc.configureBlocking(false);
- sel = Selector.open();
- sc.register(sel, SelectionKey.OP_READ);
- if (sel.select(TIMEOUT) != 1)
- throw new Exception("One selected key expected");
- sel.selectedKeys().clear();
- // previously on Windows a channel would get selected only once
- if (sel.selectNow() != 1)
- throw new Exception("One selected key expected");
- // Previously on Windows two consequent reads would cause select()
- // to select a channel, although there was nothing remaining to
- // read in the channel
- if (sc.read(ByteBuffer.allocate(1)) != 1)
- throw new Exception("One byte expected");
- if (sc.read(ByteBuffer.allocate(1)) != 1)
- throw new Exception("One byte expected");
- if (sel.selectNow() != 0)
- throw new Exception("Select returned nonzero value");
- sc.close();
- sel.close();
- server.exit();
+ try (ByteServer server = new ByteServer();
+ SocketChannel sc = SocketChannel.open(server.address())) {
+
+ server.acceptConnection();
+ server.write(2);
+
+ try (Selector sel = Selector.open()) {
+ sc.configureBlocking(false);
+ sc.register(sel, SelectionKey.OP_READ);
+ if (sel.select(TIMEOUT) != 1)
+ throw new Exception("One selected key expected");
+ sel.selectedKeys().clear();
+ // previously on Windows a channel would get selected only once
+ if (sel.selectNow() != 1)
+ throw new Exception("One selected key expected");
+ // Previously on Windows two consequent reads would cause select()
+ // to select a channel, although there was nothing remaining to
+ // read in the channel
+ if (sc.read(ByteBuffer.allocate(1)) != 1)
+ throw new Exception("One byte expected");
+ if (sc.read(ByteBuffer.allocate(1)) != 1)
+ throw new Exception("One byte expected");
+ if (sel.selectNow() != 0)
+ throw new Exception("Select returned nonzero value");
+ }
+ }
}
}
diff --git a/test/java/nio/channels/Selector/SelectWrite.java b/test/java/nio/channels/Selector/SelectWrite.java
index 3c2d3d8..ab305ed 100644
--- a/test/java/nio/channels/Selector/SelectWrite.java
+++ b/test/java/nio/channels/Selector/SelectWrite.java
@@ -22,36 +22,33 @@
*/
/* @test
- @bug 4645302
- @summary Socket with OP_WRITE would get selected only once
- @author kladko
+ * @bug 4645302
+ * @summary Socket with OP_WRITE would get selected only once
+ * @author kladko
*/
-import java.net.*;
-import java.nio.*;
-import java.nio.channels.*;
-
+import java.nio.channels.Selector;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.SocketChannel;
public class SelectWrite {
public static void main(String[] argv) throws Exception {
- ByteServer server = new ByteServer(0);
- // server: accept connection and do nothing
- server.start();
- InetSocketAddress isa = new InetSocketAddress(
- InetAddress.getByName(ByteServer.LOCALHOST), server.port());
- Selector sel = Selector.open();
- SocketChannel sc = SocketChannel.open();
- sc.connect(isa);
- sc.configureBlocking(false);
- sc.register(sel, SelectionKey.OP_WRITE);
- sel.select();
- sel.selectedKeys().clear();
- if (sel.select() == 0) {
- throw new Exception("Select returned zero");
+ try (ByteServer server = new ByteServer();
+ SocketChannel sc = SocketChannel.open(server.address())) {
+
+ server.acceptConnection();
+
+ try (Selector sel = Selector.open()) {
+ sc.configureBlocking(false);
+ sc.register(sel, SelectionKey.OP_WRITE);
+ sel.select();
+ sel.selectedKeys().clear();
+ if (sel.select() == 0) {
+ throw new Exception("Select returned zero");
+ }
+ }
}
- sc.close();
- sel.close();
}
}
diff --git a/test/javax/management/remote/mandatory/util/CacheMapTest.java b/test/javax/management/remote/mandatory/util/CacheMapTest.java
deleted file mode 100644
index bdd55db..0000000
--- a/test/javax/management/remote/mandatory/util/CacheMapTest.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (c) 2003, 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 7654321
- * @summary Tests the CacheMap class.
- * @author Eamonn McManus
- * @run clean CacheMapTest
- * @run build CacheMapTest
- * @run main CacheMapTest
- */
-
-import java.util.Iterator;
-import java.util.Map;
-
-import com.sun.jmx.remote.util.CacheMap;
-
-public class CacheMapTest {
- public static void main(String[] args) {
- try {
- boolean ok = test(5) && test(100);
- if (ok) {
- System.out.println("Test completed");
- return;
- } else {
- System.out.println("Test failed!");
- System.exit(1);
- }
- } catch (Exception e) {
- System.err.println("Unexpected exception: " + e);
- e.printStackTrace();
- System.exit(1);
- }
- }
-
- private static boolean test(int cacheSize) throws Exception {
- System.out.println("CacheMap test with cache size " + cacheSize);
- CacheMap map = new CacheMap(cacheSize);
- int size = 0;
- int maxIterations = cacheSize * 10;
- while (map.size() == size && size < maxIterations) {
- Integer key = new Integer(size);
- Object x = map.put(key, "x");
- if (x != null) {
- System.out.println("Map already had entry " + key + "!");
- return false;
- }
- x = map.get(key);
- if (!"x".equals(x)) {
- System.out.println("Got back surprising value: " + x);
- return false;
- }
- size++;
- }
- System.out.println("Map size is " + map.size() + " after inserting " +
- size + " elements");
- do {
- System.gc();
- Thread.sleep(1);
- System.out.println("Map size is " + map.size() + " after GC");
- } while (map.size() > cacheSize);
- if (map.size() < cacheSize) {
- System.out.println("Map shrank to less than cache size: " +
- map.size() + " (surprising but not wrong)");
- } else
- System.out.println("Map shrank to cache size as expected");
- int lowest = size - cacheSize;
- // lowest value that can still be in cache if LRU is respected
- for (Iterator it = map.entrySet().iterator(); it.hasNext(); ) {
- Map.Entry entry = (Map.Entry) it.next();
- Integer x = (Integer) entry.getKey();
- int xx = x.intValue();
- if (xx < lowest || xx >= size) {
- System.out.println("Old value remained (" + x + "), " +
- "expected none earlier than " + lowest);
- return false;
- }
- Object xxx = entry.getValue();
- if (!"x".equals(xxx)) {
- System.out.println("Got back surprising value: " + xxx);
- return false;
- }
- }
- if (map.size() > 0)
- System.out.println("Remaining elements are the most recent ones");
- System.out.println("Test passed");
- return true;
- }
-}
diff --git a/test/sun/util/calendar/zi/Zoneinfo.java b/test/sun/util/calendar/zi/Zoneinfo.java
index 277c045..9e48655 100644
--- a/test/sun/util/calendar/zi/Zoneinfo.java
+++ b/test/sun/util/calendar/zi/Zoneinfo.java
@@ -372,6 +372,7 @@
ZoneRec zrec = zone.get(zone.size()-1);
tz.getOffsetIndex(zrec.getGmtOffset());
+ int lastGmtOffsetValue = -1;
int currentSave = 0;
boolean usedZone;
for (int zindex = 0; zindex < zone.size(); zindex++) {
@@ -380,9 +381,12 @@
gmtOffset = zrec.getGmtOffset();
int stdOffset = zrec.getDirectSave();
+ if (gmtOffset != lastGmtOffsetValue) {
+ tz.setRawOffset(gmtOffset, fromTime);
+ lastGmtOffsetValue = gmtOffset;
+ }
// If this is the last zone record, take the last rule info.
if (!zrec.hasUntil()) {
- tz.setRawOffset(gmtOffset, fromTime);
if (zrec.hasRuleReference()) {
tz.setLastRules(zrec.getRuleRef().getLastRules());
} else if (stdOffset != 0) {
diff --git a/test/sun/util/calendar/zi/tzdata/VERSION b/test/sun/util/calendar/zi/tzdata/VERSION
index 2f162e0..8ab96a7 100644
--- a/test/sun/util/calendar/zi/tzdata/VERSION
+++ b/test/sun/util/calendar/zi/tzdata/VERSION
@@ -21,4 +21,4 @@
# or visit www.oracle.com if you need additional information or have any
# questions.
#
-tzdata2013i
+tzdata2014a
diff --git a/test/sun/util/calendar/zi/tzdata/asia b/test/sun/util/calendar/zi/tzdata/asia
index 1a8f83d..dc3c94b 100644
--- a/test/sun/util/calendar/zi/tzdata/asia
+++ b/test/sun/util/calendar/zi/tzdata/asia
@@ -1113,8 +1113,13 @@
Rule Zion 1986 only - Sep 7 0:00 0 S
Rule Zion 1987 only - Apr 15 0:00 1:00 D
Rule Zion 1987 only - Sep 13 0:00 0 S
-Rule Zion 1988 only - Apr 9 0:00 1:00 D
-Rule Zion 1988 only - Sep 3 0:00 0 S
+
+# From Avigdor Finkelstein (2014-03-05):
+# I check the Parliament (Knesset) records and there it's stated that the
+# [1988] transition should take place on Saturday night, when the Sabbath
+# ends and changes to Sunday.
+Rule Zion 1988 only - Apr 10 0:00 1:00 D
+Rule Zion 1988 only - Sep 4 0:00 0 S
# From Ephraim Silverberg
# (1997-03-04, 1998-03-16, 1998-12-28, 2000-01-17, 2000-07-25, 2004-12-22,
diff --git a/test/sun/util/calendar/zi/tzdata/australasia b/test/sun/util/calendar/zi/tzdata/australasia
index cd6b724..a0e8b5a 100644
--- a/test/sun/util/calendar/zi/tzdata/australasia
+++ b/test/sun/util/calendar/zi/tzdata/australasia
@@ -377,16 +377,18 @@
# http://www.fiji.gov.fj/index.php?option=com_content&view=article&id=6702&catid=71&Itemid=155
# From the Fijian Government Media Center (2013-08-30) via David Wheeler:
-# Fiji will start daylight savings on Sunday 27th October, 2013 and end at 3am
-# on Sunday 19th January, 2014.... move clocks forward by one hour from 2am
+# Fiji will start daylight savings on Sunday 27th October, 2013 ...
+# move clocks forward by one hour from 2am
# http://www.fiji.gov.fj/Media-Center/Press-Releases/DAYLIGHT-SAVING-STARTS-ON-SUNDAY,-27th-OCTOBER-201.aspx
-#
-# From Paul Eggert (2013-09-09):
+
+# From Steffen Thorsen (2013-01-10):
+# Fiji will end DST on 2014-01-19 02:00:
+# http://www.fiji.gov.fj/Media-Center/Press-Releases/DAYLIGHT-SAVINGS-TO-END-THIS-MONTH-%281%29.aspx
+
+# From Paul Eggert (2014-01-10):
# For now, guess that Fiji springs forward the Sunday before the fourth
-# Monday in October. This matches both recent practice and
-# timeanddate.com's current spring-forward prediction.
-# For the January 2014 transition we guessed right while timeanddate.com
-# guessed wrong, so leave the fall-back prediction alone.
+# Monday in October, and springs back the penultimate Sunday in January.
+# This is ad hoc, but matches recent practice.
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule Fiji 1998 1999 - Nov Sun>=1 2:00 1:00 S
@@ -395,7 +397,8 @@
Rule Fiji 2010 only - Mar lastSun 3:00 0 -
Rule Fiji 2010 max - Oct Sun>=21 2:00 1:00 S
Rule Fiji 2011 only - Mar Sun>=1 3:00 0 -
-Rule Fiji 2012 max - Jan Sun>=18 3:00 0 -
+Rule Fiji 2012 2013 - Jan Sun>=18 3:00 0 -
+Rule Fiji 2014 max - Jan Sun>=18 2:00 0 -
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Pacific/Fiji 11:55:44 - LMT 1915 Oct 26 # Suva
12:00 Fiji FJ%sT # Fiji Time
diff --git a/test/sun/util/calendar/zi/tzdata/europe b/test/sun/util/calendar/zi/tzdata/europe
index 9f574a3..585e64d 100644
--- a/test/sun/util/calendar/zi/tzdata/europe
+++ b/test/sun/util/calendar/zi/tzdata/europe
@@ -2768,14 +2768,18 @@
# According to the articles linked below, Turkey will change into summer
# time zone (GMT+3) on March 28, 2011 at 3:00 a.m. instead of March 27.
# This change is due to a nationwide exam on 27th.
-#
-# <a href="http://www.worldbulletin.net/?aType=haber&ArticleID=70872">
# http://www.worldbulletin.net/?aType=haber&ArticleID=70872
-# </a>
# Turkish:
-# <a href="http://www.hurriyet.com.tr/ekonomi/17230464.asp?gid=373">
# http://www.hurriyet.com.tr/ekonomi/17230464.asp?gid=373
-# </a>
+
+# From Faruk Pasin (2014-02-14):
+# The DST for Turkey has been changed for this year because of the
+# Turkish Local election....
+# http://www.sabah.com.tr/Ekonomi/2014/02/12/yaz-saatinde-onemli-degisiklik
+# ... so Turkey will move clocks forward one hour on March 31 at 3:00 a.m.
+# From Paul Eggert (2014-02-17):
+# Here is an English-language source:
+# http://www.worldbulletin.net/turkey/129016/turkey-switches-to-daylight-saving-time-march-31
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule Turkey 1916 only - May 1 0:00 1:00 S
@@ -2844,6 +2848,8 @@
2:00 Turkey EE%sT 2007
2:00 EU EE%sT 2011 Mar 27 1:00u
2:00 - EET 2011 Mar 28 1:00u
+ 2:00 EU EE%sT 2014 Mar 30 1:00u
+ 2:00 - EET 2014 Mar 31 1:00u
2:00 EU EE%sT
Link Europe/Istanbul Asia/Istanbul # Istanbul is in both continents.
@@ -2865,19 +2871,13 @@
# approval from 266 deputies.
#
# Ukraine abolishes transter back to the winter time (in Russian)
-# <a href="http://news.mail.ru/politics/6861560/">
# http://news.mail.ru/politics/6861560/
-# </a>
#
# The Ukrainians will no longer change the clock (in Russian)
-# <a href="http://www.segodnya.ua/news/14290482.html">
# http://www.segodnya.ua/news/14290482.html
-# </a>
#
# Deputies cancelled the winter time (in Russian)
-# <a href="http://www.pravda.com.ua/rus/news/2011/09/20/6600616/">
# http://www.pravda.com.ua/rus/news/2011/09/20/6600616/
-# </a>
#
# From Philip Pizzey (2011-10-18):
# Today my Ukrainian colleagues have informed me that the
@@ -2888,18 +2888,39 @@
# As far as I understand, the recent change to the Ukrainian time zone
# (Europe/Kiev) to introduce permanent daylight saving time (similar
# to Russia) was reverted today:
-#
-# <a href="http://portal.rada.gov.ua/rada/control/en/publish/article/info_left?art_id=287324&cat_id=105995">
# http://portal.rada.gov.ua/rada/control/en/publish/article/info_left?art_id=287324&cat_id=105995
-# </a>
#
# Also reported by Alexander Bokovoy (2011-10-18) who also noted:
# The law documents themselves are at
-#
-# <a href="http://w1.c1.rada.gov.ua/pls/zweb_n/webproc4_1?id=&pf3511=41484">
# http://w1.c1.rada.gov.ua/pls/zweb_n/webproc4_1?id=&pf3511=41484
-# </a>
+# From Vladimir in Moscow via Alois Treindl re Kiev time 1991/2 (2014-02-28):
+# First in Ukraine they changed Time zone from UTC+3 to UTC+2 with DST:
+# 03 25 1990 02:00 -03.00 1 Time Zone 3 with DST
+# 07 01 1990 02:00 -02.00 1 Time Zone 2 with DST
+# * Ukrainian Government's Resolution of 18.06.1990, No. 134.
+# http://search.ligazakon.ua/l_doc2.nsf/link1/T001500.html
+#
+# They did not end DST in September, 1990 (according to the law,
+# "summer time" was still in action):
+# 09 30 1990 03:00 -02.00 1 Time Zone 2 with DST
+# * Ukrainian Government's Resolution of 21.09.1990, No. 272.
+# http://search.ligazakon.ua/l_doc2.nsf/link1/KP900272.html
+#
+# Again no change in March, 1991 ("summer time" in action):
+# 03 31 1991 02:00 -02.00 1 Time Zone 2 with DST
+#
+# DST ended in September 1991 ("summer time" ended):
+# 09 29 1991 03:00 -02.00 0 Time Zone 2, no DST
+# * Ukrainian Government's Resolution of 25.09.1991, No. 225.
+# http://www.uazakon.com/documents/date_21/pg_iwgdoc.htm
+# This is an answer.
+#
+# Since 1992 they had normal DST procedure:
+# 03 29 1992 02:00 -02.00 1 DST started
+# 09 27 1992 03:00 -02.00 0 DST ended
+# * Ukrainian Government's Resolution of 20.03.1992, No. 139.
+# http://www.uazakon.com/documents/date_8u/pg_grcasa.htm
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
# Most of Ukraine since 1970 has been like Kiev.
@@ -2910,9 +2931,8 @@
2:00 - EET 1930 Jun 21
3:00 - MSK 1941 Sep 20
1:00 C-Eur CE%sT 1943 Nov 6
- 3:00 Russia MSK/MSD 1990
- 3:00 - MSK 1990 Jul 1 2:00
- 2:00 - EET 1992
+ 3:00 Russia MSK/MSD 1990 Jul 1 2:00
+ 2:00 1:00 EEST 1991 Sep 29 3:00
2:00 E-Eur EE%sT 1995
2:00 EU EE%sT
# Ruthenia used CET 1990/1991.
diff --git a/test/sun/util/calendar/zi/tzdata/northamerica b/test/sun/util/calendar/zi/tzdata/northamerica
index 9e551bb..dc0c2e9 100644
--- a/test/sun/util/calendar/zi/tzdata/northamerica
+++ b/test/sun/util/calendar/zi/tzdata/northamerica
@@ -414,9 +414,10 @@
# US Pacific time, represented by Los Angeles
#
# California, northern Idaho (Benewah, Bonner, Boundary, Clearwater,
-# Idaho, Kootenai, Latah, Lewis, Nez Perce, and Shoshone counties,
-# and the northern three-quarters of Idaho county),
-# most of Nevada, most of Oregon, and Washington
+# Kootenai, Latah, Lewis, Nez Perce, and Shoshone counties, Idaho county
+# north of the Salmon River, and the towns of Burgdorf and Warren),
+# Nevada (except West Wendover), Oregon (except the northern 3/4 of
+# Malheur county), and Washington
#
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER
Rule CA 1948 only - Mar 14 2:00 1:00 D
diff --git a/test/sun/util/calendar/zi/tzdata/southamerica b/test/sun/util/calendar/zi/tzdata/southamerica
index 071f890..02bf3bb 100644
--- a/test/sun/util/calendar/zi/tzdata/southamerica
+++ b/test/sun/util/calendar/zi/tzdata/southamerica
@@ -1298,6 +1298,13 @@
# start date is 2013-09-08 00:00....
# http://www.gob.cl/informa/2013/02/15/gobierno-anuncia-fechas-de-cambio-de-hora-para-el-ano-2013.htm
+# From Jose Miguel Garrido (2014-02-19):
+# Today appeared in the Diario Oficial a decree amending the time change
+# dates to 2014.
+# DST End: last Saturday of April 2014 (Sun 27 Apr 2014 03:00 UTC)
+# DST Start: first Saturday of September 2014 (Sun 07 Sep 2014 04:00 UTC)
+# http://www.diariooficial.interior.gob.cl//media/2014/02/19/do-20140219.pdf
+
# NOTE: ChileAQ rules for Antarctic bases are stored separately in the
# 'antarctica' file.
@@ -1631,6 +1638,9 @@
# From Carlos Raul Perasso (2013-03-15):
# The change in Paraguay is now final. Decree number 10780
# http://www.presidencia.gov.py/uploads/pdf/presidencia-3b86ff4b691c79d4f5927ca964922ec74772ce857c02ca054a52a37b49afc7fb.pdf
+# From Carlos Raul Perasso (2014-02-28):
+# Decree 1264 can be found at:
+# http://www.presidencia.gov.py/archivos/documentos/DECRETO1264_ey9r8zai.pdf
Rule Para 2013 max - Mar Sun>=22 0:00 0 -
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
@@ -1689,18 +1699,19 @@
Zone America/Port_of_Spain -4:06:04 - LMT 1912 Mar 2
-4:00 - AST
+# These all agree with Trinidad and Tobago since 1970.
Link America/Port_of_Spain America/Anguilla
Link America/Port_of_Spain America/Dominica
Link America/Port_of_Spain America/Grenada
Link America/Port_of_Spain America/Guadeloupe
-Link America/Port_of_Spain America/Marigot
+Link America/Port_of_Spain America/Marigot # St Martin (French part)
Link America/Port_of_Spain America/Montserrat
Link America/Port_of_Spain America/St_Barthelemy
-Link America/Port_of_Spain America/St_Kitts
+Link America/Port_of_Spain America/St_Kitts # St Kitts & Nevis
Link America/Port_of_Spain America/St_Lucia
-Link America/Port_of_Spain America/St_Thomas
+Link America/Port_of_Spain America/St_Thomas # Virgin Islands (US)
Link America/Port_of_Spain America/St_Vincent
-Link America/Port_of_Spain America/Tortola
+Link America/Port_of_Spain America/Tortola # Virgin Islands (UK)
# Uruguay
# From Paul Eggert (1993-11-18):