提交 317ff359 编写于 作者: A asaha

Merge

...@@ -633,4 +633,16 @@ c4f03717831993e4658b8366810ca4682ece952d jdk8u111-b01 ...@@ -633,4 +633,16 @@ c4f03717831993e4658b8366810ca4682ece952d jdk8u111-b01
de1d09f09e571e38afdf1fb72984ec210e7c19e6 jdk8u111-b02 de1d09f09e571e38afdf1fb72984ec210e7c19e6 jdk8u111-b02
1818c0df435a5e4b8b18dd82de38a03f30714d55 jdk8u111-b03 1818c0df435a5e4b8b18dd82de38a03f30714d55 jdk8u111-b03
710f0c95444deb36b422f449f422d925a72f6b2c jdk8u111-b04 710f0c95444deb36b422f449f422d925a72f6b2c jdk8u111-b04
d689f7b806c89e535f784ba94bea1ae129ee0f19 jdk8u111-b05
6c822cce832523a5aee9632e28065f0c302187ed jdk8u111-b06
1afe84012d643b4092dbf25f1cbb761508c19ed2 jdk8u111-b07
9760ea9a63c0d48956392256bb7769ab40f2a2f7 jdk8u111-b08
47e20a90bdbb2327289e330606b73a9fe4dc857e jdk8u112-b00
96393e490afd4acba5b92c5ede68dc9bbb60a38e jdk8u112-b01
b44d695f738baba091370828b84ae2c4cd715c1b jdk8u112-b02
1af2eacbc17462f080d70e71c53e073ab0640f32 jdk8u112-b03
a11ab21bb7991509846e0e45ad3792896c4fe98c jdk8u112-b04
ecb2bae7905e2fd6f9b837521ee82a2cbb34602c jdk8u112-b06
c66f5a825a0f0b5fb833bc7f50f327aec43e213b jdk8u112-b07
89375f5c2c4c2bdc2340d7af1977dc1607908840 jdk8u112-b08
ab5ff8f1e52c5e3ca02e988f4d978af63ceca5b8 jdk8u121-b00 ab5ff8f1e52c5e3ca02e988f4d978af63ceca5b8 jdk8u121-b00
...@@ -3,7 +3,7 @@ The GNU General Public License (GPL) ...@@ -3,7 +3,7 @@ The GNU General Public License (GPL)
Version 2, June 1991 Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc. Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies of this license Everyone is permitted to copy and distribute verbatim copies of this license
document, but changing it is not allowed. document, but changing it is not allowed.
...@@ -287,8 +287,8 @@ pointer to where the full notice is found. ...@@ -287,8 +287,8 @@ pointer to where the full notice is found.
more details. more details.
You should have received a copy of the GNU General Public License along You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc., 59 with this program; if not, write to the Free Software Foundation, Inc.,
Temple Place, Suite 330, Boston, MA 02111-1307 USA 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail. Also add information on how to contact you by electronic and paper mail.
......
...@@ -21,4 +21,4 @@ ...@@ -21,4 +21,4 @@
# or visit www.oracle.com if you need additional information or have any # or visit www.oracle.com if you need additional information or have any
# questions. # questions.
# #
tzdata2016d tzdata2016f
...@@ -366,6 +366,12 @@ Rule Egypt 2007 only - Sep Thu>=1 24:00 0 - ...@@ -366,6 +366,12 @@ Rule Egypt 2007 only - Sep Thu>=1 24:00 0 -
# decision to abandon DST permanently. See Ahram Online 2015-04-24. # decision to abandon DST permanently. See Ahram Online 2015-04-24.
# http://english.ahram.org.eg/NewsContent/1/64/128509/Egypt/Politics-/Sisi-cancels-daylight-saving-time-in-Egypt.aspx # http://english.ahram.org.eg/NewsContent/1/64/128509/Egypt/Politics-/Sisi-cancels-daylight-saving-time-in-Egypt.aspx
# From Steffen Thorsen (2016-04-29):
# Egypt will have DST from July 7 until the end of October....
# http://english.ahram.org.eg/NewsContentP/1/204655/Egypt/Daylight-savings-time-returning-to-Egypt-on--July.aspx
# From Mina Samuel (2016-07-04):
# Egyptian government took the decision to cancel the DST,
Rule Egypt 2008 only - Aug lastThu 24:00 0 - Rule Egypt 2008 only - Aug lastThu 24:00 0 -
Rule Egypt 2009 only - Aug 20 24:00 0 - Rule Egypt 2009 only - Aug 20 24:00 0 -
Rule Egypt 2010 only - Aug 10 24:00 0 - Rule Egypt 2010 only - Aug 10 24:00 0 -
...@@ -881,11 +887,11 @@ Rule Morocco 2009 only - Aug 21 0:00 0 - ...@@ -881,11 +887,11 @@ Rule Morocco 2009 only - Aug 21 0:00 0 -
Rule Morocco 2010 only - May 2 0:00 1:00 S Rule Morocco 2010 only - May 2 0:00 1:00 S
Rule Morocco 2010 only - Aug 8 0:00 0 - Rule Morocco 2010 only - Aug 8 0:00 0 -
Rule Morocco 2011 only - Apr 3 0:00 1:00 S Rule Morocco 2011 only - Apr 3 0:00 1:00 S
Rule Morocco 2011 only - Jul 31 0 0 - Rule Morocco 2011 only - Jul 31 0:00 0 -
Rule Morocco 2012 2013 - Apr lastSun 2:00 1:00 S Rule Morocco 2012 2013 - Apr lastSun 2:00 1:00 S
Rule Morocco 2012 only - Sep 30 3:00 0 -
Rule Morocco 2012 only - Jul 20 3:00 0 - Rule Morocco 2012 only - Jul 20 3:00 0 -
Rule Morocco 2012 only - Aug 20 2:00 1:00 S Rule Morocco 2012 only - Aug 20 2:00 1:00 S
Rule Morocco 2012 only - Sep 30 3:00 0 -
Rule Morocco 2013 only - Jul 7 3:00 0 - Rule Morocco 2013 only - Jul 7 3:00 0 -
Rule Morocco 2013 only - Aug 10 2:00 1:00 S Rule Morocco 2013 only - Aug 10 2:00 1:00 S
Rule Morocco 2013 max - Oct lastSun 3:00 0 - Rule Morocco 2013 max - Oct lastSun 3:00 0 -
......
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
# #
# Except for the French entries, # Except for the French entries,
# I made up all time zone abbreviations mentioned here; corrections welcome! # I made up all time zone abbreviations mentioned here; corrections welcome!
# FORMAT is 'zzz' and GMTOFF is 0 for locations while uninhabited. # FORMAT is '-00' and GMTOFF is 0 for locations while uninhabited.
# Argentina - year-round bases # Argentina - year-round bases
# Belgrano II, Confin Coast, -770227-0343737, since 1972-02-05 # Belgrano II, Confin Coast, -770227-0343737, since 1972-02-05
...@@ -90,22 +90,22 @@ ...@@ -90,22 +90,22 @@
# http://www.timeanddate.com/news/time/antartica-time-changes-2010.html # http://www.timeanddate.com/news/time/antartica-time-changes-2010.html
# Zone NAME GMTOFF RULES FORMAT [UNTIL] # Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Antarctica/Casey 0 - zzz 1969 Zone Antarctica/Casey 0 - -00 1969
8:00 - AWST 2009 Oct 18 2:00 8:00 - AWST 2009 Oct 18 2:00
# Australian Western Std Time # Australian Western Std Time
11:00 - CAST 2010 Mar 5 2:00 # Casey Time 11:00 - CAST 2010 Mar 5 2:00 # Casey Time
8:00 - AWST 2011 Oct 28 2:00 8:00 - AWST 2011 Oct 28 2:00
11:00 - CAST 2012 Feb 21 17:00u 11:00 - CAST 2012 Feb 21 17:00u
8:00 - AWST 8:00 - AWST
Zone Antarctica/Davis 0 - zzz 1957 Jan 13 Zone Antarctica/Davis 0 - -00 1957 Jan 13
7:00 - DAVT 1964 Nov # Davis Time 7:00 - DAVT 1964 Nov # Davis Time
0 - zzz 1969 Feb 0 - -00 1969 Feb
7:00 - DAVT 2009 Oct 18 2:00 7:00 - DAVT 2009 Oct 18 2:00
5:00 - DAVT 2010 Mar 10 20:00u 5:00 - DAVT 2010 Mar 10 20:00u
7:00 - DAVT 2011 Oct 28 2:00 7:00 - DAVT 2011 Oct 28 2:00
5:00 - DAVT 2012 Feb 21 20:00u 5:00 - DAVT 2012 Feb 21 20:00u
7:00 - DAVT 7:00 - DAVT
Zone Antarctica/Mawson 0 - zzz 1954 Feb 13 Zone Antarctica/Mawson 0 - -00 1954 Feb 13
6:00 - MAWT 2009 Oct 18 2:00 # Mawson Time 6:00 - MAWT 2009 Oct 18 2:00 # Mawson Time
5:00 - MAWT 5:00 - MAWT
# References: # References:
...@@ -160,7 +160,7 @@ Zone Antarctica/Mawson 0 - zzz 1954 Feb 13 ...@@ -160,7 +160,7 @@ Zone Antarctica/Mawson 0 - zzz 1954 Feb 13
# fishing stations operated variously 1819/1931 # fishing stations operated variously 1819/1931
# #
# Zone NAME GMTOFF RULES FORMAT [UNTIL] # Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Indian/Kerguelen 0 - zzz 1950 # Port-aux-Français Zone Indian/Kerguelen 0 - -00 1950 # Port-aux-Français
5:00 - TFT # ISO code TF Time 5:00 - TFT # ISO code TF Time
# #
# year-round base in the main continent # year-round base in the main continent
...@@ -171,9 +171,9 @@ Zone Indian/Kerguelen 0 - zzz 1950 # Port-aux-Français ...@@ -171,9 +171,9 @@ Zone Indian/Kerguelen 0 - zzz 1950 # Port-aux-Français
# It was destroyed by fire on 1952-01-14. # It was destroyed by fire on 1952-01-14.
# #
# Zone NAME GMTOFF RULES FORMAT [UNTIL] # Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Antarctica/DumontDUrville 0 - zzz 1947 Zone Antarctica/DumontDUrville 0 - -00 1947
10:00 - PMT 1952 Jan 14 # Port-Martin Time 10:00 - PMT 1952 Jan 14 # Port-Martin Time
0 - zzz 1956 Nov 0 - -00 1956 Nov
10:00 - DDUT # Dumont-d'Urville Time 10:00 - DDUT # Dumont-d'Urville Time
# France & Italy - year-round base # France & Italy - year-round base
...@@ -199,7 +199,7 @@ Zone Antarctica/DumontDUrville 0 - zzz 1947 ...@@ -199,7 +199,7 @@ Zone Antarctica/DumontDUrville 0 - zzz 1947
# was established on 1957-01-29. Since Syowa station is still the main # was established on 1957-01-29. Since Syowa station is still the main
# station of Japan, it's appropriate for the principal location. # station of Japan, it's appropriate for the principal location.
# Zone NAME GMTOFF RULES FORMAT [UNTIL] # Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Antarctica/Syowa 0 - zzz 1957 Jan 29 Zone Antarctica/Syowa 0 - -00 1957 Jan 29
3:00 - SYOT # Syowa Time 3:00 - SYOT # Syowa Time
# See: # See:
# NIPR Antarctic Research Activities (1999-08-17) # NIPR Antarctic Research Activities (1999-08-17)
...@@ -249,7 +249,7 @@ Rule Troll 2005 max - Mar lastSun 1:00u 2:00 CEST ...@@ -249,7 +249,7 @@ Rule Troll 2005 max - Mar lastSun 1:00u 2:00 CEST
# Remove the following line when uncommenting the above '#Rule' lines. # Remove the following line when uncommenting the above '#Rule' lines.
Rule Troll 2004 max - Oct lastSun 1:00u 0:00 UTC Rule Troll 2004 max - Oct lastSun 1:00u 0:00 UTC
# Zone NAME GMTOFF RULES FORMAT [UNTIL] # Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Antarctica/Troll 0 - zzz 2005 Feb 12 Zone Antarctica/Troll 0 - -00 2005 Feb 12
0:00 Troll %s 0:00 Troll %s
# Poland - year-round base # Poland - year-round base
...@@ -290,7 +290,7 @@ Zone Antarctica/Troll 0 - zzz 2005 Feb 12 ...@@ -290,7 +290,7 @@ Zone Antarctica/Troll 0 - zzz 2005 Feb 12
# happened to be during their visit. So we still don't really know what time # happened to be during their visit. So we still don't really know what time
# it is at Vostok. But we'll guess UTC+6. # it is at Vostok. But we'll guess UTC+6.
# #
Zone Antarctica/Vostok 0 - zzz 1957 Dec 16 Zone Antarctica/Vostok 0 - -00 1957 Dec 16
6:00 - VOST # Vostok time 6:00 - VOST # Vostok time
# S Africa - year-round bases # S Africa - year-round bases
...@@ -323,7 +323,7 @@ Zone Antarctica/Vostok 0 - zzz 1957 Dec 16 ...@@ -323,7 +323,7 @@ Zone Antarctica/Vostok 0 - zzz 1957 Dec 16
# <http://webexhibits.org/daylightsaving/g.html> says Rothera is -03 all year. # <http://webexhibits.org/daylightsaving/g.html> says Rothera is -03 all year.
# #
# Zone NAME GMTOFF RULES FORMAT [UNTIL] # Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Antarctica/Rothera 0 - zzz 1976 Dec 1 Zone Antarctica/Rothera 0 - -00 1976 Dec 1
-3:00 - ROTT # Rothera time -3:00 - ROTT # Rothera time
# Uruguay - year round base # Uruguay - year round base
......
...@@ -169,7 +169,7 @@ Zone Asia/Baku 3:19:24 - LMT 1924 May 2 ...@@ -169,7 +169,7 @@ Zone Asia/Baku 3:19:24 - LMT 1924 May 2
3:00 - BAKT 1957 Mar # Baku Time 3:00 - BAKT 1957 Mar # Baku Time
4:00 RussiaAsia BAK%sT 1991 Mar 31 2:00s 4:00 RussiaAsia BAK%sT 1991 Mar 31 2:00s
3:00 1:00 BAKST 1991 Aug 30 # independence 3:00 1:00 BAKST 1991 Aug 30 # independence
3:00 RussiaAsia AZ%sT 1992 Sep lastSat 23:00 3:00 RussiaAsia AZ%sT 1992 Sep lastSun 2:00s
4:00 - AZT 1996 # Azerbaijan Time 4:00 - AZT 1996 # Azerbaijan Time
4:00 EUAsia AZ%sT 1997 4:00 EUAsia AZ%sT 1997
4:00 Azer AZ%sT 4:00 Azer AZ%sT
......
...@@ -266,11 +266,11 @@ Zone Australia/Lord_Howe 10:36:20 - LMT 1895 Feb ...@@ -266,11 +266,11 @@ Zone Australia/Lord_Howe 10:36:20 - LMT 1895 Feb
# will produce a binary file with an [A]EST-type as the first 32-bit type; # will produce a binary file with an [A]EST-type as the first 32-bit type;
# this is required for correct handling of times before 1916 by # this is required for correct handling of times before 1916 by
# pre-2013 versions of localtime. # pre-2013 versions of localtime.
Zone Antarctica/Macquarie 0 - zzz 1899 Nov Zone Antarctica/Macquarie 0 - -00 1899 Nov
10:00 - AEST 1916 Oct 1 2:00 10:00 - AEST 1916 Oct 1 2:00
10:00 1:00 AEDT 1917 Feb 10:00 1:00 AEDT 1917 Feb
10:00 Aus AE%sT 1919 Apr 1 0:00s 10:00 Aus AE%sT 1919 Apr 1 0:00s
0 - zzz 1948 Mar 25 0 - -00 1948 Mar 25
10:00 Aus AE%sT 1967 10:00 Aus AE%sT 1967
10:00 AT AE%sT 2010 Apr 4 3:00 10:00 AT AE%sT 2010 Apr 4 3:00
11:00 - MIST # Macquarie I Standard Time 11:00 - MIST # Macquarie I Standard Time
......
...@@ -778,6 +778,14 @@ Zone Europe/Vienna 1:05:21 - LMT 1893 Apr ...@@ -778,6 +778,14 @@ Zone Europe/Vienna 1:05:21 - LMT 1893 Apr
1:00 EU CE%sT 1:00 EU CE%sT
# Belarus # Belarus
#
# From Stepan Golosunov (2016-07-02):
# http://www.lawbelarus.com/repub/sub30/texf9611.htm
# (Act of the Cabinet of Ministers of the Republic of Belarus from
# 1992-03-25 No. 157) ... says clocks were to be moved forward at 2:00
# on last Sunday of March and backward at 3:00 on last Sunday of September
# (the same as previous USSR and contemporary Russian regulations).
#
# From Yauhen Kharuzhy (2011-09-16): # From Yauhen Kharuzhy (2011-09-16):
# By latest Belarus government act Europe/Minsk timezone was changed to # By latest Belarus government act Europe/Minsk timezone was changed to
# GMT+3 without DST (was GMT+2 with DST). # GMT+3 without DST (was GMT+2 with DST).
...@@ -801,9 +809,6 @@ Zone Europe/Minsk 1:50:16 - LMT 1880 ...@@ -801,9 +809,6 @@ Zone Europe/Minsk 1:50:16 - LMT 1880
1:00 C-Eur CE%sT 1944 Jul 3 1:00 C-Eur CE%sT 1944 Jul 3
3:00 Russia MSK/MSD 1990 3:00 Russia MSK/MSD 1990
3:00 - MSK 1991 Mar 31 2:00s 3:00 - MSK 1991 Mar 31 2:00s
2:00 1:00 EEST 1991 Sep 29 2:00s
2:00 - EET 1992 Mar 29 0:00s
2:00 1:00 EEST 1992 Sep 27 0:00s
2:00 Russia EE%sT 2011 Mar 27 2:00s 2:00 Russia EE%sT 2011 Mar 27 2:00s
3:00 - FET 2014 Oct 26 1:00s 3:00 - FET 2014 Oct 26 1:00s
3:00 - MSK 3:00 - MSK
...@@ -2746,14 +2751,22 @@ Zone Asia/Barnaul 5:35:00 - LMT 1919 Dec 10 ...@@ -2746,14 +2751,22 @@ Zone Asia/Barnaul 5:35:00 - LMT 1919 Dec 10
# Asia/Novosibirsk covers: # Asia/Novosibirsk covers:
# 54 RU-NVS Novosibirsk Oblast # 54 RU-NVS Novosibirsk Oblast
# From Stepan Golosunov (2016-05-30):
# http://asozd2.duma.gov.ru/main.nsf/(Spravka)?OpenAgent&RN=1085784-6
# moves Novosibirsk oblast from UTC+6 to UTC+7.
# From Stepan Golosunov (2016-07-04):
# The law was signed yesterday and published today on
# http://publication.pravo.gov.ru/Document/View/0001201607040064
Zone Asia/Novosibirsk 5:31:40 - LMT 1919 Dec 14 6:00 Zone Asia/Novosibirsk 5:31:40 - LMT 1919 Dec 14 6:00
6:00 - NOVT 1930 Jun 21 # Novosibirsk Time 6:00 - +06 1930 Jun 21
7:00 Russia NOV%sT 1991 Mar 31 2:00s 7:00 Russia +07/+08 1991 Mar 31 2:00s
6:00 Russia NOV%sT 1992 Jan 19 2:00s 6:00 Russia +06/+07 1992 Jan 19 2:00s
7:00 Russia NOV%sT 1993 May 23 # say Shanks & P. 7:00 Russia +07/+08 1993 May 23 # say Shanks & P.
6:00 Russia NOV%sT 2011 Mar 27 2:00s 6:00 Russia +06/+07 2011 Mar 27 2:00s
7:00 - NOVT 2014 Oct 26 2:00s 7:00 - +07 2014 Oct 26 2:00s
6:00 - NOVT 6:00 - +06 2016 Jul 24 2:00s
7:00 - +07
# From Paul Eggert (2016-03-18): # From Paul Eggert (2016-03-18):
# Asia/Tomsk covers: # Asia/Tomsk covers:
...@@ -2794,6 +2807,9 @@ Zone Asia/Novosibirsk 5:31:40 - LMT 1919 Dec 14 6:00 ...@@ -2794,6 +2807,9 @@ Zone Asia/Novosibirsk 5:31:40 - LMT 1919 Dec 14 6:00
# approved by the Federation Council on 2016-04-20, signed by the President and # approved by the Federation Council on 2016-04-20, signed by the President and
# published as a law around 2016-04-26. # published as a law around 2016-04-26.
# From Matt Johnson (2016-04-26):
# http://publication.pravo.gov.ru/Document/View/0001201604260048
Zone Asia/Tomsk 5:39:51 - LMT 1919 Dec 22 Zone Asia/Tomsk 5:39:51 - LMT 1919 Dec 22
6:00 - +06 1930 Jun 21 6:00 - +06 1930 Jun 21
7:00 Russia +07/+08 1991 Mar 31 2:00s 7:00 Russia +07/+08 1991 Mar 31 2:00s
...@@ -2833,14 +2849,12 @@ Zone Asia/Tomsk 5:39:51 - LMT 1919 Dec 22 ...@@ -2833,14 +2849,12 @@ Zone Asia/Tomsk 5:39:51 - LMT 1919 Dec 22
# realigning itself with KRAT. # realigning itself with KRAT.
Zone Asia/Novokuznetsk 5:48:48 - LMT 1924 May 1 Zone Asia/Novokuznetsk 5:48:48 - LMT 1924 May 1
6:00 - KRAT 1930 Jun 21 # Krasnoyarsk Time 6:00 - +06 1930 Jun 21
7:00 Russia KRA%sT 1991 Mar 31 2:00s 7:00 Russia +07/+08 1991 Mar 31 2:00s
6:00 Russia KRA%sT 1992 Jan 19 2:00s 6:00 Russia +06/+07 1992 Jan 19 2:00s
7:00 Russia KRA%sT 2010 Mar 28 2:00s 7:00 Russia +07/+08 2010 Mar 28 2:00s
6:00 Russia NOV%sT 2011 Mar 27 2:00s # Novosibirsk 6:00 Russia +06/+07 2011 Mar 27 2:00s
7:00 - NOVT 2014 Oct 26 2:00s 7:00 - +07
7:00 - KRAT # Krasnoyarsk Time
# From Tim Parenti (2014-07-03), per Oscar van Vlijmen (2001-08-25): # From Tim Parenti (2014-07-03), per Oscar van Vlijmen (2001-08-25):
# Asia/Krasnoyarsk covers... # Asia/Krasnoyarsk covers...
......
...@@ -2214,39 +2214,39 @@ Rule NT_YK 1980 2006 - Oct lastSun 2:00 0 S ...@@ -2214,39 +2214,39 @@ Rule NT_YK 1980 2006 - Oct lastSun 2:00 0 S
Rule NT_YK 1987 2006 - Apr Sun>=1 2:00 1:00 D Rule NT_YK 1987 2006 - Apr Sun>=1 2:00 1:00 D
# Zone NAME GMTOFF RULES FORMAT [UNTIL] # Zone NAME GMTOFF RULES FORMAT [UNTIL]
# aka Panniqtuuq # aka Panniqtuuq
Zone America/Pangnirtung 0 - zzz 1921 # trading post est. Zone America/Pangnirtung 0 - -00 1921 # trading post est.
-4:00 NT_YK A%sT 1995 Apr Sun>=1 2:00 -4:00 NT_YK A%sT 1995 Apr Sun>=1 2:00
-5:00 Canada E%sT 1999 Oct 31 2:00 -5:00 Canada E%sT 1999 Oct 31 2:00
-6:00 Canada C%sT 2000 Oct 29 2:00 -6:00 Canada C%sT 2000 Oct 29 2:00
-5:00 Canada E%sT -5:00 Canada E%sT
# formerly Frobisher Bay # formerly Frobisher Bay
Zone America/Iqaluit 0 - zzz 1942 Aug # Frobisher Bay est. Zone America/Iqaluit 0 - -00 1942 Aug # Frobisher Bay est.
-5:00 NT_YK E%sT 1999 Oct 31 2:00 -5:00 NT_YK E%sT 1999 Oct 31 2:00
-6:00 Canada C%sT 2000 Oct 29 2:00 -6:00 Canada C%sT 2000 Oct 29 2:00
-5:00 Canada E%sT -5:00 Canada E%sT
# aka Qausuittuq # aka Qausuittuq
Zone America/Resolute 0 - zzz 1947 Aug 31 # Resolute founded Zone America/Resolute 0 - -00 1947 Aug 31 # Resolute founded
-6:00 NT_YK C%sT 2000 Oct 29 2:00 -6:00 NT_YK C%sT 2000 Oct 29 2:00
-5:00 - EST 2001 Apr 1 3:00 -5:00 - EST 2001 Apr 1 3:00
-6:00 Canada C%sT 2006 Oct 29 2:00 -6:00 Canada C%sT 2006 Oct 29 2:00
-5:00 - EST 2007 Mar 11 3:00 -5:00 - EST 2007 Mar 11 3:00
-6:00 Canada C%sT -6:00 Canada C%sT
# aka Kangiqiniq # aka Kangiqiniq
Zone America/Rankin_Inlet 0 - zzz 1957 # Rankin Inlet founded Zone America/Rankin_Inlet 0 - -00 1957 # Rankin Inlet founded
-6:00 NT_YK C%sT 2000 Oct 29 2:00 -6:00 NT_YK C%sT 2000 Oct 29 2:00
-5:00 - EST 2001 Apr 1 3:00 -5:00 - EST 2001 Apr 1 3:00
-6:00 Canada C%sT -6:00 Canada C%sT
# aka Iqaluktuuttiaq # aka Iqaluktuuttiaq
Zone America/Cambridge_Bay 0 - zzz 1920 # trading post est.? Zone America/Cambridge_Bay 0 - -00 1920 # trading post est.?
-7:00 NT_YK M%sT 1999 Oct 31 2:00 -7:00 NT_YK M%sT 1999 Oct 31 2:00
-6:00 Canada C%sT 2000 Oct 29 2:00 -6:00 Canada C%sT 2000 Oct 29 2:00
-5:00 - EST 2000 Nov 5 0:00 -5:00 - EST 2000 Nov 5 0:00
-6:00 - CST 2001 Apr 1 3:00 -6:00 - CST 2001 Apr 1 3:00
-7:00 Canada M%sT -7:00 Canada M%sT
Zone America/Yellowknife 0 - zzz 1935 # Yellowknife founded? Zone America/Yellowknife 0 - -00 1935 # Yellowknife founded?
-7:00 NT_YK M%sT 1980 -7:00 NT_YK M%sT 1980
-7:00 Canada M%sT -7:00 Canada M%sT
Zone America/Inuvik 0 - zzz 1953 # Inuvik founded Zone America/Inuvik 0 - -00 1953 # Inuvik founded
-8:00 NT_YK P%sT 1979 Apr lastSun 2:00 -8:00 NT_YK P%sT 1979 Apr lastSun 2:00
-7:00 NT_YK M%sT 1980 -7:00 NT_YK M%sT 1980
-7:00 Canada M%sT -7:00 Canada M%sT
......
...@@ -1332,7 +1332,7 @@ Zone Pacific/Easter -7:17:28 - LMT 1890 ...@@ -1332,7 +1332,7 @@ Zone Pacific/Easter -7:17:28 - LMT 1890
# Palmer used to be supplied from Argentina. # Palmer used to be supplied from Argentina.
# #
# Zone NAME GMTOFF RULES FORMAT [UNTIL] # Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Antarctica/Palmer 0 - zzz 1965 Zone Antarctica/Palmer 0 - -00 1965
-4:00 Arg AR%sT 1969 Oct 5 -4:00 Arg AR%sT 1969 Oct 5
-3:00 Arg AR%sT 1982 May -3:00 Arg AR%sT 1982 May
-4:00 Chile CL%sT -4:00 Chile CL%sT
...@@ -1782,16 +1782,16 @@ Zone America/Montevideo -3:44:44 - LMT 1898 Jun 28 ...@@ -1782,16 +1782,16 @@ Zone America/Montevideo -3:44:44 - LMT 1898 Jun 28
# https://actualidad.rt.com/actualidad/204758-venezuela-modificar-huso-horario-sequia-elnino # https://actualidad.rt.com/actualidad/204758-venezuela-modificar-huso-horario-sequia-elnino
# #
# From Paul Eggert (2016-04-15): # From Paul Eggert (2016-04-15):
# Clocks advance 30 minutes on 2016-05-01 at 02:30. See: # Clocks advance 30 minutes on 2016-05-01 at 02:30....
# Barboza AD. Huso horario en Venezuela volverá a 4 horas menos con
# respecto al "Greenwich". Panorama 2016-04-15 12:20 -0430.
# http://www.panorama.com.ve/ciudad/Huso-horario-en-Venezuela-volvera-a-4-horas-menos-con-respecto-al-Greenwich-20160415-0032.html
#
# "'Venezuela's new time-zone: hours without light, hours without water, # "'Venezuela's new time-zone: hours without light, hours without water,
# hours of presidential broadcasts, hours of lines," quipped comedian # hours of presidential broadcasts, hours of lines,' quipped comedian
# Jean Mary Curro ...". See: Cawthorne A, Kai D. Venezuela scraps # Jean Mary Curró ...". See: Cawthorne A, Kai D. Venezuela scraps
# half-hour time difference set by Chavez. Reuters 2016-04-15 14:50 -0400 # half-hour time difference set by Chavez. Reuters 2016-04-15 14:50 -0400
# http://www.reuters.com/article/us-venezuela-timezone-idUSKCN0XC2BE # http://www.reuters.com/article/us-venezuela-timezone-idUSKCN0XC2BE
#
# From Matt Johnson (2016-04-20):
# ... published in the official Gazette [2016-04-18], here:
# http://historico.tsj.gob.ve/gaceta_ext/abril/1842016/E-1842016-4551.pdf
# Zone NAME GMTOFF RULES FORMAT [UNTIL] # Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone America/Caracas -4:27:44 - LMT 1890 Zone America/Caracas -4:27:44 - LMT 1890
......
/* /*
* Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -25,6 +25,8 @@ ...@@ -25,6 +25,8 @@
package sun.lwawt.macosx; package sun.lwawt.macosx;
import sun.lwawt.LWWindowPeer;
import java.awt.*; import java.awt.*;
import java.beans.*; import java.beans.*;
import java.lang.reflect.Field; import java.lang.reflect.Field;
...@@ -421,6 +423,8 @@ class CAccessibility implements PropertyChangeListener { ...@@ -421,6 +423,8 @@ class CAccessibility implements PropertyChangeListener {
} }
public static AccessibleAction getAccessibleAction(final Accessible a, final Component c) { public static AccessibleAction getAccessibleAction(final Accessible a, final Component c) {
if (a == null) return null;
return invokeAndWait(new Callable<AccessibleAction>() { return invokeAndWait(new Callable<AccessibleAction>() {
public AccessibleAction call() throws Exception { public AccessibleAction call() throws Exception {
final AccessibleContext ac = a.getAccessibleContext(); final AccessibleContext ac = a.getAccessibleContext();
...@@ -667,4 +671,28 @@ class CAccessibility implements PropertyChangeListener { ...@@ -667,4 +671,28 @@ class CAccessibility implements PropertyChangeListener {
} }
}, c); }, c);
} }
/**
* @return AWTView ptr, a peer of the CPlatformView associated with the toplevel container of the Accessible, if any
*/
private static long getAWTView(Accessible a) {
Accessible ax = CAccessible.getSwingAccessible(a);
if (!(ax instanceof Component)) return 0;
return invokeAndWait(new Callable<Long>() {
public Long call() throws Exception {
Component cont = (Component) ax;
while (cont != null && !(cont instanceof Window)) {
cont = cont.getParent();
}
if (cont != null) {
LWWindowPeer peer = (LWWindowPeer) cont.getPeer();
if (peer != null) {
return ((CPlatformWindow) peer.getPlatformWindow()).getContentView().getAWTView();
}
}
return 0L;
}
}, (Component)ax);
}
} }
/* /*
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -264,6 +264,8 @@ class CAccessibleText { ...@@ -264,6 +264,8 @@ class CAccessibleText {
final double localY = boundsUnion.getY(); final double localY = boundsUnion.getY();
final Point componentLocation = ac.getAccessibleComponent().getLocationOnScreen(); final Point componentLocation = ac.getAccessibleComponent().getLocationOnScreen();
if (componentLocation == null) return ret;
final double screenX = componentLocation.getX() + localX; final double screenX = componentLocation.getX() + localX;
final double screenY = componentLocation.getY() + localY; final double screenY = componentLocation.getY() + localY;
......
...@@ -34,6 +34,7 @@ import java.awt.event.MouseEvent; ...@@ -34,6 +34,7 @@ import java.awt.event.MouseEvent;
import java.awt.event.InputEvent; import java.awt.event.InputEvent;
import java.awt.event.MouseWheelEvent; import java.awt.event.MouseWheelEvent;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import java.util.Locale;
/** /**
* Translates NSEvents/NPCocoaEvents into AWT events. * Translates NSEvents/NPCocoaEvents into AWT events.
...@@ -171,6 +172,16 @@ final class CPlatformResponder { ...@@ -171,6 +172,16 @@ final class CPlatformResponder {
} }
} }
// If Pinyin Simplified input method is selected, CAPS_LOCK key is supposed to switch
// input to latin letters.
// It is necessary to use testCharIgnoringModifiers instead of testChar for event
// generation in such case to avoid uppercase letters in text components.
LWCToolkit lwcToolkit = (LWCToolkit)Toolkit.getDefaultToolkit();
if (lwcToolkit.getLockingKeyState(KeyEvent.VK_CAPS_LOCK) &&
Locale.SIMPLIFIED_CHINESE.equals(lwcToolkit.getDefaultKeyboardLocale())) {
testChar = testCharIgnoringModifiers;
}
jkeyCode = out[0]; jkeyCode = out[0];
jkeyLocation = out[1]; jkeyLocation = out[1];
jeventType = isNpapiCallback ? NSEvent.npToJavaEventType(eventType) : jeventType = isNpapiCallback ? NSEvent.npToJavaEventType(eventType) :
......
...@@ -427,9 +427,6 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo ...@@ -427,9 +427,6 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
@Override // PlatformWindow @Override // PlatformWindow
public void dispose() { public void dispose() {
if (owner != null) {
CWrapper.NSWindow.removeChildWindow(owner.getNSWindowPtr(), getNSWindowPtr());
}
contentView.dispose(); contentView.dispose();
nativeDispose(getNSWindowPtr()); nativeDispose(getNSWindowPtr());
CPlatformWindow.super.dispose(); CPlatformWindow.super.dispose();
...@@ -526,25 +523,6 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo ...@@ -526,25 +523,6 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
public void setVisible(boolean visible) { public void setVisible(boolean visible) {
final long nsWindowPtr = getNSWindowPtr(); final long nsWindowPtr = getNSWindowPtr();
// Process parent-child relationship when hiding
if (!visible) {
// Unparent my children
for (Window w : target.getOwnedWindows()) {
WindowPeer p = (WindowPeer)w.getPeer();
if (p instanceof LWWindowPeer) {
CPlatformWindow pw = (CPlatformWindow)((LWWindowPeer)p).getPlatformWindow();
if (pw != null && pw.isVisible()) {
CWrapper.NSWindow.removeChildWindow(nsWindowPtr, pw.getNSWindowPtr());
}
}
}
// Unparent myself
if (owner != null && owner.isVisible()) {
CWrapper.NSWindow.removeChildWindow(owner.getNSWindowPtr(), nsWindowPtr);
}
}
// Configure stuff // Configure stuff
updateIconImages(); updateIconImages();
updateFocusabilityForAutoRequestFocus(false); updateFocusabilityForAutoRequestFocus(false);
...@@ -618,19 +596,19 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo ...@@ -618,19 +596,19 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
// Manage parent-child relationship when showing // Manage parent-child relationship when showing
if (visible) { if (visible) {
// Add myself as a child // Order myself above my parent
if (owner != null && owner.isVisible()) { if (owner != null && owner.isVisible()) {
CWrapper.NSWindow.addChildWindow(owner.getNSWindowPtr(), nsWindowPtr, CWrapper.NSWindow.NSWindowAbove); CWrapper.NSWindow.orderWindow(nsWindowPtr, CWrapper.NSWindow.NSWindowAbove, owner.getNSWindowPtr());
applyWindowLevel(target); applyWindowLevel(target);
} }
// Add my own children to myself // Order my own children above myself
for (Window w : target.getOwnedWindows()) { for (Window w : target.getOwnedWindows()) {
WindowPeer p = (WindowPeer)w.getPeer(); WindowPeer p = (WindowPeer)w.getPeer();
if (p instanceof LWWindowPeer) { if (p instanceof LWWindowPeer) {
CPlatformWindow pw = (CPlatformWindow)((LWWindowPeer)p).getPlatformWindow(); CPlatformWindow pw = (CPlatformWindow)((LWWindowPeer)p).getPlatformWindow();
if (pw != null && pw.isVisible()) { if (pw != null && pw.isVisible()) {
CWrapper.NSWindow.addChildWindow(nsWindowPtr, pw.getNSWindowPtr(), CWrapper.NSWindow.NSWindowAbove); CWrapper.NSWindow.orderWindow(pw.getNSWindowPtr(), CWrapper.NSWindow.NSWindowAbove, nsWindowPtr);
pw.applyWindowLevel(w); pw.applyWindowLevel(w);
} }
} }
...@@ -1059,8 +1037,8 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo ...@@ -1059,8 +1037,8 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
// Order the window to front of the stack of child windows // Order the window to front of the stack of child windows
final long nsWindowSelfPtr = getNSWindowPtr(); final long nsWindowSelfPtr = getNSWindowPtr();
final long nsWindowOwnerPtr = owner.getNSWindowPtr(); final long nsWindowOwnerPtr = owner.getNSWindowPtr();
CWrapper.NSWindow.removeChildWindow(nsWindowOwnerPtr, nsWindowSelfPtr); CWrapper.NSWindow.orderFront(nsWindowOwnerPtr);
CWrapper.NSWindow.addChildWindow(nsWindowOwnerPtr, nsWindowSelfPtr, CWrapper.NSWindow.NSWindowAbove); CWrapper.NSWindow.orderWindow(nsWindowSelfPtr, CWrapper.NSWindow.NSWindowAbove, nsWindowOwnerPtr);
} }
applyWindowLevel(target); applyWindowLevel(target);
......
...@@ -221,15 +221,6 @@ public final class CWarningWindow extends CPlatformWindow ...@@ -221,15 +221,6 @@ public final class CWarningWindow extends CPlatformWindow
synchronized (lock) { synchronized (lock) {
final long nsWindowPtr = getNSWindowPtr(); final long nsWindowPtr = getNSWindowPtr();
// Process parent-child relationship when hiding
if (!visible) {
// Unparent myself
if (owner != null && owner.isVisible()) {
CWrapper.NSWindow.removeChildWindow(
owner.getNSWindowPtr(), nsWindowPtr);
}
}
// Actually show or hide the window // Actually show or hide the window
if (visible) { if (visible) {
CWrapper.NSWindow.orderFront(nsWindowPtr); CWrapper.NSWindow.orderFront(nsWindowPtr);
...@@ -241,10 +232,10 @@ public final class CWarningWindow extends CPlatformWindow ...@@ -241,10 +232,10 @@ public final class CWarningWindow extends CPlatformWindow
// Manage parent-child relationship when showing // Manage parent-child relationship when showing
if (visible) { if (visible) {
// Add myself as a child // Order myself above my parent
if (owner != null && owner.isVisible()) { if (owner != null && owner.isVisible()) {
CWrapper.NSWindow.addChildWindow(owner.getNSWindowPtr(), CWrapper.NSWindow.orderWindow(nsWindowPtr,
nsWindowPtr, CWrapper.NSWindow.NSWindowAbove); CWrapper.NSWindow.NSWindowAbove, owner.getNSWindowPtr());
// do not allow security warning to be obscured by other windows // do not allow security warning to be obscured by other windows
applyWindowLevel(ownerWindow); applyWindowLevel(ownerWindow);
......
/* /*
* Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -63,6 +63,8 @@ ...@@ -63,6 +63,8 @@
- (void) deliverJavaMouseEvent: (NSEvent *) event; - (void) deliverJavaMouseEvent: (NSEvent *) event;
- (jobject) awtComponent:(JNIEnv *)env; - (jobject) awtComponent:(JNIEnv *)env;
+ (AWTView *) awtView:(JNIEnv *)env ofAccessible:(jobject)jaccessible;
// Input method-related events // Input method-related events
- (void)setInputMethod:(jobject)inputMethod; - (void)setInputMethod:(jobject)inputMethod;
- (void)abandonInput; - (void)abandonInput;
......
/* /*
* Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#import "LWCToolkit.h" #import "LWCToolkit.h"
#import "JavaComponentAccessibility.h" #import "JavaComponentAccessibility.h"
#import "JavaTextAccessibility.h" #import "JavaTextAccessibility.h"
#import "JavaAccessibilityUtilities.h"
#import "GeomUtilities.h" #import "GeomUtilities.h"
#import "OSVersion.h" #import "OSVersion.h"
#import "CGLLayer.h" #import "CGLLayer.h"
...@@ -132,7 +133,7 @@ AWT_ASSERT_APPKIT_THREAD; ...@@ -132,7 +133,7 @@ AWT_ASSERT_APPKIT_THREAD;
self.cglLayer = nil; self.cglLayer = nil;
JNIEnv *env = [ThreadUtilities getJNIEnvUncached]; JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
(*env)->DeleteGlobalRef(env, m_cPlatformView); (*env)->DeleteWeakGlobalRef(env, m_cPlatformView);
m_cPlatformView = NULL; m_cPlatformView = NULL;
if (fInputMethodLOCKABLE != NULL) if (fInputMethodLOCKABLE != NULL)
...@@ -402,7 +403,12 @@ AWT_ASSERT_APPKIT_THREAD; ...@@ -402,7 +403,12 @@ AWT_ASSERT_APPKIT_THREAD;
static JNF_CLASS_CACHE(jc_PlatformView, "sun/lwawt/macosx/CPlatformView"); static JNF_CLASS_CACHE(jc_PlatformView, "sun/lwawt/macosx/CPlatformView");
static JNF_MEMBER_CACHE(jm_deliverMouseEvent, jc_PlatformView, "deliverMouseEvent", "(Lsun/lwawt/macosx/NSEvent;)V"); static JNF_MEMBER_CACHE(jm_deliverMouseEvent, jc_PlatformView, "deliverMouseEvent", "(Lsun/lwawt/macosx/NSEvent;)V");
JNFCallVoidMethod(env, m_cPlatformView, jm_deliverMouseEvent, jEvent);
jobject jlocal = (*env)->NewLocalRef(env, m_cPlatformView);
if (!(*env)->IsSameObject(env, jlocal, NULL)) {
JNFCallVoidMethod(env, jlocal, jm_deliverMouseEvent, jEvent);
(*env)->DeleteLocalRef(env, jlocal);
}
} }
- (void) resetTrackingArea { - (void) resetTrackingArea {
...@@ -463,7 +469,12 @@ AWT_ASSERT_APPKIT_THREAD; ...@@ -463,7 +469,12 @@ AWT_ASSERT_APPKIT_THREAD;
static JNF_CLASS_CACHE(jc_PlatformView, "sun/lwawt/macosx/CPlatformView"); static JNF_CLASS_CACHE(jc_PlatformView, "sun/lwawt/macosx/CPlatformView");
static JNF_MEMBER_CACHE(jm_deliverKeyEvent, jc_PlatformView, static JNF_MEMBER_CACHE(jm_deliverKeyEvent, jc_PlatformView,
"deliverKeyEvent", "(Lsun/lwawt/macosx/NSEvent;)V"); "deliverKeyEvent", "(Lsun/lwawt/macosx/NSEvent;)V");
JNFCallVoidMethod(env, m_cPlatformView, jm_deliverKeyEvent, jevent);
jobject jlocal = (*env)->NewLocalRef(env, m_cPlatformView);
if (!(*env)->IsSameObject(env, jlocal, NULL)) {
JNFCallVoidMethod(env, jlocal, jm_deliverKeyEvent, jevent);
(*env)->DeleteLocalRef(env, jlocal);
}
if (characters != NULL) { if (characters != NULL) {
(*env)->DeleteLocalRef(env, characters); (*env)->DeleteLocalRef(env, characters);
...@@ -478,7 +489,12 @@ AWT_ASSERT_APPKIT_THREAD; ...@@ -478,7 +489,12 @@ AWT_ASSERT_APPKIT_THREAD;
JNIEnv *env = [ThreadUtilities getJNIEnv]; JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_CLASS_CACHE(jc_PlatformView, "sun/lwawt/macosx/CPlatformView"); static JNF_CLASS_CACHE(jc_PlatformView, "sun/lwawt/macosx/CPlatformView");
static JNF_MEMBER_CACHE(jm_deliverResize, jc_PlatformView, "deliverResize", "(IIII)V"); static JNF_MEMBER_CACHE(jm_deliverResize, jc_PlatformView, "deliverResize", "(IIII)V");
JNFCallVoidMethod(env, m_cPlatformView, jm_deliverResize, x,y,w,h);
jobject jlocal = (*env)->NewLocalRef(env, m_cPlatformView);
if (!(*env)->IsSameObject(env, jlocal, NULL)) {
JNFCallVoidMethod(env, jlocal, jm_deliverResize, x,y,w,h);
(*env)->DeleteLocalRef(env, jlocal);
}
} }
...@@ -507,7 +523,12 @@ AWT_ASSERT_APPKIT_THREAD; ...@@ -507,7 +523,12 @@ AWT_ASSERT_APPKIT_THREAD;
*/ */
static JNF_CLASS_CACHE(jc_CPlatformView, "sun/lwawt/macosx/CPlatformView"); static JNF_CLASS_CACHE(jc_CPlatformView, "sun/lwawt/macosx/CPlatformView");
static JNF_MEMBER_CACHE(jm_deliverWindowDidExposeEvent, jc_CPlatformView, "deliverWindowDidExposeEvent", "()V"); static JNF_MEMBER_CACHE(jm_deliverWindowDidExposeEvent, jc_CPlatformView, "deliverWindowDidExposeEvent", "()V");
JNFCallVoidMethod(env, m_cPlatformView, jm_deliverWindowDidExposeEvent);
jobject jlocal = (*env)->NewLocalRef(env, m_cPlatformView);
if (!(*env)->IsSameObject(env, jlocal, NULL)) {
JNFCallVoidMethod(env, jlocal, jm_deliverWindowDidExposeEvent);
(*env)->DeleteLocalRef(env, jlocal);
}
/* /*
} }
*/ */
...@@ -515,8 +536,10 @@ AWT_ASSERT_APPKIT_THREAD; ...@@ -515,8 +536,10 @@ AWT_ASSERT_APPKIT_THREAD;
} }
-(BOOL) isCodePointInUnicodeBlockNeedingIMEvent: (unichar) codePoint { -(BOOL) isCodePointInUnicodeBlockNeedingIMEvent: (unichar) codePoint {
if ((codePoint >= 0x3000) && (codePoint <= 0x303F)) { if (((codePoint >= 0x3000) && (codePoint <= 0x303F)) ||
// Code point is in 'CJK Symbols and Punctuation' Unicode block. ((codePoint >= 0xFF00) && (codePoint <= 0xFFEF))) {
// Code point is in 'CJK Symbols and Punctuation' or
// 'Halfwidth and Fullwidth Forms' Unicode block.
return YES; return YES;
} }
return NO; return NO;
...@@ -535,7 +558,13 @@ AWT_ASSERT_APPKIT_THREAD; ...@@ -535,7 +558,13 @@ AWT_ASSERT_APPKIT_THREAD;
} }
return NULL; return NULL;
} }
jobject peer = JNFGetObjectField(env, m_cPlatformView, jf_Peer);
jobject peer = NULL;
jobject jlocal = (*env)->NewLocalRef(env, m_cPlatformView);
if (!(*env)->IsSameObject(env, jlocal, NULL)) {
peer = JNFGetObjectField(env, jlocal, jf_Peer);
(*env)->DeleteLocalRef(env, jlocal);
}
static JNF_CLASS_CACHE(jc_LWWindowPeer, "sun/lwawt/LWWindowPeer"); static JNF_CLASS_CACHE(jc_LWWindowPeer, "sun/lwawt/LWWindowPeer");
static JNF_MEMBER_CACHE(jf_Target, jc_LWWindowPeer, "target", "Ljava/awt/Component;"); static JNF_MEMBER_CACHE(jf_Target, jc_LWWindowPeer, "target", "Ljava/awt/Component;");
if (peer == NULL) { if (peer == NULL) {
...@@ -543,12 +572,27 @@ AWT_ASSERT_APPKIT_THREAD; ...@@ -543,12 +572,27 @@ AWT_ASSERT_APPKIT_THREAD;
JNFDumpJavaStack(env); JNFDumpJavaStack(env);
return NULL; return NULL;
} }
return JNFGetObjectField(env, peer, jf_Target); jobject comp = JNFGetObjectField(env, peer, jf_Target);
(*env)->DeleteLocalRef(env, peer);
return comp;
}
+ (AWTView *) awtView:(JNIEnv*)env ofAccessible:(jobject)jaccessible
{
static JNF_STATIC_MEMBER_CACHE(jm_getAWTView, sjc_CAccessibility, "getAWTView", "(Ljavax/accessibility/Accessible;)J");
jlong jptr = JNFCallStaticLongMethod(env, jm_getAWTView, jaccessible);
if (jptr == 0) return nil;
return (AWTView *)jlong_to_ptr(jptr);
} }
- (id)getAxData:(JNIEnv*)env - (id)getAxData:(JNIEnv*)env
{ {
return [[[JavaComponentAccessibility alloc] initWithParent:self withEnv:env withAccessible:[self awtComponent:env] withIndex:-1 withView:self withJavaRole:nil] autorelease]; jobject jcomponent = [self awtComponent:env];
id ax = [[[JavaComponentAccessibility alloc] initWithParent:self withEnv:env withAccessible:jcomponent withIndex:-1 withView:self withJavaRole:nil] autorelease];
(*env)->DeleteLocalRef(env, jcomponent);
return ax;
} }
- (NSArray *)accessibilityAttributeNames - (NSArray *)accessibilityAttributeNames
...@@ -1291,7 +1335,7 @@ Java_sun_lwawt_macosx_CPlatformView_nativeCreateView ...@@ -1291,7 +1335,7 @@ Java_sun_lwawt_macosx_CPlatformView_nativeCreateView
JNF_COCOA_ENTER(env); JNF_COCOA_ENTER(env);
NSRect rect = NSMakeRect(originX, originY, width, height); NSRect rect = NSMakeRect(originX, originY, width, height);
jobject cPlatformView = (*env)->NewGlobalRef(env, obj); jobject cPlatformView = (*env)->NewWeakGlobalRef(env, obj);
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){ [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
......
...@@ -46,6 +46,7 @@ ...@@ -46,6 +46,7 @@
NSWindow *nsWindow; NSWindow *nsWindow;
AWTWindow *ownerWindow; AWTWindow *ownerWindow;
jint preFullScreenLevel; jint preFullScreenLevel;
BOOL isMinimizing;
} }
// An instance of either AWTWindow_Normal or AWTWindow_Panel // An instance of either AWTWindow_Normal or AWTWindow_Panel
...@@ -59,6 +60,7 @@ ...@@ -59,6 +60,7 @@
@property (nonatomic) jint styleBits; @property (nonatomic) jint styleBits;
@property (nonatomic) BOOL isEnabled; @property (nonatomic) BOOL isEnabled;
@property (nonatomic) jint preFullScreenLevel; @property (nonatomic) jint preFullScreenLevel;
@property (nonatomic) BOOL isMinimizing;
- (id) initWithPlatformWindow:(JNFWeakJObjectWrapper *)javaPlatformWindow - (id) initWithPlatformWindow:(JNFWeakJObjectWrapper *)javaPlatformWindow
......
...@@ -184,6 +184,7 @@ AWT_NS_WINDOW_IMPLEMENTATION ...@@ -184,6 +184,7 @@ AWT_NS_WINDOW_IMPLEMENTATION
@synthesize isEnabled; @synthesize isEnabled;
@synthesize ownerWindow; @synthesize ownerWindow;
@synthesize preFullScreenLevel; @synthesize preFullScreenLevel;
@synthesize isMinimizing;
- (void) updateMinMaxSize:(BOOL)resizable { - (void) updateMinMaxSize:(BOOL)resizable {
if (resizable) { if (resizable) {
...@@ -308,6 +309,7 @@ AWT_ASSERT_APPKIT_THREAD; ...@@ -308,6 +309,7 @@ AWT_ASSERT_APPKIT_THREAD;
[self.nsWindow release]; // the property retains the object already [self.nsWindow release]; // the property retains the object already
self.isEnabled = YES; self.isEnabled = YES;
self.isMinimizing = NO;
self.javaPlatformWindow = platformWindow; self.javaPlatformWindow = platformWindow;
self.styleBits = bits; self.styleBits = bits;
self.ownerWindow = owner; self.ownerWindow = owner;
...@@ -427,6 +429,68 @@ AWT_ASSERT_APPKIT_THREAD; ...@@ -427,6 +429,68 @@ AWT_ASSERT_APPKIT_THREAD;
[super dealloc]; [super dealloc];
} }
// Tests wheather the corresponding Java paltform window is visible or not
+ (BOOL) isJavaPlatformWindowVisible:(NSWindow *)window {
BOOL isVisible = NO;
if ([AWTWindow isAWTWindow:window] && [window delegate] != nil) {
AWTWindow *awtWindow = (AWTWindow *)[window delegate];
[AWTToolkit eventCountPlusPlus];
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject platformWindow = [awtWindow.javaPlatformWindow jObjectWithEnv:env];
if (platformWindow != NULL) {
static JNF_MEMBER_CACHE(jm_isVisible, jc_CPlatformWindow, "isVisible", "()Z");
isVisible = JNFCallBooleanMethod(env, platformWindow, jm_isVisible) == JNI_TRUE ? YES : NO;
(*env)->DeleteLocalRef(env, platformWindow);
}
}
return isVisible;
}
// Orders window's childs based on the current focus state
- (void) orderChildWindows:(BOOL)focus {
AWT_ASSERT_APPKIT_THREAD;
if (self.isMinimizing) {
// Do not perform any ordering, if iconify is in progress
return;
}
NSEnumerator *windowEnumerator = [[NSApp windows]objectEnumerator];
NSWindow *window;
while ((window = [windowEnumerator nextObject]) != nil) {
if ([AWTWindow isJavaPlatformWindowVisible:window]) {
AWTWindow *awtWindow = (AWTWindow *)[window delegate];
AWTWindow *owner = awtWindow.ownerWindow;
if (IS(awtWindow.styleBits, ALWAYS_ON_TOP)) {
// Do not order 'always on top' windows
continue;
}
while (awtWindow.ownerWindow != nil) {
if (awtWindow.ownerWindow == self) {
if (focus) {
// Move the childWindow to floating level
// so it will appear in front of its
// parent which owns the focus
[window setLevel:NSFloatingWindowLevel];
} else {
// Focus owner has changed, move the childWindow
// back to normal window level
[window setLevel:NSNormalWindowLevel];
}
// The childWindow should be displayed in front of
// its nearest parentWindow
[window orderWindow:NSWindowAbove relativeTo:[owner.nsWindow windowNumber]];
break;
}
awtWindow = awtWindow.ownerWindow;
}
}
}
}
// NSWindow overrides // NSWindow overrides
- (BOOL) canBecomeKeyWindow { - (BOOL) canBecomeKeyWindow {
AWT_ASSERT_APPKIT_THREAD; AWT_ASSERT_APPKIT_THREAD;
...@@ -509,6 +573,30 @@ AWT_ASSERT_APPKIT_THREAD; ...@@ -509,6 +573,30 @@ AWT_ASSERT_APPKIT_THREAD;
// window exposing in _setVisible:(BOOL) // window exposing in _setVisible:(BOOL)
} }
// Hides/shows window's childs during iconify/de-iconify operation
- (void) iconifyChildWindows:(BOOL)iconify {
AWT_ASSERT_APPKIT_THREAD;
NSEnumerator *windowEnumerator = [[NSApp windows]objectEnumerator];
NSWindow *window;
while ((window = [windowEnumerator nextObject]) != nil) {
if ([AWTWindow isJavaPlatformWindowVisible:window]) {
AWTWindow *awtWindow = (AWTWindow *)[window delegate];
while (awtWindow.ownerWindow != nil) {
if (awtWindow.ownerWindow == self) {
if (iconify) {
[window orderOut:window];
} else {
[window orderFront:window];
}
break;
}
awtWindow = awtWindow.ownerWindow;
}
}
}
}
- (void) _deliverIconify:(BOOL)iconify { - (void) _deliverIconify:(BOOL)iconify {
AWT_ASSERT_APPKIT_THREAD; AWT_ASSERT_APPKIT_THREAD;
...@@ -522,16 +610,28 @@ AWT_ASSERT_APPKIT_THREAD; ...@@ -522,16 +610,28 @@ AWT_ASSERT_APPKIT_THREAD;
} }
} }
- (void)windowWillMiniaturize:(NSNotification *)notification {
AWT_ASSERT_APPKIT_THREAD;
self.isMinimizing = YES;
// Excplicitly make myself a key window to avoid possible
// negative visual effects during iconify operation
[self.nsWindow makeKeyAndOrderFront:self.nsWindow];
[self iconifyChildWindows:YES];
}
- (void)windowDidMiniaturize:(NSNotification *)notification { - (void)windowDidMiniaturize:(NSNotification *)notification {
AWT_ASSERT_APPKIT_THREAD; AWT_ASSERT_APPKIT_THREAD;
[self _deliverIconify:JNI_TRUE]; [self _deliverIconify:JNI_TRUE];
self.isMinimizing = NO;
} }
- (void)windowDidDeminiaturize:(NSNotification *)notification { - (void)windowDidDeminiaturize:(NSNotification *)notification {
AWT_ASSERT_APPKIT_THREAD; AWT_ASSERT_APPKIT_THREAD;
[self _deliverIconify:JNI_FALSE]; [self _deliverIconify:JNI_FALSE];
[self iconifyChildWindows:NO];
} }
- (void) _deliverWindowFocusEvent:(BOOL)focused oppositeWindow:(AWTWindow *)opposite { - (void) _deliverWindowFocusEvent:(BOOL)focused oppositeWindow:(AWTWindow *)opposite {
...@@ -577,6 +677,7 @@ AWT_ASSERT_APPKIT_THREAD; ...@@ -577,6 +677,7 @@ AWT_ASSERT_APPKIT_THREAD;
[AWTWindow setLastKeyWindow:nil]; [AWTWindow setLastKeyWindow:nil];
[self _deliverWindowFocusEvent:YES oppositeWindow: opposite]; [self _deliverWindowFocusEvent:YES oppositeWindow: opposite];
[self orderChildWindows:YES];
} }
- (void) windowDidResignKey: (NSNotification *) notification { - (void) windowDidResignKey: (NSNotification *) notification {
...@@ -604,6 +705,7 @@ AWT_ASSERT_APPKIT_THREAD; ...@@ -604,6 +705,7 @@ AWT_ASSERT_APPKIT_THREAD;
} }
[self _deliverWindowFocusEvent:NO oppositeWindow: opposite]; [self _deliverWindowFocusEvent:NO oppositeWindow: opposite];
[self orderChildWindows:NO];
} }
- (void) windowDidBecomeMain: (NSNotification *) notification { - (void) windowDidBecomeMain: (NSNotification *) notification {
......
/* /*
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -35,9 +35,9 @@ ...@@ -35,9 +35,9 @@
{ {
self = [super init]; self = [super init];
if (self) { if (self) {
fAccessibleAction = JNFNewGlobalRef(env, accessibleAction); fAccessibleAction = JNFNewWeakGlobalRef(env, accessibleAction);
fIndex = index; fIndex = index;
fComponent = JNFNewGlobalRef(env, component); fComponent = JNFNewWeakGlobalRef(env, component);
} }
return self; return self;
} }
...@@ -46,10 +46,10 @@ ...@@ -46,10 +46,10 @@
{ {
JNIEnv *env = [ThreadUtilities getJNIEnvUncached]; JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
JNFDeleteGlobalRef(env, fAccessibleAction); JNFDeleteWeakGlobalRef(env, fAccessibleAction);
fAccessibleAction = NULL; fAccessibleAction = NULL;
JNFDeleteGlobalRef(env, fComponent); JNFDeleteWeakGlobalRef(env, fComponent);
fComponent = NULL; fComponent = NULL;
[super dealloc]; [super dealloc];
...@@ -59,10 +59,10 @@ ...@@ -59,10 +59,10 @@
{ {
JNIEnv *env = [ThreadUtilities getJNIEnvUncached]; JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
JNFDeleteGlobalRef(env, fAccessibleAction); JNFDeleteWeakGlobalRef(env, fAccessibleAction);
fAccessibleAction = NULL; fAccessibleAction = NULL;
JNFDeleteGlobalRef(env, fComponent); JNFDeleteWeakGlobalRef(env, fComponent);
fComponent = NULL; fComponent = NULL;
[super finalize]; [super finalize];
...@@ -75,7 +75,18 @@ ...@@ -75,7 +75,18 @@
JNIEnv* env = [ThreadUtilities getJNIEnv]; JNIEnv* env = [ThreadUtilities getJNIEnv];
return JNFJavaToNSString(env, JNFCallStaticObjectMethod(env, jm_getAccessibleActionDescription, fAccessibleAction, fIndex, fComponent)); // AWT_THREADING Safe (AWTRunLoopMode) jobject fCompLocal = (*env)->NewLocalRef(env, fComponent);
if ((*env)->IsSameObject(env, fCompLocal, NULL)) {
return @"unknown";
}
NSString *str = nil;
jobject jstr = JNFCallStaticObjectMethod(env, jm_getAccessibleActionDescription, fAccessibleAction, fIndex, fCompLocal);
if (jstr != NULL) {
NSString *str = JNFJavaToNSString(env, jstr); // AWT_THREADING Safe (AWTRunLoopMode)
(*env)->DeleteLocalRef(env, jstr);
}
(*env)->DeleteLocalRef(env, fCompLocal);
return str == nil ? @"unknown" : str;
} }
- (void)perform - (void)perform
...@@ -96,9 +107,9 @@ ...@@ -96,9 +107,9 @@
{ {
self = [super init]; self = [super init];
if (self) { if (self) {
fTabGroup = JNFNewGlobalRef(env, tabGroup); fTabGroup = JNFNewWeakGlobalRef(env, tabGroup);
fIndex = index; fIndex = index;
fComponent = JNFNewGlobalRef(env, component); fComponent = JNFNewWeakGlobalRef(env, component);
} }
return self; return self;
} }
...@@ -107,10 +118,10 @@ ...@@ -107,10 +118,10 @@
{ {
JNIEnv *env = [ThreadUtilities getJNIEnvUncached]; JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
JNFDeleteGlobalRef(env, fTabGroup); JNFDeleteWeakGlobalRef(env, fTabGroup);
fTabGroup = NULL; fTabGroup = NULL;
JNFDeleteGlobalRef(env, fComponent); JNFDeleteWeakGlobalRef(env, fComponent);
fComponent = NULL; fComponent = NULL;
[super dealloc]; [super dealloc];
...@@ -120,10 +131,10 @@ ...@@ -120,10 +131,10 @@
{ {
JNIEnv *env = [ThreadUtilities getJNIEnvUncached]; JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
JNFDeleteGlobalRef(env, fTabGroup); JNFDeleteWeakGlobalRef(env, fTabGroup);
fTabGroup = NULL; fTabGroup = NULL;
JNFDeleteGlobalRef(env, fComponent); JNFDeleteWeakGlobalRef(env, fComponent);
fComponent = NULL; fComponent = NULL;
[super finalize]; [super finalize];
......
/* /*
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -77,7 +77,9 @@ NSString *getJavaRole(JNIEnv *env, jobject axComponent, jobject component) ...@@ -77,7 +77,9 @@ NSString *getJavaRole(JNIEnv *env, jobject axComponent, jobject component)
jobject axRole = JNFCallStaticObjectMethod(env, sjm_getAccessibleRole, axComponent, component); // AWT_THREADING Safe (AWTRunLoopMode) jobject axRole = JNFCallStaticObjectMethod(env, sjm_getAccessibleRole, axComponent, component); // AWT_THREADING Safe (AWTRunLoopMode)
if (axRole == NULL) return @"unknown"; if (axRole == NULL) return @"unknown";
return JNFJavaToNSString(env, axRole); NSString* str = JNFJavaToNSString(env, axRole);
(*env)->DeleteLocalRef(env, axRole);
return str;
} }
jobject getAxSelection(JNIEnv *env, jobject axContext, jobject component) jobject getAxSelection(JNIEnv *env, jobject axContext, jobject component)
...@@ -126,21 +128,27 @@ BOOL isVertical(JNIEnv *env, jobject axContext, jobject component) ...@@ -126,21 +128,27 @@ BOOL isVertical(JNIEnv *env, jobject axContext, jobject component)
{ {
static JNF_STATIC_MEMBER_CACHE(jm_VERTICAL, sjc_AccessibleState, "VERTICAL", "Ljavax/accessibility/AccessibleState;"); static JNF_STATIC_MEMBER_CACHE(jm_VERTICAL, sjc_AccessibleState, "VERTICAL", "Ljavax/accessibility/AccessibleState;");
jobject axVertState = JNFGetStaticObjectField(env, jm_VERTICAL); jobject axVertState = JNFGetStaticObjectField(env, jm_VERTICAL);
return containsAxState(env, axContext, axVertState, component); BOOL vertical = containsAxState(env, axContext, axVertState, component);
(*env)->DeleteLocalRef(env, axVertState);
return vertical;
} }
BOOL isHorizontal(JNIEnv *env, jobject axContext, jobject component) BOOL isHorizontal(JNIEnv *env, jobject axContext, jobject component)
{ {
static JNF_STATIC_MEMBER_CACHE(jm_HORIZONTAL, sjc_AccessibleState, "HORIZONTAL", "Ljavax/accessibility/AccessibleState;"); static JNF_STATIC_MEMBER_CACHE(jm_HORIZONTAL, sjc_AccessibleState, "HORIZONTAL", "Ljavax/accessibility/AccessibleState;");
jobject axHorizState = JNFGetStaticObjectField(env, jm_HORIZONTAL); jobject axHorizState = JNFGetStaticObjectField(env, jm_HORIZONTAL);
return containsAxState(env, axContext, axHorizState, component); BOOL horizontal = containsAxState(env, axContext, axHorizState, component);
(*env)->DeleteLocalRef(env, axHorizState);
return horizontal;
} }
BOOL isShowing(JNIEnv *env, jobject axContext, jobject component) BOOL isShowing(JNIEnv *env, jobject axContext, jobject component)
{ {
static JNF_STATIC_MEMBER_CACHE(jm_SHOWING, sjc_AccessibleState, "SHOWING", "Ljavax/accessibility/AccessibleState;"); static JNF_STATIC_MEMBER_CACHE(jm_SHOWING, sjc_AccessibleState, "SHOWING", "Ljavax/accessibility/AccessibleState;");
jobject axVisibleState = JNFGetStaticObjectField(env, jm_SHOWING); jobject axVisibleState = JNFGetStaticObjectField(env, jm_SHOWING);
return containsAxState(env, axContext, axVisibleState, component); BOOL showing = containsAxState(env, axContext, axVisibleState, component);
(*env)->DeleteLocalRef(env, axVisibleState);
return showing;
} }
NSPoint getAxComponentLocationOnScreen(JNIEnv *env, jobject axComponent, jobject component) NSPoint getAxComponentLocationOnScreen(JNIEnv *env, jobject axComponent, jobject component)
......
/* /*
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -112,7 +112,9 @@ NSValue *javaIntArrayToNSRangeValue(JNIEnv* env, jintArray array) { ...@@ -112,7 +112,9 @@ NSValue *javaIntArrayToNSRangeValue(JNIEnv* env, jintArray array) {
// if it's static text, the AppKit AXValue is the java accessibleName // if it's static text, the AppKit AXValue is the java accessibleName
jobject axName = JNFCallStaticObjectMethod(env, sjm_getAccessibleName, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) jobject axName = JNFCallStaticObjectMethod(env, sjm_getAccessibleName, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
if (axName != NULL) { if (axName != NULL) {
return JNFJavaToNSString(env, axName); NSString* str = JNFJavaToNSString(env, axName);
(*env)->DeleteLocalRef(env, axName);
return str;
} }
// value is still nil if no accessibleName for static text. Below, try to get the accessibleText. // value is still nil if no accessibleName for static text. Below, try to get the accessibleText.
} }
...@@ -120,12 +122,18 @@ NSValue *javaIntArrayToNSRangeValue(JNIEnv* env, jintArray array) { ...@@ -120,12 +122,18 @@ NSValue *javaIntArrayToNSRangeValue(JNIEnv* env, jintArray array) {
// cmcnote: inefficient to make three distinct JNI calls. Coalesce. radr://3951923 // cmcnote: inefficient to make three distinct JNI calls. Coalesce. radr://3951923
jobject axText = JNFCallStaticObjectMethod(env, sjm_getAccessibleText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) jobject axText = JNFCallStaticObjectMethod(env, sjm_getAccessibleText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
if (axText == NULL) return nil; if (axText == NULL) return nil;
(*env)->DeleteLocalRef(env, axText);
jobject axEditableText = JNFCallStaticObjectMethod(env, sjm_getAccessibleEditableText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) jobject axEditableText = JNFCallStaticObjectMethod(env, sjm_getAccessibleEditableText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
if (axEditableText == NULL) return nil; if (axEditableText == NULL) return nil;
static JNF_STATIC_MEMBER_CACHE(jm_getTextRange, sjc_CAccessibleText, "getTextRange", "(Ljavax/accessibility/AccessibleEditableText;IILjava/awt/Component;)Ljava/lang/String;"); static JNF_STATIC_MEMBER_CACHE(jm_getTextRange, sjc_CAccessibleText, "getTextRange", "(Ljavax/accessibility/AccessibleEditableText;IILjava/awt/Component;)Ljava/lang/String;");
NSString *string = JNFJavaToNSString(env, JNFCallStaticObjectMethod(env, jm_getTextRange, axEditableText, 0, getAxTextCharCount(env, axEditableText, fComponent), fComponent)); // AWT_THREADING Safe (AWTRunLoop) jobject jrange = JNFCallStaticObjectMethod(env, jm_getTextRange, axEditableText, 0, getAxTextCharCount(env, axEditableText, fComponent), fComponent);
NSString *string = JNFJavaToNSString(env, jrange); // AWT_THREADING Safe (AWTRunLoop)
(*env)->DeleteLocalRef(env, jrange);
(*env)->DeleteLocalRef(env, axEditableText);
if (string == nil) string = @""; if (string == nil) string = @"";
return string; return string;
} }
...@@ -139,6 +147,7 @@ NSValue *javaIntArrayToNSRangeValue(JNIEnv* env, jintArray array) { ...@@ -139,6 +147,7 @@ NSValue *javaIntArrayToNSRangeValue(JNIEnv* env, jintArray array) {
JNIEnv* env = [ThreadUtilities getJNIEnv]; JNIEnv* env = [ThreadUtilities getJNIEnv];
jobject axEditableText = JNFCallStaticObjectMethod(env, sjm_getAccessibleEditableText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) jobject axEditableText = JNFCallStaticObjectMethod(env, sjm_getAccessibleEditableText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
if (axEditableText == NULL) return NO; if (axEditableText == NULL) return NO;
(*env)->DeleteLocalRef(env, axEditableText);
return YES; return YES;
} }
...@@ -157,7 +166,9 @@ NSValue *javaIntArrayToNSRangeValue(JNIEnv* env, jintArray array) { ...@@ -157,7 +166,9 @@ NSValue *javaIntArrayToNSRangeValue(JNIEnv* env, jintArray array) {
static JNF_STATIC_MEMBER_CACHE(jm_getSelectedText, sjc_CAccessibleText, "getSelectedText", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/String;"); static JNF_STATIC_MEMBER_CACHE(jm_getSelectedText, sjc_CAccessibleText, "getSelectedText", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/String;");
jobject axText = JNFCallStaticObjectMethod(env, jm_getSelectedText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) jobject axText = JNFCallStaticObjectMethod(env, jm_getSelectedText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
if (axText == NULL) return @""; if (axText == NULL) return @"";
return JNFJavaToNSString(env, axText); NSString* str = JNFJavaToNSString(env, axText);
(*env)->DeleteLocalRef(env, axText);
return str;
} }
- (BOOL)accessibilityIsSelectedTextAttributeSettable - (BOOL)accessibilityIsSelectedTextAttributeSettable
...@@ -220,7 +231,9 @@ NSValue *javaIntArrayToNSRangeValue(JNIEnv* env, jintArray array) { ...@@ -220,7 +231,9 @@ NSValue *javaIntArrayToNSRangeValue(JNIEnv* env, jintArray array) {
// also, static text doesn't always have accessibleText. if axText is null, should get the charcount of the accessibleName instead // also, static text doesn't always have accessibleText. if axText is null, should get the charcount of the accessibleName instead
JNIEnv *env = [ThreadUtilities getJNIEnv]; JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject axText = JNFCallStaticObjectMethod(env, sjm_getAccessibleText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) jobject axText = JNFCallStaticObjectMethod(env, sjm_getAccessibleText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
return [NSNumber numberWithInt:getAxTextCharCount(env, axText, fComponent)]; NSNumber* num = [NSNumber numberWithInt:getAxTextCharCount(env, axText, fComponent)];
(*env)->DeleteLocalRef(env, axText);
return num;
} }
- (BOOL)accessibilityIsNumberOfCharactersAttributeSettable - (BOOL)accessibilityIsNumberOfCharactersAttributeSettable
...@@ -285,7 +298,7 @@ NSValue *javaIntArrayToNSRangeValue(JNIEnv* env, jintArray array) { ...@@ -285,7 +298,7 @@ NSValue *javaIntArrayToNSRangeValue(JNIEnv* env, jintArray array) {
JNIEnv *env = [ThreadUtilities getJNIEnv]; JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getBoundsForRange, sjc_CAccessibleText, "getBoundsForRange", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;II)[D"); static JNF_STATIC_MEMBER_CACHE(jm_getBoundsForRange, sjc_CAccessibleText, "getBoundsForRange", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;II)[D");
jdoubleArray axBounds = JNFCallStaticObjectMethod(env, jm_getBoundsForRange, fAccessible, fComponent, range.location, range.length); // AWT_THREADING Safe (AWTRunLoop) jdoubleArray axBounds = (jdoubleArray)JNFCallStaticObjectMethod(env, jm_getBoundsForRange, fAccessible, fComponent, range.location, range.length); // AWT_THREADING Safe (AWTRunLoop)
if (axBounds == NULL) return nil; if (axBounds == NULL) return nil;
// We cheat because we know that the array is 4 elements long (x, y, width, height) // We cheat because we know that the array is 4 elements long (x, y, width, height)
...@@ -324,7 +337,7 @@ NSValue *javaIntArrayToNSRangeValue(JNIEnv* env, jintArray array) { ...@@ -324,7 +337,7 @@ NSValue *javaIntArrayToNSRangeValue(JNIEnv* env, jintArray array) {
JNIEnv *env = [ThreadUtilities getJNIEnv]; JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getRangeForLine, sjc_CAccessibleText, "getRangeForLine", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;I)[I"); static JNF_STATIC_MEMBER_CACHE(jm_getRangeForLine, sjc_CAccessibleText, "getRangeForLine", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;I)[I");
jintArray axTextRange = JNFCallStaticObjectMethod(env, jm_getRangeForLine, fAccessible, fComponent, [line intValue]); // AWT_THREADING Safe (AWTRunLoop) jintArray axTextRange = (jintArray)JNFCallStaticObjectMethod(env, jm_getRangeForLine, fAccessible, fComponent, [line intValue]); // AWT_THREADING Safe (AWTRunLoop)
if (axTextRange == NULL) return nil; if (axTextRange == NULL) return nil;
return javaIntArrayToNSRangeValue(env,axTextRange); return javaIntArrayToNSRangeValue(env,axTextRange);
...@@ -350,10 +363,12 @@ NSValue *javaIntArrayToNSRangeValue(JNIEnv* env, jintArray array) { ...@@ -350,10 +363,12 @@ NSValue *javaIntArrayToNSRangeValue(JNIEnv* env, jintArray array) {
JNIEnv *env = [ThreadUtilities getJNIEnv]; JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getStringForRange, sjc_CAccessibleText, "getStringForRange", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;II)Ljava/lang/String;"); static JNF_STATIC_MEMBER_CACHE(jm_getStringForRange, sjc_CAccessibleText, "getStringForRange", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;II)Ljava/lang/String;");
jstring jstringForRange = JNFCallStaticObjectMethod(env, jm_getStringForRange, fAccessible, fComponent, range.location, range.length); // AWT_THREADING Safe (AWTRunLoop) jstring jstringForRange = (jstring)JNFCallStaticObjectMethod(env, jm_getStringForRange, fAccessible, fComponent, range.location, range.length); // AWT_THREADING Safe (AWTRunLoop)
if (jstringForRange == NULL) return @""; if (jstringForRange == NULL) return @"";
return JNFJavaToNSString(env, jstringForRange); NSString* str = JNFJavaToNSString(env, jstringForRange);
(*env)->DeleteLocalRef(env, jstringForRange);
return str;
} }
// //
...@@ -406,7 +421,7 @@ NSValue *javaIntArrayToNSRangeValue(JNIEnv* env, jintArray array) { ...@@ -406,7 +421,7 @@ NSValue *javaIntArrayToNSRangeValue(JNIEnv* env, jintArray array) {
JNIEnv *env = [ThreadUtilities getJNIEnv]; JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getRangeForIndex, sjc_CAccessibleText, "getRangeForIndex", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;I)[I"); static JNF_STATIC_MEMBER_CACHE(jm_getRangeForIndex, sjc_CAccessibleText, "getRangeForIndex", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;I)[I");
jintArray axTextRange = JNFCallStaticObjectMethod(env, jm_getRangeForIndex, fAccessible, fComponent, index); // AWT_THREADING Safe (AWTRunLoop) jintArray axTextRange = (jintArray)JNFCallStaticObjectMethod(env, jm_getRangeForIndex, fAccessible, fComponent, index); // AWT_THREADING Safe (AWTRunLoop)
if (axTextRange == NULL) return nil; if (axTextRange == NULL) return nil;
return javaIntArrayToNSRangeValue(env, axTextRange); return javaIntArrayToNSRangeValue(env, axTextRange);
......
/* /*
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
@interface CGLLayer : CAOpenGLLayer @interface CGLLayer : CAOpenGLLayer
{ {
@private @private
JNFJObjectWrapper *javaLayer; JNFWeakJObjectWrapper *javaLayer;
// intermediate buffer, used the RQ lock to synchronize // intermediate buffer, used the RQ lock to synchronize
GLuint textureID; GLuint textureID;
...@@ -45,7 +45,7 @@ ...@@ -45,7 +45,7 @@
#endif /* REMOTELAYER */ #endif /* REMOTELAYER */
} }
@property (nonatomic, retain) JNFJObjectWrapper *javaLayer; @property (nonatomic, retain) JNFWeakJObjectWrapper *javaLayer;
@property (readwrite, assign) GLuint textureID; @property (readwrite, assign) GLuint textureID;
@property (readwrite, assign) GLenum target; @property (readwrite, assign) GLenum target;
@property (readwrite, assign) float textureWidth; @property (readwrite, assign) float textureWidth;
...@@ -57,7 +57,7 @@ ...@@ -57,7 +57,7 @@
@property (nonatomic, retain) NSObject<JRSRemoteLayer> *jrsRemoteLayer; @property (nonatomic, retain) NSObject<JRSRemoteLayer> *jrsRemoteLayer;
#endif #endif
- (id) initWithJavaLayer:(JNFJObjectWrapper *)javaLayer; - (id) initWithJavaLayer:(JNFWeakJObjectWrapper *)javaLayer;
- (void) blitTexture; - (void) blitTexture;
@end @end
......
/* /*
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -46,7 +46,7 @@ extern NSOpenGLContext *sharedContext; ...@@ -46,7 +46,7 @@ extern NSOpenGLContext *sharedContext;
@synthesize jrsRemoteLayer; @synthesize jrsRemoteLayer;
#endif #endif
- (id) initWithJavaLayer:(JNFJObjectWrapper *)layer; - (id) initWithJavaLayer:(JNFWeakJObjectWrapper *)layer;
{ {
AWT_ASSERT_APPKIT_THREAD; AWT_ASSERT_APPKIT_THREAD;
// Initialize ourselves // Initialize ourselves
...@@ -133,6 +133,15 @@ AWT_ASSERT_APPKIT_THREAD; ...@@ -133,6 +133,15 @@ AWT_ASSERT_APPKIT_THREAD;
{ {
AWT_ASSERT_APPKIT_THREAD; AWT_ASSERT_APPKIT_THREAD;
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_CLASS_CACHE(jc_JavaLayer, "sun/java2d/opengl/CGLLayer");
static JNF_MEMBER_CACHE(jm_drawInCGLContext, jc_JavaLayer, "drawInCGLContext", "()V");
jobject javaLayerLocalRef = [self.javaLayer jObjectWithEnv:env];
if ((*env)->IsSameObject(env, javaLayerLocalRef, NULL)) {
return;
}
// Set the current context to the one given to us. // Set the current context to the one given to us.
CGLSetCurrentContext(glContext); CGLSetCurrentContext(glContext);
...@@ -141,12 +150,7 @@ AWT_ASSERT_APPKIT_THREAD; ...@@ -141,12 +150,7 @@ AWT_ASSERT_APPKIT_THREAD;
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
glViewport(0, 0, textureWidth, textureHeight); glViewport(0, 0, textureWidth, textureHeight);
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_CLASS_CACHE(jc_JavaLayer, "sun/java2d/opengl/CGLLayer");
static JNF_MEMBER_CACHE(jm_drawInCGLContext, jc_JavaLayer, "drawInCGLContext", "()V");
jobject javaLayerLocalRef = [self.javaLayer jObjectWithEnv:env];
JNFCallVoidMethod(env, javaLayerLocalRef, jm_drawInCGLContext); JNFCallVoidMethod(env, javaLayerLocalRef, jm_drawInCGLContext);
(*env)->DeleteLocalRef(env, javaLayerLocalRef); (*env)->DeleteLocalRef(env, javaLayerLocalRef);
...@@ -171,7 +175,7 @@ Java_sun_java2d_opengl_CGLLayer_nativeCreateLayer ...@@ -171,7 +175,7 @@ Java_sun_java2d_opengl_CGLLayer_nativeCreateLayer
JNF_COCOA_ENTER(env); JNF_COCOA_ENTER(env);
JNFJObjectWrapper *javaLayer = [JNFJObjectWrapper wrapperWithJObject:obj withEnv:env]; JNFWeakJObjectWrapper *javaLayer = [JNFWeakJObjectWrapper wrapperWithJObject:obj withEnv:env];
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){ [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
AWT_ASSERT_APPKIT_THREAD; AWT_ASSERT_APPKIT_THREAD;
......
...@@ -1013,7 +1013,7 @@ static void ...@@ -1013,7 +1013,7 @@ static void
atexit_finish_logging(void) atexit_finish_logging(void)
{ {
/* Normal exit(0) (not _exit()) may only reach here */ /* Normal exit(0) (not _exit()) may only reach here */
finish_logging(0); /* Only first call matters */ finish_logging(); /* Only first call matters */
} }
static jboolean static jboolean
...@@ -1301,39 +1301,49 @@ bad_option_no_msg: ...@@ -1301,39 +1301,49 @@ bad_option_no_msg:
void void
debugInit_exit(jvmtiError error, const char *msg) debugInit_exit(jvmtiError error, const char *msg)
{ {
int exit_code = 0; enum exit_codes { EXIT_NO_ERRORS = 0, EXIT_JVMTI_ERROR = 1, EXIT_TRANSPORT_ERROR = 2 };
/* Pick an error code */ // Prepare to exit. Log error and finish logging
if ( error != JVMTI_ERROR_NONE ) { LOG_MISC(("Exiting with error %s(%d): %s", jvmtiErrorText(error), error,
exit_code = 1; ((msg == NULL) ? "" : msg)));
if ( docoredump ) {
finish_logging(exit_code);
abort();
}
}
if ( msg==NULL ) {
msg = "";
}
LOG_MISC(("Exiting with error %s(%d): %s", jvmtiErrorText(error), error, msg)); // coredump requested by command line. Keep JVMTI data dirty
if (error != JVMTI_ERROR_NONE && docoredump) {
LOG_MISC(("Dumping core as requested by command line"));
finish_logging();
abort();
}
gdata->vmDead = JNI_TRUE; finish_logging();
/* Let's try and cleanup the JVMTI, if we even have one */ // Cleanup the JVMTI if we have one
if ( gdata->jvmti != NULL ) { if (gdata != NULL) {
/* Dispose of jvmti (gdata->jvmti becomes NULL) */ gdata->vmDead = JNI_TRUE;
disposeEnvironment(gdata->jvmti); if (gdata->jvmti != NULL) {
// Dispose of jvmti (gdata->jvmti becomes NULL)
disposeEnvironment(gdata->jvmti);
}
} }
/* Finish up logging. We reach here if JDWP is doing the exiting. */ // We are here with no errors. Kill entire process and exit with zero exit code
finish_logging(exit_code); /* Only first call matters */ if (error == JVMTI_ERROR_NONE) {
forceExit(EXIT_NO_ERRORS);
return;
}
/* Let's give the JNI a FatalError if non-exit 0, which is historic way */ // No transport initilized.
if ( exit_code != 0 ) { // As we don't have any details here exiting with separate exit code
JNIEnv *env = NULL; if (error == AGENT_ERROR_TRANSPORT_INIT) {
jniFatalError(env, msg, error, exit_code); forceExit(EXIT_TRANSPORT_ERROR);
return;
} }
/* Last chance to die, this kills the entire process. */ // We have JVMTI error. Call hotspot jni_FatalError handler
forceExit(exit_code); jniFatalError(NULL, msg, error, EXIT_JVMTI_ERROR);
// hotspot calls os:abort() so we should never reach code below,
// but guard against possible hotspot changes
// Last chance to die, this kills the entire process.
forceExit(EXIT_JVMTI_ERROR);
} }
...@@ -230,7 +230,7 @@ setup_logging(const char *filename, unsigned flags) ...@@ -230,7 +230,7 @@ setup_logging(const char *filename, unsigned flags)
/* Finish up logging, flush output to the logfile. */ /* Finish up logging, flush output to the logfile. */
void void
finish_logging(int exit_code) finish_logging()
{ {
#ifdef JDWP_LOGGING #ifdef JDWP_LOGGING
MUTEX_LOCK(my_mutex); MUTEX_LOCK(my_mutex);
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
/* LOG: Must be called like: LOG_category(("anything")) or LOG_category((format,args)) */ /* LOG: Must be called like: LOG_category(("anything")) or LOG_category((format,args)) */
void setup_logging(const char *, unsigned); void setup_logging(const char *, unsigned);
void finish_logging(int); void finish_logging();
#define LOG_NULL ((void)0) #define LOG_NULL ((void)0)
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -26,6 +26,8 @@ ...@@ -26,6 +26,8 @@
package com.sun.crypto.provider; package com.sun.crypto.provider;
import java.security.InvalidKeyException; import java.security.InvalidKeyException;
import java.security.ProviderException;
/** /**
* This class represents ciphers in cipher block chaining (CBC) mode. * This class represents ciphers in cipher block chaining (CBC) mode.
...@@ -122,31 +124,31 @@ class CipherBlockChaining extends FeedbackCipher { ...@@ -122,31 +124,31 @@ class CipherBlockChaining extends FeedbackCipher {
* *
* <p>The input plain text <code>plain</code>, starting at * <p>The input plain text <code>plain</code>, starting at
* <code>plainOffset</code> and ending at * <code>plainOffset</code> and ending at
* <code>(plainOffset + len - 1)</code>, is encrypted. * <code>(plainOffset + plainLen - 1)</code>, is encrypted.
* The result is stored in <code>cipher</code>, starting at * The result is stored in <code>cipher</code>, starting at
* <code>cipherOffset</code>. * <code>cipherOffset</code>.
* *
* <p>It is the application's responsibility to make sure that
* <code>plainLen</code> is a multiple of the embedded cipher's block size,
* as any excess bytes are ignored.
*
* @param plain the buffer with the input data to be encrypted * @param plain the buffer with the input data to be encrypted
* @param plainOffset the offset in <code>plain</code> * @param plainOffset the offset in <code>plain</code>
* @param plainLen the length of the input data * @param plainLen the length of the input data
* @param cipher the buffer for the result * @param cipher the buffer for the result
* @param cipherOffset the offset in <code>cipher</code> * @param cipherOffset the offset in <code>cipher</code>
* @exception ProviderException if <code>len</code> is not
* a multiple of the block size
* @return the length of the encrypted data * @return the length of the encrypted data
*/ */
int encrypt(byte[] plain, int plainOffset, int plainLen, int encrypt(byte[] plain, int plainOffset, int plainLen,
byte[] cipher, int cipherOffset) byte[] cipher, int cipherOffset)
{ {
int i; if ((plainLen % blockSize) != 0) {
throw new ProviderException("Internal error in input buffering");
}
int endIndex = plainOffset + plainLen; int endIndex = plainOffset + plainLen;
for (; plainOffset < endIndex; for (; plainOffset < endIndex;
plainOffset+=blockSize, cipherOffset += blockSize) { plainOffset+=blockSize, cipherOffset += blockSize) {
for (i=0; i<blockSize; i++) { for (int i = 0; i < blockSize; i++) {
k[i] = (byte)(plain[i+plainOffset] ^ r[i]); k[i] = (byte)(plain[i + plainOffset] ^ r[i]);
} }
embeddedCipher.encryptBlock(k, 0, cipher, cipherOffset); embeddedCipher.encryptBlock(k, 0, cipher, cipherOffset);
System.arraycopy(cipher, cipherOffset, r, 0, blockSize); System.arraycopy(cipher, cipherOffset, r, 0, blockSize);
...@@ -159,14 +161,10 @@ class CipherBlockChaining extends FeedbackCipher { ...@@ -159,14 +161,10 @@ class CipherBlockChaining extends FeedbackCipher {
* *
* <p>The input cipher text <code>cipher</code>, starting at * <p>The input cipher text <code>cipher</code>, starting at
* <code>cipherOffset</code> and ending at * <code>cipherOffset</code> and ending at
* <code>(cipherOffset + len - 1)</code>, is decrypted. * <code>(cipherOffset + cipherLen - 1)</code>, is decrypted.
* The result is stored in <code>plain</code>, starting at * The result is stored in <code>plain</code>, starting at
* <code>plainOffset</code>. * <code>plainOffset</code>.
* *
* <p>It is the application's responsibility to make sure that
* <code>cipherLen</code> is a multiple of the embedded cipher's block
* size, as any excess bytes are ignored.
*
* <p>It is also the application's responsibility to make sure that * <p>It is also the application's responsibility to make sure that
* <code>init</code> has been called before this method is called. * <code>init</code> has been called before this method is called.
* (This check is omitted here, to avoid double checking.) * (This check is omitted here, to avoid double checking.)
...@@ -176,23 +174,23 @@ class CipherBlockChaining extends FeedbackCipher { ...@@ -176,23 +174,23 @@ class CipherBlockChaining extends FeedbackCipher {
* @param cipherLen the length of the input data * @param cipherLen the length of the input data
* @param plain the buffer for the result * @param plain the buffer for the result
* @param plainOffset the offset in <code>plain</code> * @param plainOffset the offset in <code>plain</code>
* @exception ProviderException if <code>len</code> is not
* a multiple of the block size
* @return the length of the decrypted data * @return the length of the decrypted data
*
* @exception IllegalBlockSizeException if input data whose length does
* not correspond to the embedded cipher's block size is passed to the
* embedded cipher
*/ */
int decrypt(byte[] cipher, int cipherOffset, int cipherLen, int decrypt(byte[] cipher, int cipherOffset, int cipherLen,
byte[] plain, int plainOffset) byte[] plain, int plainOffset)
{ {
int i; if ((cipherLen % blockSize) != 0) {
throw new ProviderException("Internal error in input buffering");
}
int endIndex = cipherOffset + cipherLen; int endIndex = cipherOffset + cipherLen;
for (; cipherOffset < endIndex; for (; cipherOffset < endIndex;
cipherOffset += blockSize, plainOffset += blockSize) { cipherOffset += blockSize, plainOffset += blockSize) {
embeddedCipher.decryptBlock(cipher, cipherOffset, k, 0); embeddedCipher.decryptBlock(cipher, cipherOffset, k, 0);
for (i = 0; i < blockSize; i++) { for (int i = 0; i < blockSize; i++) {
plain[i+plainOffset] = (byte)(k[i] ^ r[i]); plain[i + plainOffset] = (byte)(k[i] ^ r[i]);
} }
System.arraycopy(cipher, cipherOffset, r, 0, blockSize); System.arraycopy(cipher, cipherOffset, r, 0, blockSize);
} }
......
...@@ -717,7 +717,7 @@ final class CipherCore { ...@@ -717,7 +717,7 @@ final class CipherCore {
len -= blockSize; len -= blockSize;
} }
// do not count the trailing bytes which do not make up a unit // do not count the trailing bytes which do not make up a unit
len = (len > 0 ? (len - (len%unitBytes)) : 0); len = (len > 0 ? (len - (len % unitBytes)) : 0);
// check output buffer capacity // check output buffer capacity
if ((output == null) || if ((output == null) ||
...@@ -729,6 +729,15 @@ final class CipherCore { ...@@ -729,6 +729,15 @@ final class CipherCore {
int outLen = 0; int outLen = 0;
if (len != 0) { // there is some work to do if (len != 0) { // there is some work to do
if ((input == output)
&& (outputOffset < (inputOffset + inputLen))
&& (inputOffset < (outputOffset + buffer.length))) {
// copy 'input' out to avoid its content being
// overwritten prematurely.
input = Arrays.copyOfRange(input, inputOffset,
inputOffset + inputLen);
inputOffset = 0;
}
if (len <= buffered) { if (len <= buffered) {
// all to-be-processed data are from 'buffer' // all to-be-processed data are from 'buffer'
if (decrypting) { if (decrypting) {
...@@ -741,37 +750,40 @@ final class CipherCore { ...@@ -741,37 +750,40 @@ final class CipherCore {
System.arraycopy(buffer, len, buffer, 0, buffered); System.arraycopy(buffer, len, buffer, 0, buffered);
} }
} else { // len > buffered } else { // len > buffered
if ((input != output) && (buffered == 0)) { int inputConsumed = len - buffered;
// all to-be-processed data are from 'input' int temp;
// however, note that if 'input' and 'output' are the same, if (buffered > 0) {
// then they can't be passed directly to the underlying cipher int bufferCapacity = buffer.length - buffered;
// engine operations as data may be overwritten before they if (bufferCapacity != 0) {
// are read. temp = Math.min(bufferCapacity, inputConsumed);
if (unitBytes != blockSize) {
temp -= ((buffered + temp) % unitBytes);
}
System.arraycopy(input, inputOffset, buffer, buffered, temp);
inputOffset += temp;
inputConsumed -= temp;
inputLen -= temp;
buffered += temp;
}
// process 'buffer'
if (decrypting) { if (decrypting) {
outLen = cipher.decrypt(input, inputOffset, len, output, outputOffset); outLen = cipher.decrypt(buffer, 0, buffered, output, outputOffset);
} else { } else {
outLen = cipher.encrypt(input, inputOffset, len, output, outputOffset); outLen = cipher.encrypt(buffer, 0, buffered, output, outputOffset);
}
inputOffset += len;
inputLen -= len;
} else {
// assemble the data using both 'buffer' and 'input'
byte[] in = new byte[len];
int inConsumed = len - buffered;
if (buffered != 0) {
System.arraycopy(buffer, 0, in, 0, buffered);
buffered = 0;
}
if (inConsumed != 0) {
System.arraycopy(input, inputOffset, in, len - inConsumed, inConsumed);
inputOffset += inConsumed;
inputLen -= inConsumed;
} }
outputOffset += outLen;
buffered = 0;
}
if (inputConsumed > 0) { // still has input to process
if (decrypting) { if (decrypting) {
outLen = cipher.decrypt(in, 0, len, output, outputOffset); outLen += cipher.decrypt(input, inputOffset, inputConsumed,
output, outputOffset);
} else { } else {
outLen = cipher.encrypt(in, 0, len, output, outputOffset); outLen += cipher.encrypt(input, inputOffset, inputConsumed,
output, outputOffset);
} }
inputOffset += inputConsumed;
inputLen -= inputConsumed;
} }
} }
// Let's keep track of how many bytes are needed to make // Let's keep track of how many bytes are needed to make
...@@ -934,8 +946,10 @@ final class CipherCore { ...@@ -934,8 +946,10 @@ final class CipherCore {
byte[] finalBuf = input; byte[] finalBuf = input;
int finalOffset = inputOffset; int finalOffset = inputOffset;
int finalBufLen = inputLen; int finalBufLen = inputLen;
if ((input == output) || (buffered != 0) || if ((buffered != 0) || (!decrypting && padding != null) ||
(!decrypting && padding != null)) { ((input == output)
&& (outputOffset < (inputOffset + inputLen))
&& (inputOffset < (outputOffset + buffer.length)))) {
if (decrypting || padding == null) { if (decrypting || padding == null) {
paddingLen = 0; paddingLen = 0;
} }
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
package com.sun.crypto.provider; package com.sun.crypto.provider;
import java.security.InvalidKeyException; import java.security.InvalidKeyException;
import java.security.ProviderException;
/** /**
* This class represents ciphers in cipher-feedback (CFB) mode. * This class represents ciphers in cipher-feedback (CFB) mode.
...@@ -133,66 +134,72 @@ final class CipherFeedback extends FeedbackCipher { ...@@ -133,66 +134,72 @@ final class CipherFeedback extends FeedbackCipher {
* *
* <p>The input plain text <code>plain</code>, starting at * <p>The input plain text <code>plain</code>, starting at
* <code>plainOffset</code> and ending at * <code>plainOffset</code> and ending at
* <code>(plainOffset + len - 1)</code>, is encrypted. * <code>(plainOffset + plainLen - 1)</code>, is encrypted.
* The result is stored in <code>cipher</code>, starting at * The result is stored in <code>cipher</code>, starting at
* <code>cipherOffset</code>. * <code>cipherOffset</code>.
* *
* <p>It is the application's responsibility to make sure that
* <code>plainLen</code> is a multiple of the stream unit size
* <code>numBytes</code>, as any excess bytes are ignored.
*
* <p>It is also the application's responsibility to make sure that
* <code>init</code> has been called before this method is called.
* (This check is omitted here, to avoid double checking.)
*
* @param plain the buffer with the input data to be encrypted * @param plain the buffer with the input data to be encrypted
* @param plainOffset the offset in <code>plain</code> * @param plainOffset the offset in <code>plain</code>
* @param plainLen the length of the input data * @param plainLen the length of the input data
* @param cipher the buffer for the result * @param cipher the buffer for the result
* @param cipherOffset the offset in <code>cipher</code> * @param cipherOffset the offset in <code>cipher</code>
* @exception ProviderException if <code>plainLen</code> is not
* a multiple of the <code>numBytes</code>
* @return the length of the encrypted data * @return the length of the encrypted data
*/ */
int encrypt(byte[] plain, int plainOffset, int plainLen, int encrypt(byte[] plain, int plainOffset, int plainLen,
byte[] cipher, int cipherOffset) byte[] cipher, int cipherOffset) {
{ if ((plainLen % numBytes) != 0) {
int i, len; throw new ProviderException("Internal error in input buffering");
len = blockSize - numBytes; }
int nShift = blockSize - numBytes;
int loopCount = plainLen / numBytes; int loopCount = plainLen / numBytes;
int oddBytes = plainLen % numBytes;
if (len == 0) { for (; loopCount > 0 ;
for (; loopCount > 0 ; plainOffset += numBytes, cipherOffset += numBytes,
plainOffset += numBytes, cipherOffset += numBytes, loopCount--) {
loopCount--) { embeddedCipher.encryptBlock(register, 0, k, 0);
embeddedCipher.encryptBlock(register, 0, k, 0); if (nShift != 0) {
for (i = 0; i < blockSize; i++) System.arraycopy(register, numBytes, register, 0, nShift);
register[i] = cipher[i+cipherOffset] =
(byte)(k[i] ^ plain[i+plainOffset]);
} }
if (oddBytes > 0) { for (int i = 0; i < numBytes; i++) {
embeddedCipher.encryptBlock(register, 0, k, 0); register[nShift + i] = cipher[i + cipherOffset] =
for (i=0; i<oddBytes; i++) (byte)(k[i] ^ plain[i + plainOffset]);
register[i] = cipher[i+cipherOffset] =
(byte)(k[i] ^ plain[i+plainOffset]);
} }
} else { }
for (; loopCount > 0 ; return plainLen;
plainOffset += numBytes, cipherOffset += numBytes, }
loopCount--) {
embeddedCipher.encryptBlock(register, 0, k, 0);
System.arraycopy(register, numBytes, register, 0, len);
for (i=0; i<numBytes; i++)
register[i+len] = cipher[i+cipherOffset] =
(byte)(k[i] ^ plain[i+plainOffset]);
} /**
if (oddBytes != 0) { * Performs the last encryption operation.
embeddedCipher.encryptBlock(register, 0, k, 0); *
System.arraycopy(register, numBytes, register, 0, len); * <p>The input plain text <code>plain</code>, starting at
for (i=0; i<oddBytes; i++) { * <code>plainOffset</code> and ending at
register[i+len] = cipher[i+cipherOffset] = * <code>(plainOffset + plainLen - 1)</code>, is encrypted.
(byte)(k[i] ^ plain[i+plainOffset]); * The result is stored in <code>cipher</code>, starting at
} * <code>cipherOffset</code>.
*
* @param plain the buffer with the input data to be encrypted
* @param plainOffset the offset in <code>plain</code>
* @param plainLen the length of the input data
* @param cipher the buffer for the result
* @param cipherOffset the offset in <code>cipher</code>
* @return the number of bytes placed into <code>cipher</code>
*/
int encryptFinal(byte[] plain, int plainOffset, int plainLen,
byte[] cipher, int cipherOffset) {
int oddBytes = plainLen % numBytes;
int len = encrypt(plain, plainOffset, (plainLen - oddBytes),
cipher, cipherOffset);
plainOffset += len;
cipherOffset += len;
if (oddBytes != 0) {
embeddedCipher.encryptBlock(register, 0, k, 0);
for (int i = 0; i < oddBytes; i++) {
cipher[i + cipherOffset] =
(byte)(k[i] ^ plain[i + plainOffset]);
} }
} }
return plainLen; return plainLen;
...@@ -203,72 +210,73 @@ final class CipherFeedback extends FeedbackCipher { ...@@ -203,72 +210,73 @@ final class CipherFeedback extends FeedbackCipher {
* *
* <p>The input cipher text <code>cipher</code>, starting at * <p>The input cipher text <code>cipher</code>, starting at
* <code>cipherOffset</code> and ending at * <code>cipherOffset</code> and ending at
* <code>(cipherOffset + len - 1)</code>, is decrypted. * <code>(cipherOffset + cipherLen - 1)</code>, is decrypted.
* The result is stored in <code>plain</code>, starting at * The result is stored in <code>plain</code>, starting at
* <code>plainOffset</code>. * <code>plainOffset</code>.
* *
* <p>It is the application's responsibility to make sure that
* <code>cipherLen</code> is a multiple of the stream unit size
* <code>numBytes</code>, as any excess bytes are ignored.
*
* <p>It is also the application's responsibility to make sure that
* <code>init</code> has been called before this method is called.
* (This check is omitted here, to avoid double checking.)
*
* @param cipher the buffer with the input data to be decrypted * @param cipher the buffer with the input data to be decrypted
* @param cipherOffset the offset in <code>cipherOffset</code> * @param cipherOffset the offset in <code>cipherOffset</code>
* @param cipherLen the length of the input data * @param cipherLen the length of the input data
* @param plain the buffer for the result * @param plain the buffer for the result
* @param plainOffset the offset in <code>plain</code> * @param plainOffset the offset in <code>plain</code>
* @exception ProviderException if <code>cipherLen</code> is not
* a multiple of the <code>numBytes</code>
* @return the length of the decrypted data * @return the length of the decrypted data
*/ */
int decrypt(byte[] cipher, int cipherOffset, int cipherLen, int decrypt(byte[] cipher, int cipherOffset, int cipherLen,
byte[] plain, int plainOffset) byte[] plain, int plainOffset) {
{ if ((cipherLen % numBytes) != 0) {
int i, len; throw new ProviderException("Internal error in input buffering");
len = blockSize - numBytes; }
int nShift = blockSize - numBytes;
int loopCount = cipherLen / numBytes; int loopCount = cipherLen / numBytes;
int oddBytes = cipherLen % numBytes;
if (len == 0) { for (; loopCount > 0;
for (; loopCount > 0; plainOffset += numBytes, cipherOffset += numBytes,
plainOffset += numBytes, cipherOffset += numBytes, loopCount--) {
loopCount--) { embeddedCipher.encryptBlock(register, 0, k, 0);
embeddedCipher.encryptBlock(register, 0, k, 0); if (nShift != 0) {
for (i = 0; i < blockSize; i++) { System.arraycopy(register, numBytes, register, 0, nShift);
register[i] = cipher[i+cipherOffset];
plain[i+plainOffset]
= (byte)(cipher[i+cipherOffset] ^ k[i]);
}
} }
if (oddBytes > 0) { for (int i = 0; i < numBytes; i++) {
embeddedCipher.encryptBlock(register, 0, k, 0); register[i + nShift] = cipher[i + cipherOffset];
for (i=0; i<oddBytes; i++) { plain[i + plainOffset]
register[i] = cipher[i+cipherOffset]; = (byte)(cipher[i + cipherOffset] ^ k[i]);
plain[i+plainOffset]
= (byte)(cipher[i+cipherOffset] ^ k[i]);
}
} }
} else { }
for (; loopCount > 0; return cipherLen;
plainOffset += numBytes, cipherOffset += numBytes, }
loopCount--) {
embeddedCipher.encryptBlock(register, 0, k, 0); /**
System.arraycopy(register, numBytes, register, 0, len); * Performs the last decryption operation.
for (i=0; i<numBytes; i++) { *
register[i+len] = cipher[i+cipherOffset]; * <p>The input cipher text <code>cipher</code>, starting at
plain[i+plainOffset] * <code>cipherOffset</code> and ending at
= (byte)(cipher[i+cipherOffset] ^ k[i]); * <code>(cipherOffset + cipherLen - 1)</code>, is decrypted.
} * The result is stored in <code>plain</code>, starting at
} * <code>plainOffset</code>.
if (oddBytes != 0) { *
embeddedCipher.encryptBlock(register, 0, k, 0); * @param cipher the buffer with the input data to be decrypted
System.arraycopy(register, numBytes, register, 0, len); * @param cipherOffset the offset in <code>cipherOffset</code>
for (i=0; i<oddBytes; i++) { * @param cipherLen the length of the input data
register[i+len] = cipher[i+cipherOffset]; * @param plain the buffer for the result
plain[i+plainOffset] * @param plainOffset the offset in <code>plain</code>
= (byte)(cipher[i+cipherOffset] ^ k[i]); * @return the length of the decrypted data
} */
int decryptFinal(byte[] cipher, int cipherOffset, int cipherLen,
byte[] plain, int plainOffset) {
int oddBytes = cipherLen % numBytes;
int len = decrypt(cipher, cipherOffset, (cipherLen - oddBytes),
plain, plainOffset);
cipherOffset += len;
plainOffset += len;
if (oddBytes != 0) {
embeddedCipher.encryptBlock(register, 0, k, 0);
for (int i = 0; i < oddBytes; i++) {
plain[i + plainOffset]
= (byte)(cipher[i + cipherOffset] ^ k[i]);
} }
} }
return cipherLen; return cipherLen;
......
/* /*
* Copyright (c) 2002, 201313, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -27,6 +27,7 @@ package com.sun.crypto.provider; ...@@ -27,6 +27,7 @@ package com.sun.crypto.provider;
import java.security.InvalidKeyException; import java.security.InvalidKeyException;
/** /**
* This class represents ciphers in counter (CTR) mode. * This class represents ciphers in counter (CTR) mode.
* *
...@@ -136,14 +137,6 @@ final class CounterMode extends FeedbackCipher { ...@@ -136,14 +137,6 @@ final class CounterMode extends FeedbackCipher {
* The result is stored in <code>cipher</code>, starting at * The result is stored in <code>cipher</code>, starting at
* <code>cipherOffset</code>. * <code>cipherOffset</code>.
* *
* <p>It is the application's responsibility to make sure that
* <code>plainLen</code> is a multiple of the embedded cipher's block size,
* as any excess bytes are ignored.
*
* <p>It is also the application's responsibility to make sure that
* <code>init</code> has been called before this method is called.
* (This check is omitted here, to avoid double checking.)
*
* @param in the buffer with the input data to be encrypted * @param in the buffer with the input data to be encrypted
* @param inOffset the offset in <code>plain</code> * @param inOffset the offset in <code>plain</code>
* @param len the length of the input data * @param len the length of the input data
...@@ -155,30 +148,7 @@ final class CounterMode extends FeedbackCipher { ...@@ -155,30 +148,7 @@ final class CounterMode extends FeedbackCipher {
return crypt(in, inOff, len, out, outOff); return crypt(in, inOff, len, out, outOff);
} }
/** // CTR encrypt and decrypt are identical
* Performs decryption operation.
*
* <p>The input cipher text <code>cipher</code>, starting at
* <code>cipherOffset</code> and ending at
* <code>(cipherOffset + len - 1)</code>, is decrypted.
* The result is stored in <code>plain</code>, starting at
* <code>plainOffset</code>.
*
* <p>It is the application's responsibility to make sure that
* <code>cipherLen</code> is a multiple of the embedded cipher's block
* size, as any excess bytes are ignored.
*
* <p>It is also the application's responsibility to make sure that
* <code>init</code> has been called before this method is called.
* (This check is omitted here, to avoid double checking.)
*
* @param in the buffer with the input data to be decrypted
* @param inOff the offset in <code>cipherOffset</code>
* @param len the length of the input data
* @param out the buffer for the result
* @param outOff the offset in <code>plain</code>
* @return the length of the decrypted data
*/
int decrypt(byte[] in, int inOff, int len, byte[] out, int outOff) { int decrypt(byte[] in, int inOff, int len, byte[] out, int outOff) {
return crypt(in, inOff, len, out, outOff); return crypt(in, inOff, len, out, outOff);
} }
......
...@@ -71,6 +71,17 @@ public final class DHKeyPairGenerator extends KeyPairGeneratorSpi { ...@@ -71,6 +71,17 @@ public final class DHKeyPairGenerator extends KeyPairGeneratorSpi {
initialize(1024, null); initialize(1024, null);
} }
private static void checkKeySize(int keysize)
throws InvalidParameterException {
if ((keysize < 512) || (keysize > 2048) || ((keysize & 0x3F) != 0)) {
throw new InvalidParameterException(
"DH key size must be multiple of 64, and can only range " +
"from 512 to 2048 (inclusive). " +
"The specific key size " + keysize + " is not supported");
}
}
/** /**
* Initializes this key pair generator for a certain keysize and source of * Initializes this key pair generator for a certain keysize and source of
* randomness. * randomness.
...@@ -80,12 +91,8 @@ public final class DHKeyPairGenerator extends KeyPairGeneratorSpi { ...@@ -80,12 +91,8 @@ public final class DHKeyPairGenerator extends KeyPairGeneratorSpi {
* @param random the source of randomness * @param random the source of randomness
*/ */
public void initialize(int keysize, SecureRandom random) { public void initialize(int keysize, SecureRandom random) {
if ((keysize < 512) || (keysize > 2048) || (keysize % 64 != 0)) { checkKeySize(keysize);
throw new InvalidParameterException("Keysize must be multiple "
+ "of 64, and can only range "
+ "from 512 to 2048 "
+ "(inclusive)");
}
this.pSize = keysize; this.pSize = keysize;
this.lSize = 0; this.lSize = 0;
this.random = random; this.random = random;
...@@ -115,11 +122,10 @@ public final class DHKeyPairGenerator extends KeyPairGeneratorSpi { ...@@ -115,11 +122,10 @@ public final class DHKeyPairGenerator extends KeyPairGeneratorSpi {
params = (DHParameterSpec)algParams; params = (DHParameterSpec)algParams;
pSize = params.getP().bitLength(); pSize = params.getP().bitLength();
if ((pSize < 512) || (pSize > 2048) || try {
(pSize % 64 != 0)) { checkKeySize(pSize);
throw new InvalidAlgorithmParameterException } catch (InvalidParameterException ipe) {
("Prime size must be multiple of 64, and can only range " throw new InvalidAlgorithmParameterException(ipe.getMessage());
+ "from 512 to 2048 (inclusive)");
} }
// exponent size is optional, could be 0 // exponent size is optional, could be 0
......
...@@ -59,12 +59,13 @@ extends AlgorithmParameterGeneratorSpi { ...@@ -59,12 +59,13 @@ extends AlgorithmParameterGeneratorSpi {
private SecureRandom random = null; private SecureRandom random = null;
private static void checkKeySize(int keysize) private static void checkKeySize(int keysize)
throws InvalidAlgorithmParameterException { throws InvalidParameterException {
if ((keysize != 2048) && if ((keysize != 2048) &&
((keysize < 512) || (keysize > 1024) || (keysize % 64 != 0))) { ((keysize < 512) || (keysize > 1024) || (keysize % 64 != 0))) {
throw new InvalidAlgorithmParameterException( throw new InvalidParameterException(
"Keysize must be multiple of 64 ranging from " "DH key size must be multiple of 64 and range " +
+ "512 to 1024 (inclusive), or 2048"); "from 512 to 1024 (inclusive), or 2048. " +
"The specific key size " + keysize + " is not supported");
} }
} }
...@@ -78,11 +79,7 @@ extends AlgorithmParameterGeneratorSpi { ...@@ -78,11 +79,7 @@ extends AlgorithmParameterGeneratorSpi {
*/ */
protected void engineInit(int keysize, SecureRandom random) { protected void engineInit(int keysize, SecureRandom random) {
// Re-uses DSA parameters and thus have the same range // Re-uses DSA parameters and thus have the same range
try { checkKeySize(keysize);
checkKeySize(keysize);
} catch (InvalidAlgorithmParameterException ex) {
throw new InvalidParameterException(ex.getMessage());
}
this.primeSize = keysize; this.primeSize = keysize;
this.random = random; this.random = random;
} }
...@@ -111,7 +108,11 @@ extends AlgorithmParameterGeneratorSpi { ...@@ -111,7 +108,11 @@ extends AlgorithmParameterGeneratorSpi {
primeSize = dhParamSpec.getPrimeSize(); primeSize = dhParamSpec.getPrimeSize();
// Re-uses DSA parameters and thus have the same range // Re-uses DSA parameters and thus have the same range
checkKeySize(primeSize); try {
checkKeySize(primeSize);
} catch (InvalidParameterException ipe) {
throw new InvalidAlgorithmParameterException(ipe.getMessage());
}
exponentSize = dhParamSpec.getExponentSize(); exponentSize = dhParamSpec.getExponentSize();
if (exponentSize <= 0) { if (exponentSize <= 0) {
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
package com.sun.crypto.provider; package com.sun.crypto.provider;
import java.security.InvalidKeyException; import java.security.InvalidKeyException;
import java.security.ProviderException;
/** /**
* This class represents ciphers in electronic codebook (ECB) mode. * This class represents ciphers in electronic codebook (ECB) mode.
...@@ -96,28 +97,24 @@ final class ElectronicCodeBook extends FeedbackCipher { ...@@ -96,28 +97,24 @@ final class ElectronicCodeBook extends FeedbackCipher {
/** /**
* Performs encryption operation. * Performs encryption operation.
* *
* <p>The input plain text <code>plain</code>, starting at * <p>The input plain text <code>in</code>, starting at
* <code>plainOffset</code> and ending at * <code>inOff</code> and ending at * <code>(inOff + len - 1)</code>,
* <code>(plainOffset + len - 1)</code>, is encrypted. * is encrypted. The result is stored in <code>out</code>, starting at
* The result is stored in <code>cipher</code>, starting at * <code>outOff</code>.
* <code>cipherOffset</code>.
*
* <p>It is the application's responsibility to make sure that
* <code>plainLen</code> is a multiple of the embedded cipher's block size,
* as any excess bytes are ignored.
*
* <p>It is also the application's responsibility to make sure that
* <code>init</code> has been called before this method is called.
* (This check is omitted here, to avoid double checking.)
* *
* @param in the buffer with the input data to be encrypted * @param in the buffer with the input data to be encrypted
* @param inOffset the offset in <code>plain</code> * @param inOff the offset in <code>plain</code>
* @param len the length of the input data * @param len the length of the input data
* @param out the buffer for the result * @param out the buffer for the result
* @param outOff the offset in <code>cipher</code> * @param outOff the offset in <code>cipher</code>
* @exception ProviderException if <code>len</code> is not
* a multiple of the block size
* @return the length of the encrypted data * @return the length of the encrypted data
*/ */
int encrypt(byte[] in, int inOff, int len, byte[] out, int outOff) { int encrypt(byte[] in, int inOff, int len, byte[] out, int outOff) {
if ((len % blockSize) != 0) {
throw new ProviderException("Internal error in input buffering");
}
for (int i = len; i >= blockSize; i -= blockSize) { for (int i = len; i >= blockSize; i -= blockSize) {
embeddedCipher.encryptBlock(in, inOff, out, outOff); embeddedCipher.encryptBlock(in, inOff, out, outOff);
inOff += blockSize; inOff += blockSize;
...@@ -129,28 +126,24 @@ final class ElectronicCodeBook extends FeedbackCipher { ...@@ -129,28 +126,24 @@ final class ElectronicCodeBook extends FeedbackCipher {
/** /**
* Performs decryption operation. * Performs decryption operation.
* *
* <p>The input cipher text <code>cipher</code>, starting at * <p>The input cipher text <code>in</code>, starting at
* <code>cipherOffset</code> and ending at * <code>inOff</code> and ending at * <code>(inOff + len - 1)</code>,
* <code>(cipherOffset + len - 1)</code>, is decrypted. * is decrypted.The result is stored in <code>out</code>, starting at
* The result is stored in <code>plain</code>, starting at * <code>outOff</code>.
* <code>plainOffset</code>.
*
* <p>It is the application's responsibility to make sure that
* <code>cipherLen</code> is a multiple of the embedded cipher's block
* size, as any excess bytes are ignored.
*
* <p>It is also the application's responsibility to make sure that
* <code>init</code> has been called before this method is called.
* (This check is omitted here, to avoid double checking.)
* *
* @param in the buffer with the input data to be decrypted * @param in the buffer with the input data to be decrypted
* @param inOff the offset in <code>cipherOffset</code> * @param inOff the offset in <code>cipherOffset</code>
* @param len the length of the input data * @param len the length of the input data
* @param out the buffer for the result * @param out the buffer for the result
* @param outOff the offset in <code>plain</code> * @param outOff the offset in <code>plain</code>
* @exception ProviderException if <code>len</code> is not
* a multiple of the block size
* @return the length of the decrypted data * @return the length of the decrypted data
*/ */
int decrypt(byte[] in, int inOff, int len, byte[] out, int outOff) { int decrypt(byte[] in, int inOff, int len, byte[] out, int outOff) {
if ((len % blockSize) != 0) {
throw new ProviderException("Internal error in input buffering");
}
for (int i = len; i >= blockSize; i -= blockSize) { for (int i = len; i >= blockSize; i -= blockSize) {
embeddedCipher.decryptBlock(in, inOff, out, outOff); embeddedCipher.decryptBlock(in, inOff, out, outOff);
inOff += blockSize; inOff += blockSize;
......
...@@ -403,23 +403,21 @@ final class GaloisCounterMode extends FeedbackCipher { ...@@ -403,23 +403,21 @@ final class GaloisCounterMode extends FeedbackCipher {
* and ending at <code>(inOff + len - 1)</code>, is encrypted. The result * and ending at <code>(inOff + len - 1)</code>, is encrypted. The result
* is stored in <code>out</code>, starting at <code>outOfs</code>. * is stored in <code>out</code>, starting at <code>outOfs</code>.
* *
* <p>It is the application's responsibility to make sure that
* <code>len</code> is a multiple of the embedded cipher's block size,
* otherwise, a ProviderException will be thrown.
*
* <p>It is also the application's responsibility to make sure that
* <code>init</code> has been called before this method is called.
* (This check is omitted here, to avoid double checking.)
*
* @param in the buffer with the input data to be encrypted * @param in the buffer with the input data to be encrypted
* @param inOfs the offset in <code>in</code> * @param inOfs the offset in <code>in</code>
* @param len the length of the input data * @param len the length of the input data
* @param out the buffer for the result * @param out the buffer for the result
* @param outOfs the offset in <code>out</code> * @param outOfs the offset in <code>out</code>
* @exception ProviderException if <code>len</code> is not
* a multiple of the block size
* @return the number of bytes placed into the <code>out</code> buffer
*/ */
int encrypt(byte[] in, int inOfs, int len, byte[] out, int outOfs) { int encrypt(byte[] in, int inOfs, int len, byte[] out, int outOfs) {
checkDataLength(processed, len); checkDataLength(processed, len);
if ((len % blockSize) != 0) {
throw new ProviderException("Internal error in input buffering");
}
processAAD(); processAAD();
if (len > 0) { if (len > 0) {
gctrPAndC.update(in, inOfs, len, out, outOfs); gctrPAndC.update(in, inOfs, len, out, outOfs);
...@@ -432,9 +430,6 @@ final class GaloisCounterMode extends FeedbackCipher { ...@@ -432,9 +430,6 @@ final class GaloisCounterMode extends FeedbackCipher {
/** /**
* Performs encryption operation for the last time. * Performs encryption operation for the last time.
* *
* <p>NOTE: <code>len</code> may not be multiple of the embedded
* cipher's block size for this call.
*
* @param in the input buffer with the data to be encrypted * @param in the input buffer with the data to be encrypted
* @param inOfs the offset in <code>in</code> * @param inOfs the offset in <code>in</code>
* @param len the length of the input data * @param len the length of the input data
...@@ -479,23 +474,21 @@ final class GaloisCounterMode extends FeedbackCipher { ...@@ -479,23 +474,21 @@ final class GaloisCounterMode extends FeedbackCipher {
* is decrypted. The result is stored in <code>out</code>, starting at * is decrypted. The result is stored in <code>out</code>, starting at
* <code>outOfs</code>. * <code>outOfs</code>.
* *
* <p>It is the application's responsibility to make sure that
* <code>len</code> is a multiple of the embedded cipher's block
* size, as any excess bytes are ignored.
*
* <p>It is also the application's responsibility to make sure that
* <code>init</code> has been called before this method is called.
* (This check is omitted here, to avoid double checking.)
*
* @param in the buffer with the input data to be decrypted * @param in the buffer with the input data to be decrypted
* @param inOfs the offset in <code>in</code> * @param inOfs the offset in <code>in</code>
* @param len the length of the input data * @param len the length of the input data
* @param out the buffer for the result * @param out the buffer for the result
* @param outOfs the offset in <code>out</code> * @param outOfs the offset in <code>out</code>
* @exception ProviderException if <code>len</code> is not
* a multiple of the block size
* @return the number of bytes placed into the <code>out</code> buffer
*/ */
int decrypt(byte[] in, int inOfs, int len, byte[] out, int outOfs) { int decrypt(byte[] in, int inOfs, int len, byte[] out, int outOfs) {
checkDataLength(ibuffer.size(), len); checkDataLength(ibuffer.size(), len);
if ((len % blockSize) != 0) {
throw new ProviderException("Internal error in input buffering");
}
processAAD(); processAAD();
if (len > 0) { if (len > 0) {
......
/* /*
* Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -864,7 +864,9 @@ public final class JceKeyStore extends KeyStoreSpi { ...@@ -864,7 +864,9 @@ public final class JceKeyStore extends KeyStoreSpi {
if (computed[i] != actual[i]) { if (computed[i] != actual[i]) {
throw new IOException( throw new IOException(
"Keystore was tampered with, or " "Keystore was tampered with, or "
+ "password was incorrect"); + "password was incorrect",
new UnrecoverableKeyException(
"Password verification failed"));
} }
} }
} }
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
package com.sun.crypto.provider; package com.sun.crypto.provider;
import java.security.InvalidKeyException; import java.security.InvalidKeyException;
import java.security.ProviderException;
/** /**
* This class represents ciphers in output-feedback (OFB) mode. * This class represents ciphers in output-feedback (OFB) mode.
...@@ -132,101 +133,88 @@ final class OutputFeedback extends FeedbackCipher { ...@@ -132,101 +133,88 @@ final class OutputFeedback extends FeedbackCipher {
* *
* <p>The input plain text <code>plain</code>, starting at * <p>The input plain text <code>plain</code>, starting at
* <code>plainOffset</code> and ending at * <code>plainOffset</code> and ending at
* <code>(plainOffset + len - 1)</code>, is encrypted. * <code>(plainOffset + plainLen - 1)</code>, is encrypted.
* The result is stored in <code>cipher</code>, starting at * The result is stored in <code>cipher</code>, starting at
* <code>cipherOffset</code>. * <code>cipherOffset</code>.
* *
* <p>It is the application's responsibility to make sure that
* <code>plainLen</code> is a multiple of the stream unit size
* <code>numBytes</code>, as any excess bytes are ignored.
*
* <p>It is also the application's responsibility to make sure that
* <code>init</code> has been called before this method is called.
* (This check is omitted here, to avoid double checking.)
*
* @param plain the buffer with the input data to be encrypted * @param plain the buffer with the input data to be encrypted
* @param plainOffset the offset in <code>plain</code> * @param plainOffset the offset in <code>plain</code>
* @param plainLen the length of the input data * @param plainLen the length of the input data
* @param cipher the buffer for the result * @param cipher the buffer for the result
* @param cipherOffset the offset in <code>cipher</code> * @param cipherOffset the offset in <code>cipher</code>
* @exception ProviderException if <code>plainLen</code> is not
* a multiple of the <code>numBytes</code>
* @return the length of the encrypted data * @return the length of the encrypted data
*/ */
int encrypt(byte[] plain, int plainOffset, int plainLen, int encrypt(byte[] plain, int plainOffset, int plainLen,
byte[] cipher, int cipherOffset) byte[] cipher, int cipherOffset) {
{
int i; if ((plainLen % numBytes) != 0) {
int len = blockSize - numBytes; throw new ProviderException("Internal error in input buffering");
}
int nShift = blockSize - numBytes;
int loopCount = plainLen / numBytes; int loopCount = plainLen / numBytes;
int oddBytes = plainLen % numBytes;
if (len == 0) { for (; loopCount > 0;
for (; loopCount > 0; plainOffset += numBytes, cipherOffset += numBytes,
plainOffset += numBytes, cipherOffset += numBytes, loopCount--) {
loopCount--) { embeddedCipher.encryptBlock(register, 0, k, 0);
embeddedCipher.encryptBlock(register, 0, k, 0); for (int i = 0; i < numBytes; i++) {
for (i=0; i<numBytes; i++) cipher[i + cipherOffset] =
cipher[i+cipherOffset] = (byte)(k[i] ^ plain[i + plainOffset]);
(byte)(k[i] ^ plain[i+plainOffset]); if (nShift != 0) {
System.arraycopy(k, 0, register, 0, numBytes); System.arraycopy(register, numBytes, register, 0, nShift);
} }
if (oddBytes > 0) { System.arraycopy(k, 0, register, nShift, numBytes);
embeddedCipher.encryptBlock(register, 0, k, 0);
for (i=0; i<oddBytes; i++)
cipher[i+cipherOffset] =
(byte)(k[i] ^ plain[i+plainOffset]);
System.arraycopy(k, 0, register, 0, numBytes);
}
} else {
for (; loopCount > 0;
plainOffset += numBytes, cipherOffset += numBytes,
loopCount--) {
embeddedCipher.encryptBlock(register, 0, k, 0);
for (i=0; i<numBytes; i++)
cipher[i+cipherOffset] =
(byte)(k[i] ^ plain[i+plainOffset]);
System.arraycopy(register, numBytes, register, 0, len);
System.arraycopy(k, 0, register, len, numBytes);
}
if (oddBytes > 0) {
embeddedCipher.encryptBlock(register, 0, k, 0);
for (i=0; i<oddBytes; i++)
cipher[i+cipherOffset] =
(byte)(k[i] ^ plain[i+plainOffset]);
System.arraycopy(register, numBytes, register, 0, len);
System.arraycopy(k, 0, register, len, numBytes);
} }
} }
return plainLen; return plainLen;
} }
/** /**
* Performs decryption operation. * Performs last encryption operation.
* *
* <p>The input cipher text <code>cipher</code>, starting at * <p>The input plain text <code>plain</code>, starting at
* <code>cipherOffset</code> and ending at * <code>plainOffset</code> and ending at
* <code>(cipherOffset + len - 1)</code>, is decrypted. * <code>(plainOffset + plainLen - 1)</code>, is encrypted.
* The result is stored in <code>plain</code>, starting at * The result is stored in <code>cipher</code>, starting at
* <code>plainOffset</code>. * <code>cipherOffset</code>.
*
* <p>It is the application's responsibility to make sure that
* <code>cipherLen</code> is a multiple of the stream unit size
* <code>numBytes</code>, as any excess bytes are ignored.
*
* <p>It is also the application's responsibility to make sure that
* <code>init</code> has been called before this method is called.
* (This check is omitted here, to avoid double checking.)
* *
* @param cipher the buffer with the input data to be decrypted * @param plain the buffer with the input data to be encrypted
* @param cipherOffset the offset in <code>cipherOffset</code>
* @param cipherLen the length of the input data
* @param plain the buffer for the result
* @param plainOffset the offset in <code>plain</code> * @param plainOffset the offset in <code>plain</code>
* @return the length of the decrypted data * @param plainLen the length of the input data
* @param cipher the buffer for the result
* @param cipherOffset the offset in <code>cipher</code>
* @return the length of the encrypted data
*/ */
int encryptFinal(byte[] plain, int plainOffset, int plainLen,
byte[] cipher, int cipherOffset) {
int oddBytes = plainLen % numBytes;
int len = encrypt(plain, plainOffset, (plainLen - oddBytes),
cipher, cipherOffset);
plainOffset += len;
cipherOffset += len;
if (oddBytes != 0) {
embeddedCipher.encryptBlock(register, 0, k, 0);
for (int i = 0; i < oddBytes; i++) {
cipher[i + cipherOffset] =
(byte)(k[i] ^ plain[ i + plainOffset]);
}
}
return plainLen;
}
// OFB encrypt and decrypt are identical
int decrypt(byte[] cipher, int cipherOffset, int cipherLen, int decrypt(byte[] cipher, int cipherOffset, int cipherLen,
byte[] plain, int plainOffset) byte[] plain, int plainOffset) {
{
// OFB encrypt and decrypt are identical
return encrypt(cipher, cipherOffset, cipherLen, plain, plainOffset); return encrypt(cipher, cipherOffset, cipherLen, plain, plainOffset);
} }
// OFB encrypt and decrypt are identical
int decryptFinal(byte[] cipher, int cipherOffset, int cipherLen,
byte[] plain, int plainOffset) {
// OFB encrypt and decrypt are identical
return encryptFinal(cipher, cipherOffset, cipherLen, plain, plainOffset);
}
} }
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -26,6 +26,8 @@ ...@@ -26,6 +26,8 @@
package com.sun.crypto.provider; package com.sun.crypto.provider;
import java.security.InvalidKeyException; import java.security.InvalidKeyException;
import java.security.ProviderException;
/** /**
* This class represents ciphers in Plaintext Cipher Block Chaining (PCBC) * This class represents ciphers in Plaintext Cipher Block Chaining (PCBC)
...@@ -118,38 +120,36 @@ final class PCBC extends FeedbackCipher { ...@@ -118,38 +120,36 @@ final class PCBC extends FeedbackCipher {
* *
* <p>The input plain text <code>plain</code>, starting at * <p>The input plain text <code>plain</code>, starting at
* <code>plainOffset</code> and ending at * <code>plainOffset</code> and ending at
* <code>(plainOffset + len - 1)</code>, is encrypted. * <code>(plainOffset + plainLen - 1)</code>, is encrypted.
* The result is stored in <code>cipher</code>, starting at * The result is stored in <code>cipher</code>, starting at
* <code>cipherOffset</code>. * <code>cipherOffset</code>.
* *
* <p>It is the application's responsibility to make sure that
* <code>plainLen</code> is a multiple of the embedded cipher's block size,
* as any excess bytes are ignored.
*
* <p>It is also the application's responsibility to make sure that
* <code>init</code> has been called before this method is called.
* (This check is omitted here, to avoid double checking.)
*
* @param plain the buffer with the input data to be encrypted * @param plain the buffer with the input data to be encrypted
* @param plainOffset the offset in <code>plain</code> * @param plainOffset the offset in <code>plain</code>
* @param plainLen the length of the input data * @param plainLen the length of the input data
* @param cipher the buffer for the result * @param cipher the buffer for the result
* @param cipherOffset the offset in <code>cipher</code> * @param cipherOffset the offset in <code>cipher</code>
* @exception ProviderException if <code>plainLen</code> is not
* a multiple of the block size
* @return the length of the encrypted data
*/ */
int encrypt(byte[] plain, int plainOffset, int plainLen, int encrypt(byte[] plain, int plainOffset, int plainLen,
byte[] cipher, int cipherOffset) byte[] cipher, int cipherOffset)
{ {
if ((plainLen % blockSize) != 0) {
throw new ProviderException("Internal error in input buffering");
}
int i; int i;
int endIndex = plainOffset + plainLen; int endIndex = plainOffset + plainLen;
for (; plainOffset < endIndex; for (; plainOffset < endIndex;
plainOffset += blockSize, cipherOffset += blockSize) { plainOffset += blockSize, cipherOffset += blockSize) {
for (i=0; i<blockSize; i++) { for (i = 0; i < blockSize; i++) {
k[i] ^= plain[i+plainOffset]; k[i] ^= plain[i + plainOffset];
} }
embeddedCipher.encryptBlock(k, 0, cipher, cipherOffset); embeddedCipher.encryptBlock(k, 0, cipher, cipherOffset);
for (i = 0; i < blockSize; i++) { for (i = 0; i < blockSize; i++) {
k[i] = (byte)(plain[i+plainOffset] ^ cipher[i+cipherOffset]); k[i] = (byte)(plain[i + plainOffset] ^ cipher[i + cipherOffset]);
} }
} }
return plainLen; return plainLen;
...@@ -160,27 +160,25 @@ final class PCBC extends FeedbackCipher { ...@@ -160,27 +160,25 @@ final class PCBC extends FeedbackCipher {
* *
* <p>The input cipher text <code>cipher</code>, starting at * <p>The input cipher text <code>cipher</code>, starting at
* <code>cipherOffset</code> and ending at * <code>cipherOffset</code> and ending at
* <code>(cipherOffset + len - 1)</code>, is decrypted. * <code>(cipherOffset + cipherLen - 1)</code>, is decrypted.
* The result is stored in <code>plain</code>, starting at * The result is stored in <code>plain</code>, starting at
* <code>plainOffset</code>. * <code>plainOffset</code>.
* *
* <p>It is the application's responsibility to make sure that
* <code>cipherLen</code> is a multiple of the embedded cipher's block
* size, as any excess bytes are ignored.
*
* <p>It is also the application's responsibility to make sure that
* <code>init</code> has been called before this method is called.
* (This check is omitted here, to avoid double checking.)
*
* @param cipher the buffer with the input data to be decrypted * @param cipher the buffer with the input data to be decrypted
* @param cipherOffset the offset in <code>cipherOffset</code> * @param cipherOffset the offset in <code>cipherOffset</code>
* @param cipherLen the length of the input data * @param cipherLen the length of the input data
* @param plain the buffer for the result * @param plain the buffer for the result
* @param plainOffset the offset in <code>plain</code> * @param plainOffset the offset in <code>plain</code>
* @exception ProviderException if <code>cipherLen</code> is not
* a multiple of the block size
* @return the length of the decrypted data
*/ */
int decrypt(byte[] cipher, int cipherOffset, int cipherLen, int decrypt(byte[] cipher, int cipherOffset, int cipherLen,
byte[] plain, int plainOffset) byte[] plain, int plainOffset)
{ {
if ((cipherLen % blockSize) != 0) {
throw new ProviderException("Internal error in input buffering");
}
int i; int i;
int endIndex = cipherOffset + cipherLen; int endIndex = cipherOffset + cipherLen;
...@@ -189,10 +187,10 @@ final class PCBC extends FeedbackCipher { ...@@ -189,10 +187,10 @@ final class PCBC extends FeedbackCipher {
embeddedCipher.decryptBlock(cipher, cipherOffset, embeddedCipher.decryptBlock(cipher, cipherOffset,
plain, plainOffset); plain, plainOffset);
for (i = 0; i < blockSize; i++) { for (i = 0; i < blockSize; i++) {
plain[i+plainOffset] ^= k[i]; plain[i + plainOffset] ^= k[i];
} }
for (i = 0; i < blockSize; i++) { for (i = 0; i < blockSize; i++) {
k[i] = (byte)(plain[i+plainOffset] ^ cipher[i+cipherOffset]); k[i] = (byte)(plain[i + plainOffset] ^ cipher[i + cipherOffset]);
} }
} }
return cipherLen; return cipherLen;
......
/* /*
* Copyright (c) 2013, 2015 Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
......
...@@ -300,7 +300,7 @@ abstract class AbstractLdapNamingEnumeration<T extends NameClassPair> ...@@ -300,7 +300,7 @@ abstract class AbstractLdapNamingEnumeration<T extends NameClassPair>
errEx = e; errEx = e;
} }
protected abstract AbstractLdapNamingEnumeration<T> getReferredResults( protected abstract AbstractLdapNamingEnumeration<? extends NameClassPair> getReferredResults(
LdapReferralContext refCtx) throws NamingException; LdapReferralContext refCtx) throws NamingException;
/* /*
...@@ -360,7 +360,7 @@ abstract class AbstractLdapNamingEnumeration<T extends NameClassPair> ...@@ -360,7 +360,7 @@ abstract class AbstractLdapNamingEnumeration<T extends NameClassPair>
* Merge the entries and/or referrals from the supplied enumeration * Merge the entries and/or referrals from the supplied enumeration
* with those of the current enumeration. * with those of the current enumeration.
*/ */
protected void update(AbstractLdapNamingEnumeration<T> ne) { protected void update(AbstractLdapNamingEnumeration<? extends NameClassPair> ne) {
// Cleanup previous context first // Cleanup previous context first
homeCtx.decEnumCount(); homeCtx.decEnumCount();
......
/* /*
* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -60,7 +60,6 @@ class DigestClientId extends SimpleClientId { ...@@ -60,7 +60,6 @@ class DigestClientId extends SimpleClientId {
final private String[] propvals; final private String[] propvals;
final private int myHash; final private int myHash;
private int pHash = 0;
DigestClientId(int version, String hostname, int port, DigestClientId(int version, String hostname, int port,
String protocol, Control[] bindCtls, OutputStream trace, String protocol, Control[] bindCtls, OutputStream trace,
...@@ -78,12 +77,9 @@ class DigestClientId extends SimpleClientId { ...@@ -78,12 +77,9 @@ class DigestClientId extends SimpleClientId {
propvals = new String[SASL_PROPS.length]; propvals = new String[SASL_PROPS.length];
for (int i = 0; i < SASL_PROPS.length; i++) { for (int i = 0; i < SASL_PROPS.length; i++) {
propvals[i] = (String) env.get(SASL_PROPS[i]); propvals[i] = (String) env.get(SASL_PROPS[i]);
if (propvals[i] != null) {
pHash = pHash * 31 + propvals[i].hashCode();
}
} }
} }
myHash = super.hashCode() + pHash; myHash = super.hashCode() ^ Arrays.hashCode(propvals);
} }
public boolean equals(Object obj) { public boolean equals(Object obj) {
...@@ -92,7 +88,6 @@ class DigestClientId extends SimpleClientId { ...@@ -92,7 +88,6 @@ class DigestClientId extends SimpleClientId {
} }
DigestClientId other = (DigestClientId)obj; DigestClientId other = (DigestClientId)obj;
return myHash == other.myHash return myHash == other.myHash
&& pHash == other.pHash
&& super.equals(obj) && super.equals(obj)
&& Arrays.equals(propvals, other.propvals); && Arrays.equals(propvals, other.propvals);
} }
......
...@@ -104,9 +104,9 @@ final class LdapBindingEnumeration ...@@ -104,9 +104,9 @@ final class LdapBindingEnumeration
} }
@Override @Override
protected LdapBindingEnumeration getReferredResults( protected AbstractLdapNamingEnumeration<? extends NameClassPair> getReferredResults(
LdapReferralContext refCtx) throws NamingException{ LdapReferralContext refCtx) throws NamingException{
// repeat the original operation at the new context // repeat the original operation at the new context
return (LdapBindingEnumeration)refCtx.listBindings(listArg); return (AbstractLdapNamingEnumeration<? extends NameClassPair>)refCtx.listBindings(listArg);
} }
} }
...@@ -72,9 +72,9 @@ final class LdapNamingEnumeration ...@@ -72,9 +72,9 @@ final class LdapNamingEnumeration
} }
@Override @Override
protected LdapNamingEnumeration getReferredResults( protected AbstractLdapNamingEnumeration<? extends NameClassPair> getReferredResults(
LdapReferralContext refCtx) throws NamingException { LdapReferralContext refCtx) throws NamingException {
// repeat the original operation at the new context // repeat the original operation at the new context
return (LdapNamingEnumeration)refCtx.list(listArg); return (AbstractLdapNamingEnumeration<? extends NameClassPair>)refCtx.list(listArg);
} }
} }
...@@ -199,15 +199,15 @@ final class LdapSearchEnumeration ...@@ -199,15 +199,15 @@ final class LdapSearchEnumeration
} }
@Override @Override
protected LdapSearchEnumeration getReferredResults( protected AbstractLdapNamingEnumeration<? extends NameClassPair> getReferredResults(
LdapReferralContext refCtx) throws NamingException { LdapReferralContext refCtx) throws NamingException {
// repeat the original operation at the new context // repeat the original operation at the new context
return (LdapSearchEnumeration)refCtx.search( return (AbstractLdapNamingEnumeration<? extends NameClassPair>)refCtx.search(
searchArgs.name, searchArgs.filter, searchArgs.cons); searchArgs.name, searchArgs.filter, searchArgs.cons);
} }
@Override @Override
protected void update(AbstractLdapNamingEnumeration<SearchResult> ne) { protected void update(AbstractLdapNamingEnumeration<? extends NameClassPair> ne) {
super.update(ne); super.update(ne);
// Update search-specific variables // Update search-specific variables
......
/* /*
* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -49,21 +49,23 @@ class SimpleClientId extends ClientId { ...@@ -49,21 +49,23 @@ class SimpleClientId extends ClientId {
socketFactory); socketFactory);
this.username = username; this.username = username;
int pwdHashCode = 0;
if (passwd == null) { if (passwd == null) {
this.passwd = null; this.passwd = null;
} else if (passwd instanceof String) {
this.passwd = passwd;
} else if (passwd instanceof byte[]) { } else if (passwd instanceof byte[]) {
this.passwd = ((byte[])passwd).clone(); this.passwd = ((byte[])passwd).clone();
pwdHashCode = Arrays.hashCode((byte[])passwd);
} else if (passwd instanceof char[]) { } else if (passwd instanceof char[]) {
this.passwd = ((char[])passwd).clone(); this.passwd = ((char[])passwd).clone();
pwdHashCode = Arrays.hashCode((char[])passwd);
} else { } else {
this.passwd = passwd; this.passwd = passwd;
pwdHashCode = passwd.hashCode();
} }
myHash = super.hashCode() myHash = super.hashCode()
+ (username != null ? username.hashCode() : 0) ^ (username != null ? username.hashCode() : 0)
+ (passwd != null ? passwd.hashCode() : 0); ^ pwdHashCode;
} }
public boolean equals(Object obj) { public boolean equals(Object obj) {
......
...@@ -118,7 +118,11 @@ final public class Pool { ...@@ -118,7 +118,11 @@ final public class Pool {
PooledConnectionFactory factory) throws NamingException { PooledConnectionFactory factory) throws NamingException {
d("get(): ", id); d("get(): ", id);
d("size: ", map.size()); if (debug) {
synchronized (map) {
d("size: ", map.size());
}
}
expungeStaleConnections(); expungeStaleConnections();
...@@ -141,10 +145,9 @@ final public class Pool { ...@@ -141,10 +145,9 @@ final public class Pool {
// Keep the weak reference through the element of a linked list // Keep the weak reference through the element of a linked list
weakRefs.add(weakRef); weakRefs.add(weakRef);
} }
d("get(): size after: ", map.size());
} }
d("get(): size after: ", map.size());
return conns.get(timeout, factory); // get one connection from list return conns.get(timeout, factory); // get one connection from list
} }
...@@ -209,19 +212,24 @@ final public class Pool { ...@@ -209,19 +212,24 @@ final public class Pool {
out.println("maximum pool size: " + maxSize); out.println("maximum pool size: " + maxSize);
out.println("preferred pool size: " + prefSize); out.println("preferred pool size: " + prefSize);
out.println("initial pool size: " + initSize); out.println("initial pool size: " + initSize);
out.println("current pool size: " + map.size());
for (Map.Entry<Object, ConnectionsRef> entry : map.entrySet()) { synchronized (map) {
id = entry.getKey(); out.println("current pool size: " + map.size());
conns = entry.getValue().getConnections();
out.println(" " + id + ":" + conns.getStats()); for (Map.Entry<Object, ConnectionsRef> entry : map.entrySet()) {
id = entry.getKey();
conns = entry.getValue().getConnections();
out.println(" " + id + ":" + conns.getStats());
}
} }
out.println("====== Pool end ====================="); out.println("====== Pool end =====================");
} }
public String toString() { public String toString() {
return super.toString() + " " + map.toString(); synchronized (map) {
return super.toString() + " " + map.toString();
}
} }
private void d(String msg, int i) { private void d(String msg, int i) {
......
/* /*
* Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -133,6 +133,10 @@ public class EventHandler implements Runnable { ...@@ -133,6 +133,10 @@ public class EventHandler implements Runnable {
if (!vmDied) { if (!vmDied) {
vmDisconnectEvent(event); vmDisconnectEvent(event);
} }
/*
* Inform jdb command line processor that jdb is being shutdown. JDK-8154144.
*/
((TTY)notifier).setShuttingDown(true);
Env.shutdown(shutdownMessageKey); Env.shutdown(shutdownMessageKey);
return false; return false;
} else { } else {
......
/* /*
* Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -56,6 +56,16 @@ public class TTY implements EventNotifier { ...@@ -56,6 +56,16 @@ public class TTY implements EventNotifier {
*/ */
private static final String progname = "jdb"; private static final String progname = "jdb";
private volatile boolean shuttingDown = false;
public void setShuttingDown(boolean s) {
shuttingDown = s;
}
public boolean isShuttingDown() {
return shuttingDown;
}
@Override @Override
public void vmStartEvent(VMStartEvent se) { public void vmStartEvent(VMStartEvent se) {
Thread.yield(); // fetch output Thread.yield(); // fetch output
...@@ -750,7 +760,13 @@ public class TTY implements EventNotifier { ...@@ -750,7 +760,13 @@ public class TTY implements EventNotifier {
while (true) { while (true) {
String ln = in.readLine(); String ln = in.readLine();
if (ln == null) { if (ln == null) {
MessageOutput.println("Input stream closed."); /*
* Jdb is being shutdown because debuggee exited, ignore any 'null'
* returned by readLine() during shutdown. JDK-8154144.
*/
if (!isShuttingDown()) {
MessageOutput.println("Input stream closed.");
}
ln = "quit"; ln = "quit";
} }
......
...@@ -250,7 +250,7 @@ public final class SplashScreen { ...@@ -250,7 +250,7 @@ public final class SplashScreen {
assert scale > 0; assert scale > 0;
if (scale > 0 && scale != 1) { if (scale > 0 && scale != 1) {
bounds.setSize((int) (bounds.getWidth() / scale), bounds.setSize((int) (bounds.getWidth() / scale),
(int) (bounds.getWidth() / scale)); (int) (bounds.getHeight() / scale));
} }
return bounds; return bounds;
} }
......
/* /*
* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -915,6 +915,9 @@ assertEquals("[x, y, z]", pb.command().toString()); ...@@ -915,6 +915,9 @@ assertEquals("[x, y, z]", pb.command().toString());
* @throws NullPointerException if any argument is null * @throws NullPointerException if any argument is null
*/ */
public MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException { public MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException {
if (refc.isArray()) {
throw new NoSuchMethodException("no constructor for array class: " + refc.getName());
}
String name = "<init>"; String name = "<init>";
MemberName ctor = resolveOrFail(REF_newInvokeSpecial, refc, name, type); MemberName ctor = resolveOrFail(REF_newInvokeSpecial, refc, name, type);
return getDirectConstructor(refc, ctor); return getDirectConstructor(refc, ctor);
......
/* /*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -25,12 +25,16 @@ ...@@ -25,12 +25,16 @@
package java.security; package java.security;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.WeakHashMap; import java.util.concurrent.ConcurrentHashMap;
import sun.misc.JavaSecurityProtectionDomainAccess; import sun.misc.JavaSecurityProtectionDomainAccess;
import static sun.misc.JavaSecurityProtectionDomainAccess.ProtectionDomainCache; import static sun.misc.JavaSecurityProtectionDomainAccess.ProtectionDomainCache;
import sun.security.util.Debug; import sun.security.util.Debug;
...@@ -456,24 +460,14 @@ public class ProtectionDomain { ...@@ -456,24 +460,14 @@ public class ProtectionDomain {
/** /**
* Used for storing ProtectionDomains as keys in a Map. * Used for storing ProtectionDomains as keys in a Map.
*/ */
final class Key {} static final class Key {}
static { static {
SharedSecrets.setJavaSecurityProtectionDomainAccess( SharedSecrets.setJavaSecurityProtectionDomainAccess(
new JavaSecurityProtectionDomainAccess() { new JavaSecurityProtectionDomainAccess() {
@Override
public ProtectionDomainCache getProtectionDomainCache() { public ProtectionDomainCache getProtectionDomainCache() {
return new ProtectionDomainCache() { return new PDCache();
private final Map<Key, PermissionCollection> map =
Collections.synchronizedMap
(new WeakHashMap<Key, PermissionCollection>());
public void put(ProtectionDomain pd,
PermissionCollection pc) {
map.put((pd == null ? null : pd.key), pc);
}
public PermissionCollection get(ProtectionDomain pd) {
return pd == null ? map.get(null) : map.get(pd.key);
}
};
} }
@Override @Override
...@@ -482,4 +476,119 @@ public class ProtectionDomain { ...@@ -482,4 +476,119 @@ public class ProtectionDomain {
} }
}); });
} }
/**
* A cache of ProtectionDomains and their Permissions.
*
* This class stores ProtectionDomains as weak keys in a ConcurrentHashMap
* with additional support for checking and removing weak keys that are no
* longer in use. There can be cases where the permission collection may
* have a chain of strong references back to the ProtectionDomain, which
* ordinarily would prevent the entry from being removed from the map. To
* address that, we wrap the permission collection in a SoftReference so
* that it can be reclaimed by the garbage collector due to memory demand.
*/
private static class PDCache implements ProtectionDomainCache {
private final ConcurrentHashMap<WeakProtectionDomainKey,
SoftReference<PermissionCollection>>
pdMap = new ConcurrentHashMap<>();
private final ReferenceQueue<Key> queue = new ReferenceQueue<>();
@Override
public void put(ProtectionDomain pd, PermissionCollection pc) {
processQueue(queue, pdMap);
WeakProtectionDomainKey weakPd =
new WeakProtectionDomainKey(pd, queue);
pdMap.put(weakPd, new SoftReference<>(pc));
}
@Override
public PermissionCollection get(ProtectionDomain pd) {
processQueue(queue, pdMap);
WeakProtectionDomainKey weakPd = new WeakProtectionDomainKey(pd);
SoftReference<PermissionCollection> sr = pdMap.get(weakPd);
return (sr == null) ? null : sr.get();
}
/**
* Removes weak keys from the map that have been enqueued
* on the reference queue and are no longer in use.
*/
private static void processQueue(ReferenceQueue<Key> queue,
ConcurrentHashMap<? extends
WeakReference<Key>, ?> pdMap) {
Reference<? extends Key> ref;
while ((ref = queue.poll()) != null) {
pdMap.remove(ref);
}
}
}
/**
* A weak key for a ProtectionDomain.
*/
private static class WeakProtectionDomainKey extends WeakReference<Key> {
/**
* Saved value of the referent's identity hash code, to maintain
* a consistent hash code after the referent has been cleared
*/
private final int hash;
/**
* A key representing a null ProtectionDomain.
*/
private static final Key NULL_KEY = new Key();
/**
* Create a new WeakProtectionDomain with the specified domain and
* registered with a queue.
*/
WeakProtectionDomainKey(ProtectionDomain pd, ReferenceQueue<Key> rq) {
this((pd == null ? NULL_KEY : pd.key), rq);
}
WeakProtectionDomainKey(ProtectionDomain pd) {
this(pd == null ? NULL_KEY : pd.key);
}
private WeakProtectionDomainKey(Key key, ReferenceQueue<Key> rq) {
super(key, rq);
hash = key.hashCode();
}
private WeakProtectionDomainKey(Key key) {
super(key);
hash = key.hashCode();
}
/**
* Returns the identity hash code of the original referent.
*/
@Override
public int hashCode() {
return hash;
}
/**
* Returns true if the given object is an identical
* WeakProtectionDomainKey instance, or, if this object's referent
* has not been cleared and the given object is another
* WeakProtectionDomainKey instance with an identical non-null
* referent as this one.
*/
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj instanceof WeakProtectionDomainKey) {
Object referent = get();
return (referent != null) &&
(referent == ((WeakProtectionDomainKey)obj).get());
} else {
return false;
}
}
}
} }
...@@ -464,7 +464,7 @@ public class SecureRandom extends java.util.Random { ...@@ -464,7 +464,7 @@ public class SecureRandom extends java.util.Random {
* @param bytes the array to be filled in with random bytes. * @param bytes the array to be filled in with random bytes.
*/ */
@Override @Override
synchronized public void nextBytes(byte[] bytes) { public void nextBytes(byte[] bytes) {
secureRandomSpi.engineNextBytes(bytes); secureRandomSpi.engineNextBytes(bytes);
} }
......
/* /*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -125,8 +125,6 @@ public class BasicComboBoxUI extends ComboBoxUI { ...@@ -125,8 +125,6 @@ public class BasicComboBoxUI extends ComboBoxUI {
protected MouseMotionListener popupMouseMotionListener; protected MouseMotionListener popupMouseMotionListener;
protected KeyListener popupKeyListener; protected KeyListener popupKeyListener;
private MouseWheelListener mouseWheelListener;
// This is used for knowing when to cache the minimum preferred size. // This is used for knowing when to cache the minimum preferred size.
// If the data in the list changes, the cached value get marked for recalc. // If the data in the list changes, the cached value get marked for recalc.
// Added to the current JComboBox model // Added to the current JComboBox model
...@@ -377,10 +375,6 @@ public class BasicComboBoxUI extends ComboBoxUI { ...@@ -377,10 +375,6 @@ public class BasicComboBoxUI extends ComboBoxUI {
comboBox.getModel().addListDataListener( listDataListener ); comboBox.getModel().addListDataListener( listDataListener );
} }
} }
if ((mouseWheelListener = createMouseWheelListener()) != null) {
comboBox.addMouseWheelListener(mouseWheelListener);
}
} }
/** /**
...@@ -427,9 +421,6 @@ public class BasicComboBoxUI extends ComboBoxUI { ...@@ -427,9 +421,6 @@ public class BasicComboBoxUI extends ComboBoxUI {
comboBox.getModel().removeListDataListener( listDataListener ); comboBox.getModel().removeListDataListener( listDataListener );
} }
} }
if (mouseWheelListener != null) {
comboBox.removeMouseWheelListener(mouseWheelListener);
}
} }
/** /**
...@@ -543,10 +534,6 @@ public class BasicComboBoxUI extends ComboBoxUI { ...@@ -543,10 +534,6 @@ public class BasicComboBoxUI extends ComboBoxUI {
return handler; return handler;
} }
private MouseWheelListener createMouseWheelListener() {
return getHandler();
}
// //
// end UI Initialization // end UI Initialization
//====================== //======================
...@@ -1682,8 +1669,7 @@ public class BasicComboBoxUI extends ComboBoxUI { ...@@ -1682,8 +1669,7 @@ public class BasicComboBoxUI extends ComboBoxUI {
// //
private class Handler implements ActionListener, FocusListener, private class Handler implements ActionListener, FocusListener,
KeyListener, LayoutManager, KeyListener, LayoutManager,
ListDataListener, PropertyChangeListener, ListDataListener, PropertyChangeListener {
MouseWheelListener {
// //
// PropertyChangeListener // PropertyChangeListener
// //
...@@ -1967,10 +1953,6 @@ public class BasicComboBoxUI extends ComboBoxUI { ...@@ -1967,10 +1953,6 @@ public class BasicComboBoxUI extends ComboBoxUI {
} }
} }
} }
public void mouseWheelMoved(MouseWheelEvent e) {
e.consume();
}
} }
class DefaultKeySelectionManager implements JComboBox.KeySelectionManager, UIResource { class DefaultKeySelectionManager implements JComboBox.KeySelectionManager, UIResource {
......
/* /*
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -345,17 +345,26 @@ public class BasicComboPopup extends JPopupMenu implements ComboPopup { ...@@ -345,17 +345,26 @@ public class BasicComboPopup extends JPopupMenu implements ComboPopup {
// PopupMenuListeners. // PopupMenuListeners.
protected void firePopupMenuWillBecomeVisible() { protected void firePopupMenuWillBecomeVisible() {
if (scrollerMouseWheelListener != null) {
comboBox.addMouseWheelListener(scrollerMouseWheelListener);
}
super.firePopupMenuWillBecomeVisible(); super.firePopupMenuWillBecomeVisible();
// comboBox.firePopupMenuWillBecomeVisible() is called from BasicComboPopup.show() method // comboBox.firePopupMenuWillBecomeVisible() is called from BasicComboPopup.show() method
// to let the user change the popup menu from the PopupMenuListener.popupMenuWillBecomeVisible() // to let the user change the popup menu from the PopupMenuListener.popupMenuWillBecomeVisible()
} }
protected void firePopupMenuWillBecomeInvisible() { protected void firePopupMenuWillBecomeInvisible() {
if (scrollerMouseWheelListener != null) {
comboBox.removeMouseWheelListener(scrollerMouseWheelListener);
}
super.firePopupMenuWillBecomeInvisible(); super.firePopupMenuWillBecomeInvisible();
comboBox.firePopupMenuWillBecomeInvisible(); comboBox.firePopupMenuWillBecomeInvisible();
} }
protected void firePopupMenuCanceled() { protected void firePopupMenuCanceled() {
if (scrollerMouseWheelListener != null) {
comboBox.removeMouseWheelListener(scrollerMouseWheelListener);
}
super.firePopupMenuCanceled(); super.firePopupMenuCanceled();
comboBox.firePopupMenuCanceled(); comboBox.firePopupMenuCanceled();
} }
...@@ -997,6 +1006,8 @@ public class BasicComboPopup extends JPopupMenu implements ComboPopup { ...@@ -997,6 +1006,8 @@ public class BasicComboPopup extends JPopupMenu implements ComboPopup {
if (e.getStateChange() == ItemEvent.SELECTED) { if (e.getStateChange() == ItemEvent.SELECTED) {
JComboBox comboBox = (JComboBox)e.getSource(); JComboBox comboBox = (JComboBox)e.getSource();
setListSelection(comboBox.getSelectedIndex()); setListSelection(comboBox.getSelectedIndex());
} else {
setListSelection(-1);
} }
} }
......
...@@ -13407,7 +13407,7 @@ ...@@ -13407,7 +13407,7 @@
<cacheSettingsInherited>false</cacheSettingsInherited> <cacheSettingsInherited>false</cacheSettingsInherited>
<cacheMode>NO_CACHING</cacheMode> <cacheMode>NO_CACHING</cacheMode>
<uiproperties> <uiproperties>
<uiProperty name="rendererUseListColors" type="BOOLEAN" value="true"/> <uiProperty name="rendererUseListColors" type="BOOLEAN" value="false"/>
<uiProperty name="rendererUseUIBorder" type="BOOLEAN" value="true"/> <uiProperty name="rendererUseUIBorder" type="BOOLEAN" value="true"/>
<uiProperty name="cellNoFocusBorder" type="BORDER"> <uiProperty name="cellNoFocusBorder" type="BORDER">
<border type="empty" top="2" left="5" bottom="2" right="5"/> <border type="empty" top="2" left="5" bottom="2" right="5"/>
...@@ -13513,10 +13513,10 @@ ...@@ -13513,10 +13513,10 @@
<uiproperties/> <uiproperties/>
</style> </style>
<backgroundStates> <backgroundStates>
<state stateKeys="Disabled"> <state stateKeys="Selected">
<style> <style>
<textForeground> <textForeground>
<matte red="142" green="143" blue="145" alpha="255" uiDefaultParentName="nimbusDisabledText" hueOffset="0.0" saturationOffset="0.0" brightnessOffset="0.0" alphaOffset="0"/> <matte red="255" green="255" blue="255" alpha="255" uiDefaultParentName="nimbusLightBackground" hueOffset="0.0" saturationOffset="0.0" brightnessOffset="0.0" alphaOffset="0"/>
</textForeground> </textForeground>
<textBackground/> <textBackground/>
<background> <background>
...@@ -13541,6 +13541,56 @@ ...@@ -13541,6 +13541,56 @@
</layer> </layer>
</canvas> </canvas>
</state> </state>
<state stateKeys="Disabled+Selected">
<style>
<textForeground/>
<textBackground/>
<background>
<matte red="57" green="105" blue="138" alpha="255" uiDefaultParentName="nimbusSelectionBackground" hueOffset="0.0" saturationOffset="0.0" brightnessOffset="0.0" alphaOffset="0"/>
</background>
<inherit-background>false</inherit-background>
<uiproperties/>
</style>
<canvas>
<size width="100" height="30"/>
<nextLayerNameIndex>2</nextLayerNameIndex>
<stretchingInsets top="0" bottom="0" left="0" right="0"/>
<layer name="Layer 1">
<opacity>1.0</opacity>
<fillOpacity>1.0</fillOpacity>
<blendingMode>NORMAL</blendingMode>
<locked>false</locked>
<visible>true</visible>
<shapes/>
<effects/>
</layer>
</canvas>
</state>
<state stateKeys="Disabled">
<style>
<textForeground>
<matte red="142" green="143" blue="145" alpha="255" uiDefaultParentName="nimbusDisabledText" hueOffset="0.0" saturationOffset="0.0" brightnessOffset="0.0" alphaOffset="0"/>
</textForeground>
<textBackground/>
<background/>
<inherit-textForeground>false</inherit-textForeground>
<uiproperties/>
</style>
<canvas>
<size width="100" height="30"/>
<nextLayerNameIndex>2</nextLayerNameIndex>
<stretchingInsets top="0" bottom="0" left="0" right="0"/>
<layer name="Layer 1">
<opacity>1.0</opacity>
<fillOpacity>1.0</fillOpacity>
<blendingMode>NORMAL</blendingMode>
<locked>false</locked>
<visible>true</visible>
<shapes/>
<effects/>
</layer>
</canvas>
</state>
</backgroundStates> </backgroundStates>
<foregroundStates/> <foregroundStates/>
<borderStates/> <borderStates/>
...@@ -1986,57 +1986,69 @@ class Parser implements DTDConstants { ...@@ -1986,57 +1986,69 @@ class Parser implements DTDConstants {
while (true) { while (true) {
int i = 0; int i = 0;
while (!insideComment && i < SCRIPT_END_TAG.length while (!insideComment && i < SCRIPT_END_TAG.length
&& (SCRIPT_END_TAG[i] == ch && (SCRIPT_END_TAG[i] == ch
|| SCRIPT_END_TAG_UPPER_CASE[i] == ch)) { || SCRIPT_END_TAG_UPPER_CASE[i] == ch)) {
charsToAdd[i] = (char) ch; charsToAdd[i] = (char) ch;
ch = readCh(); ch = readCh();
i++; i++;
} }
if (i == SCRIPT_END_TAG.length) { if (i == SCRIPT_END_TAG.length) {
/* '</script>' tag detected */
/* Here, ch == the first character after </script> */
return; return;
} else { }
/* To account for extra read()'s that happened */
for (int j = 0; j < i; j++) {
addString(charsToAdd[j]);
}
switch (ch) { if (!insideComment && i == 1 && charsToAdd[0] == START_COMMENT.charAt(0)) {
case -1: // it isn't end script tag, but may be it's start comment tag?
error("eof.script"); while (i < START_COMMENT.length()
return; && START_COMMENT.charAt(i) == ch) {
case '\n': charsToAdd[i] = (char) ch;
ln++;
ch = readCh(); ch = readCh();
lfCount++; i++;
addString('\n'); }
break; if (i == START_COMMENT.length()) {
case '\r': insideComment = true;
ln++; }
if ((ch = readCh()) == '\n') { }
ch = readCh(); if (insideComment) {
crlfCount++; while (i < END_COMMENT.length()
} else { && END_COMMENT.charAt(i) == ch) {
crCount++; charsToAdd[i] = (char) ch;
}
addString('\n');
break;
default:
addString(ch);
String str = new String(getChars(0, strpos));
if (!insideComment && str.endsWith(START_COMMENT)) {
insideComment = true;
}
if (insideComment && str.endsWith(END_COMMENT)) {
insideComment = false;
}
ch = readCh(); ch = readCh();
break; i++;
} // switch }
if (i == END_COMMENT.length()) {
insideComment = false;
}
}
/* To account for extra read()'s that happened */
for (int j = 0; j < i; j++) {
addString(charsToAdd[j]);
} }
switch (ch) {
case -1:
error("eof.script");
return;
case '\n':
ln++;
ch = readCh();
lfCount++;
addString('\n');
break;
case '\r':
ln++;
if ((ch = readCh()) == '\n') {
ch = readCh();
crlfCount++;
} else {
crCount++;
}
addString('\n');
break;
default:
addString(ch);
ch = readCh();
break;
} // switch
} // while } // while
} }
......
...@@ -270,10 +270,21 @@ public final class CompositeFont extends Font2D { ...@@ -270,10 +270,21 @@ public final class CompositeFont extends Font2D {
if (componentNames[slot] == null) { if (componentNames[slot] == null) {
componentNames[slot] = name; componentNames[slot] = name;
} else if (!componentNames[slot].equalsIgnoreCase(name)) { } else if (!componentNames[slot].equalsIgnoreCase(name)) {
components[slot] = /* If a component specifies the file with a bad font,
(PhysicalFont) fm.findFont2D(componentNames[slot], * the corresponding slot will be initialized by
style, * default physical font. In such case findFont2D may
* return composite font which cannot be casted to
* physical font.
*/
try {
components[slot] =
(PhysicalFont) fm.findFont2D(componentNames[slot],
style,
FontManager.PHYSICAL_FALLBACK); FontManager.PHYSICAL_FALLBACK);
} catch (ClassCastException cce) {
/* Assign default physical font to the slot */
components[slot] = fm.getDefaultPhysicalFont();
}
} }
} }
deferredInitialisation[slot] = false; deferredInitialisation[slot] = false;
......
...@@ -335,9 +335,9 @@ public class FontFamily { ...@@ -335,9 +335,9 @@ public class FontFamily {
case Font.BOLD|Font.ITALIC: case Font.BOLD|Font.ITALIC:
if (bolditalic != null) { if (bolditalic != null) {
return bolditalic; return bolditalic;
} else if (italic != null && italic.canDoStyle(style)) {
return italic;
} else if (bold != null && bold.canDoStyle(style)) { } else if (bold != null && bold.canDoStyle(style)) {
return bold;
} else if (italic != null && italic.canDoStyle(style)) {
return italic; return italic;
} else if (plain != null && plain.canDoStyle(style)) { } else if (plain != null && plain.canDoStyle(style)) {
return plain; return plain;
......
...@@ -44,7 +44,7 @@ public final class ScriptRunData { ...@@ -44,7 +44,7 @@ public final class ScriptRunData {
if (cp >= data[cache] && cp < data[cache+2]) { if (cp >= data[cache] && cp < data[cache+2]) {
return data[cache+1]; return data[cache+1];
} }
if (cp >= CHAR_START & cp < CHAR_LIMIT) { if ((cp >= CHAR_START) && (cp < CHAR_LIMIT)) {
int probe = dataPower; int probe = dataPower;
int index = 0; int index = 0;
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
package sun.java2d.opengl; package sun.java2d.opengl;
import java.awt.Composite; import java.awt.Composite;
import sun.java2d.InvalidPipeException;
import sun.java2d.SunGraphics2D; import sun.java2d.SunGraphics2D;
import sun.java2d.loops.GraphicsPrimitive; import sun.java2d.loops.GraphicsPrimitive;
import sun.java2d.loops.GraphicsPrimitiveMgr; import sun.java2d.loops.GraphicsPrimitiveMgr;
...@@ -67,7 +68,14 @@ class OGLMaskFill extends BufferedMaskFill { ...@@ -67,7 +68,14 @@ class OGLMaskFill extends BufferedMaskFill {
protected void validateContext(SunGraphics2D sg2d, protected void validateContext(SunGraphics2D sg2d,
Composite comp, int ctxflags) Composite comp, int ctxflags)
{ {
OGLSurfaceData dstData = (OGLSurfaceData)sg2d.surfaceData; OGLSurfaceData dstData;
try {
dstData = (OGLSurfaceData) sg2d.surfaceData;
} catch (ClassCastException e) {
throw new InvalidPipeException("wrong surface data type: " +
sg2d.surfaceData);
}
OGLContext.validateContext(dstData, dstData, OGLContext.validateContext(dstData, dstData,
sg2d.getCompClip(), comp, sg2d.getCompClip(), comp,
null, sg2d.paint, sg2d, ctxflags); null, sg2d.paint, sg2d, ctxflags);
......
/* /*
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -38,6 +38,8 @@ import static sun.java2d.pipe.BufferedOpCodes.*; ...@@ -38,6 +38,8 @@ import static sun.java2d.pipe.BufferedOpCodes.*;
import static sun.java2d.pipe.BufferedRenderPipe.BYTES_PER_SPAN; import static sun.java2d.pipe.BufferedRenderPipe.BYTES_PER_SPAN;
import java.lang.annotation.Native; import java.lang.annotation.Native;
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
/** /**
* Base context class for managing state in a single-threaded rendering * Base context class for managing state in a single-threaded rendering
...@@ -87,11 +89,11 @@ public abstract class BufferedContext { ...@@ -87,11 +89,11 @@ public abstract class BufferedContext {
*/ */
protected static BufferedContext currentContext; protected static BufferedContext currentContext;
private AccelSurface validatedSrcData; private Reference<AccelSurface> validSrcDataRef = new WeakReference<>(null);
private AccelSurface validatedDstData; private Reference<AccelSurface> validDstDataRef = new WeakReference<>(null);
private Region validatedClip; private Reference<Region> validClipRef = new WeakReference<>(null);
private Composite validatedComp; private Reference<Composite> validCompRef = new WeakReference<>(null);
private Paint validatedPaint; private Reference<Paint> validPaintRef = new WeakReference<>(null);
// renamed from isValidatedPaintAColor as part of a work around for 6764257 // renamed from isValidatedPaintAColor as part of a work around for 6764257
private boolean isValidatedPaintJustAColor; private boolean isValidatedPaintJustAColor;
private int validatedRGB; private int validatedRGB;
...@@ -127,9 +129,9 @@ public abstract class BufferedContext { ...@@ -127,9 +129,9 @@ public abstract class BufferedContext {
int flags) int flags)
{ {
// assert rq.lock.isHeldByCurrentThread(); // assert rq.lock.isHeldByCurrentThread();
BufferedContext d3dc = dstData.getContext(); BufferedContext context = dstData.getContext();
d3dc.validate(srcData, dstData, context.validate(srcData, dstData,
clip, comp, xform, paint, sg2d, flags); clip, comp, xform, paint, sg2d, flags);
} }
/** /**
...@@ -200,13 +202,15 @@ public abstract class BufferedContext { ...@@ -200,13 +202,15 @@ public abstract class BufferedContext {
updatePaint = true; updatePaint = true;
isValidatedPaintJustAColor = true; isValidatedPaintJustAColor = true;
} }
} else if (validatedPaint != paint) { } else if (validPaintRef.get() != paint) {
updatePaint = true; updatePaint = true;
// this should be set when we are switching from paint to color // this should be set when we are switching from paint to color
// in which case this condition will be true // in which case this condition will be true
isValidatedPaintJustAColor = false; isValidatedPaintJustAColor = false;
} }
final AccelSurface validatedSrcData = validSrcDataRef.get();
final AccelSurface validatedDstData = validDstDataRef.get();
if ((currentContext != this) || if ((currentContext != this) ||
(srcData != validatedSrcData) || (srcData != validatedSrcData) ||
(dstData != validatedDstData)) (dstData != validatedDstData))
...@@ -228,11 +232,12 @@ public abstract class BufferedContext { ...@@ -228,11 +232,12 @@ public abstract class BufferedContext {
setSurfaces(srcData, dstData); setSurfaces(srcData, dstData);
currentContext = this; currentContext = this;
validatedSrcData = srcData; validSrcDataRef = new WeakReference<>(srcData);
validatedDstData = dstData; validDstDataRef = new WeakReference<>(dstData);
} }
// validate clip // validate clip
final Region validatedClip = validClipRef.get();
if ((clip != validatedClip) || updateClip) { if ((clip != validatedClip) || updateClip) {
if (clip != null) { if (clip != null) {
if (updateClip || if (updateClip ||
...@@ -248,13 +253,13 @@ public abstract class BufferedContext { ...@@ -248,13 +253,13 @@ public abstract class BufferedContext {
} else { } else {
resetClip(); resetClip();
} }
validatedClip = clip; validClipRef = new WeakReference<>(clip);
} }
// validate composite (note that a change in the context flags // validate composite (note that a change in the context flags
// may require us to update the composite state, even if the // may require us to update the composite state, even if the
// composite has not changed) // composite has not changed)
if ((comp != validatedComp) || (flags != validatedFlags)) { if ((comp != validCompRef.get()) || (flags != validatedFlags)) {
if (comp != null) { if (comp != null) {
setComposite(comp, flags); setComposite(comp, flags);
} else { } else {
...@@ -263,7 +268,7 @@ public abstract class BufferedContext { ...@@ -263,7 +268,7 @@ public abstract class BufferedContext {
// the paint state is dependent on the composite state, so make // the paint state is dependent on the composite state, so make
// sure we update the color below // sure we update the color below
updatePaint = true; updatePaint = true;
validatedComp = comp; validCompRef = new WeakReference<>(comp);
validatedFlags = flags; validatedFlags = flags;
} }
...@@ -297,7 +302,7 @@ public abstract class BufferedContext { ...@@ -297,7 +302,7 @@ public abstract class BufferedContext {
} else { } else {
BufferedPaints.resetPaint(rq); BufferedPaints.resetPaint(rq);
} }
validatedPaint = paint; validPaintRef = new WeakReference<>(paint);
} }
// mark dstData dirty // mark dstData dirty
...@@ -315,9 +320,9 @@ public abstract class BufferedContext { ...@@ -315,9 +320,9 @@ public abstract class BufferedContext {
* @see RenderQueue#lock * @see RenderQueue#lock
* @see RenderQueue#unlock * @see RenderQueue#unlock
*/ */
public void invalidateSurfaces() { private void invalidateSurfaces() {
validatedSrcData = null; validSrcDataRef.clear();
validatedDstData = null; validDstDataRef.clear();
} }
private void setSurfaces(AccelSurface srcData, private void setSurfaces(AccelSurface srcData,
...@@ -434,9 +439,9 @@ public abstract class BufferedContext { ...@@ -434,9 +439,9 @@ public abstract class BufferedContext {
resetClip(); resetClip();
BufferedPaints.resetPaint(rq); BufferedPaints.resetPaint(rq);
invalidateSurfaces(); invalidateSurfaces();
validatedComp = null; validCompRef.clear();
validatedClip = null; validClipRef.clear();
validatedPaint = null; validPaintRef.clear();
isValidatedPaintJustAColor = false; isValidatedPaintJustAColor = false;
xformInUse = false; xformInUse = false;
} }
......
/* /*
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -118,16 +118,22 @@ public class AnnotationType { ...@@ -118,16 +118,22 @@ public class AnnotationType {
members = new HashMap<String, Method>(methods.length+1, 1.0f); members = new HashMap<String, Method>(methods.length+1, 1.0f);
for (Method method : methods) { for (Method method : methods) {
if (method.getParameterTypes().length != 0) if (Modifier.isPublic(method.getModifiers()) &&
throw new IllegalArgumentException(method + " has params"); Modifier.isAbstract(method.getModifiers()) &&
String name = method.getName(); !method.isSynthetic()) {
Class<?> type = method.getReturnType(); if (method.getParameterTypes().length != 0) {
memberTypes.put(name, invocationHandlerReturnType(type)); throw new IllegalArgumentException(method + " has params");
members.put(name, method); }
String name = method.getName();
Object defaultValue = method.getDefaultValue(); Class<?> type = method.getReturnType();
if (defaultValue != null) memberTypes.put(name, invocationHandlerReturnType(type));
memberDefaults.put(name, defaultValue); members.put(name, method);
Object defaultValue = method.getDefaultValue();
if (defaultValue != null) {
memberDefaults.put(name, defaultValue);
}
}
} }
// Initialize retention, & inherited fields. Special treatment // Initialize retention, & inherited fields. Special treatment
......
/* /*
* Copyright (c) 2003, 2009, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -255,6 +255,15 @@ final class ProviderConfig { ...@@ -255,6 +255,15 @@ final class ProviderConfig {
disableLoad(); disableLoad();
} }
return null; return null;
} catch (ExceptionInInitializerError err) {
// unexpected exception thrown from static initialization block in provider
// (ex: insufficient permission to initialize provider class)
if (debug != null) {
debug.println("Error loading provider " + ProviderConfig.this);
err.printStackTrace();
}
disableLoad();
return null;
} }
} }
}); });
......
...@@ -525,9 +525,9 @@ public class Config { ...@@ -525,9 +525,9 @@ public class Config {
String previous = null; String previous = null;
while ((line = br.readLine()) != null) { while ((line = br.readLine()) != null) {
line = line.trim(); line = line.trim();
if (line.startsWith("#") || line.isEmpty()) { if (line.isEmpty() || line.startsWith("#") || line.startsWith(";")) {
// ignore comments and blank line // ignore comments and blank line
// Comments start with #. // Comments start with '#' or ';'
continue; continue;
} }
// In practice, a subsection might look like: // In practice, a subsection might look like:
......
...@@ -62,7 +62,8 @@ abstract class KrbKdcRep { ...@@ -62,7 +62,8 @@ abstract class KrbKdcRep {
throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED); throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED);
} }
for (int i = 1; i < 6; i++) { // We allow KDC to return a non-forwardable ticket if request has -f
for (int i = 2; i < 6; i++) {
if (req.reqBody.kdcOptions.get(i) != if (req.reqBody.kdcOptions.get(i) !=
rep.encKDCRepPart.flags.get(i)) { rep.encKDCRepPart.flags.get(i)) {
if (Krb5.DEBUG) { if (Krb5.DEBUG) {
......
...@@ -150,19 +150,11 @@ public class KrbTgsReq { ...@@ -150,19 +150,11 @@ public class KrbTgsReq {
ctime = KerberosTime.now(); ctime = KerberosTime.now();
// check if they are valid arguments. The optional fields // check if they are valid arguments. The optional fields
// should be consistent with settings in KDCOptions. // should be consistent with settings in KDCOptions.
// TODO: Is this necessary? If the TGT is not FORWARDABLE,
// you can still request for a FORWARDABLE ticket, just the
// KDC will give you a non-FORWARDABLE one. Even if you
// cannot use the ticket expected, it still contains info.
// This means there will be problem later. We already have
// flags check in KrbTgsRep. Of course, sometimes the KDC
// will not issue the ticket at all.
if (options.get(KDCOptions.FORWARDABLE) && if (options.get(KDCOptions.FORWARDABLE) &&
(!(asCreds.flags.get(Krb5.TKT_OPTS_FORWARDABLE)))) { (!(asCreds.flags.get(Krb5.TKT_OPTS_FORWARDABLE)))) {
throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS); options.set(KDCOptions.FORWARDABLE, false);
} }
if (options.get(KDCOptions.FORWARDED)) { if (options.get(KDCOptions.FORWARDED)) {
if (!(asCreds.flags.get(KDCOptions.FORWARDABLE))) if (!(asCreds.flags.get(KDCOptions.FORWARDABLE)))
......
...@@ -58,6 +58,9 @@ public class CredentialsUtil { ...@@ -58,6 +58,9 @@ public class CredentialsUtil {
// TODO: we do not support kerberos referral now // TODO: we do not support kerberos referral now
throw new KrbException("Cross realm impersonation not supported"); throw new KrbException("Cross realm impersonation not supported");
} }
if (!ccreds.isForwardable()) {
throw new KrbException("S4U2self needs a FORWARDABLE ticket");
}
KrbTgsReq req = new KrbTgsReq( KrbTgsReq req = new KrbTgsReq(
ccreds, ccreds,
ccreds.getClient(), ccreds.getClient(),
...@@ -68,6 +71,9 @@ public class CredentialsUtil { ...@@ -68,6 +71,9 @@ public class CredentialsUtil {
if (!creds.getClient().equals(client)) { if (!creds.getClient().equals(client)) {
throw new KrbException("S4U2self request not honored by KDC"); throw new KrbException("S4U2self request not honored by KDC");
} }
if (!creds.isForwardable()) {
throw new KrbException("S4U2self ticket must be FORWARDABLE");
}
return creds; return creds;
} }
......
...@@ -228,29 +228,34 @@ final class P11KeyPairGenerator extends KeyPairGeneratorSpi { ...@@ -228,29 +228,34 @@ final class P11KeyPairGenerator extends KeyPairGeneratorSpi {
// check native range first // check native range first
if ((minKeySize != -1) && (keySize < minKeySize)) { if ((minKeySize != -1) && (keySize < minKeySize)) {
throw new InvalidAlgorithmParameterException(algorithm + throw new InvalidAlgorithmParameterException(algorithm +
" key must be at least " + minKeySize + " bits"); " key must be at least " + minKeySize + " bits. " +
"The specific key size " + keySize + " is not supported");
} }
if ((maxKeySize != -1) && (keySize > maxKeySize)) { if ((maxKeySize != -1) && (keySize > maxKeySize)) {
throw new InvalidAlgorithmParameterException(algorithm + throw new InvalidAlgorithmParameterException(algorithm +
" key must be at most " + maxKeySize + " bits"); " key must be at most " + maxKeySize + " bits. " +
"The specific key size " + keySize + " is not supported");
} }
// check our own algorithm-specific limits also // check our own algorithm-specific limits also
if (algorithm.equals("EC")) { if (algorithm.equals("EC")) {
if (keySize < 112) { if (keySize < 112) {
throw new InvalidAlgorithmParameterException throw new InvalidAlgorithmParameterException(
("Key size must be at least 112 bit"); "EC key size must be at least 112 bit. " +
"The specific key size " + keySize + " is not supported");
} }
if (keySize > 2048) { if (keySize > 2048) {
// sanity check, nobody really wants keys this large // sanity check, nobody really wants keys this large
throw new InvalidAlgorithmParameterException throw new InvalidAlgorithmParameterException(
("Key size must be at most 2048 bit"); "EC key size must be at most 2048 bit. " +
"The specific key size " + keySize + " is not supported");
} }
} else { } else {
// RSA, DH, DSA // RSA, DH, DSA
if (keySize < 512) { if (keySize < 512) {
throw new InvalidAlgorithmParameterException throw new InvalidAlgorithmParameterException(algorithm +
("Key size must be at least 512 bit"); " key size must be at least 512 bit. " +
"The specific key size " + keySize + " is not supported");
} }
if (algorithm.equals("RSA")) { if (algorithm.equals("RSA")) {
BigInteger tmpExponent = rsaPublicExponent; BigInteger tmpExponent = rsaPublicExponent;
...@@ -271,8 +276,10 @@ final class P11KeyPairGenerator extends KeyPairGeneratorSpi { ...@@ -271,8 +276,10 @@ final class P11KeyPairGenerator extends KeyPairGeneratorSpi {
if (algorithm.equals("DH") && (params != null)) { if (algorithm.equals("DH") && (params != null)) {
// sanity check, nobody really wants keys this large // sanity check, nobody really wants keys this large
if (keySize > 64 * 1024) { if (keySize > 64 * 1024) {
throw new InvalidAlgorithmParameterException throw new InvalidAlgorithmParameterException(
("Key size must be at most 65536 bit"); "DH key size must be at most 65536 bit. " +
"The specific key size " +
keySize + " is not supported");
} }
} else { } else {
// this restriction is in the spec for DSA // this restriction is in the spec for DSA
...@@ -282,7 +289,9 @@ final class P11KeyPairGenerator extends KeyPairGeneratorSpi { ...@@ -282,7 +289,9 @@ final class P11KeyPairGenerator extends KeyPairGeneratorSpi {
((keySize > 1024) || ((keySize & 0x3f) != 0))) { ((keySize > 1024) || ((keySize & 0x3f) != 0))) {
throw new InvalidAlgorithmParameterException(algorithm + throw new InvalidAlgorithmParameterException(algorithm +
" key must be multiples of 64 if less than 1024 bits" + " key must be multiples of 64 if less than 1024 bits" +
", or 2048 bits"); ", or 2048 bits. " +
"The specific key size " +
keySize + " is not supported");
} }
} }
} }
......
/* /*
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -752,6 +752,21 @@ final class P11KeyStore extends KeyStoreSpi { ...@@ -752,6 +752,21 @@ final class P11KeyStore extends KeyStoreSpi {
} else { } else {
login(new PasswordCallbackHandler(password)); login(new PasswordCallbackHandler(password));
} }
} catch(LoginException e) {
Throwable cause = e.getCause();
if (cause instanceof PKCS11Exception) {
PKCS11Exception pe = (PKCS11Exception) cause;
if (pe.getErrorCode() == CKR_PIN_INCORRECT) {
// if password is wrong, the cause of the IOException
// should be an UnrecoverableKeyException
throw new IOException("load failed",
new UnrecoverableKeyException().initCause(e));
}
}
throw new IOException("load failed", e);
}
try {
if (mapLabels() == true) { if (mapLabels() == true) {
// CKA_LABELs are shared by multiple certs // CKA_LABELs are shared by multiple certs
writeDisabled = true; writeDisabled = true;
...@@ -759,7 +774,7 @@ final class P11KeyStore extends KeyStoreSpi { ...@@ -759,7 +774,7 @@ final class P11KeyStore extends KeyStoreSpi {
if (debug != null) { if (debug != null) {
dumpTokenMap(); dumpTokenMap();
} }
} catch (LoginException | KeyStoreException | PKCS11Exception e) { } catch (KeyStoreException | PKCS11Exception e) {
throw new IOException("load failed", e); throw new IOException("load failed", e);
} }
} }
......
...@@ -2051,7 +2051,7 @@ public final class PKCS12KeyStore extends KeyStoreSpi { ...@@ -2051,7 +2051,7 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
} }
if (!MessageDigest.isEqual(macData.getDigest(), macResult)) { if (!MessageDigest.isEqual(macData.getDigest(), macResult)) {
throw new SecurityException("Failed PKCS12" + throw new UnrecoverableKeyException("Failed PKCS12" +
" integrity checking"); " integrity checking");
} }
} catch (Exception e) { } catch (Exception e) {
......
...@@ -1044,40 +1044,6 @@ final class CipherBox { ...@@ -1044,40 +1044,6 @@ final class CipherBox {
return nonce; return nonce;
} }
/*
* Is this cipher available?
*
* This method can only be called by CipherSuite.BulkCipher.isAvailable()
* to test the availability of a cipher suites. Please DON'T use it in
* other places, otherwise, the behavior may be unexpected because we may
* initialize AEAD cipher improperly in the method.
*/
Boolean isAvailable() {
// We won't know whether a cipher for a particular key size is
// available until the cipher is successfully initialized.
//
// We do not initialize AEAD cipher in the constructor. Need to
// initialize the cipher to ensure that the AEAD mode for a
// particular key size is supported.
if (cipherType == AEAD_CIPHER) {
try {
Authenticator authenticator =
new Authenticator(protocolVersion);
byte[] nonce = authenticator.sequenceNumber();
byte[] iv = Arrays.copyOf(fixedIv,
fixedIv.length + nonce.length);
System.arraycopy(nonce, 0, iv, fixedIv.length, nonce.length);
GCMParameterSpec spec = new GCMParameterSpec(tagSize * 8, iv);
cipher.init(mode, key, spec, random);
} catch (Exception e) {
return Boolean.FALSE;
}
} // Otherwise, we have initialized the cipher in the constructor.
return Boolean.TRUE;
}
/** /**
* Sanity check the length of a fragment before decryption. * Sanity check the length of a fragment before decryption.
* *
......
...@@ -75,12 +75,6 @@ final class CipherSuite implements Comparable<CipherSuite> { ...@@ -75,12 +75,6 @@ final class CipherSuite implements Comparable<CipherSuite> {
// minimum priority for default enabled CipherSuites // minimum priority for default enabled CipherSuites
final static int DEFAULT_SUITES_PRIORITY = 300; final static int DEFAULT_SUITES_PRIORITY = 300;
// Flag indicating if CipherSuite availability can change dynamically.
// This is the case when we rely on a JCE cipher implementation that
// may not be available in the installed JCE providers.
// It is true because we might not have an ECC implementation.
final static boolean DYNAMIC_AVAILABILITY = true;
private final static boolean ALLOW_ECC = Debug.getBooleanProperty private final static boolean ALLOW_ECC = Debug.getBooleanProperty
("com.sun.net.ssl.enableECC", true); ("com.sun.net.ssl.enableECC", true);
...@@ -186,9 +180,6 @@ final class CipherSuite implements Comparable<CipherSuite> { ...@@ -186,9 +180,6 @@ final class CipherSuite implements Comparable<CipherSuite> {
* Return whether this CipherSuite is available for use. A * Return whether this CipherSuite is available for use. A
* CipherSuite may be unavailable even if it is supported * CipherSuite may be unavailable even if it is supported
* (i.e. allowed == true) if the required JCE cipher is not installed. * (i.e. allowed == true) if the required JCE cipher is not installed.
* In some configuration, this situation may change over time, call
* CipherSuiteList.clearAvailableCache() before this method to obtain
* the most current status.
*/ */
boolean isAvailable() { boolean isAvailable() {
return allowed && keyExchange.isAvailable() && cipher.isAvailable(); return allowed && keyExchange.isAvailable() && cipher.isAvailable();
...@@ -404,10 +395,6 @@ final class CipherSuite implements Comparable<CipherSuite> { ...@@ -404,10 +395,6 @@ final class CipherSuite implements Comparable<CipherSuite> {
*/ */
final static class BulkCipher { final static class BulkCipher {
// Map BulkCipher -> Boolean(available)
private final static Map<BulkCipher,Boolean> availableCache =
new HashMap<>(8);
// descriptive name including key size, e.g. AES/128 // descriptive name including key size, e.g. AES/128
final String description; final String description;
...@@ -451,6 +438,9 @@ final class CipherSuite implements Comparable<CipherSuite> { ...@@ -451,6 +438,9 @@ final class CipherSuite implements Comparable<CipherSuite> {
// The secure random used to detect the cipher availability. // The secure random used to detect the cipher availability.
private final static SecureRandom secureRandom; private final static SecureRandom secureRandom;
// runtime availability
private final boolean isAvailable;
static { static {
try { try {
secureRandom = JsseJce.getSecureRandom(); secureRandom = JsseJce.getSecureRandom();
...@@ -475,6 +465,17 @@ final class CipherSuite implements Comparable<CipherSuite> { ...@@ -475,6 +465,17 @@ final class CipherSuite implements Comparable<CipherSuite> {
this.expandedKeySize = expandedKeySize; this.expandedKeySize = expandedKeySize;
this.exportable = true; this.exportable = true;
// availability of this bulk cipher
//
// Currently all supported ciphers except AES are always available
// via the JSSE internal implementations. We also assume AES/128 of
// CBC mode is always available since it is shipped with the SunJCE
// provider. However, AES/256 is unavailable when the default JCE
// policy jurisdiction files are installed because of key length
// restrictions.
this.isAvailable =
allowed ? isUnlimited(keySize, transformation) : false;
} }
BulkCipher(String transformation, CipherType cipherType, int keySize, BulkCipher(String transformation, CipherType cipherType, int keySize,
...@@ -491,6 +492,17 @@ final class CipherSuite implements Comparable<CipherSuite> { ...@@ -491,6 +492,17 @@ final class CipherSuite implements Comparable<CipherSuite> {
this.expandedKeySize = keySize; this.expandedKeySize = keySize;
this.exportable = false; this.exportable = false;
// availability of this bulk cipher
//
// Currently all supported ciphers except AES are always available
// via the JSSE internal implementations. We also assume AES/128 of
// CBC mode is always available since it is shipped with the SunJCE
// provider. However, AES/256 is unavailable when the default JCE
// policy jurisdiction files are installed because of key length
// restrictions.
this.isAvailable =
allowed ? isUnlimited(keySize, transformation) : false;
} }
/** /**
...@@ -508,84 +520,27 @@ final class CipherSuite implements Comparable<CipherSuite> { ...@@ -508,84 +520,27 @@ final class CipherSuite implements Comparable<CipherSuite> {
/** /**
* Test if this bulk cipher is available. For use by CipherSuite. * Test if this bulk cipher is available. For use by CipherSuite.
*
* Currently all supported ciphers except AES are always available
* via the JSSE internal implementations. We also assume AES/128 of
* CBC mode is always available since it is shipped with the SunJCE
* provider. However, AES/256 is unavailable when the default JCE
* policy jurisdiction files are installed because of key length
* restrictions, and AEAD is unavailable when the underlying providers
* do not support AEAD/GCM mode.
*/ */
boolean isAvailable() { boolean isAvailable() {
if (allowed == false) { return this.isAvailable;
return false;
}
if ((this == B_AES_256) ||
(this.cipherType == CipherType.AEAD_CIPHER)) {
return isAvailable(this);
}
// always available
return true;
} }
// for use by CipherSuiteList.clearAvailableCache(); private static boolean isUnlimited(int keySize, String transformation) {
static synchronized void clearAvailableCache() { int keySizeInBits = keySize * 8;
if (DYNAMIC_AVAILABILITY) { if (keySizeInBits > 128) { // need the JCE unlimited
availableCache.clear(); // strength jurisdiction policy
} try {
} if (Cipher.getMaxAllowedKeyLength(
transformation) < keySizeInBits) {
private static synchronized boolean isAvailable(BulkCipher cipher) { return false;
Boolean b = availableCache.get(cipher);
if (b == null) {
int keySizeInBits = cipher.keySize * 8;
if (keySizeInBits > 128) { // need the JCE unlimited
// strength jurisdiction policy
try {
if (Cipher.getMaxAllowedKeyLength(
cipher.transformation) < keySizeInBits) {
b = Boolean.FALSE;
}
} catch (Exception e) {
b = Boolean.FALSE;
} }
} catch (Exception e) {
return false;
} }
if (b == null) {
b = Boolean.FALSE; // may be reset to TRUE if
// the cipher is available
CipherBox temporary = null;
try {
SecretKey key = new SecretKeySpec(
new byte[cipher.expandedKeySize],
cipher.algorithm);
IvParameterSpec iv;
if (cipher.cipherType == CipherType.AEAD_CIPHER) {
iv = new IvParameterSpec(
new byte[cipher.fixedIvSize]);
} else {
iv = new IvParameterSpec(new byte[cipher.ivSize]);
}
temporary = cipher.newCipher(
ProtocolVersion.DEFAULT,
key, iv, secureRandom, true);
b = temporary.isAvailable();
} catch (NoSuchAlgorithmException e) {
// not available
} finally {
if (temporary != null) {
temporary.dispose();
}
}
}
availableCache.put(cipher, b);
} }
return b.booleanValue(); return true;
} }
@Override @Override
......
/* /*
* Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -74,24 +74,12 @@ final class CipherSuiteList { ...@@ -74,24 +74,12 @@ final class CipherSuiteList {
throw new IllegalArgumentException("CipherSuites may not be null"); throw new IllegalArgumentException("CipherSuites may not be null");
} }
cipherSuites = new ArrayList<CipherSuite>(names.length); cipherSuites = new ArrayList<CipherSuite>(names.length);
// refresh available cache once if a CipherSuite is not available
// (maybe new JCE providers have been installed)
boolean refreshed = false;
for (int i = 0; i < names.length; i++) { for (int i = 0; i < names.length; i++) {
String suiteName = names[i]; String suiteName = names[i];
CipherSuite suite = CipherSuite.valueOf(suiteName); CipherSuite suite = CipherSuite.valueOf(suiteName);
if (suite.isAvailable() == false) { if (suite.isAvailable() == false) {
if (refreshed == false) { throw new IllegalArgumentException("Cannot support "
// clear the cache so that the isAvailable() call below + suiteName + " with currently installed providers");
// does a full check
clearAvailableCache();
refreshed = true;
}
// still missing?
if (suite.isAvailable() == false) {
throw new IllegalArgumentException("Cannot support "
+ suiteName + " with currently installed providers");
}
} }
cipherSuites.add(suite); cipherSuites.add(suite);
} }
...@@ -195,16 +183,4 @@ final class CipherSuiteList { ...@@ -195,16 +183,4 @@ final class CipherSuiteList {
} }
s.putBytes16(suiteBytes); s.putBytes16(suiteBytes);
} }
/**
* Clear cache of available ciphersuites. If we support all ciphers
* internally, there is no need to clear the cache and calling this
* method has no effect.
*/
static synchronized void clearAvailableCache() {
if (CipherSuite.DYNAMIC_AVAILABILITY) {
CipherSuite.BulkCipher.clearAvailableCache();
JsseJce.clearEcAvailable();
}
}
} }
...@@ -55,11 +55,6 @@ final class JsseJce { ...@@ -55,11 +55,6 @@ final class JsseJce {
private final static ProviderList fipsProviderList; private final static ProviderList fipsProviderList;
// Flag indicating whether EC crypto is available.
// If null, then we have not checked yet.
// If yes, then all the EC based crypto we need is available.
private static Boolean ecAvailable;
// Flag indicating whether Kerberos crypto is available. // Flag indicating whether Kerberos crypto is available.
// If true, then all the Kerberos-based crypto we need is available. // If true, then all the Kerberos-based crypto we need is available.
private final static boolean kerberosAvailable; private final static boolean kerberosAvailable;
...@@ -195,24 +190,8 @@ final class JsseJce { ...@@ -195,24 +190,8 @@ final class JsseJce {
// no instantiation of this class // no instantiation of this class
} }
synchronized static boolean isEcAvailable() { static boolean isEcAvailable() {
if (ecAvailable == null) { return EcAvailability.isAvailable;
try {
JsseJce.getSignature(SIGNATURE_ECDSA);
JsseJce.getSignature(SIGNATURE_RAWECDSA);
JsseJce.getKeyAgreement("ECDH");
JsseJce.getKeyFactory("EC");
JsseJce.getKeyPairGenerator("EC");
ecAvailable = true;
} catch (Exception e) {
ecAvailable = false;
}
}
return ecAvailable;
}
synchronized static void clearEcAvailable() {
ecAvailable = null;
} }
static boolean isKerberosAvailable() { static boolean isKerberosAvailable() {
...@@ -414,4 +393,27 @@ final class JsseJce { ...@@ -414,4 +393,27 @@ final class JsseJce {
} }
} }
// lazy initialization holder class idiom for static default parameters
//
// See Effective Java Second Edition: Item 71.
private static class EcAvailability {
// Is EC crypto available?
private final static boolean isAvailable;
static {
boolean mediator = true;
try {
JsseJce.getSignature(SIGNATURE_ECDSA);
JsseJce.getSignature(SIGNATURE_RAWECDSA);
JsseJce.getKeyAgreement("ECDH");
JsseJce.getKeyFactory("EC");
JsseJce.getKeyPairGenerator("EC");
} catch (Exception e) {
mediator = false;
}
isAvailable = mediator;
}
}
} }
...@@ -89,6 +89,30 @@ final class RSAClientKeyExchange extends HandshakeMessage { ...@@ -89,6 +89,30 @@ final class RSAClientKeyExchange extends HandshakeMessage {
} }
} }
/*
* Retrieving the cipher's provider name for the debug purposes
* can throw an exception by itself.
*/
private static String safeProviderName(Cipher cipher) {
try {
return cipher.getProvider().toString();
} catch (Exception e) {
if (debug != null && Debug.isOn("handshake")) {
System.out.println("Retrieving The Cipher provider name" +
" caused exception " + e.getMessage());
}
}
try {
return cipher.toString() + " (provider name not available)";
} catch (Exception e) {
if (debug != null && Debug.isOn("handshake")) {
System.out.println("Retrieving The Cipher name" +
" caused exception " + e.getMessage());
}
}
return "(cipher/provider names not available)";
}
/* /*
* Server gets the PKCS #1 (block format 02) data, decrypts * Server gets the PKCS #1 (block format 02) data, decrypts
* it with its private key. * it with its private key.
...@@ -130,15 +154,19 @@ final class RSAClientKeyExchange extends HandshakeMessage { ...@@ -130,15 +154,19 @@ final class RSAClientKeyExchange extends HandshakeMessage {
cipher.getProvider().getName()); cipher.getProvider().getName());
} catch (InvalidKeyException | UnsupportedOperationException iue) { } catch (InvalidKeyException | UnsupportedOperationException iue) {
if (debug != null && Debug.isOn("handshake")) { if (debug != null && Debug.isOn("handshake")) {
System.out.println("The Cipher provider " + System.out.println("The Cipher provider "
cipher.getProvider().getName() + + safeProviderName(cipher)
" caused exception: " + iue.getMessage()); + " caused exception: " + iue.getMessage());
} }
needFailover = true; needFailover = true;
} }
if (needFailover) { if (needFailover) {
// The cipher might be spoiled by unsuccessful call to init(),
// so request a fresh instance
cipher = JsseJce.getCipher(JsseJce.CIPHER_RSA_PKCS1);
// Use DECRYPT_MODE and dispose the previous initialization. // Use DECRYPT_MODE and dispose the previous initialization.
cipher.init(Cipher.DECRYPT_MODE, privateKey); cipher.init(Cipher.DECRYPT_MODE, privateKey);
boolean failed = false; boolean failed = false;
......
...@@ -137,8 +137,10 @@ final class ServerHandshaker extends Handshaker { ...@@ -137,8 +137,10 @@ final class ServerHandshaker extends Handshaker {
customizedDHKeySize = Integer.parseUnsignedInt(property); customizedDHKeySize = Integer.parseUnsignedInt(property);
if (customizedDHKeySize < 1024 || customizedDHKeySize > 2048) { if (customizedDHKeySize < 1024 || customizedDHKeySize > 2048) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"Customized DH key size should be positive integer " + "Unsupported customized DH key size: " +
"between 1024 and 2048 bits, inclusive"); customizedDHKeySize + ". " +
"The key size can only range from 1024" +
" to 2048 (inclusive)");
} }
} catch (NumberFormatException nfe) { } catch (NumberFormatException nfe) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
......
...@@ -71,11 +71,8 @@ import java.text.MessageFormat; ...@@ -71,11 +71,8 @@ import java.text.MessageFormat;
import java.nio.charset.CharsetEncoder; import java.nio.charset.CharsetEncoder;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.nio.charset.IllegalCharsetNameException; import java.nio.charset.IllegalCharsetNameException;
import java.nio.file.Files;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.nio.charset.UnsupportedCharsetException; import java.nio.charset.UnsupportedCharsetException;
import sun.tools.native2ascii.A2NFilter;
import sun.tools.native2ascii.N2AFilter;
/** /**
* Main program of the native2ascii * Main program of the native2ascii
...@@ -94,7 +91,7 @@ public class Main { ...@@ -94,7 +91,7 @@ public class Main {
/** /**
* Run the converter * Run the converter
*/ */
public synchronized boolean convert(String argv[]){ public synchronized boolean convert(String argv[]) {
List<String> v = new ArrayList<>(2); List<String> v = new ArrayList<>(2);
File outputFile = null; File outputFile = null;
boolean createOutputFile = false; boolean createOutputFile = false;
...@@ -102,14 +99,14 @@ public class Main { ...@@ -102,14 +99,14 @@ public class Main {
// Parse arguments // Parse arguments
for (int i = 0; i < argv.length; i++) { for (int i = 0; i < argv.length; i++) {
if (argv[i].equals("-encoding")) { if (argv[i].equals("-encoding")) {
if ((i + 1) < argv.length){ if ((i + 1) < argv.length) {
encodingString = argv[++i]; encodingString = argv[++i];
} else { } else {
error(getMsg("err.bad.arg")); error(getMsg("err.bad.arg"));
usage(); usage();
return false; return false;
} }
} else if (argv[i].equals("-reverse")){ } else if (argv[i].equals("-reverse")) {
reverse = true; reverse = true;
} else { } else {
if (v.size() > 1) { if (v.size() > 1) {
...@@ -119,15 +116,18 @@ public class Main { ...@@ -119,15 +116,18 @@ public class Main {
v.add(argv[i]); v.add(argv[i]);
} }
} }
if (encodingString == null)
defaultEncoding = Charset.defaultCharset().name();
if (encodingString == null) {
defaultEncoding = Charset.defaultCharset().name();
}
char[] lineBreak = System.getProperty("line.separator").toCharArray(); char[] lineBreak = System.getProperty("line.separator").toCharArray();
try { try {
initializeConverter(); initializeConverter();
if (v.size() == 1) if (v.size() == 1) {
inputFileName = v.get(0); inputFileName = v.get(0);
}
if (v.size() == 2) { if (v.size() == 2) {
inputFileName = v.get(0); inputFileName = v.get(0);
...@@ -137,40 +137,38 @@ public class Main { ...@@ -137,40 +137,38 @@ public class Main {
if (createOutputFile) { if (createOutputFile) {
outputFile = new File(outputFileName); outputFile = new File(outputFileName);
if (outputFile.exists() && !outputFile.canWrite()) { if (outputFile.exists() && !outputFile.canWrite()) {
throw new Exception(formatMsg("err.cannot.write", outputFileName)); throw new Exception(formatMsg("err.cannot.write", outputFileName));
} }
} }
if (reverse){ if (reverse) {
BufferedReader reader = getA2NInput(inputFileName); try (BufferedReader reader = getA2NInput(inputFileName);
Writer osw = getA2NOutput(outputFileName); Writer osw = getA2NOutput(outputFileName);) {
String line; String line;
while ((line = reader.readLine()) != null) {
while ((line = reader.readLine()) != null) { osw.write(line.toCharArray());
osw.write(line.toCharArray()); osw.write(lineBreak);
osw.write(lineBreak); if (outputFileName == null) { // flush stdout
if (outputFileName == null) { // flush stdout osw.flush();
osw.flush(); }
} }
} }
reader.close(); // Close the stream.
osw.close();
} else { } else {
//N2A // N2A
String inLine; try (BufferedReader in = getN2AInput(inputFileName);
BufferedReader in = getN2AInput(inputFileName); BufferedWriter out = getN2AOutput(outputFileName);) {
BufferedWriter out = getN2AOutput(outputFileName); String inLine;
while ((inLine = in.readLine()) != null) {
while ((inLine = in.readLine()) != null) { out.write(inLine.toCharArray());
out.write(inLine.toCharArray()); out.write(lineBreak);
out.write(lineBreak); if (outputFileName == null) { // flush stdout
if (outputFileName == null) { // flush stdout out.flush();
out.flush(); }
} }
} }
out.close();
} }
// Since we are done rename temporary file to desired output file // Since we are done rename temporary file to desired output file
if (createOutputFile) { if (createOutputFile) {
if (outputFile.exists()) { if (outputFile.exists()) {
...@@ -182,8 +180,7 @@ public class Main { ...@@ -182,8 +180,7 @@ public class Main {
} }
tempFile.renameTo(outputFile); tempFile.renameTo(outputFile);
} }
} catch (Exception e) {
} catch(Exception e){
error(e.toString()); error(e.toString());
return false; return false;
} }
......
...@@ -18,6 +18,7 @@ attributes = compatibility ...@@ -18,6 +18,7 @@ attributes = compatibility
disabledMechanisms = { disabledMechanisms = {
CKM_DSA_KEY_PAIR_GEN CKM_DSA_KEY_PAIR_GEN
SecureRandom
# the following mechanisms are disabled due to performance issues # the following mechanisms are disabled due to performance issues
# (Solaris bug 6337157) # (Solaris bug 6337157)
CKM_DSA_SHA1 CKM_DSA_SHA1
......
...@@ -331,6 +331,7 @@ const char * isJar(const char * path) { ...@@ -331,6 +331,7 @@ const char * isJar(const char * path) {
off_t end = start + xlen; off_t end = start + xlen;
if (end <= count) { if (end <= count) {
end -= 4; // make sure there are 4 bytes to read at start
while (start < end) { while (start < end) {
off_t xhid = SH(buf, start); off_t xhid = SH(buf, start);
off_t xdlen = SH(buf, start + 2); off_t xdlen = SH(buf, start + 2);
......
...@@ -28,6 +28,7 @@ package sun.java2d.xr; ...@@ -28,6 +28,7 @@ package sun.java2d.xr;
import java.awt.*; import java.awt.*;
import java.awt.geom.*; import java.awt.geom.*;
import sun.awt.SunToolkit; import sun.awt.SunToolkit;
import sun.java2d.InvalidPipeException;
import sun.java2d.SunGraphics2D; import sun.java2d.SunGraphics2D;
import sun.java2d.loops.*; import sun.java2d.loops.*;
import sun.java2d.pipe.Region; import sun.java2d.pipe.Region;
...@@ -69,7 +70,12 @@ public class XRRenderer implements PixelDrawPipe, PixelFillPipe, ShapeDrawPipe { ...@@ -69,7 +70,12 @@ public class XRRenderer implements PixelDrawPipe, PixelFillPipe, ShapeDrawPipe {
* destination context. * destination context.
*/ */
private final void validateSurface(SunGraphics2D sg2d) { private final void validateSurface(SunGraphics2D sg2d) {
XRSurfaceData xrsd = (XRSurfaceData) sg2d.surfaceData; XRSurfaceData xrsd;
try {
xrsd = (XRSurfaceData) sg2d.surfaceData;
} catch (ClassCastException e) {
throw new InvalidPipeException("wrong surface data type: " + sg2d.surfaceData);
}
xrsd.validateAsDestination(sg2d, sg2d.getCompClip()); xrsd.validateAsDestination(sg2d, sg2d.getCompClip());
xrsd.maskBuffer.validateCompositeState(sg2d.composite, sg2d.transform, xrsd.maskBuffer.validateCompositeState(sg2d.composite, sg2d.transform,
sg2d.paint, sg2d); sg2d.paint, sg2d);
......
/* /*
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -28,6 +28,8 @@ package sun.security.provider; ...@@ -28,6 +28,8 @@ package sun.security.provider;
import java.io.*; import java.io.*;
import java.net.*; import java.net.*;
import java.security.*; import java.security.*;
import java.util.Arrays;
import sun.security.util.Debug; import sun.security.util.Debug;
/** /**
...@@ -334,7 +336,9 @@ public final class NativePRNG extends SecureRandomSpi { ...@@ -334,7 +336,9 @@ public final class NativePRNG extends SecureRandomSpi {
private final static long MAX_BUFFER_TIME = 100; private final static long MAX_BUFFER_TIME = 100;
// size of the "next" buffer // size of the "next" buffer
private final static int BUFFER_SIZE = 32; private static final int MAX_BUFFER_SIZE = 65536;
private static final int MIN_BUFFER_SIZE = 32;
private int bufferSize = 256;
// Holder for the seedFile. Used if we ever add seed material. // Holder for the seedFile. Used if we ever add seed material.
File seedFile; File seedFile;
...@@ -351,7 +355,7 @@ public final class NativePRNG extends SecureRandomSpi { ...@@ -351,7 +355,7 @@ public final class NativePRNG extends SecureRandomSpi {
private volatile sun.security.provider.SecureRandom mixRandom; private volatile sun.security.provider.SecureRandom mixRandom;
// buffer for next bits // buffer for next bits
private final byte[] nextBuffer; private byte[] nextBuffer;
// number of bytes left in nextBuffer // number of bytes left in nextBuffer
private int buffered; private int buffered;
...@@ -359,6 +363,16 @@ public final class NativePRNG extends SecureRandomSpi { ...@@ -359,6 +363,16 @@ public final class NativePRNG extends SecureRandomSpi {
// time we read the data into the nextBuffer // time we read the data into the nextBuffer
private long lastRead; private long lastRead;
// Count for the number of buffer size changes requests
// Positive value in increase size, negative to lower it.
private int change_buffer = 0;
// Request limit to trigger an increase in nextBuffer size
private static final int REQ_LIMIT_INC = 1000;
// Request limit to trigger a decrease in nextBuffer size
private static final int REQ_LIMIT_DEC = -100;
// mutex lock for nextBytes() // mutex lock for nextBytes()
private final Object LOCK_GET_BYTES = new Object(); private final Object LOCK_GET_BYTES = new Object();
...@@ -373,7 +387,7 @@ public final class NativePRNG extends SecureRandomSpi { ...@@ -373,7 +387,7 @@ public final class NativePRNG extends SecureRandomSpi {
this.seedFile = seedFile; this.seedFile = seedFile;
seedIn = new FileInputStream(seedFile); seedIn = new FileInputStream(seedFile);
nextIn = new FileInputStream(nextFile); nextIn = new FileInputStream(nextFile);
nextBuffer = new byte[BUFFER_SIZE]; nextBuffer = new byte[bufferSize];
} }
// get the SHA1PRNG for mixing // get the SHA1PRNG for mixing
...@@ -466,9 +480,47 @@ public final class NativePRNG extends SecureRandomSpi { ...@@ -466,9 +480,47 @@ public final class NativePRNG extends SecureRandomSpi {
// if not, read new bytes // if not, read new bytes
private void ensureBufferValid() throws IOException { private void ensureBufferValid() throws IOException {
long time = System.currentTimeMillis(); long time = System.currentTimeMillis();
if ((buffered > 0) && (time - lastRead < MAX_BUFFER_TIME)) { int new_buffer_size = 0;
return;
// Check if buffer has bytes available that are not too old
if (buffered > 0) {
if (time - lastRead < MAX_BUFFER_TIME) {
return;
} else {
// byte is old, so subtract from counter to shrink buffer
change_buffer--;
}
} else {
// No bytes available, so add to count to increase buffer
change_buffer++;
} }
// If counter has it a limit, increase or decrease size
if (change_buffer > REQ_LIMIT_INC) {
new_buffer_size = nextBuffer.length * 2;
} else if (change_buffer < REQ_LIMIT_DEC) {
new_buffer_size = nextBuffer.length / 2;
}
// If buffer size is to be changed, replace nextBuffer.
if (new_buffer_size > 0) {
if (new_buffer_size <= MAX_BUFFER_SIZE &&
new_buffer_size >= MIN_BUFFER_SIZE) {
nextBuffer = new byte[new_buffer_size];
if (debug != null) {
debug.println("Buffer size changed to " +
new_buffer_size);
}
} else {
if (debug != null) {
debug.println("Buffer reached limit: " +
nextBuffer.length);
}
}
change_buffer = 0;
}
// Load fresh random bytes into nextBuffer
lastRead = time; lastRead = time;
readFully(nextIn, nextBuffer); readFully(nextIn, nextBuffer);
buffered = nextBuffer.length; buffered = nextBuffer.length;
...@@ -478,24 +530,40 @@ public final class NativePRNG extends SecureRandomSpi { ...@@ -478,24 +530,40 @@ public final class NativePRNG extends SecureRandomSpi {
// read from "next" and XOR with bytes generated by the // read from "next" and XOR with bytes generated by the
// mixing SHA1PRNG // mixing SHA1PRNG
private void implNextBytes(byte[] data) { private void implNextBytes(byte[] data) {
synchronized (LOCK_GET_BYTES) {
try { try {
getMixRandom().engineNextBytes(data); getMixRandom().engineNextBytes(data);
int len = data.length; int data_len = data.length;
int ofs = 0; int ofs = 0;
while (len > 0) { int len;
ensureBufferValid(); int buf_pos;
int bufferOfs = nextBuffer.length - buffered; int localofs;
while ((len > 0) && (buffered > 0)) { byte[] localBuffer;
data[ofs++] ^= nextBuffer[bufferOfs++];
len--; while (data_len > 0) {
buffered--; synchronized (LOCK_GET_BYTES) {
ensureBufferValid();
buf_pos = nextBuffer.length - buffered;
if (data_len > buffered) {
len = buffered;
buffered = 0;
} else {
len = data_len;
buffered -= len;
}
localBuffer = Arrays.copyOfRange(nextBuffer, buf_pos,
buf_pos + len);
} }
localofs = 0;
while (len > localofs) {
data[ofs] ^= localBuffer[localofs];
ofs++;
localofs++;
}
data_len -= len;
} }
} catch (IOException e) { } catch (IOException e){
throw new ProviderException("nextBytes() failed", e); throw new ProviderException("nextBytes() failed", e);
} }
}
} }
} }
} }
...@@ -992,17 +992,24 @@ Java_java_net_PlainDatagramSocketImpl_datagramSocketCreate(JNIEnv *env, ...@@ -992,17 +992,24 @@ Java_java_net_PlainDatagramSocketImpl_datagramSocketCreate(JNIEnv *env,
(char *)&arg, sizeof(arg)) < 0) { (char *)&arg, sizeof(arg)) < 0) {
getErrorString(errno, tmpbuf, sizeof(tmpbuf)); getErrorString(errno, tmpbuf, sizeof(tmpbuf));
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", tmpbuf); JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", tmpbuf);
close(fd);
return; return;
} }
if (JVM_SetSockOpt(fd, SOL_SOCKET, SO_RCVBUF, if (JVM_SetSockOpt(fd, SOL_SOCKET, SO_RCVBUF,
(char *)&arg, sizeof(arg)) < 0) { (char *)&arg, sizeof(arg)) < 0) {
getErrorString(errno, tmpbuf, sizeof(tmpbuf)); getErrorString(errno, tmpbuf, sizeof(tmpbuf));
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", tmpbuf); JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", tmpbuf);
close(fd);
return; return;
} }
#endif /* __APPLE__ */ #endif /* __APPLE__ */
setsockopt(fd, SOL_SOCKET, SO_BROADCAST, (char*) &t, sizeof(int)); if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, (char*) &t, sizeof (int)) < 0) {
getErrorString(errno, tmpbuf, sizeof(tmpbuf));
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", tmpbuf);
close(fd);
return;
}
#if defined(__linux__) #if defined(__linux__)
arg = 0; arg = 0;
...@@ -1024,8 +1031,13 @@ Java_java_net_PlainDatagramSocketImpl_datagramSocketCreate(JNIEnv *env, ...@@ -1024,8 +1031,13 @@ Java_java_net_PlainDatagramSocketImpl_datagramSocketCreate(JNIEnv *env,
*/ */
if (domain == AF_INET6) { if (domain == AF_INET6) {
int ttl = 1; int ttl = 1;
setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (char *)&ttl, if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (char *) &ttl,
sizeof(ttl)); sizeof (ttl)) < 0) {
getErrorString(errno, tmpbuf, sizeof(tmpbuf));
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", tmpbuf);
close(fd);
return;
}
} }
#endif /* __linux__ */ #endif /* __linux__ */
...@@ -2182,7 +2194,7 @@ static void mcast_join_leave(JNIEnv *env, jobject this, ...@@ -2182,7 +2194,7 @@ static void mcast_join_leave(JNIEnv *env, jobject this,
caddr[14] = ((address >> 8) & 0xff); caddr[14] = ((address >> 8) & 0xff);
caddr[15] = (address & 0xff); caddr[15] = (address & 0xff);
} else { } else {
getInet6Address_ipaddress(env, iaObj, caddr); getInet6Address_ipaddress(env, iaObj, (char *) caddr);
} }
memcpy((void *)&(mname6.ipv6mr_multiaddr), caddr, sizeof(struct in6_addr)); memcpy((void *)&(mname6.ipv6mr_multiaddr), caddr, sizeof(struct in6_addr));
......
/* /*
* Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -94,6 +94,7 @@ idevpoll(jint wfd, int dpctl, struct dvpoll a) ...@@ -94,6 +94,7 @@ idevpoll(jint wfd, int dpctl, struct dvpoll a)
return 0; return 0;
} }
start = now; start = now;
a.dp_timeout = remaining;
} }
} else { } else {
return res; return res;
......
/* /*
* Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -53,7 +53,7 @@ iepoll(int epfd, struct epoll_event *events, int numfds, jlong timeout) ...@@ -53,7 +53,7 @@ iepoll(int epfd, struct epoll_event *events, int numfds, jlong timeout)
start = t.tv_sec * 1000 + t.tv_usec / 1000; start = t.tv_sec * 1000 + t.tv_usec / 1000;
for (;;) { for (;;) {
int res = epoll_wait(epfd, events, numfds, timeout); int res = epoll_wait(epfd, events, numfds, remaining);
if (res < 0 && errno == EINTR) { if (res < 0 && errno == EINTR) {
if (remaining >= 0) { if (remaining >= 0) {
gettimeofday(&t, NULL); gettimeofday(&t, NULL);
......
...@@ -155,6 +155,7 @@ static char* next_arg(char* cmdline, char* arg, jboolean* wildcard) { ...@@ -155,6 +155,7 @@ static char* next_arg(char* cmdline, char* arg, jboolean* wildcard) {
} }
} }
dest += copyCh(ch, dest); dest += copyCh(ch, dest);
slashes = 0;
break; break;
default: default:
......
...@@ -40,6 +40,7 @@ allfonts.devanagari=Mangal ...@@ -40,6 +40,7 @@ allfonts.devanagari=Mangal
allfonts.dingbats=Wingdings allfonts.dingbats=Wingdings
allfonts.lucida=Lucida Sans Regular allfonts.lucida=Lucida Sans Regular
allfonts.symbol=Symbol allfonts.symbol=Symbol
allfonts.symbols=Segoe UI Symbol
allfonts.thai=Lucida Sans Regular allfonts.thai=Lucida Sans Regular
allfonts.georgian=Sylfaen allfonts.georgian=Sylfaen
...@@ -236,7 +237,7 @@ sequence.dialoginput.x-windows-949=alphabetic,korean,dingbats,symbol ...@@ -236,7 +237,7 @@ sequence.dialoginput.x-windows-949=alphabetic,korean,dingbats,symbol
sequence.allfonts.x-windows-874=alphabetic,thai,dingbats,symbol sequence.allfonts.x-windows-874=alphabetic,thai,dingbats,symbol
sequence.fallback=lucida,\ sequence.fallback=lucida,symbols,\
chinese-ms950,chinese-hkscs,chinese-ms936,chinese-gb18030,\ chinese-ms950,chinese-hkscs,chinese-ms936,chinese-gb18030,\
japanese,korean,chinese-ms950-extb,chinese-ms936-extb,georgian japanese,korean,chinese-ms950-extb,chinese-ms936-extb,georgian
...@@ -298,3 +299,4 @@ filename.Symbol=SYMBOL.TTF ...@@ -298,3 +299,4 @@ filename.Symbol=SYMBOL.TTF
filename.Wingdings=WINGDING.TTF filename.Wingdings=WINGDING.TTF
filename.Sylfaen=sylfaen.ttf filename.Sylfaen=sylfaen.ttf
filename.Segoe_UI_Symbol=SEGUISYM.TTF
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
package sun.java2d.d3d; package sun.java2d.d3d;
import java.awt.Composite; import java.awt.Composite;
import sun.java2d.InvalidPipeException;
import sun.java2d.SunGraphics2D; import sun.java2d.SunGraphics2D;
import sun.java2d.loops.GraphicsPrimitive; import sun.java2d.loops.GraphicsPrimitive;
import sun.java2d.loops.GraphicsPrimitiveMgr; import sun.java2d.loops.GraphicsPrimitiveMgr;
...@@ -67,7 +68,13 @@ class D3DMaskFill extends BufferedMaskFill { ...@@ -67,7 +68,13 @@ class D3DMaskFill extends BufferedMaskFill {
protected void validateContext(SunGraphics2D sg2d, protected void validateContext(SunGraphics2D sg2d,
Composite comp, int ctxflags) Composite comp, int ctxflags)
{ {
D3DSurfaceData dstData = (D3DSurfaceData)sg2d.surfaceData; D3DSurfaceData dstData;
try {
dstData = (D3DSurfaceData) sg2d.surfaceData;
} catch (ClassCastException e) {
throw new InvalidPipeException("wrong surface data type: " +
sg2d.surfaceData);
}
D3DContext.validateContext(dstData, dstData, D3DContext.validateContext(dstData, dstData,
sg2d.getCompClip(), comp, sg2d.getCompClip(), comp,
null, sg2d.paint, sg2d, ctxflags); null, sg2d.paint, sg2d, ctxflags);
......
/* /*
* Copyright (c) 2003, 2014 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
......
...@@ -292,7 +292,6 @@ Java_java_net_Inet4AddressImpl_getHostByAddr(JNIEnv *env, jobject this, ...@@ -292,7 +292,6 @@ Java_java_net_Inet4AddressImpl_getHostByAddr(JNIEnv *env, jobject this,
} }
static BOOL static BOOL
WindowsVersionCheck(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor) { WindowsVersionCheck(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor) {
OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0, {0}, 0, 0 }; OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0, {0}, 0, 0 };
...@@ -316,7 +315,7 @@ isVistaSP1OrGreater() { ...@@ -316,7 +315,7 @@ isVistaSP1OrGreater() {
} }
static jboolean static jboolean
wxp_ping4(JNIEnv *env, tcp_ping4(JNIEnv *env,
jbyteArray addrArray, jbyteArray addrArray,
jint timeout, jint timeout,
jbyteArray ifArray, jbyteArray ifArray,
...@@ -471,23 +470,17 @@ static jboolean ...@@ -471,23 +470,17 @@ static jboolean
ping4(JNIEnv *env, ping4(JNIEnv *env,
unsigned long src_addr, unsigned long src_addr,
unsigned long dest_addr, unsigned long dest_addr,
jint timeout) jint timeout,
HANDLE hIcmpFile)
{ {
// See https://msdn.microsoft.com/en-us/library/aa366050%28VS.85%29.aspx // See https://msdn.microsoft.com/en-us/library/aa366050%28VS.85%29.aspx
HANDLE hIcmpFile;
DWORD dwRetVal = 0; DWORD dwRetVal = 0;
char SendData[32] = {0}; char SendData[32] = {0};
LPVOID ReplyBuffer = NULL; LPVOID ReplyBuffer = NULL;
DWORD ReplySize = 0; DWORD ReplySize = 0;
jboolean ret = JNI_FALSE; jboolean ret = JNI_FALSE;
hIcmpFile = IcmpCreateFile();
if (hIcmpFile == INVALID_HANDLE_VALUE) {
NET_ThrowNew(env, WSAGetLastError(), "Unable to open handle");
return JNI_FALSE;
}
ReplySize = sizeof(ICMP_ECHO_REPLY) + sizeof(SendData); ReplySize = sizeof(ICMP_ECHO_REPLY) + sizeof(SendData);
ReplyBuffer = (VOID*) malloc(ReplySize); ReplyBuffer = (VOID*) malloc(ReplySize);
if (ReplyBuffer == NULL) { if (ReplyBuffer == NULL) {
...@@ -553,6 +546,7 @@ Java_java_net_Inet4AddressImpl_isReachable0(JNIEnv *env, jobject this, ...@@ -553,6 +546,7 @@ Java_java_net_Inet4AddressImpl_isReachable0(JNIEnv *env, jobject this,
jint dest_addr = 0; jint dest_addr = 0;
jbyte caddr[4]; jbyte caddr[4];
int sz; int sz;
HANDLE hIcmpFile;
/** /**
* Convert IP address from byte array to integer * Convert IP address from byte array to integer
...@@ -583,8 +577,20 @@ Java_java_net_Inet4AddressImpl_isReachable0(JNIEnv *env, jobject this, ...@@ -583,8 +577,20 @@ Java_java_net_Inet4AddressImpl_isReachable0(JNIEnv *env, jobject this,
src_addr = htonl(src_addr); src_addr = htonl(src_addr);
} }
return ping4(env, src_addr, dest_addr, timeout); hIcmpFile = IcmpCreateFile();
if (hIcmpFile == INVALID_HANDLE_VALUE) {
int err = WSAGetLastError();
if (err == ERROR_ACCESS_DENIED) {
// fall back to TCP echo if access is denied to ICMP
return tcp_ping4(env, addrArray, timeout, ifArray, ttl);
} else {
NET_ThrowNew(env, err, "Unable to create ICMP file handle");
return JNI_FALSE;
}
} else {
return ping4(env, src_addr, dest_addr, timeout, hIcmpFile);
}
} else { } else {
wxp_ping4(env, addrArray, timeout, ifArray, ttl); tcp_ping4(env, addrArray, timeout, ifArray, ttl);
} }
} }
...@@ -360,6 +360,109 @@ Java_java_net_Inet6AddressImpl_getHostByAddr(JNIEnv *env, jobject this, ...@@ -360,6 +360,109 @@ Java_java_net_Inet6AddressImpl_getHostByAddr(JNIEnv *env, jobject this,
#ifdef AF_INET6 #ifdef AF_INET6
/**
* ping implementation using tcp port 7 (echo)
*/
static jboolean
tcp_ping6(JNIEnv *env,
jint timeout,
jint ttl,
struct sockaddr_in6 him6,
struct sockaddr_in6* netif,
int len)
{
jint fd;
WSAEVENT hEvent;
int connect_rv = -1;
fd = NET_Socket(AF_INET6, SOCK_STREAM, 0);
if (fd == SOCKET_ERROR) {
/* note: if you run out of fds, you may not be able to load
* the exception class, and get a NoClassDefFoundError
* instead.
*/
NET_ThrowNew(env, errno, "Can't create socket");
return JNI_FALSE;
}
/**
* A TTL was specified, let's set the socket option.
*/
if (ttl > 0) {
setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, (const char *)&ttl, sizeof(ttl));
}
/**
* A network interface was specified, let's bind to it.
*/
if (netif != NULL) {
if (NET_Bind(fd, (struct sockaddr*)netif, sizeof(struct sockaddr_in6)) < 0) {
NET_ThrowNew(env, WSAGetLastError(), "Can't bind socket to interface");
closesocket(fd);
return JNI_FALSE;
}
}
/**
* Make the socket non blocking.
*/
hEvent = WSACreateEvent();
WSAEventSelect(fd, hEvent, FD_READ|FD_CONNECT|FD_CLOSE);
/* no need to use NET_Connect as non-blocking */
him6.sin6_port = htons((short) 7); /* Echo port */
connect_rv = connect(fd, (struct sockaddr *)&him6, len);
/**
* connection established or refused immediately, either way it means
* we were able to reach the host!
*/
if (connect_rv == 0 || WSAGetLastError() == WSAECONNREFUSED) {
WSACloseEvent(hEvent);
closesocket(fd);
return JNI_TRUE;
} else {
int optlen;
switch (WSAGetLastError()) {
case WSAEHOSTUNREACH: /* Host Unreachable */
case WSAENETUNREACH: /* Network Unreachable */
case WSAENETDOWN: /* Network is down */
case WSAEPFNOSUPPORT: /* Protocol Family unsupported */
WSACloseEvent(hEvent);
closesocket(fd);
return JNI_FALSE;
}
if (WSAGetLastError() != WSAEWOULDBLOCK) {
NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "ConnectException",
"connect failed");
WSACloseEvent(hEvent);
closesocket(fd);
return JNI_FALSE;
}
timeout = NET_Wait(env, fd, NET_WAIT_CONNECT, timeout);
if (timeout >= 0) {
/* has connection been established? */
optlen = sizeof(connect_rv);
if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (void*)&connect_rv,
&optlen) <0) {
connect_rv = WSAGetLastError();
}
if (connect_rv == 0 || connect_rv == WSAECONNREFUSED) {
WSACloseEvent(hEvent);
closesocket(fd);
return JNI_TRUE;
}
}
}
WSACloseEvent(hEvent);
closesocket(fd);
return JNI_FALSE;
}
/** /**
* ping implementation. * ping implementation.
...@@ -371,9 +474,9 @@ static jboolean ...@@ -371,9 +474,9 @@ static jboolean
ping6(JNIEnv *env, ping6(JNIEnv *env,
struct sockaddr_in6* src, struct sockaddr_in6* src,
struct sockaddr_in6* dest, struct sockaddr_in6* dest,
jint timeout) jint timeout,
HANDLE hIcmpFile)
{ {
HANDLE hIcmpFile;
DWORD dwRetVal = 0; DWORD dwRetVal = 0;
char SendData[32] = {0}; char SendData[32] = {0};
LPVOID ReplyBuffer = NULL; LPVOID ReplyBuffer = NULL;
...@@ -381,12 +484,6 @@ ping6(JNIEnv *env, ...@@ -381,12 +484,6 @@ ping6(JNIEnv *env,
IP_OPTION_INFORMATION ipInfo = {255, 0, 0, 0, NULL}; IP_OPTION_INFORMATION ipInfo = {255, 0, 0, 0, NULL};
struct sockaddr_in6 sa6Source; struct sockaddr_in6 sa6Source;
hIcmpFile = Icmp6CreateFile();
if (hIcmpFile == INVALID_HANDLE_VALUE) {
NET_ThrowNew(env, WSAGetLastError(), "Unable to open handle");
return JNI_FALSE;
}
ReplySize = sizeof(ICMPV6_ECHO_REPLY) + sizeof(SendData); ReplySize = sizeof(ICMPV6_ECHO_REPLY) + sizeof(SendData);
ReplyBuffer = (VOID*) malloc(ReplySize); ReplyBuffer = (VOID*) malloc(ReplySize);
if (ReplyBuffer == NULL) { if (ReplyBuffer == NULL) {
...@@ -445,7 +542,7 @@ Java_java_net_Inet6AddressImpl_isReachable0(JNIEnv *env, jobject this, ...@@ -445,7 +542,7 @@ Java_java_net_Inet6AddressImpl_isReachable0(JNIEnv *env, jobject this,
struct sockaddr_in6* netif = NULL; struct sockaddr_in6* netif = NULL;
struct sockaddr_in6 inf6; struct sockaddr_in6 inf6;
int len = 0; int len = 0;
int connect_rv = -1; HANDLE hIcmpFile;
/* /*
* If IPv6 is not enable, then we can't reach an IPv6 address, can we? * If IPv6 is not enable, then we can't reach an IPv6 address, can we?
...@@ -489,7 +586,21 @@ Java_java_net_Inet6AddressImpl_isReachable0(JNIEnv *env, jobject this, ...@@ -489,7 +586,21 @@ Java_java_net_Inet6AddressImpl_isReachable0(JNIEnv *env, jobject this,
inf6.sin6_scope_id = if_scope; inf6.sin6_scope_id = if_scope;
netif = &inf6; netif = &inf6;
} }
return ping6(env, netif, &him6, timeout);
hIcmpFile = Icmp6CreateFile();
if (hIcmpFile == INVALID_HANDLE_VALUE) {
int err = WSAGetLastError();
if (err == ERROR_ACCESS_DENIED) {
// fall back to TCP echo if access is denied to ICMP
return tcp_ping6(env, timeout, ttl, him6, netif, len);
} else {
NET_ThrowNew(env, err, "Unable to create ICMP file handle");
return JNI_FALSE;
}
} else {
return ping6(env, netif, &him6, timeout, hIcmpFile);
}
#endif /* AF_INET6 */ #endif /* AF_INET6 */
return JNI_FALSE; return JNI_FALSE;
} }
/* /*
* Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -1125,7 +1125,7 @@ WinAccessBridge::getAccessibleContextWithFocus(HWND window, long *vmID, JOBJECT6 ...@@ -1125,7 +1125,7 @@ WinAccessBridge::getAccessibleContextWithFocus(HWND window, long *vmID, JOBJECT6
PrintDebugString("WinAccessBridge::getAccessibleContextWithFocus(%p, %X, )", window, vmID); PrintDebugString("WinAccessBridge::getAccessibleContextWithFocus(%p, %X, )", window, vmID);
// find vmID, etc. from HWND; ask that VM for the AC w/Focus // find vmID, etc. from HWND; ask that VM for the AC w/Focus
HWND pkgVMID = (HWND)ABLongToHandle( pkg->rVMID ) ; HWND pkgVMID;
if (getAccessibleContextFromHWND(window, (long *)&(pkgVMID), &(pkg->rAccessibleContext)) == TRUE) { if (getAccessibleContextFromHWND(window, (long *)&(pkgVMID), &(pkg->rAccessibleContext)) == TRUE) {
HWND destABWindow = javaVMs->findAccessBridgeWindow((long)pkgVMID); // ineffecient [[[FIXME]]] HWND destABWindow = javaVMs->findAccessBridgeWindow((long)pkgVMID); // ineffecient [[[FIXME]]]
if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
......
...@@ -93,6 +93,12 @@ AwtTrayIcon::~AwtTrayIcon() { ...@@ -93,6 +93,12 @@ AwtTrayIcon::~AwtTrayIcon() {
void AwtTrayIcon::Dispose() { void AwtTrayIcon::Dispose() {
SendTrayMessage(NIM_DELETE); SendTrayMessage(NIM_DELETE);
// Destroy the icon to avoid leak of GDI objects
if (m_nid.hIcon != NULL) {
::DestroyIcon(m_nid.hIcon);
}
UnlinkObjects(); UnlinkObjects();
if (--sm_instCount == 0) { if (--sm_instCount == 0) {
......
...@@ -875,6 +875,9 @@ Java_sun_awt_Win32GraphicsDevice_initIDs(JNIEnv *env, jclass cls) ...@@ -875,6 +875,9 @@ Java_sun_awt_Win32GraphicsDevice_initIDs(JNIEnv *env, jclass cls)
// Only want to call this once per session // Only want to call this once per session
make_uns_ordered_dither_array(img_oda_alpha, 256); make_uns_ordered_dither_array(img_oda_alpha, 256);
// workaround JDK-6477756, ignore return value to keep dll in memory
JDK_LoadSystemLibrary("opengl32.dll");
CATCH_BAD_ALLOC; CATCH_BAD_ALLOC;
} }
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册