Merge jdk7u25-b04 into jdk7u25-b05
diff --git a/.hgtags-top-repo b/.hgtags-top-repo
index 1ebe538..2a89c9a 100644
--- a/.hgtags-top-repo
+++ b/.hgtags-top-repo
@@ -251,6 +251,7 @@
8e49ff2feda30801d7826ca1778eb7b901a7089c jdk7u17-b02
933d424580f967ed11eda2bbfd690f985a72df6e jdk7u17-b30
790582955edb617b41abbc73cf82544dbf8c1d97 jdk7u17-b31
+941539a9f6441f053e8e7f31064944b2fc08879f jdk7u17-b32
527d3cf769ec073d7348e4c31f97c47c943c96b6 jdk7u21-b01
bc264b362dc7b4f2bda34e1a5b87a4f0c2bd4d82 jdk7u21-b02
20603c659295a40c7f16259cb08c91475092efed jdk7u21-b03
@@ -259,4 +260,10 @@
14522481739dc6981beb5cc55d543dcc62cda067 jdk7u21-b06
0df382e8c17bf817d55fc8759c7f5c9e9d0337f0 jdk7u21-b07
1aff32a21aba64c3767e9a72ebf1b8ba490e99ec jdk7u21-b08
+a2e0099b4cf70be026a7a0ba7918fcd71d57fdce jdk7u21-b09
+602ad1a5b09fb9136e8bf1b708e0524fbdb35324 jdk7u21-b10
+fa322ca378324750ea049f2e92357e51eca27ae4 jdk7u21-b11
+450e8dde919df278fe75ae95e0eb0a6464f5bc41 jdk7u21-b30
+170520883597f90771aca8251a8d089e7566e4bf jdk7u21-b12
50bfbd21bf42f6ae4167226ac45cd79e0ab7758c jdk7u25-b03
+a94c9aa356bbed13c1e2b4a9a380117ddff1668f jdk7u25-b04
diff --git a/corba/.hgtags b/corba/.hgtags
index fe9c91e..0f22d82 100644
--- a/corba/.hgtags
+++ b/corba/.hgtags
@@ -251,6 +251,7 @@
e82d31e1f1189ae6f02d6855f0cd78074599b2e1 jdk7u17-b02
d4366e557c4c5af62a94fc9885aed87c99abc848 jdk7u17-b30
a6f066dd2cd526da73070d1e46c9b1e1ab1a6756 jdk7u17-b31
+6401c6b99d2d43ed4f0e2d38dce496069f6e91f8 jdk7u17-b32
f5ef46204dba19679edd7492b221110fd1a0bd33 jdk7u21-b01
17ecd70a2247ed86a095aae9f1a201fa7feea861 jdk7u21-b02
bf0877613aeba816d5f18ea6316d535819f628e9 jdk7u21-b03
@@ -259,6 +260,12 @@
94f2ebfccc5e057169284bb2c858296b235868ea jdk7u21-b06
23a57aceeb69e688f8ce8b8361fad3a49cf4ac5f jdk7u21-b07
ebedf04bfffe289e8bf9661b38f73ca6c0dad17c jdk7u21-b08
+b8f92ad1f0cc86d8571a0e23192e667f0ef8e421 jdk7u21-b09
+b2adfd931a2504948d4fee780e4175122be10484 jdk7u21-b10
+61e2e2d9cfcea20132b50d8fb7ead66a8a373db7 jdk7u21-b11
+3c774492beaaff241c654add2c4e683b9ff002f2 jdk7u21-b30
+fa2a377ce52dfa88fca858d735d78b53f2b5b754 jdk7u21-b12
3d0f2d5b1866860f7089b51cca8ca0ca41c04d9c jdk7u25-b01
cdbafc5080eeb8ea3fec9fe7d071e0bf96635581 jdk7u25-b02
2057de7ee6b17ab3335ec6cd5730f88f4cfe9502 jdk7u25-b03
+b180f1282ad221bde0d4d865c879c0fa7f8ef4c8 jdk7u25-b04
diff --git a/corba/make/com/sun/corba/minclude/com_sun_corba_se_impl_orbutil.jmk b/corba/make/com/sun/corba/minclude/com_sun_corba_se_impl_orbutil.jmk
index 465c546..d007b4e 100644
--- a/corba/make/com/sun/corba/minclude/com_sun_corba_se_impl_orbutil.jmk
+++ b/corba/make/com/sun/corba/minclude/com_sun_corba_se_impl_orbutil.jmk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -39,7 +39,6 @@
com/sun/corba/se/impl/orbutil/ObjectStreamClassUtil_1_3.java \
com/sun/corba/se/impl/orbutil/ORBConstants.java \
com/sun/corba/se/impl/orbutil/ORBUtility.java \
- com/sun/corba/se/impl/orbutil/ORBClassLoader.java \
com/sun/corba/se/impl/orbutil/RepIdDelegator.java \
com/sun/corba/se/impl/orbutil/RepositoryIdFactory.java \
com/sun/corba/se/impl/orbutil/RepositoryIdStrings.java \
diff --git a/corba/src/share/classes/com/sun/corba/se/impl/activation/ServerManagerImpl.java b/corba/src/share/classes/com/sun/corba/se/impl/activation/ServerManagerImpl.java
index 4fde9aa..745f0aa 100644
--- a/corba/src/share/classes/com/sun/corba/se/impl/activation/ServerManagerImpl.java
+++ b/corba/src/share/classes/com/sun/corba/se/impl/activation/ServerManagerImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -81,7 +81,6 @@
import com.sun.corba.se.impl.oa.poa.BadServerIdHandler;
import com.sun.corba.se.impl.orbutil.ORBConstants;
-import com.sun.corba.se.impl.orbutil.ORBClassLoader;
import com.sun.corba.se.impl.orbutil.ORBUtility;
import com.sun.corba.se.impl.util.Utility;
diff --git a/corba/src/share/classes/com/sun/corba/se/impl/interceptors/PIHandlerImpl.java b/corba/src/share/classes/com/sun/corba/se/impl/interceptors/PIHandlerImpl.java
index e7d7ae2..9ad417e 100644
--- a/corba/src/share/classes/com/sun/corba/se/impl/interceptors/PIHandlerImpl.java
+++ b/corba/src/share/classes/com/sun/corba/se/impl/interceptors/PIHandlerImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -77,7 +77,6 @@
import com.sun.corba.se.impl.logging.ORBUtilSystemException;
import com.sun.corba.se.impl.logging.OMGSystemException;
import com.sun.corba.se.impl.corba.RequestImpl;
-import com.sun.corba.se.impl.orbutil.ORBClassLoader;
import com.sun.corba.se.impl.orbutil.ORBConstants;
import com.sun.corba.se.impl.orbutil.ORBUtility;
import com.sun.corba.se.impl.orbutil.StackImpl;
diff --git a/corba/src/share/classes/com/sun/corba/se/impl/interceptors/RequestInfoImpl.java b/corba/src/share/classes/com/sun/corba/se/impl/interceptors/RequestInfoImpl.java
index a20de7a..9ef904b 100644
--- a/corba/src/share/classes/com/sun/corba/se/impl/interceptors/RequestInfoImpl.java
+++ b/corba/src/share/classes/com/sun/corba/se/impl/interceptors/RequestInfoImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -86,13 +86,14 @@
import com.sun.corba.se.impl.encoding.EncapsOutputStream;
import com.sun.corba.se.impl.orbutil.ORBUtility;
-import com.sun.corba.se.impl.orbutil.ORBClassLoader;
import com.sun.corba.se.impl.util.RepositoryId;
import com.sun.corba.se.impl.logging.InterceptorsSystemException;
import com.sun.corba.se.impl.logging.OMGSystemException;
+import sun.corba.SharedSecrets;
+
/**
* Implementation of the RequestInfo interface as specified in
* orbos/99-12-02 section 5.4.1.
@@ -452,7 +453,8 @@
// Find the read method on the helper class:
String helperClassName = className + "Helper";
- Class helperClass = ORBClassLoader.loadClass( helperClassName );
+ Class<?> helperClass =
+ SharedSecrets.getJavaCorbaAccess().loadClass( helperClassName );
Class[] readParams = new Class[1];
readParams[0] = org.omg.CORBA.portable.InputStream.class;
Method readMethod = helperClass.getMethod( "read", readParams );
@@ -512,7 +514,8 @@
Class exceptionClass = userException.getClass();
String className = exceptionClass.getName();
String helperClassName = className + "Helper";
- Class helperClass = ORBClassLoader.loadClass( helperClassName );
+ Class<?> helperClass =
+ SharedSecrets.getJavaCorbaAccess().loadClass( helperClassName );
// Find insert( Any, class ) method
Class[] insertMethodParams = new Class[2];
diff --git a/corba/src/share/classes/com/sun/corba/se/impl/io/ValueUtility.java b/corba/src/share/classes/com/sun/corba/se/impl/io/ValueUtility.java
index 41d85a2..20cec8d 100644
--- a/corba/src/share/classes/com/sun/corba/se/impl/io/ValueUtility.java
+++ b/corba/src/share/classes/com/sun/corba/se/impl/io/ValueUtility.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -98,6 +98,14 @@
public ValueHandlerImpl newValueHandlerImpl() {
return ValueHandlerImpl.getInstance();
}
+ public Class<?> loadClass(String className) throws ClassNotFoundException {
+ if (Thread.currentThread().getContextClassLoader() != null) {
+ return Thread.currentThread().getContextClassLoader().
+ loadClass(className);
+ } else {
+ return ClassLoader.getSystemClassLoader().loadClass(className);
+ }
+ }
});
}
diff --git a/corba/src/share/classes/com/sun/corba/se/impl/javax/rmi/CORBA/Util.java b/corba/src/share/classes/com/sun/corba/se/impl/javax/rmi/CORBA/Util.java
index aa2c648..7829d52 100644
--- a/corba/src/share/classes/com/sun/corba/se/impl/javax/rmi/CORBA/Util.java
+++ b/corba/src/share/classes/com/sun/corba/se/impl/javax/rmi/CORBA/Util.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -109,12 +109,9 @@
import com.sun.corba.se.impl.util.Utility;
import com.sun.corba.se.impl.util.IdentityHashtable;
import com.sun.corba.se.impl.util.JDKBridge;
-import com.sun.corba.se.impl.orbutil.ORBClassLoader;
import com.sun.corba.se.impl.logging.UtilSystemException;
import com.sun.corba.se.spi.logging.CORBALogDomains;
import sun.corba.SharedSecrets;
-import sun.corba.JavaCorbaAccess;
-
/**
* Provides utility methods that can be used by stubs and ties to
@@ -263,7 +260,7 @@
return new MarshalException(message,inner);
} else if (ex instanceof ACTIVITY_REQUIRED) {
try {
- Class cl = ORBClassLoader.loadClass(
+ Class<?> cl = SharedSecrets.getJavaCorbaAccess().loadClass(
"javax.activity.ActivityRequiredException");
Class[] params = new Class[2];
params[0] = java.lang.String.class;
@@ -279,7 +276,7 @@
}
} else if (ex instanceof ACTIVITY_COMPLETED) {
try {
- Class cl = ORBClassLoader.loadClass(
+ Class<?> cl = SharedSecrets.getJavaCorbaAccess().loadClass(
"javax.activity.ActivityCompletedException");
Class[] params = new Class[2];
params[0] = java.lang.String.class;
@@ -295,7 +292,7 @@
}
} else if (ex instanceof INVALID_ACTIVITY) {
try {
- Class cl = ORBClassLoader.loadClass(
+ Class<?> cl = SharedSecrets.getJavaCorbaAccess().loadClass(
"javax.activity.InvalidActivityException");
Class[] params = new Class[2];
params[0] = java.lang.String.class;
diff --git a/corba/src/share/classes/com/sun/corba/se/impl/orb/ORBDataParserImpl.java b/corba/src/share/classes/com/sun/corba/se/impl/orb/ORBDataParserImpl.java
index 46b0627..94bb5d9 100644
--- a/corba/src/share/classes/com/sun/corba/se/impl/orb/ORBDataParserImpl.java
+++ b/corba/src/share/classes/com/sun/corba/se/impl/orb/ORBDataParserImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -48,7 +48,6 @@
import com.sun.corba.se.impl.encoding.CodeSetComponentInfo ;
import com.sun.corba.se.impl.legacy.connection.USLPort;
-import com.sun.corba.se.impl.orbutil.ORBClassLoader ;
import com.sun.corba.se.impl.orbutil.ORBConstants ;
import com.sun.corba.se.impl.logging.ORBUtilSystemException ;
diff --git a/corba/src/share/classes/com/sun/corba/se/impl/orb/ORBImpl.java b/corba/src/share/classes/com/sun/corba/se/impl/orb/ORBImpl.java
index 5db8573..ee0a535 100644
--- a/corba/src/share/classes/com/sun/corba/se/impl/orb/ORBImpl.java
+++ b/corba/src/share/classes/com/sun/corba/se/impl/orb/ORBImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -152,7 +152,6 @@
import com.sun.corba.se.impl.oa.poa.BadServerIdHandler;
import com.sun.corba.se.impl.oa.poa.DelegateImpl;
import com.sun.corba.se.impl.oa.poa.POAFactory;
-import com.sun.corba.se.impl.orbutil.ORBClassLoader;
import com.sun.corba.se.impl.orbutil.ORBConstants;
import com.sun.corba.se.impl.orbutil.ORBUtility;
import com.sun.corba.se.impl.orbutil.StackImpl;
diff --git a/corba/src/share/classes/com/sun/corba/se/impl/orb/ParserTable.java b/corba/src/share/classes/com/sun/corba/se/impl/orb/ParserTable.java
index 550c4a7..6229de4 100644
--- a/corba/src/share/classes/com/sun/corba/se/impl/orb/ParserTable.java
+++ b/corba/src/share/classes/com/sun/corba/se/impl/orb/ParserTable.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -78,7 +78,6 @@
import com.sun.corba.se.impl.legacy.connection.USLPort ;
import com.sun.corba.se.impl.logging.ORBUtilSystemException ;
import com.sun.corba.se.impl.oa.poa.BadServerIdHandler ;
-import com.sun.corba.se.impl.orbutil.ORBClassLoader ;
import com.sun.corba.se.impl.orbutil.ORBConstants ;
import com.sun.corba.se.impl.protocol.giopmsgheaders.KeyAddr ;
import com.sun.corba.se.impl.protocol.giopmsgheaders.ProfileAddr ;
@@ -86,6 +85,8 @@
import com.sun.corba.se.impl.transport.DefaultIORToSocketInfoImpl;
import com.sun.corba.se.impl.transport.DefaultSocketFactoryImpl;
+import sun.corba.SharedSecrets;
+
/** Initialize the parser data for the standard ORB parser. This is used both
* to implement ORBDataParserImpl and to provide the basic testing framework
* for ORBDataParserImpl.
@@ -640,8 +641,8 @@
String param = (String)value ;
try {
- Class legacySocketFactoryClass =
- ORBClassLoader.loadClass(param);
+ Class<?> legacySocketFactoryClass =
+ SharedSecrets.getJavaCorbaAccess().loadClass(param);
// For security reasons avoid creating an instance if
// this socket factory class is not one that would fail
// the class cast anyway.
@@ -670,7 +671,8 @@
String param = (String)value ;
try {
- Class socketFactoryClass = ORBClassLoader.loadClass(param);
+ Class<?> socketFactoryClass =
+ SharedSecrets.getJavaCorbaAccess().loadClass(param);
// For security reasons avoid creating an instance if
// this socket factory class is not one that would fail
// the class cast anyway.
@@ -699,7 +701,8 @@
String param = (String)value ;
try {
- Class iorToSocketInfoClass = ORBClassLoader.loadClass(param);
+ Class<?> iorToSocketInfoClass =
+ SharedSecrets.getJavaCorbaAccess().loadClass(param);
// For security reasons avoid creating an instance if
// this socket factory class is not one that would fail
// the class cast anyway.
@@ -728,7 +731,8 @@
String param = (String)value ;
try {
- Class iiopPrimaryToContactInfoClass = ORBClassLoader.loadClass(param);
+ Class<?> iiopPrimaryToContactInfoClass =
+ SharedSecrets.getJavaCorbaAccess().loadClass(param);
// For security reasons avoid creating an instance if
// this socket factory class is not one that would fail
// the class cast anyway.
@@ -757,8 +761,8 @@
String param = (String)value ;
try {
- Class contactInfoListFactoryClass =
- ORBClassLoader.loadClass(param);
+ Class<?> contactInfoListFactoryClass =
+ SharedSecrets.getJavaCorbaAccess().loadClass(param);
// For security reasons avoid creating an instance if
// this socket factory class is not one that would fail
// the class cast anyway.
diff --git a/corba/src/share/classes/com/sun/corba/se/impl/orbutil/ORBClassLoader.java b/corba/src/share/classes/com/sun/corba/se/impl/orbutil/ORBClassLoader.java
deleted file mode 100644
index 3e3ba8d..0000000
--- a/corba/src/share/classes/com/sun/corba/se/impl/orbutil/ORBClassLoader.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2001, 2002, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.sun.corba.se.impl.orbutil;
-
-/**
- * Based on feedback from bug report 4452016, all class loading
- * in the ORB is isolated here. It is acceptable to use
- * Class.forName only when one is certain that the desired class
- * should come from the core JDK.
- */
-public class ORBClassLoader
-{
- public static Class loadClass(String className)
- throws ClassNotFoundException
- {
- return ORBClassLoader.getClassLoader().loadClass(className);
- }
-
- public static ClassLoader getClassLoader() {
- if (Thread.currentThread().getContextClassLoader() != null)
- return Thread.currentThread().getContextClassLoader();
- else
- return ClassLoader.getSystemClassLoader();
- }
-}
diff --git a/corba/src/share/classes/com/sun/corba/se/impl/orbutil/ORBUtility.java b/corba/src/share/classes/com/sun/corba/se/impl/orbutil/ORBUtility.java
index 23d51f9..41dba4d 100644
--- a/corba/src/share/classes/com/sun/corba/se/impl/orbutil/ORBUtility.java
+++ b/corba/src/share/classes/com/sun/corba/se/impl/orbutil/ORBUtility.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -90,6 +90,8 @@
import com.sun.corba.se.impl.logging.OMGSystemException ;
import com.sun.corba.se.impl.ior.iiop.JavaSerializationComponent;
+import sun.corba.SharedSecrets;
+
/**
* Handy class full of static functions that don't belong in util.Utility for pure ORB reasons.
*/
@@ -262,8 +264,8 @@
{
try {
String name = classNameOf(strm.read_string());
- SystemException ex
- = (SystemException)ORBClassLoader.loadClass(name).newInstance();
+ SystemException ex = (SystemException)SharedSecrets.
+ getJavaCorbaAccess().loadClass(name).newInstance();
ex.minor = strm.read_long();
ex.completed = CompletionStatus.from_int(strm.read_long());
return ex;
diff --git a/corba/src/share/classes/com/sun/corba/se/impl/protocol/giopmsgheaders/LocateReplyMessage_1_2.java b/corba/src/share/classes/com/sun/corba/se/impl/protocol/giopmsgheaders/LocateReplyMessage_1_2.java
index a3af1ec..8274de6 100644
--- a/corba/src/share/classes/com/sun/corba/se/impl/protocol/giopmsgheaders/LocateReplyMessage_1_2.java
+++ b/corba/src/share/classes/com/sun/corba/se/impl/protocol/giopmsgheaders/LocateReplyMessage_1_2.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -41,7 +41,6 @@
import com.sun.corba.se.impl.orbutil.ORBUtility;
import com.sun.corba.se.impl.orbutil.ORBConstants;
-import com.sun.corba.se.impl.orbutil.ORBClassLoader;
import com.sun.corba.se.spi.logging.CORBALogDomains ;
import com.sun.corba.se.impl.logging.ORBUtilSystemException ;
diff --git a/corba/src/share/classes/com/sun/corba/se/impl/protocol/giopmsgheaders/MessageBase.java b/corba/src/share/classes/com/sun/corba/se/impl/protocol/giopmsgheaders/MessageBase.java
index b1eb366..6559be7 100644
--- a/corba/src/share/classes/com/sun/corba/se/impl/protocol/giopmsgheaders/MessageBase.java
+++ b/corba/src/share/classes/com/sun/corba/se/impl/protocol/giopmsgheaders/MessageBase.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -60,9 +60,10 @@
import com.sun.corba.se.impl.logging.ORBUtilSystemException ;
import com.sun.corba.se.impl.orbutil.ORBUtility;
import com.sun.corba.se.impl.orbutil.ORBConstants;
-import com.sun.corba.se.impl.orbutil.ORBClassLoader;
import com.sun.corba.se.impl.protocol.AddressingDispositionException;
+import sun.corba.SharedSecrets;
+
/**
* This class acts as the base class for the various GIOP message types. This
* also serves as a factory to create various message types. We currently
@@ -909,7 +910,8 @@
SystemException sysEx = null;
try {
- Class clazz = ORBClassLoader.loadClass(exClassName);
+ Class<?> clazz =
+ SharedSecrets.getJavaCorbaAccess().loadClass(exClassName);
if (message == null) {
sysEx = (SystemException) clazz.newInstance();
} else {
diff --git a/corba/src/share/classes/com/sun/corba/se/impl/protocol/giopmsgheaders/ReplyMessage_1_0.java b/corba/src/share/classes/com/sun/corba/se/impl/protocol/giopmsgheaders/ReplyMessage_1_0.java
index 8bcc4e8..4d77e3a 100644
--- a/corba/src/share/classes/com/sun/corba/se/impl/protocol/giopmsgheaders/ReplyMessage_1_0.java
+++ b/corba/src/share/classes/com/sun/corba/se/impl/protocol/giopmsgheaders/ReplyMessage_1_0.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -37,7 +37,6 @@
import com.sun.corba.se.spi.servicecontext.ServiceContexts;
import com.sun.corba.se.spi.ior.iiop.GIOPVersion;
import com.sun.corba.se.impl.orbutil.ORBUtility;
-import com.sun.corba.se.impl.orbutil.ORBClassLoader;
import com.sun.corba.se.spi.ior.IOR;
import com.sun.corba.se.impl.encoding.CDRInputStream;
diff --git a/corba/src/share/classes/com/sun/corba/se/impl/protocol/giopmsgheaders/ReplyMessage_1_1.java b/corba/src/share/classes/com/sun/corba/se/impl/protocol/giopmsgheaders/ReplyMessage_1_1.java
index e22e0fb..65d8578 100644
--- a/corba/src/share/classes/com/sun/corba/se/impl/protocol/giopmsgheaders/ReplyMessage_1_1.java
+++ b/corba/src/share/classes/com/sun/corba/se/impl/protocol/giopmsgheaders/ReplyMessage_1_1.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -37,7 +37,6 @@
import com.sun.corba.se.spi.servicecontext.ServiceContexts;
import com.sun.corba.se.spi.ior.iiop.GIOPVersion;
import com.sun.corba.se.impl.orbutil.ORBUtility;
-import com.sun.corba.se.impl.orbutil.ORBClassLoader;
import com.sun.corba.se.spi.ior.IOR;
import com.sun.corba.se.impl.encoding.CDRInputStream;
diff --git a/corba/src/share/classes/com/sun/corba/se/spi/orb/ORB.java b/corba/src/share/classes/com/sun/corba/se/spi/orb/ORB.java
index 89506e7..d2eddfb 100644
--- a/corba/src/share/classes/com/sun/corba/se/spi/orb/ORB.java
+++ b/corba/src/share/classes/com/sun/corba/se/spi/orb/ORB.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -97,8 +97,8 @@
import com.sun.corba.se.impl.presentation.rmi.PresentationManagerImpl ;
-import com.sun.corba.se.impl.orbutil.ORBClassLoader ;
import sun.awt.AppContext;
+import sun.corba.SharedSecrets;
public abstract class ORB extends com.sun.corba.se.org.omg.CORBA.ORB
implements Broker, TypeCodeFactory
@@ -201,7 +201,7 @@
try {
// First try the configured class name, if any
- Class cls = ORBClassLoader.loadClass( className ) ;
+ Class<?> cls = SharedSecrets.getJavaCorbaAccess().loadClass( className ) ;
sff = (PresentationManager.StubFactoryFactory)cls.newInstance() ;
} catch (Exception exc) {
// Use the default. Log the error as a warning.
diff --git a/corba/src/share/classes/com/sun/corba/se/spi/orb/OperationFactory.java b/corba/src/share/classes/com/sun/corba/se/spi/orb/OperationFactory.java
index eb81eb5..d84523b 100644
--- a/corba/src/share/classes/com/sun/corba/se/spi/orb/OperationFactory.java
+++ b/corba/src/share/classes/com/sun/corba/se/spi/orb/OperationFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -35,9 +35,10 @@
import com.sun.corba.se.spi.logging.CORBALogDomains ;
import com.sun.corba.se.impl.logging.ORBUtilSystemException ;
-import com.sun.corba.se.impl.orbutil.ORBClassLoader ;
import com.sun.corba.se.impl.orbutil.ObjectUtility ;
+import sun.corba.SharedSecrets;
+
/** This is a static factory class for commonly used operations
* for property parsing. The following operations are supported:
* <ul>
@@ -247,7 +248,8 @@
String className = getString( value ) ;
try {
- Class result = ORBClassLoader.loadClass( className ) ;
+ Class<?> result =
+ SharedSecrets.getJavaCorbaAccess().loadClass( className ) ;
return result ;
} catch (Exception exc) {
ORBUtilSystemException wrapper = ORBUtilSystemException.get(
diff --git a/corba/src/share/classes/sun/corba/JavaCorbaAccess.java b/corba/src/share/classes/sun/corba/JavaCorbaAccess.java
index 046453f..0d21551 100644
--- a/corba/src/share/classes/sun/corba/JavaCorbaAccess.java
+++ b/corba/src/share/classes/sun/corba/JavaCorbaAccess.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,4 +29,5 @@
public interface JavaCorbaAccess {
public ValueHandlerImpl newValueHandlerImpl();
+ public Class<?> loadClass(String className) throws ClassNotFoundException;
}
diff --git a/hotspot/.hgtags b/hotspot/.hgtags
index 26bff18..3cd8a20 100644
--- a/hotspot/.hgtags
+++ b/hotspot/.hgtags
@@ -372,6 +372,7 @@
0d82bf449a610602b6e9ddcc9e076839d5351449 jdk7u17-b02
7b357c079370e2fd324c229f2e24c982915c80a0 jdk7u17-b30
22b6fd616cfe61774525a944f162bf5e7c418f03 jdk7u17-b31
+8e04b403f5803f79db949b61b6c086758b611678 jdk7u17-b32
be57a8d7a1a75971c3b1e7777dcacd20f3d33264 jdk7u21-b01
5119d89c7cc844190c0799dca85710e7592d42e7 jdk7u21-b02
ad14169fb640ca532193cca0fd6e14910f226075 jdk7u21-b03
@@ -380,6 +381,12 @@
beeb3d6b76f06d9f60c31d6c5b9e04d82f01ad79 jdk7u21-b06
663b5c744e82d1c884048cd9b38f625e52004773 jdk7u21-b07
87e9bb582938552180b024dd99bc5166816f3921 jdk7u21-b08
+1f195ee7856aecb6527bc5c957f66e1960e51a12 jdk7u21-b09
+d4a4c2bd389abcd80c25d20e0ffb7d5cee356715 jdk7u21-b10
+d07dafb51e1d75f110a3c506c250d995235acca6 jdk7u21-b11
+a977dedec81c346247631ead6f3364c76949d67a jdk7u21-b30
+c5e4585a045fe165d067ec0e98af42eace20c5f8 jdk7u21-b12
bf2d84c5103d98db1697b50071a649ea23c4e33d jdk7u25-b01
07119340f80f77dfcb03fa568641e80b43d4be74 jdk7u25-b02
655bea6843fb7beabd8d9eeda59572c0c7055b85 jdk7u25-b03
+96a4e612195c0d753be24cf38fea0ee8ce30edcf jdk7u25-b04
diff --git a/jaxp/.hgtags b/jaxp/.hgtags
index eb0e0b2..76278c1 100644
--- a/jaxp/.hgtags
+++ b/jaxp/.hgtags
@@ -251,6 +251,7 @@
7863a60ae4b4a0c7d762a95e77e589fafa4e50ae jdk7u17-b02
a5e6594fc1ae20101b5d69632f65078d7a99b76d jdk7u17-b30
8fb34202383ece5386acecc3a6c1dac68dccbf05 jdk7u17-b31
+f7d8d2c003a10c38beac2f57e77d19303c71d6fc jdk7u17-b32
0a6a09e5174a4c15632ff7e06d6b215164e3fa15 jdk7u21-b01
99ed1a3d29509fee659aabec4810c896b7234d80 jdk7u21-b02
38d4d23d167c5a623e6d771a15b1fe2ee771ce38 jdk7u21-b03
@@ -259,6 +260,12 @@
ab51202418c1c96e01a45893a26829a2d9c7b956 jdk7u21-b06
3ab71deee4a4477d89530ee9e92a36017a6092fa jdk7u21-b07
f5ef2e76669bc3179f17dac42a8a407fb6bd4d91 jdk7u21-b08
+65977091d010402ccbed41c96748866a1d50f0c4 jdk7u21-b09
+bf2d62ea518d5e4130e442e07705e7a50b821ad9 jdk7u21-b10
+3e0e331bdfb8f3adfd0cc78118e0ac588e73a2b5 jdk7u21-b11
+980fe893d8fd86d8aee14771167b6e0ac75fa208 jdk7u21-b30
+a320a590b4cac6eeff53829bde520ef46880b006 jdk7u21-b12
5704dc942da676677a820d16c9a08fc6cad5b3bb jdk7u25-b01
f9c1fe7cd1194e785807f07005369631b35b28d8 jdk7u25-b02
fe858d7d6a13829d0ef0a1f762bd0e769cd24fa1 jdk7u25-b03
+1a2822a1d6a40c6e469f4089f39e41f642a87843 jdk7u25-b04
diff --git a/jaxws/.hgtags b/jaxws/.hgtags
index 398bb34..2702b10 100644
--- a/jaxws/.hgtags
+++ b/jaxws/.hgtags
@@ -251,6 +251,7 @@
defde3ef03605b1660a246ea85d2e810e3fe4f6e jdk7u17-b02
ae4272d61bc738e2d9265a68aefdc20ec648f22c jdk7u17-b30
52c4fbd4f58f336dfdf4f680b7e7d7361ec0c3f8 jdk7u17-b31
+52810f8d2dc09ef2b5e6089435f7050c9f7def11 jdk7u17-b32
e07c518282bad3b315d8064da5fad222a5e3f7ed jdk7u21-b01
0c1365d2fefb652aea34775749d68774c171ba1a jdk7u21-b02
017171d6bc217f26e230503dd38bcf4473f339d2 jdk7u21-b03
@@ -259,6 +260,12 @@
dab51e98ee7d0f3a30b9e18b0d3591b944346868 jdk7u21-b06
4a9533495068359d574da1060bc5a8fa6946cbc6 jdk7u21-b07
ab11cef1dfaaec32281dc3d24a366f6691b51b7a jdk7u21-b08
+53c87e8a2ac494b57f6220bd7e25c7380aa7f418 jdk7u21-b09
+29c03ced9215a0bb63a4527dc5858b486cc4099d jdk7u21-b10
+fe6f5b57b9e67a7c6f52a5f926ac17e5c337d4a4 jdk7u21-b11
+12183763c6205c5cfe27924ccc4ca5480106c3b4 jdk7u21-b30
+d4eba65d0f776b77ef137022cd7bf49dc3b88a3e jdk7u21-b12
238b59ffddce3b1d7d19114006ae3be0e72b5eed jdk7u25-b01
8797b25cbeb3005336483063cef2377849bc2088 jdk7u25-b02
4635a58db6b028f78a30c972ac47f9c5577bedfd jdk7u25-b03
+57d4548795c39e19099fc0a760d7887f83b1564f jdk7u25-b04
diff --git a/jdk/.hgtags b/jdk/.hgtags
index 18d9ceb..f738230 100644
--- a/jdk/.hgtags
+++ b/jdk/.hgtags
@@ -250,14 +250,21 @@
b130c8cfecfc552614047b3244d5d94439827fcd jdk7u17-b02
a474615061bf610105a426780a7ac4c95bd76456 jdk7u17-b30
1ad6f413e250bd2671b4908e232bd0d244c917a7 jdk7u17-b31
+6c6b9d7943e78d1f797b0c2e1c1231f81816dfde jdk7u17-b32
8261e56b7f91c7553e8485b206bdc9030a3546e4 jdk7u21-b01
af6be9d7aed7c323858932c908b049f4bcdb6a3e jdk7u21-b05
ffc1454e644a39265cd6d80ef4b4c12c5dbf35c9 jdk7u21-b06
b453d9be6b3f5496aa217ade7478d3b7fa32b13b jdk7u21-b07
de4e41c5c549136209a68154d847cf126e563b88 jdk7u21-b08
+622aedcdda610a148a082558a0c25d8b3b735d07 jdk7u21-b09
+f447c3bbf074439ece0ce9fea82c857f93817801 jdk7u21-b10
+f9323b9d020ce8d313af2d2e2682e2b6cabcc40d jdk7u21-b11
+08ed0bfc9668f04ce4e3803f16aad92f6e50f885 jdk7u21-b30
+f3cf02a53684b9fbefabb212c80dfbea0c27f113 jdk7u21-b12
a5e712ea6944b1c81bcd5343a50645964f12b107 jdk7u21-b02
9d87f5f84afef6ba4c92523a76e3c81fd9acfa00 jdk7u21-b03
139d3e3b62d49374112ce1add84cd3d1e5ed5335 jdk7u21-b04
7fd0922d6ed2988954c666de313f7fceef75dc63 jdk7u25-b01
846304f476f1b1d2955d025d54307be76c3c4874 jdk7u25-b02
2a444d8e36ebc7161a735b45143b22e141d9a5c0 jdk7u25-b03
+7fc6c331082c3586fa6c6ead014c96f3c532bc34 jdk7u25-b04
diff --git a/jdk/make/common/Defs.gmk b/jdk/make/common/Defs.gmk
index 7cbb0c0..002b21f 100644
--- a/jdk/make/common/Defs.gmk
+++ b/jdk/make/common/Defs.gmk
@@ -312,6 +312,7 @@
JDK_IMAGE_DIR = $(ABS_OUTPUTDIR)/j2sdk-image
JRE_IMAGE_DIR = $(ABS_OUTPUTDIR)/j2re-image
+JDK_SERVER_IMAGE_DIR = $(ABS_OUTPUTDIR)/j2sdk-server-image
#where the demo source can be found
DEMOSRCDIR = $(SHARE_SRC)/demo
diff --git a/jdk/make/common/Release-macosx.gmk b/jdk/make/common/Release-macosx.gmk
index f56370f..ebb95bc 100644
--- a/jdk/make/common/Release-macosx.gmk
+++ b/jdk/make/common/Release-macosx.gmk
@@ -31,6 +31,8 @@
JDK_BUNDLE_DIR = $(ABS_OUTPUTDIR)/j2sdk-bundle/jdk$(JDK_VERSION).jdk/Contents
JRE_BUNDLE_DIR = $(ABS_OUTPUTDIR)/j2re-bundle/jre$(JDK_VERSION).jre/Contents
+JDK_SERVER_BUNDLE_DIR = $(ABS_OUTPUTDIR)/j2sdk-server-bundle/jdk$(JDK_VERSION).jdk/Contents
+JDK_SERVER_IMAGE_DIR = $(ABS_OUTPUTDIR)/j2sdk-server-image
MACOSX_SRC = $(JDK_TOPDIR)/src/macosx
@@ -70,6 +72,13 @@
$(SED) -e "s/@@ID@@/$(BUNDLE_ID_JDK)/g" -e "s/@@NAME@@/$(BUNDLE_NAME_JDK)/g" -e "s/@@INFO@@/$(BUNDLE_INFO_JDK)/g" -e "s/@@PLATFORM_VERSION@@/$(BUNDLE_PLATFORM_VERSION)/g" -e "s/@@VERSION@@/$(BUNDLE_VERSION)/g" -e "s/@@VENDOR@@/$(BUNDLE_VENDOR)/g" < $(MACOSX_SRC)/bundle/JDK-Info.plist > $(JDK_BUNDLE_DIR)/Info.plist
/usr/bin/SetFile -a B $(JDK_BUNDLE_DIR)/../
-EXTRA_IMAGE_TARGETS += jre-bundle-setup jdk-bundle-setup jre-bundle-files jdk-bundle-files
+jdk-server-bundle-files:
+ $(MKDIR) -p $(JDK_SERVER_BUNDLE_DIR)/MacOS
+ ln -s ../Home/jre/lib/jli/libjli.dylib $(JDK_SERVER_BUNDLE_DIR)/MacOS/
+ $(CP) -r $(JDK_IMAGE_DIR) $(JDK_SERVER_BUNDLE_DIR)/Home
+ $(SED) -e "s/@@ID@@/$(BUNDLE_ID_JDK)/g" -e "s/@@NAME@@/$(BUNDE_NAME_JDK)/g" -e "s/@@INFO@@/$(BUNDLE_INFO_JDK)/g" -e "s/@@PLATFORM_VERSION@@/$(BUNDLE_PLATFORM_VERSION)/g" -e "s/@@VERSION@@/$(BUNDLE_VERSION)/g" -e "s/@@VENDOR@@/$(BUNDLE_VENDOR)/g" < $(MACOSX_SRC)/bundle/JDK-Info.plist > $(JDK_SERVER_BUNDLE_DIR)/Info.plist
+ /usr/bin/SetFile -a B $(JDK_SERVER_BUNDLE_DIR)/../
+
+EXTRA_IMAGE_TARGETS += jre-bundle-setup jdk-bundle-setup jre-bundle-files jdk-bundle-files jdk-server-bundle-files
.PHONY: $(EXTRA_JRE_TARGETS) $(EXTRA_IMAGE_TARGETS)
diff --git a/jdk/make/common/Release.gmk b/jdk/make/common/Release.gmk
index c3db363..513d14d 100644
--- a/jdk/make/common/Release.gmk
+++ b/jdk/make/common/Release.gmk
@@ -233,8 +233,8 @@
trim-image-jre trim-image-jdk \
identify-image-jre identify-image-jdk \
process-image-jre process-image-jdk \
-compare-image \
-sec-files sec-files-win jgss-files ::
+compare-image \
+sec-files sec-files-win jgss-files server-jdk-image ::
@$(ECHO) ">>>Making "$@" @ `$(DATE)` ..."
# Order is important here, trim jre after jdk image is created
@@ -243,16 +243,17 @@
images:: sanity-images post-sanity-images \
$(INITIAL_IMAGE_JRE) $(EXTRA_JRE_TARGETS) $(INITIAL_IMAGE_JDK) \
trim-image-jre trim-image-jdk \
- identify-image-jre identify-image-jdk \
- process-image-jre process-image-jdk sec-files sec-files-win jgss-files \
- $(EXTRA_IMAGE_TARGETS)
+ identify-image-jre identify-image-jdk \
+ process-image-jre process-image-jdk sec-files sec-files-win \
+ jgss-files $(EXTRA_IMAGE_TARGETS) server-jdk-image
else
images:: sanity-images post-sanity-images \
$(INITIAL_IMAGE_JRE) $(INITIAL_IMAGE_JDK) \
trim-image-jre trim-image-jdk \
identify-image-jre identify-image-jdk \
- process-image-jre process-image-jdk sec-files sec-files-win jgss-files
+ process-image-jre process-image-jdk sec-files sec-files-win \
+ jgss-files server-jdk-image
endif
# Don't use these
@@ -928,6 +929,27 @@
done
$(RM) $(JRE_BIN_LIST)
+# Duplicate current j2re-image contents to server-j2re-image
+# for the server version of jre, before deploy build
+server-jdk-image::
+ifeq ($(PLATFORM), macosx)
+ $(RM) -r $(JDK_SERVER_BUNDLE_DIR)/Home/demo
+ $(RM) -r $(JDK_SERVER_BUNDLE_DIR)/Home/sample
+ $(RM) $(JDK_SERVER_BUNDLE_DIR)/Home/bin/jcontrol
+ $(RM) $(JDK_SERVER_BUNDLE_DIR)/Home/jre/bin/jcontrol
+ $(RM) $(JDK_SERVER_BUNDLE_DIR)/Home/man/ja_JP.UTF-8/man1/javaws.1
+ $(RM) $(JDK_SERVER_BUNDLE_DIR)/Home/man/man1/javaws.1
+else
+ $(RM) -r $(JDK_SERVER_IMAGE_DIR)
+ $(CP) -r $(JDK_IMAGE_DIR) $(JDK_SERVER_IMAGE_DIR)
+ $(RM) -r $(JDK_SERVER_IMAGE_DIR)/demo
+ $(RM) -r $(JDK_SERVER_IMAGE_DIR)/sample
+ $(RM) $(JDK_SERVER_IMAGE_DIR)/bin/jcontrol
+ $(RM) $(JDK_SERVER_IMAGE_DIR)/jre/bin/jcontrol
+ $(RM) $(JDK_SERVER_IMAGE_DIR)/man/ja_JP.UTF-8/man1/javaws.1
+ $(RM) $(JDK_SERVER_IMAGE_DIR)/man/man1/javaws.1
+endif
+
######################################################
# JDK Image
######################################################
diff --git a/jdk/make/java/java/FILES_c.gmk b/jdk/make/java/java/FILES_c.gmk
index a8256b7..538ef20 100644
--- a/jdk/make/java/java/FILES_c.gmk
+++ b/jdk/make/java/java/FILES_c.gmk
@@ -48,7 +48,6 @@
Proxy.c \
RandomAccessFile.c \
RandomAccessFile_md.c \
- ResourceBundle.c \
Runtime.c \
SecurityManager.c \
Shutdown.c \
@@ -69,7 +68,6 @@
jdk_util_md.c \
check_version.c \
java_props_md.c \
- DriverManager.c \
ConstantPool.c \
MessageUtils.c \
GC.c \
diff --git a/jdk/make/java/java/mapfile-vers b/jdk/make/java/java/mapfile-vers
index 74523b4..67ecb56 100644
--- a/jdk/make/java/java/mapfile-vers
+++ b/jdk/make/java/java/mapfile-vers
@@ -135,7 +135,6 @@
Java_java_lang_ClassLoader_00024NativeLibrary_find;
Java_java_lang_ClassLoader_00024NativeLibrary_load;
Java_java_lang_ClassLoader_00024NativeLibrary_unload;
- Java_java_lang_ClassLoader_getCaller;
Java_java_lang_ClassLoader_registerNatives;
Java_java_lang_Compiler_registerNatives;
Java_java_lang_Double_longBitsToDouble;
@@ -233,8 +232,6 @@
Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedExceptionAction_2Ljava_security_AccessControlContext_2;
Java_java_security_AccessController_getStackAccessControlContext;
Java_java_security_AccessController_getInheritedAccessControlContext;
- Java_java_sql_DriverManager_getCallerClassLoader;
- Java_java_util_ResourceBundle_getClassContext;
Java_java_util_TimeZone_getSystemTimeZoneID;
Java_java_util_TimeZone_getSystemGMTOffsetID;
Java_java_util_concurrent_atomic_AtomicLong_VMSupportsCS8;
diff --git a/jdk/make/java/java/reorder-i586 b/jdk/make/java/java/reorder-i586
index fc3202a..86fd4a5 100644
--- a/jdk/make/java/java/reorder-i586
+++ b/jdk/make/java/java/reorder-i586
@@ -73,7 +73,6 @@
# Test Sleep
# Test IntToString
# Test LoadToolkit
-text: .text%Java_java_util_ResourceBundle_getClassContext;
text: .text%Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedAction_2Ljava_security_AccessControlContext_2;
text: .text%JNU_GetEnv;
text: .text%Java_java_io_UnixFileSystem_checkAccess;
diff --git a/jdk/make/java/java/reorder-sparc b/jdk/make/java/java/reorder-sparc
index 090f000..6293ec7 100644
--- a/jdk/make/java/java/reorder-sparc
+++ b/jdk/make/java/java/reorder-sparc
@@ -78,7 +78,6 @@
# Test Sleep
# Test IntToString
# Test LoadToolkit
-text: .text%Java_java_util_ResourceBundle_getClassContext;
text: .text%Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedAction_2Ljava_security_AccessControlContext_2;
text: .text%JNU_GetEnv;
text: .text%Java_java_io_UnixFileSystem_checkAccess;
diff --git a/jdk/make/java/java/reorder-sparcv9 b/jdk/make/java/java/reorder-sparcv9
index b20b45a..29a530d 100644
--- a/jdk/make/java/java/reorder-sparcv9
+++ b/jdk/make/java/java/reorder-sparcv9
@@ -74,7 +74,6 @@
# Test Sleep
# Test IntToString
# Test LoadToolkit
-text: .text%Java_java_util_ResourceBundle_getClassContext;
text: .text%Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedAction_2Ljava_security_AccessControlContext_2;
text: .text%JNU_GetEnv;
text: .text%Java_java_io_UnixFileSystem_checkAccess;
diff --git a/jdk/make/java/zip/mapfile-vers b/jdk/make/java/zip/mapfile-vers
index f150452..f7b5050 100644
--- a/jdk/make/java/zip/mapfile-vers
+++ b/jdk/make/java/zip/mapfile-vers
@@ -68,6 +68,7 @@
Java_java_util_zip_ZipFile_initIDs;
Java_java_util_zip_ZipFile_open;
Java_java_util_zip_ZipFile_read;
+ Java_java_util_zip_ZipFile_startsWithLOC;
ZIP_Close;
ZIP_CRC32;
diff --git a/jdk/make/java/zip/reorder-i586 b/jdk/make/java/zip/reorder-i586
index ee717ff..73ea674 100644
--- a/jdk/make/java/zip/reorder-i586
+++ b/jdk/make/java/zip/reorder-i586
@@ -19,6 +19,7 @@
text: .text%Java_java_util_zip_ZipFile_initIDs;
text: .text%Java_java_util_zip_ZipFile_open;
text: .text%Java_java_util_zip_ZipFile_getTotal;
+text: .text%Java_java_util_zip_ZipFile_startsWithLOC;
text: .text%Java_java_util_zip_ZipFile_getEntry;
text: .text%Java_java_util_zip_ZipFile_freeEntry;
text: .text%Java_java_util_zip_ZipFile_getEntryTime;
diff --git a/jdk/make/java/zip/reorder-sparc b/jdk/make/java/zip/reorder-sparc
index 176c770..a5cde39 100644
--- a/jdk/make/java/zip/reorder-sparc
+++ b/jdk/make/java/zip/reorder-sparc
@@ -18,6 +18,7 @@
text: .text%Java_java_util_zip_ZipFile_initIDs;
text: .text%Java_java_util_zip_ZipFile_open;
text: .text%Java_java_util_zip_ZipFile_getTotal;
+text: .text%Java_java_util_zip_ZipFile_startsWithLOC;
text: .text%Java_java_util_zip_ZipFile_getEntry;
text: .text%Java_java_util_zip_ZipFile_freeEntry;
text: .text%Java_java_util_zip_ZipFile_getEntryTime;
diff --git a/jdk/make/java/zip/reorder-sparcv9 b/jdk/make/java/zip/reorder-sparcv9
index bf2d983..32ebae1 100644
--- a/jdk/make/java/zip/reorder-sparcv9
+++ b/jdk/make/java/zip/reorder-sparcv9
@@ -18,6 +18,7 @@
text: .text%Java_java_util_zip_ZipFile_initIDs;
text: .text%Java_java_util_zip_ZipFile_open;
text: .text%Java_java_util_zip_ZipFile_getTotal;
+text: .text%Java_java_util_zip_ZipFile_startsWithLOC;
text: .text%Java_java_util_zip_ZipFile_getEntry;
text: .text%Java_java_util_zip_ZipFile_freeEntry;
text: .text%Java_java_util_zip_ZipFile_getEntryTime;
diff --git a/jdk/src/share/classes/java/io/ObjectStreamClass.java b/jdk/src/share/classes/java/io/ObjectStreamClass.java
index f168cdb..029f3d4 100644
--- a/jdk/src/share/classes/java/io/ObjectStreamClass.java
+++ b/jdk/src/share/classes/java/io/ObjectStreamClass.java
@@ -49,6 +49,8 @@
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import sun.misc.Unsafe;
+import sun.reflect.CallerSensitive;
+import sun.reflect.Reflection;
import sun.reflect.ReflectionFactory;
import sun.reflect.misc.ReflectUtil;
@@ -259,12 +261,13 @@
*
* @return the <code>Class</code> instance that this descriptor represents
*/
+ @CallerSensitive
public Class<?> forClass() {
if (cl == null) {
return null;
}
- ClassLoader ccl = ObjectStreamField.getCallerClassLoader();
- if (ReflectUtil.needsPackageAccessCheck(ccl, cl.getClassLoader())) {
+ Class<?> caller = Reflection.getCallerClass();
+ if (ReflectUtil.needsPackageAccessCheck(caller.getClassLoader(), cl.getClassLoader())) {
ReflectUtil.checkPackageAccess(cl);
}
return cl;
diff --git a/jdk/src/share/classes/java/io/ObjectStreamField.java b/jdk/src/share/classes/java/io/ObjectStreamField.java
index b0a8e59..630637f 100644
--- a/jdk/src/share/classes/java/io/ObjectStreamField.java
+++ b/jdk/src/share/classes/java/io/ObjectStreamField.java
@@ -26,6 +26,7 @@
package java.io;
import java.lang.reflect.Field;
+import sun.reflect.CallerSensitive;
import sun.reflect.Reflection;
import sun.reflect.misc.ReflectUtil;
@@ -159,32 +160,15 @@
* @return a <code>Class</code> object representing the type of the
* serializable field
*/
+ @CallerSensitive
public Class<?> getType() {
- ClassLoader ccl = getCallerClassLoader();
- if (ReflectUtil.needsPackageAccessCheck(ccl, type.getClassLoader())) {
+ Class<?> caller = Reflection.getCallerClass();
+ if (ReflectUtil.needsPackageAccessCheck(caller.getClassLoader(), type.getClassLoader())) {
ReflectUtil.checkPackageAccess(type);
}
return type;
}
- // Returns the invoker's class loader.
- // This is package private because it is accessed from ObjectStreamClass.
- // NOTE: This must always be invoked when there is exactly one intervening
- // frame from the core libraries on the stack between this method's
- // invocation and the desired invoker. The frame count of 3 is determined
- // as follows:
- //
- // 0: Reflection.getCallerClass
- // 1: getCallerClassLoader()
- // 2: ObjectStreamField.getType() or ObjectStreamClass.forClass()
- // 3: the caller we want to check
- //
- // NOTE: copied from java.lang.ClassLoader and modified.
- static ClassLoader getCallerClassLoader() {
- Class caller = Reflection.getCallerClass(3);
- return caller.getClassLoader();
- }
-
/**
* Returns character encoding of field type. The encoding is as follows:
* <blockquote><pre>
diff --git a/jdk/src/share/classes/java/lang/Class.java b/jdk/src/share/classes/java/lang/Class.java
index e56ce43..5ef5785 100644
--- a/jdk/src/share/classes/java/lang/Class.java
+++ b/jdk/src/share/classes/java/lang/Class.java
@@ -53,6 +53,7 @@
import java.util.Map;
import java.util.HashMap;
import sun.misc.Unsafe;
+import sun.reflect.CallerSensitive;
import sun.reflect.ConstantPool;
import sun.reflect.Reflection;
import sun.reflect.ReflectionFactory;
@@ -183,9 +184,11 @@
* by this method fails
* @exception ClassNotFoundException if the class cannot be located
*/
+ @CallerSensitive
public static Class<?> forName(String className)
throws ClassNotFoundException {
- return forName0(className, true, ClassLoader.getCallerClassLoader());
+ return forName0(className, true,
+ ClassLoader.getClassLoader(Reflection.getCallerClass()));
}
@@ -249,6 +252,7 @@
* @see java.lang.ClassLoader
* @since 1.2
*/
+ @CallerSensitive
public static Class<?> forName(String name, boolean initialize,
ClassLoader loader)
throws ClassNotFoundException
@@ -256,7 +260,7 @@
if (loader == null) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
- ClassLoader ccl = ClassLoader.getCallerClassLoader();
+ ClassLoader ccl = ClassLoader.getClassLoader(Reflection.getCallerClass());
if (ccl != null) {
sm.checkPermission(
SecurityConstants.GET_CLASSLOADER_PERMISSION);
@@ -318,18 +322,14 @@
* </ul>
*
*/
+ @CallerSensitive
public T newInstance()
throws InstantiationException, IllegalAccessException
{
if (System.getSecurityManager() != null) {
- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), false);
+ checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), false);
}
- return newInstance0();
- }
- private T newInstance0()
- throws InstantiationException, IllegalAccessException
- {
// NOTE: the following code may not be strictly correct under
// the current Java memory model.
@@ -363,7 +363,7 @@
// Security check (same as in java.lang.reflect.Constructor)
int modifiers = tmpConstructor.getModifiers();
if (!Reflection.quickCheckMemberAccess(this, modifiers)) {
- Class<?> caller = Reflection.getCallerClass(3);
+ Class<?> caller = Reflection.getCallerClass();
if (newInstanceCallerCache != caller) {
Reflection.ensureMemberAccess(caller, this, null, modifiers);
newInstanceCallerCache = caller;
@@ -604,16 +604,14 @@
* @see SecurityManager#checkPermission
* @see java.lang.RuntimePermission
*/
+ @CallerSensitive
public ClassLoader getClassLoader() {
ClassLoader cl = getClassLoader0();
if (cl == null)
return null;
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
- ClassLoader ccl = ClassLoader.getCallerClassLoader();
- if (ccl != null && ccl != cl && !cl.isAncestor(ccl)) {
- sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
- }
+ ClassLoader.checkClassLoaderPermission(cl, Reflection.getCallerClass());
}
return cl;
}
@@ -894,6 +892,7 @@
* that class is a local or anonymous class; otherwise {@code null}.
* @since 1.5
*/
+ @CallerSensitive
public Method getEnclosingMethod() {
EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo();
@@ -923,7 +922,7 @@
//
// Note that we need to do this on the enclosing class
enclosingCandidate.checkMemberAccess(Member.DECLARED,
- ClassLoader.getCallerClassLoader(), true);
+ Reflection.getCallerClass(), true);
/*
* Loop over all declared methods; match method name,
* number of and type of parameters, *and* return
@@ -1031,6 +1030,7 @@
* that class is a local or anonymous class; otherwise {@code null}.
* @since 1.5
*/
+ @CallerSensitive
public Constructor<?> getEnclosingConstructor() {
EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo();
@@ -1059,7 +1059,7 @@
//
// Note that we need to do this on the enclosing class
enclosingCandidate.checkMemberAccess(Member.DECLARED,
- ClassLoader.getCallerClassLoader(), true);
+ Reflection.getCallerClass(), true);
/*
* Loop over all declared constructors; match number
* of and type of parameters.
@@ -1106,6 +1106,7 @@
* @return the immediately enclosing class of the underlying class
* @since 1.5
*/
+ @CallerSensitive
public Class<?> getEnclosingClass() {
// There are five kinds of classes (or interfaces):
// a) Top level classes
@@ -1138,7 +1139,7 @@
// see java.lang.SecurityManager.checkMemberAccess
if (enclosingCandidate != null) {
enclosingCandidate.checkMemberAccess(Member.DECLARED,
- ClassLoader.getCallerClassLoader(), true);
+ Reflection.getCallerClass(), true);
}
return enclosingCandidate;
}
@@ -1323,11 +1324,12 @@
*
* @since JDK1.1
*/
+ @CallerSensitive
public Class<?>[] getClasses() {
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), false);
+ checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), false);
// Privileged so this implementation can look at DECLARED classes,
// something the caller might not have privilege to do. The code here
@@ -1398,11 +1400,12 @@
*
* @since JDK1.1
*/
+ @CallerSensitive
public Field[] getFields() throws SecurityException {
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
+ checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
return copyFields(privateGetPublicFields(null));
}
@@ -1449,11 +1452,12 @@
*
* @since JDK1.1
*/
+ @CallerSensitive
public Method[] getMethods() throws SecurityException {
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
+ checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
return copyMethods(privateGetPublicMethods());
}
@@ -1498,11 +1502,12 @@
*
* @since JDK1.1
*/
+ @CallerSensitive
public Constructor<?>[] getConstructors() throws SecurityException {
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
+ checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
return copyConstructors(privateGetDeclaredConstructors(true));
}
@@ -1556,12 +1561,13 @@
*
* @since JDK1.1
*/
+ @CallerSensitive
public Field getField(String name)
throws NoSuchFieldException, SecurityException {
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
+ checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
Field field = getField0(name);
if (field == null) {
throw new NoSuchFieldException(name);
@@ -1641,12 +1647,13 @@
*
* @since JDK1.1
*/
+ @CallerSensitive
public Method getMethod(String name, Class<?>... parameterTypes)
throws NoSuchMethodException, SecurityException {
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
+ checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
Method method = getMethod0(name, parameterTypes);
if (method == null) {
throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes));
@@ -1695,12 +1702,13 @@
*
* @since JDK1.1
*/
+ @CallerSensitive
public Constructor<T> getConstructor(Class<?>... parameterTypes)
throws NoSuchMethodException, SecurityException {
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
+ checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
return getConstructor0(parameterTypes, Member.PUBLIC);
}
@@ -1738,11 +1746,12 @@
*
* @since JDK1.1
*/
+ @CallerSensitive
public Class<?>[] getDeclaredClasses() throws SecurityException {
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), false);
+ checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), false);
return getDeclaredClasses0();
}
@@ -1782,11 +1791,12 @@
*
* @since JDK1.1
*/
+ @CallerSensitive
public Field[] getDeclaredFields() throws SecurityException {
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
+ checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
return copyFields(privateGetDeclaredFields(false));
}
@@ -1830,11 +1840,12 @@
*
* @since JDK1.1
*/
+ @CallerSensitive
public Method[] getDeclaredMethods() throws SecurityException {
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
+ checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
return copyMethods(privateGetDeclaredMethods(false));
}
@@ -1875,11 +1886,12 @@
*
* @since JDK1.1
*/
+ @CallerSensitive
public Constructor<?>[] getDeclaredConstructors() throws SecurityException {
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
+ checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
return copyConstructors(privateGetDeclaredConstructors(false));
}
@@ -1918,12 +1930,13 @@
*
* @since JDK1.1
*/
+ @CallerSensitive
public Field getDeclaredField(String name)
throws NoSuchFieldException, SecurityException {
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
+ checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
Field field = searchFields(privateGetDeclaredFields(false), name);
if (field == null) {
throw new NoSuchFieldException(name);
@@ -1973,12 +1986,13 @@
*
* @since JDK1.1
*/
+ @CallerSensitive
public Method getDeclaredMethod(String name, Class<?>... parameterTypes)
throws NoSuchMethodException, SecurityException {
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
+ checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
Method method = searchMethods(privateGetDeclaredMethods(false), name, parameterTypes);
if (method == null) {
throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes));
@@ -2023,12 +2037,13 @@
*
* @since JDK1.1
*/
+ @CallerSensitive
public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
throws NoSuchMethodException, SecurityException {
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
+ checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
return getConstructor0(parameterTypes, Member.DECLARED);
}
@@ -2186,30 +2201,47 @@
*/
static native Class getPrimitiveClass(String name);
+ private static boolean isCheckMemberAccessOverridden(SecurityManager smgr) {
+ if (smgr.getClass() == SecurityManager.class) return false;
+
+ Class<?>[] paramTypes = new Class<?>[] {Class.class, int.class};
+ return smgr.getClass().getMethod0("checkMemberAccess", paramTypes).
+ getDeclaringClass() != SecurityManager.class;
+ }
+
/*
* Check if client is allowed to access members. If access is denied,
* throw a SecurityException.
*
- * Be very careful not to change the stack depth of this checkMemberAccess
- * call for security reasons.
- * See java.lang.SecurityManager.checkMemberAccess.
- *
* <p> Default policy: allow all clients access with normal Java access
* control.
*/
- private void checkMemberAccess(int which, ClassLoader ccl, boolean checkProxyInterfaces) {
- SecurityManager s = System.getSecurityManager();
+ private void checkMemberAccess(int which, Class<?> caller, boolean checkProxyInterfaces) {
+ final SecurityManager s = System.getSecurityManager();
if (s != null) {
- s.checkMemberAccess(this, which);
- ClassLoader cl = getClassLoader0();
+ final ClassLoader ccl = ClassLoader.getClassLoader(caller);
+ final ClassLoader cl = getClassLoader0();
+ if (!isCheckMemberAccessOverridden(s)) {
+ // Inlined SecurityManager.checkMemberAccess
+ if (which != Member.PUBLIC) {
+ if (ccl != cl) {
+ s.checkPermission(SecurityConstants.CHECK_MEMBER_ACCESS_PERMISSION);
+ }
+ }
+ } else {
+ // Don't refactor; otherwise break the stack depth for
+ // checkMemberAccess of subclasses of SecurityManager as specified.
+ s.checkMemberAccess(this, which);
+ }
+
if (ReflectUtil.needsPackageAccessCheck(ccl, cl)) {
String name = this.getName();
int i = name.lastIndexOf('.');
if (i != -1) {
// skip the package access check on a proxy class in default proxy package
String pkg = name.substring(0, i);
- if (!Proxy.isProxyClass(this) || !pkg.equals(ReflectUtil.PROXY_PACKAGE)) {
+ if (!Proxy.isProxyClass(this) || ReflectUtil.isNonPublicProxyClass(this)) {
s.checkPackageAccess(pkg);
}
}
diff --git a/jdk/src/share/classes/java/lang/ClassLoader.java b/jdk/src/share/classes/java/lang/ClassLoader.java
index 184e5ee..0814bda 100644
--- a/jdk/src/share/classes/java/lang/ClassLoader.java
+++ b/jdk/src/share/classes/java/lang/ClassLoader.java
@@ -56,6 +56,7 @@
import sun.misc.Resource;
import sun.misc.URLClassPath;
import sun.misc.VM;
+import sun.reflect.CallerSensitive;
import sun.reflect.Reflection;
import sun.security.util.SecurityConstants;
@@ -1215,11 +1216,6 @@
return java.util.Collections.emptyEnumeration();
}
- // index 0: java.lang.ClassLoader.class
- // index 1: the immediate caller of index 0.
- // index 2: the immediate caller of index 1.
- private static native Class<? extends ClassLoader> getCaller(int index);
-
/**
* Registers the caller as parallel capable.</p>
* The registration succeeds if and only if all of the following
@@ -1235,8 +1231,11 @@
*
* @since 1.7
*/
+ @CallerSensitive
protected static boolean registerAsParallelCapable() {
- return ParallelLoaders.register(getCaller(1));
+ Class<? extends ClassLoader> callerClass =
+ Reflection.getCallerClass().asSubclass(ClassLoader.class);
+ return ParallelLoaders.register(callerClass);
}
/**
@@ -1396,15 +1395,13 @@
*
* @since 1.2
*/
+ @CallerSensitive
public final ClassLoader getParent() {
if (parent == null)
return null;
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
- ClassLoader ccl = getCallerClassLoader();
- if (ccl != null && !isAncestor(ccl)) {
- sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
- }
+ checkClassLoaderPermission(parent, Reflection.getCallerClass());
}
return parent;
}
@@ -1464,6 +1461,7 @@
*
* @revised 1.4
*/
+ @CallerSensitive
public static ClassLoader getSystemClassLoader() {
initSystemClassLoader();
if (scl == null) {
@@ -1471,10 +1469,7 @@
}
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
- ClassLoader ccl = getCallerClassLoader();
- if (ccl != null && ccl != scl && !scl.isAncestor(ccl)) {
- sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
- }
+ checkClassLoaderPermission(scl, Reflection.getCallerClass());
}
return scl;
}
@@ -1522,13 +1517,25 @@
return false;
}
- // Returns the invoker's class loader, or null if none.
- // NOTE: This must always be invoked when there is exactly one intervening
- // frame from the core libraries on the stack between this method's
- // invocation and the desired invoker.
- static ClassLoader getCallerClassLoader() {
- // NOTE use of more generic Reflection.getCallerClass()
- Class caller = Reflection.getCallerClass(3);
+ // Tests if class loader access requires "getClassLoader" permission
+ // check. A class loader 'from' can access class loader 'to' if
+ // class loader 'from' is same as class loader 'to' or an ancestor
+ // of 'to'. The class loader in a system domain can access
+ // any class loader.
+ private static boolean needsClassLoaderPermissionCheck(ClassLoader from,
+ ClassLoader to)
+ {
+ if (from == to)
+ return false;
+
+ if (from == null)
+ return false;
+
+ return !to.isAncestor(from);
+ }
+
+ // Returns the class's class loader, or null if none.
+ static ClassLoader getClassLoader(Class<?> caller) {
// This can be null if the VM is requesting it
if (caller == null) {
return null;
@@ -1537,6 +1544,17 @@
return caller.getClassLoader0();
}
+ static void checkClassLoaderPermission(ClassLoader cl, Class<?> caller) {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ // caller can be null if the VM is requesting it
+ ClassLoader ccl = getClassLoader(caller);
+ if (needsClassLoaderPermissionCheck(ccl, cl)) {
+ sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
+ }
+ }
+ }
+
// The class loader for the system
// @GuardedBy("ClassLoader.class")
private static ClassLoader scl;
diff --git a/jdk/src/share/classes/java/lang/Package.java b/jdk/src/share/classes/java/lang/Package.java
index 3ea8013..395cf33 100644
--- a/jdk/src/share/classes/java/lang/Package.java
+++ b/jdk/src/share/classes/java/lang/Package.java
@@ -47,9 +47,10 @@
import java.util.HashMap;
import java.util.Iterator;
-import sun.net.www.ParseUtil;
-
import java.lang.annotation.Annotation;
+import sun.net.www.ParseUtil;
+import sun.reflect.CallerSensitive;
+import sun.reflect.Reflection;
/**
* {@code Package} objects contain version information
@@ -272,8 +273,9 @@
* @return the package of the requested name. It may be null if no package
* information is available from the archive or codebase.
*/
+ @CallerSensitive
public static Package getPackage(String name) {
- ClassLoader l = ClassLoader.getCallerClassLoader();
+ ClassLoader l = ClassLoader.getClassLoader(Reflection.getCallerClass());
if (l != null) {
return l.getPackage(name);
} else {
@@ -293,8 +295,9 @@
* @return a new array of packages known to the callers {@code ClassLoader}
* instance. An zero length array is returned if none are known.
*/
+ @CallerSensitive
public static Package[] getPackages() {
- ClassLoader l = ClassLoader.getCallerClassLoader();
+ ClassLoader l = ClassLoader.getClassLoader(Reflection.getCallerClass());
if (l != null) {
return l.getPackages();
} else {
diff --git a/jdk/src/share/classes/java/lang/Runtime.java b/jdk/src/share/classes/java/lang/Runtime.java
index 3fc29d0..9ebb35f 100644
--- a/jdk/src/share/classes/java/lang/Runtime.java
+++ b/jdk/src/share/classes/java/lang/Runtime.java
@@ -27,6 +27,8 @@
import java.io.*;
import java.util.StringTokenizer;
+import sun.reflect.CallerSensitive;
+import sun.reflect.Reflection;
/**
* Every Java application has a single instance of class
@@ -776,8 +778,9 @@
* @see java.lang.SecurityException
* @see java.lang.SecurityManager#checkLink(java.lang.String)
*/
+ @CallerSensitive
public void load(String filename) {
- load0(System.getCallerClass(), filename);
+ load0(Reflection.getCallerClass(), filename);
}
synchronized void load0(Class fromClass, String filename) {
@@ -829,8 +832,9 @@
* @see java.lang.SecurityException
* @see java.lang.SecurityManager#checkLink(java.lang.String)
*/
+ @CallerSensitive
public void loadLibrary(String libname) {
- loadLibrary0(System.getCallerClass(), libname);
+ loadLibrary0(Reflection.getCallerClass(), libname);
}
synchronized void loadLibrary0(Class fromClass, String libname) {
diff --git a/jdk/src/share/classes/java/lang/System.java b/jdk/src/share/classes/java/lang/System.java
index 0f20cd1..c0b5818 100644
--- a/jdk/src/share/classes/java/lang/System.java
+++ b/jdk/src/share/classes/java/lang/System.java
@@ -34,6 +34,7 @@
import java.nio.channels.Channel;
import java.nio.channels.spi.SelectorProvider;
import sun.nio.ch.Interruptible;
+import sun.reflect.CallerSensitive;
import sun.reflect.Reflection;
import sun.security.util.SecurityConstants;
import sun.reflect.annotation.AnnotationType;
@@ -1055,8 +1056,9 @@
* @see java.lang.Runtime#load(java.lang.String)
* @see java.lang.SecurityManager#checkLink(java.lang.String)
*/
+ @CallerSensitive
public static void load(String filename) {
- Runtime.getRuntime().load0(getCallerClass(), filename);
+ Runtime.getRuntime().load0(Reflection.getCallerClass(), filename);
}
/**
@@ -1080,8 +1082,9 @@
* @see java.lang.Runtime#loadLibrary(java.lang.String)
* @see java.lang.SecurityManager#checkLink(java.lang.String)
*/
+ @CallerSensitive
public static void loadLibrary(String libname) {
- Runtime.getRuntime().loadLibrary0(getCallerClass(), libname);
+ Runtime.getRuntime().loadLibrary0(Reflection.getCallerClass(), libname);
}
/**
@@ -1201,10 +1204,4 @@
}
});
}
-
- /* returns the class of the caller. */
- static Class<?> getCallerClass() {
- // NOTE use of more generic Reflection.getCallerClass()
- return Reflection.getCallerClass(3);
- }
}
diff --git a/jdk/src/share/classes/java/lang/Thread.java b/jdk/src/share/classes/java/lang/Thread.java
index cb166c8..8541bfe 100644
--- a/jdk/src/share/classes/java/lang/Thread.java
+++ b/jdk/src/share/classes/java/lang/Thread.java
@@ -37,6 +37,8 @@
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.locks.LockSupport;
import sun.nio.ch.Interruptible;
+import sun.reflect.CallerSensitive;
+import sun.reflect.Reflection;
import sun.security.util.SecurityConstants;
@@ -1440,16 +1442,15 @@
*
* @since 1.2
*/
+ @CallerSensitive
public ClassLoader getContextClassLoader() {
if (contextClassLoader == null)
return null;
+
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
- ClassLoader ccl = ClassLoader.getCallerClassLoader();
- if (ccl != null && ccl != contextClassLoader &&
- !contextClassLoader.isAncestor(ccl)) {
- sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
- }
+ ClassLoader.checkClassLoaderPermission(contextClassLoader,
+ Reflection.getCallerClass());
}
return contextClassLoader;
}
diff --git a/jdk/src/share/classes/java/lang/invoke/MemberName.java b/jdk/src/share/classes/java/lang/invoke/MemberName.java
index 088c568..b7570e4 100644
--- a/jdk/src/share/classes/java/lang/invoke/MemberName.java
+++ b/jdk/src/share/classes/java/lang/invoke/MemberName.java
@@ -275,10 +275,11 @@
// private flags, not part of RECOGNIZED_MODIFIERS:
static final int
- IS_METHOD = MN_IS_METHOD, // method (not constructor)
- IS_CONSTRUCTOR = MN_IS_CONSTRUCTOR, // constructor
- IS_FIELD = MN_IS_FIELD, // field
- IS_TYPE = MN_IS_TYPE; // nested type
+ IS_METHOD = MN_IS_METHOD, // method (not constructor)
+ IS_CONSTRUCTOR = MN_IS_CONSTRUCTOR, // constructor
+ IS_FIELD = MN_IS_FIELD, // field
+ IS_TYPE = MN_IS_TYPE, // nested type
+ IS_CALLER_SENSITIVE = MN_CALLER_SENSITIVE; // @CallerSensitive annotation
static final int // for MethodHandleNatives.getMembers
SEARCH_SUPERCLASSES = MN_SEARCH_SUPERCLASSES,
SEARCH_INTERFACES = MN_SEARCH_INTERFACES;
@@ -317,6 +318,10 @@
public boolean isPackage() {
return !testAnyFlags(ALL_ACCESS);
}
+ /** Utility method to query whether this member is annotated with @CallerSensitive. */
+ public boolean isCallerSensitive() {
+ return testAllFlags(IS_CALLER_SENSITIVE);
+ }
/** Initialize a query. It is not resolved. */
private void init(Class<?> defClass, String name, Object type, int flags) {
diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java b/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java
index cd680d5..01c73b2 100644
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java
@@ -37,6 +37,8 @@
import sun.invoke.util.VerifyType;
import sun.invoke.util.Wrapper;
import sun.misc.Unsafe;
+import sun.reflect.CallerSensitive;
+import sun.reflect.Reflection;
import static java.lang.invoke.MethodHandleStatics.*;
import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
@@ -1362,9 +1364,11 @@
}
}
+ @CallerSensitive
private static boolean checkCallerClass(Class<?> expected, Class<?> expected2) {
- final int FRAME_COUNT_ARG = 2; // [0] Reflection [1] BindCaller [2] Expected
- Class<?> actual = sun.reflect.Reflection.getCallerClass(FRAME_COUNT_ARG);
+ // This method is called via MH_checkCallerClass and so it's
+ // correct to ask for the immediate caller here.
+ Class<?> actual = Reflection.getCallerClass();
if (actual != expected && actual != expected2)
throw new InternalError("found "+actual.getName()+", expected "+expected.getName()
+(expected == expected2 ? "" : ", or else "+expected2.getName()));
diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java b/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java
index 271269a..18d5d2c 100644
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java
@@ -33,7 +33,7 @@
/**
* The JVM interface for the method handles package is all here.
- * This is an interface internal and private to an implemetantion of JSR 292.
+ * This is an interface internal and private to an implementation of JSR 292.
* <em>This class is not part of the JSR 292 standard.</em>
* @author jrose
*/
@@ -131,6 +131,7 @@
OP_ROT_ARGS_DOWN_LIMIT_BIAS = (k != 0) ? (byte)k : -1;
HAVE_RICOCHET_FRAMES = (CONV_OP_IMPLEMENTED_MASK & (1<<OP_COLLECT_ARGS)) != 0;
COUNT_GWT = getConstant(Constants.GC_COUNT_GWT) != 0;
+
//sun.reflect.Reflection.registerMethodsToFilter(MethodHandleImpl.class, "init");
}
@@ -162,6 +163,7 @@
MN_IS_CONSTRUCTOR = 0x00020000, // constructor
MN_IS_FIELD = 0x00040000, // field
MN_IS_TYPE = 0x00080000, // nested type
+ MN_CALLER_SENSITIVE = 0x00100000, // @CallerSensitive annotation detected
MN_SEARCH_SUPERCLASSES = 0x00100000, // for MHN.getMembers
MN_SEARCH_INTERFACES = 0x00200000, // for MHN.getMembers
VM_INDEX_UNINITIALIZED = -99;
@@ -402,40 +404,33 @@
return true;
}
+
/**
* Is this method a caller-sensitive method?
* I.e., does it call Reflection.getCallerClass or a similer method
* to ask about the identity of its caller?
*/
- // FIXME: Replace this pattern match by an annotation @sun.reflect.CallerSensitive.
static boolean isCallerSensitive(MemberName mem) {
- if (!mem.isInvocable()) return false; // fields are not caller sensitive
- Class<?> defc = mem.getDeclaringClass();
- switch (mem.getName()) {
+ if (!mem.isMethod()) return false; // only methods are caller sensitive
+
+ // when the VM support is available, call mem.isCallerSensitive() instead
+ return isCallerSensitiveMethod(mem.getDeclaringClass(), mem.getName()) ||
+ canBeCalledVirtual(mem);
+ }
+
+ // this method is also called by test/sun/reflect/CallerSensitiveFinder
+ // to validate the hand-maintained list
+ private static boolean isCallerSensitiveMethod(Class<?> defc, String method) {
+ switch (method) {
case "doPrivileged":
case "doPrivilegedWithCombiner":
return defc == java.security.AccessController.class;
case "checkMemberAccess":
- return canBeCalledVirtual(mem, java.lang.SecurityManager.class);
+ return defc == java.lang.SecurityManager.class;
case "getUnsafe":
return defc == sun.misc.Unsafe.class;
case "lookup":
return defc == java.lang.invoke.MethodHandles.class;
- case "findStatic":
- case "findVirtual":
- case "findConstructor":
- case "findSpecial":
- case "findGetter":
- case "findSetter":
- case "findStaticGetter":
- case "findStaticSetter":
- case "bind":
- case "unreflect":
- case "unreflectSpecial":
- case "unreflectConstructor":
- case "unreflectGetter":
- case "unreflectSetter":
- return defc == java.lang.invoke.MethodHandles.Lookup.class;
case "invoke":
return defc == java.lang.reflect.Method.class;
case "get":
@@ -461,10 +456,12 @@
if (defc == java.lang.reflect.Constructor.class) return true;
if (defc == java.lang.Class.class) return true;
break;
+ case "getFields":
+ return defc == java.lang.Class.class ||
+ defc == javax.sql.rowset.serial.SerialJavaObject.class;
case "forName":
case "getClassLoader":
case "getClasses":
- case "getFields":
case "getMethods":
case "getConstructors":
case "getDeclaredClasses":
@@ -486,13 +483,14 @@
case "getDrivers":
case "deregisterDriver":
return defc == java.sql.DriverManager.class;
+
case "newUpdater":
if (defc == java.util.concurrent.atomic.AtomicIntegerFieldUpdater.class) return true;
if (defc == java.util.concurrent.atomic.AtomicLongFieldUpdater.class) return true;
if (defc == java.util.concurrent.atomic.AtomicReferenceFieldUpdater.class) return true;
break;
case "getContextClassLoader":
- return canBeCalledVirtual(mem, java.lang.Thread.class);
+ return defc == java.lang.Thread.class;
case "getPackage":
case "getPackages":
return defc == java.lang.Package.class;
@@ -511,7 +509,7 @@
case "getCallerClassLoader":
return defc == java.lang.ClassLoader.class;
case "registerAsParallelCapable":
- return canBeCalledVirtual(mem, java.lang.ClassLoader.class);
+ return defc == java.lang.ClassLoader.class;
case "getProxyClass":
case "newProxyInstance":
return defc == java.lang.reflect.Proxy.class;
@@ -524,9 +522,24 @@
return defc == java.io.ObjectStreamField.class;
case "forClass":
return defc == java.io.ObjectStreamClass.class;
+ case "getLogger":
+ return defc == java.util.logging.Logger.class;
}
return false;
}
+
+ private static boolean canBeCalledVirtual(MemberName mem) {
+ assert(mem.isInvocable());
+ Class<?> defc = mem.getDeclaringClass();
+ switch (mem.getName()) {
+ case "checkMemberAccess":
+ return canBeCalledVirtual(mem, java.lang.SecurityManager.class);
+ case "getContextClassLoader":
+ return canBeCalledVirtual(mem, java.lang.Thread.class);
+ }
+ return false;
+ }
+
static boolean canBeCalledVirtual(MemberName symbolicRef, Class<?> definingClass) {
Class<?> symbolicRefClass = symbolicRef.getDeclaringClass();
if (symbolicRefClass == definingClass) return true;
diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandleProxies.java b/jdk/src/share/classes/java/lang/invoke/MethodHandleProxies.java
index a2be5d8..cca7b85 100644
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandleProxies.java
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleProxies.java
@@ -31,6 +31,7 @@
import sun.invoke.WrapperInstance;
import java.util.ArrayList;
import sun.reflect.Reflection;
+import sun.reflect.CallerSensitive;
import sun.reflect.misc.ReflectUtil;
/**
@@ -137,14 +138,14 @@
// entry points, must be covered by hand-written or automatically
// generated adapter classes.
//
+ @CallerSensitive
public static
<T> T asInterfaceInstance(final Class<T> intfc, final MethodHandle target) {
if (!intfc.isInterface() || !Modifier.isPublic(intfc.getModifiers()))
throw new IllegalArgumentException("not a public interface: "+intfc.getName());
final MethodHandle mh;
if (System.getSecurityManager() != null) {
- final int CALLER_FRAME = 2; // 0: Reflection, 1: asInterfaceInstance, 2: caller
- final Class<?> caller = Reflection.getCallerClass(CALLER_FRAME);
+ final Class<?> caller = Reflection.getCallerClass();
final ClassLoader ccl = (caller != null) ? caller.getClassLoader() : null;
ReflectUtil.checkProxyPackageAccess(ccl, intfc);
mh = maybeBindCaller(target, caller);
diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandles.java b/jdk/src/share/classes/java/lang/invoke/MethodHandles.java
index ee2a287..0da73e4 100644
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandles.java
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandles.java
@@ -26,16 +26,19 @@
package java.lang.invoke;
import java.lang.reflect.*;
-import sun.invoke.WrapperInstance;
import sun.invoke.util.ValueConversions;
import sun.invoke.util.VerifyAccess;
import sun.invoke.util.Wrapper;
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
+import sun.reflect.CallerSensitive;
import sun.reflect.Reflection;
+import sun.reflect.misc.ReflectUtil;
+
import static java.lang.invoke.MethodHandleStatics.*;
import static java.lang.invoke.MethodHandleNatives.Constants.*;
+import sun.security.util.SecurityConstants;
/**
* This class consists exclusively of static methods that operate on or return
@@ -66,8 +69,9 @@
* This lookup object is a <em>capability</em> which may be delegated to trusted agents.
* Do not store it in place where untrusted code can access it.
*/
+ @CallerSensitive
public static Lookup lookup() {
- return new Lookup();
+ return new Lookup(Reflection.getCallerClass());
}
/**
@@ -406,14 +410,9 @@
* Also, don't make it private, lest javac interpose
* an access$N method.
*/
- Lookup() {
- this(getCallerClassAtEntryPoint(false), ALL_MODES);
- // make sure we haven't accidentally picked up a privileged class:
- checkUnprivilegedlookupClass(lookupClass);
- }
-
Lookup(Class<?> lookupClass) {
this(lookupClass, ALL_MODES);
+ checkUnprivilegedlookupClass(lookupClass);
}
private Lookup(Class<?> lookupClass, int allowedModes) {
@@ -540,20 +539,6 @@
}
}
- /* Obtain the external caller class, when called from Lookup.<init> or a first-level subroutine. */
- private static Class<?> getCallerClassAtEntryPoint(boolean inSubroutine) {
- final int CALLER_DEPTH = 4;
- // Stack for the constructor entry point (inSubroutine=false):
- // 0: Reflection.getCC, 1: getCallerClassAtEntryPoint,
- // 2: Lookup.<init>, 3: MethodHandles.*, 4: caller
- // The stack is slightly different for a subroutine of a Lookup.find* method:
- // 2: Lookup.*, 3: Lookup.find*.*, 4: caller
- // Note: This should be the only use of getCallerClass in this file.
- assert(Reflection.getCallerClass(CALLER_DEPTH-2) == Lookup.class);
- assert(Reflection.getCallerClass(CALLER_DEPTH-1) == (inSubroutine ? Lookup.class : MethodHandles.class));
- return Reflection.getCallerClass(CALLER_DEPTH);
- }
-
/**
* Produces a method handle for a static method.
* The type of the method handle will be that of the method.
@@ -583,9 +568,8 @@
public
MethodHandle findStatic(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
MemberName method = resolveOrFail(refc, name, type, true);
- checkSecurityManager(refc, method); // stack walk magic: do not refactor
- Class<?> callerClass = findBoundCallerClass(method); // stack walk magic: do not refactor
- return accessStatic(refc, method, callerClass);
+ checkSecurityManager(refc, method);
+ return accessStatic(refc, method, findBoundCallerClass(method));
}
private
MethodHandle accessStatic(Class<?> refc, MemberName method, Class<?> callerClass) throws IllegalAccessException {
@@ -640,9 +624,8 @@
*/
public MethodHandle findVirtual(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
MemberName method = resolveOrFail(refc, name, type, false);
- checkSecurityManager(refc, method); // stack walk magic: do not refactor
- Class<?> callerClass = findBoundCallerClass(method); // stack walk magic: do not refactor
- return accessVirtual(refc, method, callerClass);
+ checkSecurityManager(refc, method);
+ return accessVirtual(refc, method, findBoundCallerClass(method));
}
private MethodHandle resolveVirtual(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
MemberName method = resolveOrFail(refc, name, type, false);
@@ -684,7 +667,7 @@
public MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException {
String name = "<init>";
MemberName ctor = resolveOrFail(refc, name, type, false, false, lookupClassOrNull());
- checkSecurityManager(refc, ctor); // stack walk magic: do not refactor
+ checkSecurityManager(refc, ctor);
return accessConstructor(refc, ctor);
}
private MethodHandle accessConstructor(Class<?> refc, MemberName ctor) throws IllegalAccessException {
@@ -754,9 +737,8 @@
Class<?> specialCaller) throws NoSuchMethodException, IllegalAccessException {
checkSpecialCaller(specialCaller);
MemberName method = resolveOrFail(refc, name, type, false, false, specialCaller);
- checkSecurityManager(refc, method); // stack walk magic: do not refactor
- Class<?> callerClass = findBoundCallerClass(method); // stack walk magic: do not refactor
- return accessSpecial(refc, method, callerClass, specialCaller);
+ checkSecurityManager(refc, method);
+ return accessSpecial(refc, method, findBoundCallerClass(method), specialCaller);
}
private MethodHandle accessSpecial(Class<?> refc, MemberName method,
Class<?> callerClass,
@@ -815,7 +797,7 @@
*/
public MethodHandle findGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
MemberName field = resolveOrFail(refc, name, type, false);
- checkSecurityManager(refc, field); // stack walk magic: do not refactor
+ checkSecurityManager(refc, field);
return makeAccessor(refc, field, false, false, 0);
}
private MethodHandle resolveGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
@@ -842,7 +824,7 @@
*/
public MethodHandle findSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
MemberName field = resolveOrFail(refc, name, type, false);
- checkSecurityManager(refc, field); // stack walk magic: do not refactor
+ checkSecurityManager(refc, field);
return makeAccessor(refc, field, false, true, 0);
}
private MethodHandle resolveSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
@@ -868,7 +850,7 @@
*/
public MethodHandle findStaticGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
MemberName field = resolveOrFail(refc, name, type, true);
- checkSecurityManager(refc, field); // stack walk magic: do not refactor
+ checkSecurityManager(refc, field);
return makeAccessor(refc, field, false, false, 1);
}
private MethodHandle resolveStaticGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
@@ -894,7 +876,7 @@
*/
public MethodHandle findStaticSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
MemberName field = resolveOrFail(refc, name, type, true);
- checkSecurityManager(refc, field); // stack walk magic: do not refactor
+ checkSecurityManager(refc, field);
return makeAccessor(refc, field, false, true, 1);
}
private MethodHandle resolveStaticSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
@@ -951,11 +933,10 @@
public MethodHandle bind(Object receiver, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
Class<? extends Object> refc = receiver.getClass(); // may get NPE
MemberName method = resolveOrFail(refc, name, type, false);
- checkSecurityManager(refc, method); // stack walk magic: do not refactor
+ checkSecurityManager(refc, method);
checkMethod(refc, method, false);
MethodHandle dmh = MethodHandleImpl.findMethod(method, true, lookupClassOrNull());
- Class<?> callerClass = findBoundCallerClass(method); // stack walk magic: do not refactor
- MethodHandle bcmh = maybeBindCaller(method, dmh, callerClass);
+ MethodHandle bcmh = maybeBindCaller(method, dmh, findBoundCallerClass(method));
if (bcmh != dmh) return fixVarargs(bcmh.bindTo(receiver), dmh);
MethodHandle bmh = MethodHandleImpl.bindReceiver(dmh, receiver);
if (bmh == null)
@@ -991,8 +972,7 @@
return MethodHandleImpl.findMethod(method, true, /*no lookupClass*/ null);
checkMethod(method.getDeclaringClass(), method, method.isStatic());
MethodHandle mh = MethodHandleImpl.findMethod(method, true, lookupClassOrNull());
- Class<?> callerClass = findBoundCallerClass(method); // stack walk magic: do not refactor
- mh = maybeBindCaller(method, mh, callerClass);
+ mh = maybeBindCaller(method, mh, findBoundCallerClass(method));
return restrictProtectedReceiver(method, mh);
}
@@ -1024,8 +1004,7 @@
// ignore m.isAccessible: this is a new kind of access
checkMethod(m.getDeclaringClass(), method, false);
MethodHandle mh = MethodHandleImpl.findMethod(method, false, lookupClassOrNull());
- Class<?> callerClass = findBoundCallerClass(method); // stack walk magic: do not refactor
- mh = maybeBindCaller(method, mh, callerClass);
+ mh = maybeBindCaller(method, mh, findBoundCallerClass(method));
return restrictReceiver(method, mh, specialCaller);
}
@@ -1137,69 +1116,93 @@
/**
* Find my trustable caller class if m is a caller sensitive method.
* If this lookup object has private access, then the caller class is the lookupClass.
- * Otherwise, it is the caller of the currently executing public API method (e.g., findVirtual).
- * This is the same caller class as is used by checkSecurityManager.
- * This function performs stack walk magic: do not refactor it.
+ * Otherwise, if m is caller-sensitive, throw IllegalAccessException.
*/
- Class<?> findBoundCallerClass(MemberName m) {
+ Class<?> findBoundCallerClass(MemberName m) throws IllegalAccessException {
Class<?> callerClass = null;
if (MethodHandleNatives.isCallerSensitive(m)) {
- // Do not refactor this to a more "logical" place, since it is stack walk magic.
- // Note that this is the same expression as in Step 2 below in checkSecurityManager.
- callerClass = ((allowedModes & PRIVATE) != 0
- ? lookupClass // for strong access modes, no extra check
- // next line does stack walk magic; do not refactor:
- : getCallerClassAtEntryPoint(true));
+ // Only full-power lookup is allowed to resolve caller-sensitive methods
+ if (isFullPowerLookup()) {
+ callerClass = lookupClass;
+ } else {
+ throw new IllegalAccessException("Attempt to lookup caller-sensitive method using restricted lookup object");
+ }
}
return callerClass;
}
+
+ private boolean isFullPowerLookup() {
+ return (allowedModes & PRIVATE) != 0;
+ }
+
+ /**
+ * Determine whether a security manager has an overridden
+ * SecurityManager.checkMemberAccess method.
+ */
+ private boolean isCheckMemberAccessOverridden(SecurityManager sm) {
+ final Class<? extends SecurityManager> cls = sm.getClass();
+ if (cls == SecurityManager.class) return false;
+
+ try {
+ return cls.getMethod("checkMemberAccess", Class.class, int.class).
+ getDeclaringClass() != SecurityManager.class;
+ } catch (NoSuchMethodException e) {
+ throw new InternalError("should not reach here");
+ }
+ }
+
/**
* Perform necessary <a href="MethodHandles.Lookup.html#secmgr">access checks</a>.
- * Determines a trustable caller class to compare with refc, the symbolic reference class.
- * If this lookup object has private access, then the caller class is the lookupClass.
- * Otherwise, it is the caller of the currently executing public API method (e.g., findVirtual).
* This function performs stack walk magic: do not refactor it.
*/
void checkSecurityManager(Class<?> refc, MemberName m) {
SecurityManager smgr = System.getSecurityManager();
if (smgr == null) return;
if (allowedModes == TRUSTED) return;
+
+ final boolean overridden = isCheckMemberAccessOverridden(smgr);
// Step 1:
- smgr.checkMemberAccess(refc, Member.PUBLIC);
+ {
+ // Default policy is to allow Member.PUBLIC; no need to check
+ // permission if SecurityManager is the default implementation
+ final int which = Member.PUBLIC;
+ final Class<?> clazz = refc;
+ if (overridden) {
+ // Don't refactor; otherwise break the stack depth for
+ // checkMemberAccess of subclasses of SecurityManager as specified.
+ smgr.checkMemberAccess(clazz, which);
+ }
+ }
+
// Step 2:
- Class<?> callerClass = ((allowedModes & PRIVATE) != 0
- ? lookupClass // for strong access modes, no extra check
- // next line does stack walk magic; do not refactor:
- : getCallerClassAtEntryPoint(true));
- if (!VerifyAccess.classLoaderIsAncestor(lookupClass, refc) ||
- (callerClass != lookupClass &&
- !VerifyAccess.classLoaderIsAncestor(callerClass, refc)))
- smgr.checkPackageAccess(VerifyAccess.getPackageName(refc));
+ if (!isFullPowerLookup() ||
+ !VerifyAccess.classLoaderIsAncestor(lookupClass, refc)) {
+ ReflectUtil.checkPackageAccess(refc);
+ }
+
// Step 3:
if (m.isPublic()) return;
Class<?> defc = m.getDeclaringClass();
- smgr.checkMemberAccess(defc, Member.DECLARED); // STACK WALK HERE
- // Step 4:
- if (defc != refc)
- smgr.checkPackageAccess(VerifyAccess.getPackageName(defc));
+ {
+ // Inline SecurityManager.checkMemberAccess
+ final int which = Member.DECLARED;
+ final Class<?> clazz = defc;
+ if (!overridden) {
+ if (!isFullPowerLookup() ||
+ (lookupClass.getClassLoader() != defc.getClassLoader())) {
+ smgr.checkPermission(SecurityConstants.CHECK_MEMBER_ACCESS_PERMISSION);
+ }
+ } else {
+ // Don't refactor; otherwise break the stack depth for
+ // checkMemberAccess of subclasses of SecurityManager as specified.
+ smgr.checkMemberAccess(clazz, which);
+ }
+ }
- // Comment from SM.checkMemberAccess, where which=DECLARED:
- /*
- * stack depth of 4 should be the caller of one of the
- * methods in java.lang.Class that invoke checkMember
- * access. The stack should look like:
- *
- * someCaller [3]
- * java.lang.Class.someReflectionAPI [2]
- * java.lang.Class.checkMemberAccess [1]
- * SecurityManager.checkMemberAccess [0]
- *
- */
- // For us it is this stack:
- // someCaller [3]
- // Lookup.findSomeMember [2]
- // Lookup.checkSecurityManager [1]
- // SecurityManager.checkMemberAccess [0]
+ // Step 4:
+ if (defc != refc) {
+ ReflectUtil.checkPackageAccess(defc);
+ }
}
void checkMethod(Class<?> refc, MemberName m, boolean wantStatic) throws IllegalAccessException {
diff --git a/jdk/src/share/classes/java/lang/reflect/Constructor.java b/jdk/src/share/classes/java/lang/reflect/Constructor.java
index 8ff6d41..fa7f464 100644
--- a/jdk/src/share/classes/java/lang/reflect/Constructor.java
+++ b/jdk/src/share/classes/java/lang/reflect/Constructor.java
@@ -25,6 +25,7 @@
package java.lang.reflect;
+import sun.reflect.CallerSensitive;
import sun.reflect.ConstructorAccessor;
import sun.reflect.Reflection;
import sun.reflect.generics.repository.ConstructorRepository;
@@ -505,14 +506,14 @@
* @exception ExceptionInInitializerError if the initialization provoked
* by this method fails.
*/
+ @CallerSensitive
public T newInstance(Object ... initargs)
throws InstantiationException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException
{
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
- Class<?> caller = Reflection.getCallerClass(2);
-
+ Class<?> caller = Reflection.getCallerClass();
checkAccess(caller, clazz, null, modifiers);
}
}
diff --git a/jdk/src/share/classes/java/lang/reflect/Field.java b/jdk/src/share/classes/java/lang/reflect/Field.java
index 1e6441a..8a9b0a8 100644
--- a/jdk/src/share/classes/java/lang/reflect/Field.java
+++ b/jdk/src/share/classes/java/lang/reflect/Field.java
@@ -25,6 +25,7 @@
package java.lang.reflect;
+import sun.reflect.CallerSensitive;
import sun.reflect.FieldAccessor;
import sun.reflect.Reflection;
import sun.reflect.generics.repository.FieldRepository;
@@ -366,9 +367,15 @@
* @exception ExceptionInInitializerError if the initialization provoked
* by this method fails.
*/
+ @CallerSensitive
public Object get(Object obj)
throws IllegalArgumentException, IllegalAccessException
{
+ if (!override) {
+ if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
+ checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
+ }
+ }
return getFieldAccessor(obj).get(obj);
}
@@ -394,9 +401,15 @@
* by this method fails.
* @see Field#get
*/
+ @CallerSensitive
public boolean getBoolean(Object obj)
throws IllegalArgumentException, IllegalAccessException
{
+ if (!override) {
+ if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
+ checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
+ }
+ }
return getFieldAccessor(obj).getBoolean(obj);
}
@@ -422,9 +435,15 @@
* by this method fails.
* @see Field#get
*/
+ @CallerSensitive
public byte getByte(Object obj)
throws IllegalArgumentException, IllegalAccessException
{
+ if (!override) {
+ if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
+ checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
+ }
+ }
return getFieldAccessor(obj).getByte(obj);
}
@@ -452,9 +471,15 @@
* by this method fails.
* @see Field#get
*/
+ @CallerSensitive
public char getChar(Object obj)
throws IllegalArgumentException, IllegalAccessException
{
+ if (!override) {
+ if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
+ checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
+ }
+ }
return getFieldAccessor(obj).getChar(obj);
}
@@ -482,9 +507,15 @@
* by this method fails.
* @see Field#get
*/
+ @CallerSensitive
public short getShort(Object obj)
throws IllegalArgumentException, IllegalAccessException
{
+ if (!override) {
+ if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
+ checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
+ }
+ }
return getFieldAccessor(obj).getShort(obj);
}
@@ -512,9 +543,15 @@
* by this method fails.
* @see Field#get
*/
+ @CallerSensitive
public int getInt(Object obj)
throws IllegalArgumentException, IllegalAccessException
{
+ if (!override) {
+ if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
+ checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
+ }
+ }
return getFieldAccessor(obj).getInt(obj);
}
@@ -542,9 +579,15 @@
* by this method fails.
* @see Field#get
*/
+ @CallerSensitive
public long getLong(Object obj)
throws IllegalArgumentException, IllegalAccessException
{
+ if (!override) {
+ if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
+ checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
+ }
+ }
return getFieldAccessor(obj).getLong(obj);
}
@@ -572,9 +615,15 @@
* by this method fails.
* @see Field#get
*/
+ @CallerSensitive
public float getFloat(Object obj)
throws IllegalArgumentException, IllegalAccessException
{
+ if (!override) {
+ if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
+ checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
+ }
+ }
return getFieldAccessor(obj).getFloat(obj);
}
@@ -602,9 +651,15 @@
* by this method fails.
* @see Field#get
*/
+ @CallerSensitive
public double getDouble(Object obj)
throws IllegalArgumentException, IllegalAccessException
{
+ if (!override) {
+ if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
+ checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
+ }
+ }
return getFieldAccessor(obj).getDouble(obj);
}
@@ -674,9 +729,15 @@
* @exception ExceptionInInitializerError if the initialization provoked
* by this method fails.
*/
+ @CallerSensitive
public void set(Object obj, Object value)
throws IllegalArgumentException, IllegalAccessException
{
+ if (!override) {
+ if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
+ checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
+ }
+ }
getFieldAccessor(obj).set(obj, value);
}
@@ -704,9 +765,15 @@
* by this method fails.
* @see Field#set
*/
+ @CallerSensitive
public void setBoolean(Object obj, boolean z)
throws IllegalArgumentException, IllegalAccessException
{
+ if (!override) {
+ if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
+ checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
+ }
+ }
getFieldAccessor(obj).setBoolean(obj, z);
}
@@ -734,9 +801,15 @@
* by this method fails.
* @see Field#set
*/
+ @CallerSensitive
public void setByte(Object obj, byte b)
throws IllegalArgumentException, IllegalAccessException
{
+ if (!override) {
+ if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
+ checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
+ }
+ }
getFieldAccessor(obj).setByte(obj, b);
}
@@ -764,9 +837,15 @@
* by this method fails.
* @see Field#set
*/
+ @CallerSensitive
public void setChar(Object obj, char c)
throws IllegalArgumentException, IllegalAccessException
{
+ if (!override) {
+ if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
+ checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
+ }
+ }
getFieldAccessor(obj).setChar(obj, c);
}
@@ -794,9 +873,15 @@
* by this method fails.
* @see Field#set
*/
+ @CallerSensitive
public void setShort(Object obj, short s)
throws IllegalArgumentException, IllegalAccessException
{
+ if (!override) {
+ if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
+ checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
+ }
+ }
getFieldAccessor(obj).setShort(obj, s);
}
@@ -824,9 +909,15 @@
* by this method fails.
* @see Field#set
*/
+ @CallerSensitive
public void setInt(Object obj, int i)
throws IllegalArgumentException, IllegalAccessException
{
+ if (!override) {
+ if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
+ checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
+ }
+ }
getFieldAccessor(obj).setInt(obj, i);
}
@@ -854,9 +945,15 @@
* by this method fails.
* @see Field#set
*/
+ @CallerSensitive
public void setLong(Object obj, long l)
throws IllegalArgumentException, IllegalAccessException
{
+ if (!override) {
+ if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
+ checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
+ }
+ }
getFieldAccessor(obj).setLong(obj, l);
}
@@ -884,9 +981,15 @@
* by this method fails.
* @see Field#set
*/
+ @CallerSensitive
public void setFloat(Object obj, float f)
throws IllegalArgumentException, IllegalAccessException
{
+ if (!override) {
+ if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
+ checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
+ }
+ }
getFieldAccessor(obj).setFloat(obj, f);
}
@@ -914,20 +1017,25 @@
* by this method fails.
* @see Field#set
*/
+ @CallerSensitive
public void setDouble(Object obj, double d)
throws IllegalArgumentException, IllegalAccessException
{
+ if (!override) {
+ if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
+ checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
+ }
+ }
getFieldAccessor(obj).setDouble(obj, d);
}
- // Convenience routine which performs security checks
+ // security check is done before calling this method
private FieldAccessor getFieldAccessor(Object obj)
throws IllegalAccessException
{
- doSecurityCheck(obj);
boolean ov = override;
- FieldAccessor a = (ov)? overrideFieldAccessor : fieldAccessor;
- return (a != null)? a : acquireFieldAccessor(ov);
+ FieldAccessor a = (ov) ? overrideFieldAccessor : fieldAccessor;
+ return (a != null) ? a : acquireFieldAccessor(ov);
}
// NOTE that there is no synchronization used here. It is correct
@@ -972,19 +1080,6 @@
}
}
- // NOTE: be very careful if you change the stack depth of this
- // routine. The depth of the "getCallerClass" call is hardwired so
- // that the compiler can have an easier time if this gets inlined.
- private void doSecurityCheck(Object obj) throws IllegalAccessException {
- if (!override) {
- if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
- Class<?> caller = Reflection.getCallerClass(4);
-
- checkAccess(caller, clazz, obj, modifiers);
- }
- }
- }
-
/*
* Utility routine to paper over array type names
*/
diff --git a/jdk/src/share/classes/java/lang/reflect/Method.java b/jdk/src/share/classes/java/lang/reflect/Method.java
index 0a1f7a3..60377f9 100644
--- a/jdk/src/share/classes/java/lang/reflect/Method.java
+++ b/jdk/src/share/classes/java/lang/reflect/Method.java
@@ -25,6 +25,7 @@
package java.lang.reflect;
+import sun.reflect.CallerSensitive;
import sun.reflect.MethodAccessor;
import sun.reflect.Reflection;
import sun.reflect.generics.repository.MethodRepository;
@@ -583,14 +584,18 @@
* @exception ExceptionInInitializerError if the initialization
* provoked by this method fails.
*/
+ @CallerSensitive
public Object invoke(Object obj, Object... args)
throws IllegalAccessException, IllegalArgumentException,
InvocationTargetException
{
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
- Class<?> caller = Reflection.getCallerClass(1);
-
+ // Until there is hotspot @CallerSensitive support
+ // can't call Reflection.getCallerClass() here
+ // Workaround for now: add a frame getCallerClass to
+ // make the caller at stack depth 2
+ Class<?> caller = getCallerClass();
checkAccess(caller, clazz, obj, modifiers);
}
}
@@ -601,6 +606,16 @@
return ma.invoke(obj, args);
}
+ /*
+ * This method makes the frame count to be 2 to find the caller
+ */
+ @CallerSensitive
+ private Class<?> getCallerClass() {
+ // Reflection.getCallerClass() currently returns the frame at depth 2
+ // before the hotspot support is in.
+ return Reflection.getCallerClass();
+ }
+
/**
* Returns {@code true} if this method is a bridge
* method; returns {@code false} otherwise.
diff --git a/jdk/src/share/classes/java/lang/reflect/Proxy.java b/jdk/src/share/classes/java/lang/reflect/Proxy.java
index 86ef604..26cfed0 100644
--- a/jdk/src/share/classes/java/lang/reflect/Proxy.java
+++ b/jdk/src/share/classes/java/lang/reflect/Proxy.java
@@ -39,6 +39,7 @@
import java.util.List;
import java.util.WeakHashMap;
import sun.misc.ProxyGenerator;
+import sun.reflect.CallerSensitive;
import sun.reflect.Reflection;
import sun.reflect.misc.ReflectUtil;
import sun.security.util.SecurityConstants;
@@ -302,13 +303,11 @@
return false;
}
- if (proxyClass.getName().startsWith(ReflectUtil.PROXY_PACKAGE + ".")) {
- // all proxy interfaces are public
- return false;
- }
- for (Class<?> intf : proxyClass.getInterfaces()) {
- if (!Modifier.isPublic(intf.getModifiers())) {
- return true;
+ if (ReflectUtil.isNonPublicProxyClass(proxyClass)) {
+ for (Class<?> intf : proxyClass.getInterfaces()) {
+ if (!Modifier.isPublic(intf.getModifiers())) {
+ return true;
+ }
}
}
return false;
@@ -408,28 +407,21 @@
* @throws NullPointerException if the {@code interfaces} array
* argument or any of its elements are {@code null}
*/
+ @CallerSensitive
public static Class<?> getProxyClass(ClassLoader loader,
Class<?>... interfaces)
throws IllegalArgumentException
{
- return getProxyClass0(loader, interfaces); // stack walk magic: do not refactor
- }
-
- private static void checkProxyLoader(ClassLoader ccl,
- ClassLoader loader)
- {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
- if (loader == null && ccl != null) {
- if (!ProxyAccessHelper.allowNullLoader) {
- sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
- }
- }
+ checkProxyAccess(Reflection.getCallerClass(), loader, interfaces);
}
+
+ return getProxyClass0(loader, interfaces);
}
/*
- * Generate a proxy class (caller-sensitive).
+ * Check permissions required to create a Proxy class.
*
* To define a proxy class, it performs the access checks as in
* Class.forName (VM will invoke ClassLoader.checkPackageAccess):
@@ -446,17 +438,28 @@
* will throw IllegalAccessError when the generated proxy class is
* being defined via the defineClass0 method.
*/
- private static Class<?> getProxyClass0(ClassLoader loader,
- Class<?>... interfaces) {
+ private static void checkProxyAccess(Class<?> caller,
+ ClassLoader loader,
+ Class<?>... interfaces)
+ {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
- final int CALLER_FRAME = 3; // 0: Reflection, 1: getProxyClass0 2: Proxy 3: caller
- final Class<?> caller = Reflection.getCallerClass(CALLER_FRAME);
- final ClassLoader ccl = caller.getClassLoader();
- checkProxyLoader(ccl, loader);
+ ClassLoader ccl = caller.getClassLoader();
+ if (loader == null && ccl != null) {
+ if (!ProxyAccessHelper.allowNullLoader) {
+ sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
+ }
+ }
ReflectUtil.checkProxyPackageAccess(ccl, interfaces);
}
+ }
+ /**
+ * Generate a proxy class. Must call the checkProxyAccess method
+ * to perform permission checks before calling this.
+ */
+ private static Class<?> getProxyClass0(ClassLoader loader,
+ Class<?>... interfaces) {
if (interfaces.length > 65535) {
throw new IllegalArgumentException("interface limit exceeded");
}
@@ -698,6 +701,7 @@
* if the invocation handler, {@code h}, is
* {@code null}
*/
+ @CallerSensitive
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
@@ -707,10 +711,15 @@
throw new NullPointerException();
}
+ final SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ checkProxyAccess(Reflection.getCallerClass(), loader, interfaces);
+ }
+
/*
* Look up or generate the designated proxy class.
*/
- Class<?> cl = getProxyClass0(loader, interfaces); // stack walk magic: do not refactor
+ Class<?> cl = getProxyClass0(loader, interfaces);
/*
* Invoke its constructor with the designated invocation handler.
@@ -718,7 +727,6 @@
try {
final Constructor<?> cons = cl.getConstructor(constructorParams);
final InvocationHandler ih = h;
- SecurityManager sm = System.getSecurityManager();
if (sm != null && ProxyAccessHelper.needsNewInstanceCheck(cl)) {
// create proxy instance with doPrivilege as the proxy class may
// implement non-public interfaces that requires a special permission
diff --git a/jdk/src/share/classes/java/security/AccessController.java b/jdk/src/share/classes/java/security/AccessController.java
index 225df95..1188c74 100644
--- a/jdk/src/share/classes/java/security/AccessController.java
+++ b/jdk/src/share/classes/java/security/AccessController.java
@@ -26,6 +26,8 @@
package java.security;
import sun.security.util.Debug;
+import sun.reflect.CallerSensitive;
+import sun.reflect.Reflection;
/**
* <p> The AccessController class is used for access control operations
@@ -264,6 +266,7 @@
* @see java.security.DomainCombiner
*/
+ @CallerSensitive
public static native <T> T doPrivileged(PrivilegedAction<T> action);
/**
@@ -288,14 +291,14 @@
*
* @since 1.6
*/
+ @CallerSensitive
public static <T> T doPrivilegedWithCombiner(PrivilegedAction<T> action) {
-
AccessControlContext acc = getStackAccessControlContext();
if (acc == null) {
return AccessController.doPrivileged(action);
}
DomainCombiner dc = acc.getAssignedCombiner();
- return AccessController.doPrivileged(action, preserveCombiner(dc));
+ return AccessController.doPrivileged(action, preserveCombiner(dc, Reflection.getCallerClass()));
}
@@ -326,6 +329,7 @@
* @see #doPrivileged(PrivilegedAction)
* @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext)
*/
+ @CallerSensitive
public static native <T> T doPrivileged(PrivilegedAction<T> action,
AccessControlContext context);
@@ -353,6 +357,7 @@
* @see #doPrivilegedWithCombiner(PrivilegedExceptionAction)
* @see java.security.DomainCombiner
*/
+ @CallerSensitive
public static native <T> T
doPrivileged(PrivilegedExceptionAction<T> action)
throws PrivilegedActionException;
@@ -383,6 +388,7 @@
*
* @since 1.6
*/
+ @CallerSensitive
public static <T> T doPrivilegedWithCombiner
(PrivilegedExceptionAction<T> action) throws PrivilegedActionException {
@@ -391,26 +397,18 @@
return AccessController.doPrivileged(action);
}
DomainCombiner dc = acc.getAssignedCombiner();
- return AccessController.doPrivileged(action, preserveCombiner(dc));
+ return AccessController.doPrivileged(action, preserveCombiner(dc, Reflection.getCallerClass()));
}
/**
* preserve the combiner across the doPrivileged call
*/
- private static AccessControlContext preserveCombiner
- (DomainCombiner combiner) {
-
- /**
- * callerClass[0] = Reflection.getCallerClass
- * callerClass[1] = AccessController.preserveCombiner
- * callerClass[2] = AccessController.doPrivileged
- * callerClass[3] = caller
- */
- final Class callerClass = sun.reflect.Reflection.getCallerClass(3);
+ private static AccessControlContext preserveCombiner(DomainCombiner combiner,
+ final Class<?> caller) {
ProtectionDomain callerPd = doPrivileged
(new PrivilegedAction<ProtectionDomain>() {
public ProtectionDomain run() {
- return callerClass.getProtectionDomain();
+ return caller.getProtectionDomain();
}
});
@@ -455,6 +453,7 @@
* @see #doPrivileged(PrivilegedAction)
* @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext)
*/
+ @CallerSensitive
public static native <T> T
doPrivileged(PrivilegedExceptionAction<T> action,
AccessControlContext context)
diff --git a/jdk/src/share/classes/java/sql/DriverManager.java b/jdk/src/share/classes/java/sql/DriverManager.java
index 9b1d460..8698345 100644
--- a/jdk/src/share/classes/java/sql/DriverManager.java
+++ b/jdk/src/share/classes/java/sql/DriverManager.java
@@ -30,7 +30,8 @@
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.concurrent.CopyOnWriteArrayList;
-
+import sun.reflect.CallerSensitive;
+import sun.reflect.Reflection;
/**
* <P>The basic service for managing a set of JDBC drivers.<br>
@@ -180,14 +181,10 @@
* @return a Connection to the URL
* @exception SQLException if a database access error occurs
*/
+ @CallerSensitive
public static Connection getConnection(String url,
java.util.Properties info) throws SQLException {
-
- // Gets the classloader of the code that called this method, may
- // be null.
- ClassLoader callerCL = DriverManager.getCallerClassLoader();
-
- return (getConnection(url, info, callerCL));
+ return (getConnection(url, info, Reflection.getCallerClass()));
}
/**
@@ -203,14 +200,11 @@
* @return a connection to the URL
* @exception SQLException if a database access error occurs
*/
+ @CallerSensitive
public static Connection getConnection(String url,
String user, String password) throws SQLException {
java.util.Properties info = new java.util.Properties();
- // Gets the classloader of the code that called this method, may
- // be null.
- ClassLoader callerCL = DriverManager.getCallerClassLoader();
-
if (user != null) {
info.put("user", user);
}
@@ -218,7 +212,7 @@
info.put("password", password);
}
- return (getConnection(url, info, callerCL));
+ return (getConnection(url, info, Reflection.getCallerClass()));
}
/**
@@ -231,16 +225,12 @@
* @return a connection to the URL
* @exception SQLException if a database access error occurs
*/
+ @CallerSensitive
public static Connection getConnection(String url)
throws SQLException {
java.util.Properties info = new java.util.Properties();
-
- // Gets the classloader of the code that called this method, may
- // be null.
- ClassLoader callerCL = DriverManager.getCallerClassLoader();
-
- return (getConnection(url, info, callerCL));
+ return (getConnection(url, info, Reflection.getCallerClass()));
}
/**
@@ -254,21 +244,20 @@
* that can connect to the given URL
* @exception SQLException if a database access error occurs
*/
+ @CallerSensitive
public static Driver getDriver(String url)
throws SQLException {
println("DriverManager.getDriver(\"" + url + "\")");
- // Gets the classloader of the code that called this method, may
- // be null.
- ClassLoader callerCL = DriverManager.getCallerClassLoader();
+ Class<?> callerClass = Reflection.getCallerClass();
// Walk through the loaded registeredDrivers attempting to locate someone
// who understands the given URL.
for (DriverInfo aDriver : registeredDrivers) {
// If the caller does not have permission to load the driver then
// skip it.
- if(isDriverAllowed(aDriver.driver, callerCL)) {
+ if(isDriverAllowed(aDriver.driver, callerClass)) {
try {
if(aDriver.driver.acceptsURL(url)) {
// Success!
@@ -322,20 +311,18 @@
* @param driver the JDBC Driver to drop
* @exception SQLException if a database access error occurs
*/
+ @CallerSensitive
public static synchronized void deregisterDriver(Driver driver)
throws SQLException {
if (driver == null) {
return;
}
- // Gets the classloader of the code that called this method,
- // may be null.
- ClassLoader callerCL = DriverManager.getCallerClassLoader();
println("DriverManager.deregisterDriver: " + driver);
DriverInfo aDriver = new DriverInfo(driver);
if(registeredDrivers.contains(aDriver)) {
- if (isDriverAllowed(driver, callerCL)) {
+ if (isDriverAllowed(driver, Reflection.getCallerClass())) {
registeredDrivers.remove(aDriver);
} else {
// If the caller does not have permission to load the driver then
@@ -356,18 +343,17 @@
*
* @return the list of JDBC Drivers loaded by the caller's class loader
*/
+ @CallerSensitive
public static java.util.Enumeration<Driver> getDrivers() {
java.util.Vector<Driver> result = new java.util.Vector<Driver>();
- // Gets the classloader of the code that called this method, may
- // be null.
- ClassLoader callerCL = DriverManager.getCallerClassLoader();
+ Class<?> callerClass = Reflection.getCallerClass();
// Walk through the loaded registeredDrivers.
for(DriverInfo aDriver : registeredDrivers) {
// If the caller does not have permission to load the driver then
// skip it.
- if(isDriverAllowed(aDriver.driver, callerCL)) {
+ if(isDriverAllowed(aDriver.driver, callerClass)) {
result.addElement(aDriver.driver);
} else {
println(" skipping: " + aDriver.getClass().getName());
@@ -464,6 +450,11 @@
// Indicates whether the class object that would be created if the code calling
// DriverManager is accessible.
+ private static boolean isDriverAllowed(Driver driver, Class<?> caller) {
+ ClassLoader callerCL = caller != null ? caller.getClassLoader() : null;
+ return isDriverAllowed(driver, callerCL);
+ }
+
private static boolean isDriverAllowed(Driver driver, ClassLoader classLoader) {
boolean result = false;
if(driver != null) {
@@ -546,18 +537,19 @@
// Worker method called by the public getConnection() methods.
private static Connection getConnection(
- String url, java.util.Properties info, ClassLoader callerCL) throws SQLException {
+ String url, java.util.Properties info, Class<?> caller) throws SQLException {
/*
* When callerCl is null, we should check the application's
* (which is invoking this class indirectly)
* classloader, so that the JDBC driver class outside rt.jar
* can be loaded from here.
*/
- synchronized(DriverManager.class) {
- // synchronize loading of the correct classloader.
- if(callerCL == null) {
- callerCL = Thread.currentThread().getContextClassLoader();
- }
+ ClassLoader callerCL = caller != null ? caller.getClassLoader() : null;
+ synchronized (DriverManager.class) {
+ // synchronize loading of the correct classloader.
+ if (callerCL == null) {
+ callerCL = Thread.currentThread().getContextClassLoader();
+ }
}
if(url == null) {
@@ -603,10 +595,6 @@
println("getConnection: no suitable driver found for "+ url);
throw new SQLException("No suitable driver found for "+ url, "08001");
}
-
- /* Returns the caller's class loader, or null if none */
- private static native ClassLoader getCallerClassLoader();
-
}
/*
diff --git a/jdk/src/share/classes/java/util/ResourceBundle.java b/jdk/src/share/classes/java/util/ResourceBundle.java
index 51b8487..98ee3c5 100644
--- a/jdk/src/share/classes/java/util/ResourceBundle.java
+++ b/jdk/src/share/classes/java/util/ResourceBundle.java
@@ -56,6 +56,8 @@
import java.util.concurrent.ConcurrentMap;
import java.util.jar.JarEntry;
+import sun.reflect.CallerSensitive;
+import sun.reflect.Reflection;
import sun.util.locale.BaseLocale;
import sun.util.locale.LocaleObjectCache;
@@ -412,14 +414,10 @@
/*
* Automatic determination of the ClassLoader to be used to load
- * resources on behalf of the client. N.B. The client is getLoader's
- * caller's caller.
+ * resources on behalf of the client.
*/
- private static ClassLoader getLoader() {
- Class[] stack = getClassContext();
- /* Magic number 2 identifies our caller's caller */
- Class c = stack[2];
- ClassLoader cl = (c == null) ? null : c.getClassLoader();
+ private static ClassLoader getLoader(Class<?> caller) {
+ ClassLoader cl = caller == null ? null : caller.getClassLoader();
if (cl == null) {
// When the caller's loader is the boot class loader, cl is null
// here. In that case, ClassLoader.getSystemClassLoader() may
@@ -433,8 +431,6 @@
return cl;
}
- private static native Class[] getClassContext();
-
/**
* A wrapper of ClassLoader.getSystemClassLoader().
*/
@@ -719,11 +715,12 @@
* if no resource bundle for the specified base name can be found
* @return a resource bundle for the given base name and the default locale
*/
+ @CallerSensitive
public static final ResourceBundle getBundle(String baseName)
{
return getBundleImpl(baseName, Locale.getDefault(),
/* must determine loader here, else we break stack invariant */
- getLoader(),
+ getLoader(Reflection.getCallerClass()),
Control.INSTANCE);
}
@@ -761,11 +758,12 @@
* needed.
* @since 1.6
*/
+ @CallerSensitive
public static final ResourceBundle getBundle(String baseName,
Control control) {
return getBundleImpl(baseName, Locale.getDefault(),
/* must determine loader here, else we break stack invariant */
- getLoader(),
+ getLoader(Reflection.getCallerClass()),
control);
}
@@ -790,12 +788,13 @@
* if no resource bundle for the specified base name can be found
* @return a resource bundle for the given base name and locale
*/
+ @CallerSensitive
public static final ResourceBundle getBundle(String baseName,
Locale locale)
{
return getBundleImpl(baseName, locale,
/* must determine loader here, else we break stack invariant */
- getLoader(),
+ getLoader(Reflection.getCallerClass()),
Control.INSTANCE);
}
@@ -836,11 +835,12 @@
* needed.
* @since 1.6
*/
+ @CallerSensitive
public static final ResourceBundle getBundle(String baseName, Locale targetLocale,
Control control) {
return getBundleImpl(baseName, targetLocale,
/* must determine loader here, else we break stack invariant */
- getLoader(),
+ getLoader(Reflection.getCallerClass()),
control);
}
@@ -1676,8 +1676,9 @@
* @since 1.6
* @see ResourceBundle.Control#getTimeToLive(String,Locale)
*/
+ @CallerSensitive
public static final void clearCache() {
- clearCache(getLoader());
+ clearCache(getLoader(Reflection.getCallerClass()));
}
/**
diff --git a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java
index aed5d1f..de221d4 100644
--- a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java
+++ b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java
@@ -34,8 +34,10 @@
*/
package java.util.concurrent.atomic;
-import sun.misc.Unsafe;
import java.lang.reflect.*;
+import sun.misc.Unsafe;
+import sun.reflect.CallerSensitive;
+import sun.reflect.Reflection;
/**
* A reflection-based utility that enables atomic updates to
@@ -69,8 +71,9 @@
* @throws RuntimeException with a nested reflection-based
* exception if the class does not hold field or is the wrong type
*/
+ @CallerSensitive
public static <U> AtomicIntegerFieldUpdater<U> newUpdater(Class<U> tclass, String fieldName) {
- return new AtomicIntegerFieldUpdaterImpl<U>(tclass, fieldName);
+ return new AtomicIntegerFieldUpdaterImpl<U>(tclass, fieldName, Reflection.getCallerClass());
}
/**
@@ -268,13 +271,11 @@
private final Class<T> tclass;
private final Class cclass;
- AtomicIntegerFieldUpdaterImpl(Class<T> tclass, String fieldName) {
+ AtomicIntegerFieldUpdaterImpl(Class<T> tclass, String fieldName, Class<?> caller) {
Field field = null;
- Class caller = null;
int modifiers = 0;
try {
field = tclass.getDeclaredField(fieldName);
- caller = sun.reflect.Reflection.getCallerClass(3);
modifiers = field.getModifiers();
sun.reflect.misc.ReflectUtil.ensureMemberAccess(
caller, tclass, null, modifiers);
diff --git a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java
index fa0a857..cc59c4f 100644
--- a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java
+++ b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java
@@ -34,8 +34,10 @@
*/
package java.util.concurrent.atomic;
-import sun.misc.Unsafe;
import java.lang.reflect.*;
+import sun.misc.Unsafe;
+import sun.reflect.CallerSensitive;
+import sun.reflect.Reflection;
/**
* A reflection-based utility that enables atomic updates to
@@ -69,11 +71,13 @@
* @throws RuntimeException with a nested reflection-based
* exception if the class does not hold field or is the wrong type.
*/
+ @CallerSensitive
public static <U> AtomicLongFieldUpdater<U> newUpdater(Class<U> tclass, String fieldName) {
+ Class<?> caller = Reflection.getCallerClass();
if (AtomicLong.VM_SUPPORTS_LONG_CAS)
- return new CASUpdater<U>(tclass, fieldName);
+ return new CASUpdater<U>(tclass, fieldName, caller);
else
- return new LockedUpdater<U>(tclass, fieldName);
+ return new LockedUpdater<U>(tclass, fieldName, caller);
}
/**
@@ -267,13 +271,11 @@
private final Class<T> tclass;
private final Class cclass;
- CASUpdater(Class<T> tclass, String fieldName) {
+ CASUpdater(Class<T> tclass, String fieldName, Class<?> caller) {
Field field = null;
- Class caller = null;
int modifiers = 0;
try {
field = tclass.getDeclaredField(fieldName);
- caller = sun.reflect.Reflection.getCallerClass(3);
modifiers = field.getModifiers();
sun.reflect.misc.ReflectUtil.ensureMemberAccess(
caller, tclass, null, modifiers);
@@ -350,13 +352,11 @@
private final Class<T> tclass;
private final Class cclass;
- LockedUpdater(Class<T> tclass, String fieldName) {
+ LockedUpdater(Class<T> tclass, String fieldName, Class<?> caller) {
Field field = null;
- Class caller = null;
int modifiers = 0;
try {
field = tclass.getDeclaredField(fieldName);
- caller = sun.reflect.Reflection.getCallerClass(3);
modifiers = field.getModifiers();
sun.reflect.misc.ReflectUtil.ensureMemberAccess(
caller, tclass, null, modifiers);
diff --git a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java
index 7b72f0f..e3c65b9 100644
--- a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java
+++ b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java
@@ -34,8 +34,10 @@
*/
package java.util.concurrent.atomic;
-import sun.misc.Unsafe;
import java.lang.reflect.*;
+import sun.misc.Unsafe;
+import sun.reflect.CallerSensitive;
+import sun.reflect.Reflection;
/**
* A reflection-based utility that enables atomic updates to
@@ -88,10 +90,12 @@
* @throws RuntimeException with a nested reflection-based
* exception if the class does not hold field or is the wrong type.
*/
+ @CallerSensitive
public static <U, W> AtomicReferenceFieldUpdater<U,W> newUpdater(Class<U> tclass, Class<W> vclass, String fieldName) {
return new AtomicReferenceFieldUpdaterImpl<U,W>(tclass,
vclass,
- fieldName);
+ fieldName,
+ Reflection.getCallerClass());
}
/**
@@ -199,14 +203,13 @@
AtomicReferenceFieldUpdaterImpl(Class<T> tclass,
Class<V> vclass,
- String fieldName) {
+ String fieldName,
+ Class<?> caller) {
Field field = null;
Class fieldClass = null;
- Class caller = null;
int modifiers = 0;
try {
field = tclass.getDeclaredField(fieldName);
- caller = sun.reflect.Reflection.getCallerClass(3);
modifiers = field.getModifiers();
sun.reflect.misc.ReflectUtil.ensureMemberAccess(
caller, tclass, null, modifiers);
diff --git a/jdk/src/share/classes/java/util/logging/Logger.java b/jdk/src/share/classes/java/util/logging/Logger.java
index b95c359..c941a0e 100644
--- a/jdk/src/share/classes/java/util/logging/Logger.java
+++ b/jdk/src/share/classes/java/util/logging/Logger.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,10 +26,17 @@
package java.util.logging;
-import java.util.*;
-import java.util.concurrent.CopyOnWriteArrayList;
-import java.security.*;
import java.lang.ref.WeakReference;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+import java.util.concurrent.CopyOnWriteArrayList;
+import sun.reflect.CallerSensitive;
+import sun.reflect.Reflection;
/**
* A Logger object is used to log messages for a specific
@@ -303,13 +310,10 @@
}
}
- private static Logger demandLogger(String name, String resourceBundleName) {
+ private static Logger demandLogger(String name, String resourceBundleName, Class<?> caller) {
LogManager manager = LogManager.getLogManager();
SecurityManager sm = System.getSecurityManager();
if (sm != null && !SystemLoggerHelper.disableCallerCheck) {
- // 0: Reflection 1: Logger.demandLogger 2: Logger.getLogger 3: caller
- final int SKIP_FRAMES = 3;
- Class<?> caller = sun.reflect.Reflection.getCallerClass(SKIP_FRAMES);
if (caller.getClassLoader() == null) {
return manager.demandSystemLogger(name, resourceBundleName);
}
@@ -347,6 +351,7 @@
// Synchronization is not required here. All synchronization for
// adding a new Logger object is handled by LogManager.addLogger().
+ @CallerSensitive
public static Logger getLogger(String name) {
// This method is intentionally not a wrapper around a call
// to getLogger(name, resourceBundleName). If it were then
@@ -358,7 +363,7 @@
// would throw an IllegalArgumentException in the second call
// because the wrapper would result in an attempt to replace
// the existing "resourceBundleForFoo" with null.
- return demandLogger(name, null);
+ return demandLogger(name, null, Reflection.getCallerClass());
}
/**
@@ -404,8 +409,9 @@
// Synchronization is not required here. All synchronization for
// adding a new Logger object is handled by LogManager.addLogger().
+ @CallerSensitive
public static Logger getLogger(String name, String resourceBundleName) {
- Logger result = demandLogger(name, resourceBundleName);
+ Logger result = demandLogger(name, resourceBundleName, Reflection.getCallerClass());
if (result.resourceBundleName == null) {
// Note: we may get a MissingResourceException here.
result.setupResourceInfo(resourceBundleName);
@@ -1322,12 +1328,6 @@
return useParentHandlers;
}
- // Private utility method to map a resource bundle name to an
- // actual resource bundle, using a simple one-entry cache.
- // Returns null for a null name.
- // May also return null if we can't find the resource bundle and
- // there is no suitable previous cached value.
-
static final String SYSTEM_LOGGER_RB_NAME = "sun.util.logging.resources.logging";
private static ResourceBundle findSystemResourceBundle(final Locale locale) {
@@ -1345,6 +1345,16 @@
});
}
+ /**
+ * Private utility method to map a resource bundle name to an
+ * actual resource bundle, using a simple one-entry cache.
+ * Returns null for a null name.
+ * May also return null if we can't find the resource bundle and
+ * there is no suitable previous cached value.
+ *
+ * @param name the ResourceBundle to locate
+ * @return ResourceBundle specified by name or null if not found
+ */
private synchronized ResourceBundle findResourceBundle(String name) {
// Return a null bundle for a null name.
if (name == null) {
@@ -1354,8 +1364,8 @@
Locale currentLocale = Locale.getDefault();
// Normally we should hit on our simple one entry cache.
- if (catalog != null && currentLocale == catalogLocale
- && name == catalogName) {
+ if (catalog != null && currentLocale.equals(catalogLocale)
+ && name.equals(catalogName)) {
return catalog;
}
@@ -1366,8 +1376,8 @@
return catalog;
}
- // Use the thread's context ClassLoader. If there isn't one,
- // use the SystemClassloader.
+ // Use the thread's context ClassLoader. If there isn't one, use the
+ // {@linkplain java.lang.ClassLoader#getSystemClassLoader() system ClassLoader}.
ClassLoader cl = Thread.currentThread().getContextClassLoader();
if (cl == null) {
cl = ClassLoader.getSystemClassLoader();
@@ -1378,44 +1388,8 @@
catalogLocale = currentLocale;
return catalog;
} catch (MissingResourceException ex) {
- // Woops. We can't find the ResourceBundle in the default
- // ClassLoader. Drop through.
+ return null;
}
-
- // Fall back to searching up the call stack and trying each
- // calling ClassLoader.
- for (int ix = 0; ; ix++) {
- Class clz = sun.reflect.Reflection.getCallerClass(ix);
- if (clz == null) {
- break;
- }
- ClassLoader cl2 = clz.getClassLoader();
- if (cl2 == null) {
- cl2 = ClassLoader.getSystemClassLoader();
- }
- if (cl == cl2) {
- // We've already checked this classloader.
- continue;
- }
- cl = cl2;
- try {
- catalog = ResourceBundle.getBundle(name, currentLocale, cl);
- catalogName = name;
- catalogLocale = currentLocale;
- return catalog;
- } catch (MissingResourceException ex) {
- // Ok, this one didn't work either.
- // Drop through, and try the next one.
- }
- }
-
- if (name.equals(catalogName)) {
- // Return the previous cached value for that name.
- // This may be null.
- return catalog;
- }
- // Sorry, we're out of luck.
- return null;
}
// Private utility method to initialize our one entry
@@ -1427,9 +1401,8 @@
if (name == null) {
return;
}
- ResourceBundle rb = findResourceBundle(name);
- if (rb == null) {
// We've failed to find an expected ResourceBundle.
+ if (findResourceBundle(name) == null) {
throw new MissingResourceException("Can't find " + name + " bundle", name, "");
}
resourceBundleName = name;
diff --git a/jdk/src/share/classes/java/util/zip/ZipFile.java b/jdk/src/share/classes/java/util/zip/ZipFile.java
index 9693809..b6dbc24 100644
--- a/jdk/src/share/classes/java/util/zip/ZipFile.java
+++ b/jdk/src/share/classes/java/util/zip/ZipFile.java
@@ -54,9 +54,10 @@
*/
public
class ZipFile implements ZipConstants, Closeable {
- private long jzfile; // address of jzfile data
- private String name; // zip file name
- private int total; // total number of entries
+ private long jzfile; // address of jzfile data
+ private final String name; // zip file name
+ private final int total; // total number of entries
+ private final boolean locsig; // if zip file starts with LOCSIG (usually true)
private volatile boolean closeRequested = false;
private static final int STORED = ZipEntry.STORED;
@@ -216,6 +217,7 @@
sun.misc.PerfCounter.getZipFileCount().increment();
this.name = name;
this.total = getTotal(jzfile);
+ this.locsig = startsWithLOC(jzfile);
}
/**
@@ -737,10 +739,28 @@
}
}
+ static {
+ sun.misc.SharedSecrets.setJavaUtilZipFileAccess(
+ new sun.misc.JavaUtilZipFileAccess() {
+ public boolean startsWithLocHeader(ZipFile zip) {
+ return zip.startsWithLocHeader();
+ }
+ }
+ );
+ }
+
+ /**
+ * Returns {@code true} if, and only if, the zip file begins with {@code
+ * LOCSIG}.
+ */
+ private boolean startsWithLocHeader() {
+ return locsig;
+ }
private static native long open(String name, int mode, long lastModified,
boolean usemmap) throws IOException;
private static native int getTotal(long jzfile);
+ private static native boolean startsWithLOC(long jzfile);
private static native int read(long jzfile, long jzentry,
long pos, byte[] b, int off, int len);
diff --git a/jdk/src/share/classes/javax/script/ScriptEngineManager.java b/jdk/src/share/classes/javax/script/ScriptEngineManager.java
index b3a048d..50fe781 100644
--- a/jdk/src/share/classes/javax/script/ScriptEngineManager.java
+++ b/jdk/src/share/classes/javax/script/ScriptEngineManager.java
@@ -30,8 +30,6 @@
import java.security.*;
import sun.misc.Service;
import sun.misc.ServiceConfigurationError;
-import sun.reflect.Reflection;
-import sun.security.util.SecurityConstants;
/**
* The <code>ScriptEngineManager</code> implements a discovery and instantiation
@@ -64,13 +62,7 @@
*/
public ScriptEngineManager() {
ClassLoader ctxtLoader = Thread.currentThread().getContextClassLoader();
- if (canCallerAccessLoader(ctxtLoader)) {
- if (DEBUG) System.out.println("using " + ctxtLoader);
- init(ctxtLoader);
- } else {
- if (DEBUG) System.out.println("using bootstrap loader");
- init(null);
- }
+ init(ctxtLoader);
}
/**
@@ -418,42 +410,4 @@
/** Global bindings associated with script engines created by this manager. */
private Bindings globalScope;
-
- private boolean canCallerAccessLoader(ClassLoader loader) {
- SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- ClassLoader callerLoader = getCallerClassLoader();
- if (callerLoader != null) {
- if (loader != callerLoader || !isAncestor(loader, callerLoader)) {
- try {
- sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
- } catch (SecurityException exp) {
- if (DEBUG) exp.printStackTrace();
- return false;
- }
- } // else fallthru..
- } // else fallthru..
- } // else fallthru..
-
- return true;
- }
-
- // Note that this code is same as ClassLoader.getCallerClassLoader().
- // But, that method is package private and hence we can't call here.
- private ClassLoader getCallerClassLoader() {
- Class caller = Reflection.getCallerClass(3);
- if (caller == null) {
- return null;
- }
- return caller.getClassLoader();
- }
-
- // is cl1 ancestor of cl2?
- private boolean isAncestor(ClassLoader cl1, ClassLoader cl2) {
- do {
- cl2 = cl2.getParent();
- if (cl1 == cl2) return true;
- } while (cl2 != null);
- return false;
- }
}
diff --git a/jdk/src/share/classes/javax/sql/rowset/serial/SerialJavaObject.java b/jdk/src/share/classes/javax/sql/rowset/serial/SerialJavaObject.java
index 8d194ef..9a48936 100644
--- a/jdk/src/share/classes/javax/sql/rowset/serial/SerialJavaObject.java
+++ b/jdk/src/share/classes/javax/sql/rowset/serial/SerialJavaObject.java
@@ -28,7 +28,9 @@
import java.io.*;
import java.lang.reflect.*;
import javax.sql.rowset.RowSetWarning;
+import sun.reflect.CallerSensitive;
import sun.reflect.Reflection;
+import sun.reflect.misc.ReflectUtil;
/**
* A serializable mapping in the Java programming language of an SQL
@@ -123,10 +125,22 @@
* the serialized object
* @see Class#getFields
*/
+ @CallerSensitive
public Field[] getFields() throws SerialException {
if (fields != null) {
Class<?> c = this.obj.getClass();
- checkPackageAccess(c);
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ /*
+ * Check if the caller is allowed to access the specified class's package.
+ * If access is denied, throw a SecurityException.
+ */
+ Class<?> caller = sun.reflect.Reflection.getCallerClass();
+ if (ReflectUtil.needsPackageAccessCheck(caller.getClassLoader(),
+ c.getClassLoader())) {
+ ReflectUtil.checkPackageAccess(c);
+ }
+ }
return c.getFields();
} else {
throw new SerialException("SerialJavaObject does not contain" +
@@ -156,38 +170,4 @@
}
chain.add(e);
}
-
- /*
- * Check if the caller is allowed to access the specified class's package. If access is denied,
- * throw a SecurityException.
- *
- */
- private void checkPackageAccess(Class<?> clz) {
- SecurityManager s = System.getSecurityManager();
- if (s != null) {
- if (sun.reflect.misc.ReflectUtil.needsPackageAccessCheck(
- getCallerClassLoader(), clz.getClassLoader())) {
- String name = clz.getName();
- int i = name.lastIndexOf('.');
- if (i != -1) {
- s.checkPackageAccess(name.substring(0, i));
- }
- }
- }
- }
-
- /* Internal method used to get the caller's caller class loader.
- * Caution is required if you attempt to make changes as this method assumes
- * the following stack frame count:
- * 0: Reflection
- * 1: getCallerClassLoader
- * 2: checkPackageAccess
- * 3: getFields
- * 4: caller of getFields
- */
- private static ClassLoader getCallerClassLoader() {
- Class<?> cc = Reflection.getCallerClass(4);
- ClassLoader cl = (cc != null) ? cc.getClassLoader() : null;
- return cl;
- }
}
diff --git a/jdk/src/share/classes/sun/awt/image/ByteBandedRaster.java b/jdk/src/share/classes/sun/awt/image/ByteBandedRaster.java
index 56d7316..3b564ba 100644
--- a/jdk/src/share/classes/sun/awt/image/ByteBandedRaster.java
+++ b/jdk/src/share/classes/sun/awt/image/ByteBandedRaster.java
@@ -159,7 +159,7 @@
throw new RasterFormatException("ByteBandedRasters must have"+
"BandedSampleModels");
}
- verify(false);
+ verify();
}
@@ -731,16 +731,30 @@
}
/**
- * Verify that the layout parameters are consistent with
- * the data. If strictCheck
- * is false, this method will check for ArrayIndexOutOfBounds conditions. If
- * strictCheck is true, this method will check for additional error
- * conditions such as line wraparound (width of a line greater than
- * the scanline stride).
- * @return String Error string, if the layout is incompatible with
- * the data. Otherwise returns null.
+ * Verify that the layout parameters are consistent with the data.
+ * Verifies whether the data buffer has enough data for the raster,
+ * taking into account offsets, after ensuring all offsets are >=0.
+ * @throws RasterFormatException if a problem is detected.
*/
- private void verify (boolean strictCheck) {
+ private void verify() {
+
+ /* Need to re-verify the dimensions since a sample model may be
+ * specified to the constructor
+ */
+ if (width <= 0 || height <= 0 ||
+ height > (Integer.MAX_VALUE / width))
+ {
+ throw new RasterFormatException("Invalid raster dimension");
+ }
+
+ if (scanlineStride < 0 ||
+ scanlineStride > (Integer.MAX_VALUE / height))
+ {
+ // integer overflow
+ throw new RasterFormatException("Incorrect scanline stride: "
+ + scanlineStride);
+ }
+
// Make sure data for Raster is in a legal range
for (int i=0; i < dataOffsets.length; i++) {
if (dataOffsets[i] < 0) {
@@ -750,32 +764,41 @@
}
}
- int maxSize = 0;
- int size;
+ int lastScanOffset = (height - 1) * scanlineStride;
+ int lastPixelOffset = lastScanOffset + (width-1);
+ if (lastPixelOffset < lastScanOffset) {
+ throw new RasterFormatException("Invalid raster dimension");
+ }
+
+ int maxIndex = 0;
+ int index;
for (int i=0; i < numDataElements; i++) {
- size = (height-1)*scanlineStride + (width-1) + dataOffsets[i];
- if (size > maxSize) {
- maxSize = size;
+ index = lastPixelOffset + dataOffsets[i];
+ if (index < lastPixelOffset) {
+ throw new RasterFormatException("Invalid raster dimension");
+ }
+ if (index > maxIndex) {
+ maxIndex = index;
}
}
if (data.length == 1) {
- if (data[0].length < maxSize*numDataElements) {
+ if (data[0].length <= maxIndex*numDataElements) {
throw new RasterFormatException("Data array too small "+
"(it is "+data[0].length+
- " and should be "+
- (maxSize*numDataElements)+
+ " and should be > "+
+ (maxIndex*numDataElements)+
" )");
}
}
else {
for (int i=0; i < numDataElements; i++) {
- if (data[i].length < maxSize) {
+ if (data[i].length <= maxIndex) {
throw new RasterFormatException("Data array too small "+
"(it is "+data[i].length+
- " and should be "+
- maxSize+" )");
+ " and should be > "+
+ maxIndex+" )");
}
}
}
diff --git a/jdk/src/share/classes/sun/awt/image/ByteComponentRaster.java b/jdk/src/share/classes/sun/awt/image/ByteComponentRaster.java
index f2675db..cfe98d6 100644
--- a/jdk/src/share/classes/sun/awt/image/ByteComponentRaster.java
+++ b/jdk/src/share/classes/sun/awt/image/ByteComponentRaster.java
@@ -885,9 +885,6 @@
}
}
- int maxSize = 0;
- int size;
-
// we can be sure that width and height are greater than 0
if (scanlineStride < 0 ||
scanlineStride > (Integer.MAX_VALUE / height))
@@ -913,6 +910,8 @@
}
lastPixelOffset += lastScanOffset;
+ int index;
+ int maxIndex = 0;
for (int i = 0; i < numDataElements; i++) {
if (dataOffsets[i] > (Integer.MAX_VALUE - lastPixelOffset)) {
throw new RasterFormatException("Incorrect band offset: "
@@ -920,15 +919,15 @@
}
- size = lastPixelOffset + dataOffsets[i];
+ index = lastPixelOffset + dataOffsets[i];
- if (size > maxSize) {
- maxSize = size;
+ if (index > maxIndex) {
+ maxIndex = index;
}
}
- if (data.length < maxSize) {
- throw new RasterFormatException("Data array too small (should be "
- + maxSize + " )");
+ if (data.length <= maxIndex) {
+ throw new RasterFormatException("Data array too small (should be > "
+ + maxIndex + " )");
}
}
diff --git a/jdk/src/share/classes/sun/awt/image/IntegerComponentRaster.java b/jdk/src/share/classes/sun/awt/image/IntegerComponentRaster.java
index 92bec9f..3b6401b 100644
--- a/jdk/src/share/classes/sun/awt/image/IntegerComponentRaster.java
+++ b/jdk/src/share/classes/sun/awt/image/IntegerComponentRaster.java
@@ -654,9 +654,6 @@
") must be >= 0");
}
- int maxSize = 0;
- int size;
-
// we can be sure that width and height are greater than 0
if (scanlineStride < 0 ||
scanlineStride > (Integer.MAX_VALUE / height))
@@ -682,21 +679,23 @@
}
lastPixelOffset += lastScanOffset;
+ int index;
+ int maxIndex = 0;
for (int i = 0; i < numDataElements; i++) {
if (dataOffsets[i] > (Integer.MAX_VALUE - lastPixelOffset)) {
throw new RasterFormatException("Incorrect band offset: "
+ dataOffsets[i]);
}
- size = lastPixelOffset + dataOffsets[i];
+ index = lastPixelOffset + dataOffsets[i];
- if (size > maxSize) {
- maxSize = size;
+ if (index > maxIndex) {
+ maxIndex = index;
}
}
- if (data.length < maxSize) {
- throw new RasterFormatException("Data array too small (should be "
- + maxSize + " )");
+ if (data.length <= maxIndex) {
+ throw new RasterFormatException("Data array too small (should be > "
+ + maxIndex + " )");
}
}
diff --git a/jdk/src/share/classes/sun/awt/image/ShortBandedRaster.java b/jdk/src/share/classes/sun/awt/image/ShortBandedRaster.java
index d56a25f..84c696e 100644
--- a/jdk/src/share/classes/sun/awt/image/ShortBandedRaster.java
+++ b/jdk/src/share/classes/sun/awt/image/ShortBandedRaster.java
@@ -156,7 +156,7 @@
throw new RasterFormatException("ShortBandedRasters must have "+
"BandedSampleModels");
}
- verify(false);
+ verify();
}
/**
@@ -730,16 +730,30 @@
}
/**
- * Verify that the layout parameters are consistent with
- * the data. If strictCheck
- * is false, this method will check for ArrayIndexOutOfBounds conditions. If
- * strictCheck is true, this method will check for additional error
- * conditions such as line wraparound (width of a line greater than
- * the scanline stride).
- * @return String Error string, if the layout is incompatible with
- * the data. Otherwise returns null.
+ * Verify that the layout parameters are consistent with the data.
+ * Verifies whether the data buffer has enough data for the raster,
+ * taking into account offsets, after ensuring all offsets are >=0.
+ * @throws RasterFormatException if a problem is detected.
*/
- private void verify (boolean strictCheck) {
+ private void verify() {
+
+ /* Need to re-verify the dimensions since a sample model may be
+ * specified to the constructor
+ */
+ if (width <= 0 || height <= 0 ||
+ height > (Integer.MAX_VALUE / width))
+ {
+ throw new RasterFormatException("Invalid raster dimension");
+ }
+
+ if (scanlineStride < 0 ||
+ scanlineStride > (Integer.MAX_VALUE / height))
+ {
+ // integer overflow
+ throw new RasterFormatException("Incorrect scanline stride: "
+ + scanlineStride);
+ }
+
// Make sure data for Raster is in a legal range
for (int i=0; i < dataOffsets.length; i++) {
if (dataOffsets[i] < 0) {
@@ -749,19 +763,28 @@
}
}
- int maxSize = 0;
- int size;
+ int lastScanOffset = (height - 1) * scanlineStride;
+ int lastPixelOffset = lastScanOffset + (width-1);
+ if (lastPixelOffset < lastScanOffset) {
+ throw new RasterFormatException("Invalid raster dimension");
+ }
+
+ int maxIndex = 0;
+ int index;
for (int i=0; i < numDataElements; i++) {
- size = (height-1)*scanlineStride + (width-1) + dataOffsets[i];
- if (size > maxSize) {
- maxSize = size;
+ index = lastPixelOffset + dataOffsets[i];
+ if (index < lastPixelOffset) {
+ throw new RasterFormatException("Invalid raster dimension");
+ }
+ if (index > maxIndex) {
+ maxIndex = index;
}
}
for (int i=0; i < numDataElements; i++) {
- if (data[i].length < maxSize) {
- throw new RasterFormatException("Data array too small (should be "+
- maxSize+" )");
+ if (data[i].length <= maxIndex) {
+ throw new RasterFormatException("Data array too small " +
+ "(should be > "+ maxIndex+" )");
}
}
}
diff --git a/jdk/src/share/classes/sun/awt/image/ShortComponentRaster.java b/jdk/src/share/classes/sun/awt/image/ShortComponentRaster.java
index 3b33595..8306b8b 100644
--- a/jdk/src/share/classes/sun/awt/image/ShortComponentRaster.java
+++ b/jdk/src/share/classes/sun/awt/image/ShortComponentRaster.java
@@ -819,9 +819,6 @@
}
}
- int maxSize = 0;
- int size;
-
// we can be sure that width and height are greater than 0
if (scanlineStride < 0 ||
scanlineStride > (Integer.MAX_VALUE / height))
@@ -847,21 +844,23 @@
}
lastPixelOffset += lastScanOffset;
+ int index;
+ int maxIndex = 0;
for (int i = 0; i < numDataElements; i++) {
if (dataOffsets[i] > (Integer.MAX_VALUE - lastPixelOffset)) {
throw new RasterFormatException("Incorrect band offset: "
+ dataOffsets[i]);
}
- size = lastPixelOffset + dataOffsets[i];
+ index = lastPixelOffset + dataOffsets[i];
- if (size > maxSize) {
- maxSize = size;
+ if (index > maxIndex) {
+ maxIndex = index;
}
}
- if (data.length < maxSize) {
- throw new RasterFormatException("Data array too small (should be "
- + maxSize + " )");
+ if (data.length <= maxIndex) {
+ throw new RasterFormatException("Data array too small (should be > "
+ + maxIndex + " )");
}
}
diff --git a/jdk/src/share/classes/sun/misc/JavaUtilZipFileAccess.java b/jdk/src/share/classes/sun/misc/JavaUtilZipFileAccess.java
new file mode 100644
index 0000000..f7f878b
--- /dev/null
+++ b/jdk/src/share/classes/sun/misc/JavaUtilZipFileAccess.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.misc;
+
+import java.util.zip.ZipFile;
+
+public interface JavaUtilZipFileAccess {
+ public boolean startsWithLocHeader(ZipFile zip);
+}
diff --git a/jdk/src/share/classes/sun/misc/SharedSecrets.java b/jdk/src/share/classes/sun/misc/SharedSecrets.java
index d8eeed2..dc8caa4 100644
--- a/jdk/src/share/classes/sun/misc/SharedSecrets.java
+++ b/jdk/src/share/classes/sun/misc/SharedSecrets.java
@@ -56,6 +56,7 @@
private static JavaSecurityAccess javaSecurityAccess;
private static JavaxSecurityAuthKerberosAccess javaxSecurityAuthKerberosAccess;
private static JavaUtilZipAccess javaUtilZipAccess;
+ private static JavaUtilZipFileAccess javaUtilZipFileAccess;
private static JavaAWTAccess javaAWTAccess;
public static JavaUtilJarAccess javaUtilJarAccess() {
@@ -179,6 +180,16 @@
return javaUtilZipAccess;
}
+ public static JavaUtilZipFileAccess getJavaUtilZipFileAccess() {
+ if (javaUtilZipFileAccess == null)
+ unsafe.ensureClassInitialized(java.util.zip.ZipFile.class);
+ return javaUtilZipFileAccess;
+ }
+
+ public static void setJavaUtilZipFileAccess(JavaUtilZipFileAccess access) {
+ javaUtilZipFileAccess = access;
+ }
+
public static void setJavaAWTAccess(JavaAWTAccess jaa) {
javaAWTAccess = jaa;
}
diff --git a/jdk/src/share/classes/sun/misc/URLClassPath.java b/jdk/src/share/classes/sun/misc/URLClassPath.java
index 5db540d..8cf724d 100644
--- a/jdk/src/share/classes/sun/misc/URLClassPath.java
+++ b/jdk/src/share/classes/sun/misc/URLClassPath.java
@@ -63,12 +63,16 @@
final static String USER_AGENT_JAVA_VERSION = "UA-Java-Version";
final static String JAVA_VERSION;
private static final boolean DEBUG;
+ private static final boolean DISABLE_JAR_CHECKING;
static {
JAVA_VERSION = java.security.AccessController.doPrivileged(
new sun.security.action.GetPropertyAction("java.version"));
DEBUG = (java.security.AccessController.doPrivileged(
new sun.security.action.GetPropertyAction("sun.misc.URLClassPath.debug")) != null);
+ String p = java.security.AccessController.doPrivileged(
+ new sun.security.action.GetPropertyAction("sun.misc.URLClassPath.disableJarChecking"));
+ DISABLE_JAR_CHECKING = p != null ? p.equals("true") || p.equals("") : false;
}
/* The original search path of URLs. */
@@ -536,7 +540,7 @@
* in a hurry.
*/
JarURLConnection juc = (JarURLConnection)uc;
- jarfile = juc.getJarFile();
+ jarfile = JarLoader.checkJar(juc.getJarFile());
}
} catch (Exception e) {
return null;
@@ -592,6 +596,8 @@
private URLStreamHandler handler;
private HashMap<String, Loader> lmap;
private boolean closed = false;
+ private static final sun.misc.JavaUtilZipFileAccess zipAccess =
+ sun.misc.SharedSecrets.getJavaUtilZipFileAccess();
/*
* Creates a new JarLoader for the specified URL referring to
@@ -696,6 +702,14 @@
}
}
+ /* Throws if the given jar file is does not start with the correct LOC */
+ static JarFile checkJar(JarFile jar) throws IOException {
+ if (System.getSecurityManager() != null && !DISABLE_JAR_CHECKING
+ && !zipAccess.startsWithLocHeader(jar))
+ throw new IOException("Invalid Jar file");
+ return jar;
+ }
+
private JarFile getJarFile(URL url) throws IOException {
// Optimize case where url refers to a local jar file
if (isOptimizable(url)) {
@@ -703,11 +717,12 @@
if (!p.exists()) {
throw new FileNotFoundException(p.getPath());
}
- return new JarFile (p.getPath());
+ return checkJar(new JarFile(p.getPath()));
}
URLConnection uc = getBaseURL().openConnection();
uc.setRequestProperty(USER_AGENT_JAVA_VERSION, JAVA_VERSION);
- return ((JarURLConnection)uc).getJarFile();
+ JarFile jarFile = ((JarURLConnection)uc).getJarFile();
+ return checkJar(jarFile);
}
/*
diff --git a/jdk/src/share/classes/sun/misc/Unsafe.java b/jdk/src/share/classes/sun/misc/Unsafe.java
index dba1628..a9fadbb 100644
--- a/jdk/src/share/classes/sun/misc/Unsafe.java
+++ b/jdk/src/share/classes/sun/misc/Unsafe.java
@@ -28,6 +28,9 @@
import java.security.*;
import java.lang.reflect.*;
+import sun.reflect.CallerSensitive;
+import sun.reflect.Reflection;
+
/**
* A collection of methods for performing low-level, unsafe operations.
@@ -80,8 +83,9 @@
* <code>checkPropertiesAccess</code> method doesn't allow
* access to the system properties.
*/
+ @CallerSensitive
public static Unsafe getUnsafe() {
- Class cc = sun.reflect.Reflection.getCallerClass(2);
+ Class cc = Reflection.getCallerClass();
if (cc.getClassLoader() != null)
throw new SecurityException("Unsafe");
return theUnsafe;
@@ -809,6 +813,12 @@
ClassLoader loader,
ProtectionDomain protectionDomain);
+ /**
+ * @deprecated Use defineClass(String, byte[], int, int, ClassLoader, ProtectionDomain)
+ * instead. This method will be removed in JDK 8.
+ */
+ @Deprecated
+ @CallerSensitive
public native Class defineClass(String name, byte[] b, int off, int len);
/**
diff --git a/jdk/src/share/classes/sun/reflect/CallerSensitive.java b/jdk/src/share/classes/sun/reflect/CallerSensitive.java
new file mode 100644
index 0000000..b238baa
--- /dev/null
+++ b/jdk/src/share/classes/sun/reflect/CallerSensitive.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.reflect;
+
+import java.lang.annotation.*;
+import static java.lang.annotation.ElementType.*;
+
+/**
+ * A method annotated @CallerSensitive is sensitive to its calling class,
+ * via {@link sun.reflect.Reflection#getCallerClass Reflection.getCallerClass},
+ * or via some equivalent.
+ *
+ * @author John R. Rose
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({METHOD})
+public @interface CallerSensitive {
+}
diff --git a/jdk/src/share/classes/sun/reflect/Reflection.java b/jdk/src/share/classes/sun/reflect/Reflection.java
index 64953ca..a07fbe5 100644
--- a/jdk/src/share/classes/sun/reflect/Reflection.java
+++ b/jdk/src/share/classes/sun/reflect/Reflection.java
@@ -52,16 +52,11 @@
methodFilterMap = new HashMap<Class,String[]>();
}
- /** Returns the class of the method <code>realFramesToSkip</code>
- frames up the stack (zero-based), ignoring frames associated
- with java.lang.reflect.Method.invoke() and its implementation.
- The first frame is that associated with this method, so
- <code>getCallerClass(0)</code> returns the Class object for
- sun.reflect.Reflection. Frames associated with
- java.lang.reflect.Method.invoke() and its implementation are
- completely ignored and do not count toward the number of "real"
- frames skipped. */
- public static native Class getCallerClass(int realFramesToSkip);
+ /** Returns the class of the caller of the method calling this method,
+ ignoring frames associated with java.lang.reflect.Method.invoke()
+ and its implementation. */
+ @CallerSensitive
+ public static native Class getCallerClass();
/** Retrieves the access flags written to the class file. For
inner classes these flags may differ from those returned by
@@ -322,4 +317,27 @@
}
return newMembers;
}
+
+ /**
+ * Tests if the given method is caller-sensitive and the declaring class
+ * is defined by either the bootstrap class loader or extension class loader.
+ */
+ public static boolean isCallerSensitive(Method m) {
+ final ClassLoader loader = m.getDeclaringClass().getClassLoader();
+ if (loader == null || isExtClassLoader(loader)) {
+ return m.isAnnotationPresent(CallerSensitive.class);
+ }
+ return false;
+ }
+
+ private static boolean isExtClassLoader(ClassLoader loader) {
+ ClassLoader cl = ClassLoader.getSystemClassLoader();
+ while (cl != null) {
+ if (cl.getParent() == null && cl == loader) {
+ return true;
+ }
+ cl = cl.getParent();
+ }
+ return false;
+ }
}
diff --git a/jdk/src/share/classes/sun/reflect/misc/ReflectUtil.java b/jdk/src/share/classes/sun/reflect/misc/ReflectUtil.java
index 09a96ac..81468c2 100644
--- a/jdk/src/share/classes/sun/reflect/misc/ReflectUtil.java
+++ b/jdk/src/share/classes/sun/reflect/misc/ReflectUtil.java
@@ -27,6 +27,7 @@
package sun.reflect.misc;
import java.lang.reflect.Modifier;
+import java.lang.reflect.Proxy;
import sun.reflect.Reflection;
public final class ReflectUtil {
@@ -115,10 +116,26 @@
}
- public static void checkPackageAccess(Class clazz) {
+ /**
+ * Checks package access on the given class.
+ *
+ * If it is a {@link Proxy#isProxyClass(java.lang.Class)} that implements
+ * a non-public interface (i.e. may be in a non-restricted package),
+ * also check the package access on the proxy interfaces.
+ */
+ public static void checkPackageAccess(Class<?> clazz) {
checkPackageAccess(clazz.getName());
+ if (isNonPublicProxyClass(clazz)) {
+ checkProxyPackageAccess(clazz);
+ }
}
+ /**
+ * Checks package access on the given classname.
+ * This method is typically called when the Class instance is not
+ * available and the caller attempts to load a class on behalf
+ * the true caller (application).
+ */
public static void checkPackageAccess(String name) {
SecurityManager s = System.getSecurityManager();
if (s != null) {
@@ -180,13 +197,30 @@
}
/**
+ * Check package access on the proxy interfaces that the given proxy class
+ * implements.
+ *
+ * @param clazz Proxy class object
+ */
+ public static void checkProxyPackageAccess(Class<?> clazz) {
+ SecurityManager s = System.getSecurityManager();
+ if (s != null) {
+ // check proxy interfaces if the given class is a proxy class
+ if (Proxy.isProxyClass(clazz)) {
+ for (Class<?> intf : clazz.getInterfaces()) {
+ checkPackageAccess(intf);
+ }
+ }
+ }
+ }
+
+ /**
* Access check on the interfaces that a proxy class implements and throw
- * {@code SecurityException} if it accesses a restricted package.
+ * {@code SecurityException} if it accesses a restricted package from
+ * the caller's class loader.
*
* @param ccl the caller's class loader
* @param interfaces the list of interfaces that a proxy class implements
- *
- * @see Proxy#checkProxyAccess
*/
public static void checkProxyPackageAccess(ClassLoader ccl,
Class<?>... interfaces)
@@ -203,4 +237,16 @@
}
public static final String PROXY_PACKAGE = "com.sun.proxy";
+
+ /**
+ * Test if the given class is a proxy class that implements
+ * non-public interface. Such proxy class may be in a non-restricted
+ * package that bypasses checkPackageAccess.
+ */
+ public static boolean isNonPublicProxyClass(Class<?> cls) {
+ String name = cls.getName();
+ int i = name.lastIndexOf('.');
+ String pkg = (i != -1) ? name.substring(0, i) : "";
+ return Proxy.isProxyClass(cls) && !pkg.equals(PROXY_PACKAGE);
+ }
}
diff --git a/jdk/src/share/classes/sun/security/timestamp/TimestampToken.java b/jdk/src/share/classes/sun/security/timestamp/TimestampToken.java
index a9ec092..5ca1d62 100644
--- a/jdk/src/share/classes/sun/security/timestamp/TimestampToken.java
+++ b/jdk/src/share/classes/sun/security/timestamp/TimestampToken.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -115,6 +115,10 @@
return nonce;
}
+ public BigInteger getSerialNumber() {
+ return serialNumber;
+ }
+
/*
* Parses the timestamp token info.
*
diff --git a/jdk/src/share/classes/sun/security/util/SignatureFileVerifier.java b/jdk/src/share/classes/sun/security/util/SignatureFileVerifier.java
index 96f425a..df4a717 100644
--- a/jdk/src/share/classes/sun/security/util/SignatureFileVerifier.java
+++ b/jdk/src/share/classes/sun/security/util/SignatureFileVerifier.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -548,6 +548,8 @@
// Create a timestamp token info object
TimestampToken timestampTokenInfo =
new TimestampToken(encodedTimestampTokenInfo);
+ // Check that the signature timestamp applies to this signature
+ verifyTimestamp(timestampTokenInfo, info.getEncryptedDigest());
// Create a timestamp object
timestamp =
new Timestamp(timestampTokenInfo.getDate(), tsaChain);
@@ -556,6 +558,31 @@
return timestamp;
}
+ /*
+ * Check that the signature timestamp applies to this signature.
+ * Match the hash present in the signature timestamp token against the hash
+ * of this signature.
+ */
+ private void verifyTimestamp(TimestampToken token, byte[] signature)
+ throws NoSuchAlgorithmException, SignatureException {
+
+ MessageDigest md =
+ MessageDigest.getInstance(token.getHashAlgorithm().getName());
+
+ if (!Arrays.equals(token.getHashedMessage(), md.digest(signature))) {
+ throw new SignatureException("Signature timestamp (#" +
+ token.getSerialNumber() + ") generated on " + token.getDate() +
+ " is inapplicable");
+ }
+
+ if (debug != null) {
+ debug.println();
+ debug.println("Detected signature timestamp (#" +
+ token.getSerialNumber() + ") generated on " + token.getDate());
+ debug.println();
+ }
+ }
+
// for the toHex function
private static final char[] hexc =
{'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
diff --git a/jdk/src/share/native/java/lang/ClassLoader.c b/jdk/src/share/native/java/lang/ClassLoader.c
index 8965d0a..da16171 100644
--- a/jdk/src/share/native/java/lang/ClassLoader.c
+++ b/jdk/src/share/native/java/lang/ClassLoader.c
@@ -439,20 +439,3 @@
return res;
}
-JNIEXPORT jobject JNICALL
-Java_java_lang_ClassLoader_getCaller(JNIEnv *env, jclass cls, jint index)
-{
- jobjectArray jcallerStack;
- int len;
-
- jcallerStack = JVM_GetClassContext(env);
- if ((*env)->ExceptionCheck(env)) {
- return NULL;
- }
- len = (*env)->GetArrayLength(env, jcallerStack);
- if (index < len) {
- return (*env)->GetObjectArrayElement(env, jcallerStack, index);
- }
- return NULL;
-}
-
diff --git a/jdk/src/share/native/java/lang/SecurityManager.c b/jdk/src/share/native/java/lang/SecurityManager.c
index 397e30b..a815df5 100644
--- a/jdk/src/share/native/java/lang/SecurityManager.c
+++ b/jdk/src/share/native/java/lang/SecurityManager.c
@@ -29,7 +29,6 @@
#include "java_lang_SecurityManager.h"
#include "java_lang_ClassLoader.h"
-#include "java_util_ResourceBundle.h"
/*
* Make sure a security manager instance is initialized.
diff --git a/jdk/src/share/native/java/util/zip/ZipFile.c b/jdk/src/share/native/java/util/zip/ZipFile.c
index 99d6d22..22fe62a 100644
--- a/jdk/src/share/native/java/util/zip/ZipFile.c
+++ b/jdk/src/share/native/java/util/zip/ZipFile.c
@@ -136,6 +136,14 @@
return zip->total;
}
+JNIEXPORT jboolean JNICALL
+Java_java_util_zip_ZipFile_startsWithLOC(JNIEnv *env, jclass cls, jlong zfile)
+{
+ jzfile *zip = jlong_to_ptr(zfile);
+
+ return zip->locsig;
+}
+
JNIEXPORT void JNICALL
Java_java_util_zip_ZipFile_close(JNIEnv *env, jclass cls, jlong zfile)
{
diff --git a/jdk/src/share/native/java/util/zip/zip_util.c b/jdk/src/share/native/java/util/zip/zip_util.c
index 991ed5c..ed010eb 100644
--- a/jdk/src/share/native/java/util/zip/zip_util.c
+++ b/jdk/src/share/native/java/util/zip/zip_util.c
@@ -830,6 +830,14 @@
return NULL;
}
+ // Assumption, zfd refers to start of file. Trivially, reuse errbuf.
+ if (readFully(zfd, errbuf, 4) != -1) { // errors will be handled later
+ if (GETSIG(errbuf) == LOCSIG)
+ zip->locsig = JNI_TRUE;
+ else
+ zip->locsig = JNI_FALSE;
+ }
+
len = zip->len = IO_Lseek(zfd, 0, SEEK_END);
if (len <= 0) {
if (len == 0) { /* zip file is empty */
diff --git a/jdk/src/share/native/java/util/zip/zip_util.h b/jdk/src/share/native/java/util/zip/zip_util.h
index 5771e86..b30529c 100644
--- a/jdk/src/share/native/java/util/zip/zip_util.h
+++ b/jdk/src/share/native/java/util/zip/zip_util.h
@@ -210,6 +210,7 @@
start of the file. */
jboolean usemmap; /* if mmap is used. */
#endif
+ jboolean locsig; /* if zip file starts with LOCSIG */
cencache cencache; /* CEN header cache */
ZFILE zfd; /* open file descriptor */
void *lock; /* read lock */
diff --git a/jdk/src/share/native/sun/awt/medialib/awt_ImagingLib.c b/jdk/src/share/native/sun/awt/medialib/awt_ImagingLib.c
index 5730734..e86fb6c 100644
--- a/jdk/src/share/native/sun/awt/medialib/awt_ImagingLib.c
+++ b/jdk/src/share/native/sun/awt/medialib/awt_ImagingLib.c
@@ -1152,22 +1152,127 @@
return retStatus;
}
+typedef struct {
+ jobject jArray;
+ jsize length;
+ unsigned char *table;
+} LookupArrayInfo;
+
+#define NLUT 8
+
+#ifdef _LITTLE_ENDIAN
+#define INDEXES { 3, 2, 1, 0, 7, 6, 5, 4 }
+#else
+#define INDEXES { 0, 1, 2, 3, 4, 5, 6, 7 }
+#endif
+
+static int lookupShortData(mlib_image* src, mlib_image* dst,
+ LookupArrayInfo* lookup)
+{
+ int x, y;
+ unsigned int mask = NLUT-1;
+
+ unsigned short* srcLine = (unsigned short*)src->data;
+ unsigned char* dstLine = (unsigned char*)dst->data;
+
+ static int indexes[NLUT] = INDEXES;
+
+ for (y=0; y < src->height; y++) {
+ int nloop, nx;
+ int npix = src->width;
+
+ unsigned short* srcPixel = srcLine;
+ unsigned char* dstPixel = dstLine;
+
+#ifdef SIMPLE_LOOKUP_LOOP
+ for (x=0; status && x < width; x++) {
+ unsigned short s = *srcPixel++;
+ if (s >= lookup->length) {
+ /* we can not handle source image using
+ * byte lookup table. Fall back to processing
+ * images in java
+ */
+ return 0;
+ }
+ *dstPixel++ = lookup->table[s];
+ }
+#else
+ /* Get to 32 bit-aligned point */
+ while(((uintptr_t)dstPixel & 0x3) != 0 && npix>0) {
+ unsigned short s = *srcPixel++;
+ if (s >= lookup->length) {
+ return 0;
+ }
+ *dstPixel++ = lookup->table[s];
+ npix--;
+ }
+
+ /*
+ * Do NLUT pixels per loop iteration.
+ * Pack into ints and write out 2 at a time.
+ */
+ nloop = npix/NLUT;
+ nx = npix%NLUT;
+
+ for(x=nloop; x!=0; x--) {
+ int i = 0;
+ int* dstP = (int*)dstPixel;
+
+ for (i = 0; i < NLUT; i++) {
+ if (srcPixel[i] >= lookup->length) {
+ return 0;
+ }
+ }
+
+ dstP[0] = (int)
+ ((lookup->table[srcPixel[indexes[0]]] << 24) |
+ (lookup->table[srcPixel[indexes[1]]] << 16) |
+ (lookup->table[srcPixel[indexes[2]]] << 8) |
+ lookup->table[srcPixel[indexes[3]]]);
+ dstP[1] = (int)
+ ((lookup->table[srcPixel[indexes[4]]] << 24) |
+ (lookup->table[srcPixel[indexes[5]]] << 16) |
+ (lookup->table[srcPixel[indexes[6]]] << 8) |
+ lookup->table[srcPixel[indexes[7]]]);
+
+
+ dstPixel += NLUT;
+ srcPixel += NLUT;
+ }
+
+ /*
+ * Complete any remaining pixels
+ */
+ for(x=nx; x!=0; x--) {
+ unsigned short s = *srcPixel++;
+ if (s >= lookup->length) {
+ return 0;
+ }
+ *dstPixel++ = lookup->table[s];
+ }
+#endif
+
+ dstLine += dst->stride; // array of bytes, scan stride in bytes
+ srcLine += src->stride / 2; // array of shorts, scan stride in bytes
+ }
+ return 1;
+}
+
JNIEXPORT jint JNICALL
-Java_sun_awt_image_ImagingLib_lookupByteBI(JNIEnv *env, jobject this,
+Java_sun_awt_image_ImagingLib_lookupByteBI(JNIEnv *env, jobject thisLib,
jobject jsrc, jobject jdst,
jobjectArray jtableArrays)
{
mlib_image *src;
mlib_image *dst;
void *sdata, *ddata;
- unsigned char **table;
unsigned char **tbl;
unsigned char lut[256];
int retStatus = 1;
int i;
mlib_status status;
- int jlen;
- jobject *jtable;
+ int lut_nbands;
+ LookupArrayInfo *jtable;
BufImageS_t *srcImageP, *dstImageP;
int nbands;
int ncomponents;
@@ -1193,12 +1298,29 @@
return 0;
}
- jlen = (*env)->GetArrayLength(env, jtableArrays);
+ lut_nbands = (*env)->GetArrayLength(env, jtableArrays);
ncomponents = srcImageP->cmodel.isDefaultCompatCM
? 4
: srcImageP->cmodel.numComponents;
+ if (lut_nbands > ncomponents) {
+ lut_nbands = ncomponents;
+ }
+
+ /* Make sure that color order can be used for
+ * re-ordering of lookup arrays.
+ */
+ for (i = 0; i < ncomponents; i++) {
+ int idx = srcImageP->hints.colorOrder[i];
+
+ if (idx < 0 || idx >= ncomponents) {
+ awt_freeParsedImage(srcImageP, TRUE);
+ awt_freeParsedImage(dstImageP, TRUE);
+ return 0;
+ }
+ }
+
tbl = NULL;
if (SAFE_TO_ALLOC_2(ncomponents, sizeof(unsigned char *))) {
tbl = (unsigned char **)
@@ -1206,18 +1328,12 @@
}
jtable = NULL;
- if (SAFE_TO_ALLOC_2(jlen, sizeof(jobject *))) {
- jtable = (jobject *)malloc(jlen * sizeof (jobject *));
+ if (SAFE_TO_ALLOC_2(lut_nbands, sizeof(LookupArrayInfo))) {
+ jtable = (LookupArrayInfo *)malloc(lut_nbands * sizeof (LookupArrayInfo));
}
- table = NULL;
- if (SAFE_TO_ALLOC_2(jlen, sizeof(unsigned char *))) {
- table = (unsigned char **)malloc(jlen * sizeof(unsigned char *));
- }
-
- if (tbl == NULL || table == NULL || jtable == NULL) {
+ if (tbl == NULL || jtable == NULL) {
if (tbl != NULL) free(tbl);
- if (table != NULL) free(table);
if (jtable != NULL) free(jtable);
awt_freeParsedImage(srcImageP, TRUE);
awt_freeParsedImage(dstImageP, TRUE);
@@ -1225,11 +1341,21 @@
return 0;
}
/* Need to grab these pointers before we lock down arrays */
- for (i=0; i < jlen; i++) {
- jtable[i] = (*env)->GetObjectArrayElement(env, jtableArrays, i);
- if (jtable[i] == NULL) {
+ for (i=0; i < lut_nbands; i++) {
+ jtable[i].jArray = (*env)->GetObjectArrayElement(env, jtableArrays, i);
+
+ if (jtable[i].jArray != NULL) {
+ jtable[i].length = (*env)->GetArrayLength(env, jtable[i].jArray);
+ jtable[i].table = NULL;
+
+ if (jtable[i].length < 256) {
+ /* we may read outside the table during lookup */
+ jtable[i].jArray = NULL;
+ jtable[i].length = 0;
+ }
+ }
+ if (jtable[i].jArray == NULL) {
free(tbl);
- free(table);
free(jtable);
awt_freeParsedImage(srcImageP, TRUE);
awt_freeParsedImage(dstImageP, TRUE);
@@ -1242,7 +1368,6 @@
if (nbands < 1) {
/* Can't handle any custom images */
free(tbl);
- free(table);
free(jtable);
awt_freeParsedImage(srcImageP, TRUE);
awt_freeParsedImage(dstImageP, TRUE);
@@ -1253,7 +1378,6 @@
if (allocateArray(env, srcImageP, &src, &sdata, TRUE, FALSE, FALSE) < 0) {
/* Must be some problem */
free(tbl);
- free(table);
free(jtable);
awt_freeParsedImage(srcImageP, TRUE);
awt_freeParsedImage(dstImageP, TRUE);
@@ -1262,7 +1386,6 @@
if (allocateArray(env, dstImageP, &dst, &ddata, FALSE, FALSE, FALSE) < 0) {
/* Must be some problem */
free(tbl);
- free(table);
free(jtable);
freeArray(env, srcImageP, src, sdata, NULL, NULL, NULL);
awt_freeParsedImage(srcImageP, TRUE);
@@ -1278,7 +1401,7 @@
* sufficient number of lookup arrays we add references to identity
* lookup array to make medialib happier.
*/
- if (jlen < ncomponents) {
+ if (lut_nbands < ncomponents) {
int j;
/* REMIND: This should be the size of the input lut!! */
for (j=0; j < 256; j++) {
@@ -1287,65 +1410,45 @@
for (j=0; j < ncomponents; j++) {
tbl[j] = lut;
}
-
}
- for (i=0; i < jlen; i++) {
- table[i] = (unsigned char *)
- (*env)->GetPrimitiveArrayCritical(env, jtable[i], NULL);
- if (table[i] == NULL) {
+ for (i=0; i < lut_nbands; i++) {
+ jtable[i].table = (unsigned char *)
+ (*env)->GetPrimitiveArrayCritical(env, jtable[i].jArray, NULL);
+ if (jtable[i].table == NULL) {
/* Free what we've got so far. */
int j;
for (j = 0; j < i; j++) {
(*env)->ReleasePrimitiveArrayCritical(env,
- jtable[j],
- (jbyte *) table[j],
+ jtable[j].jArray,
+ (jbyte *) jtable[j].table,
JNI_ABORT);
}
free(tbl);
- free(table);
free(jtable);
freeArray(env, srcImageP, src, sdata, NULL, NULL, NULL);
awt_freeParsedImage(srcImageP, TRUE);
awt_freeParsedImage(dstImageP, TRUE);
return 0;
}
- tbl[srcImageP->hints.colorOrder[i]] = table[i];
+ tbl[srcImageP->hints.colorOrder[i]] = jtable[i].table;
}
- if (jlen == 1) {
+ if (lut_nbands == 1) {
for (i=1; i < nbands -
srcImageP->cmodel.supportsAlpha; i++) {
- tbl[srcImageP->hints.colorOrder[i]] = table[0];
+ tbl[srcImageP->hints.colorOrder[i]] = jtable[0].table;
}
}
/* Mlib needs 16bit lookuptable and must be signed! */
if (src->type == MLIB_SHORT) {
- unsigned short *sdataP = (unsigned short *) src->data;
- unsigned short *sP;
if (dst->type == MLIB_BYTE) {
- unsigned char *cdataP = (unsigned char *) dst->data;
- unsigned char *cP;
if (nbands > 1) {
retStatus = 0;
}
else {
- int x, y;
- for (y=0; y < src->height; y++) {
- cP = cdataP;
- sP = sdataP;
- for (x=0; x < src->width; x++) {
- *cP++ = table[0][*sP++];
- }
-
- /*
- * 4554571: increment pointers using the scanline stride
- * in pixel units (not byte units)
- */
- cdataP += dstImageP->raster.scanlineStride;
- sdataP += srcImageP->raster.scanlineStride;
- }
+ retStatus = lookupShortData(src, dst, &jtable[0]);
}
}
/* How about ddata == null? */
@@ -1370,12 +1473,11 @@
}
/* Release the LUT */
- for (i=0; i < jlen; i++) {
- (*env)->ReleasePrimitiveArrayCritical(env, jtable[i],
- (jbyte *) table[i], JNI_ABORT);
+ for (i=0; i < lut_nbands; i++) {
+ (*env)->ReleasePrimitiveArrayCritical(env, jtable[i].jArray,
+ (jbyte *) jtable[i].table, JNI_ABORT);
}
free ((void *) jtable);
- free ((void *) table);
free ((void *) tbl);
/* Release the pinned memory */
@@ -1389,7 +1491,6 @@
return retStatus;
}
-
JNIEXPORT jint JNICALL
Java_sun_awt_image_ImagingLib_lookupByteRaster(JNIEnv *env,
jobject this,
@@ -1403,8 +1504,8 @@
mlib_image* dst;
void* sdata;
void* ddata;
- jobject jtable[4];
- unsigned char* table[4];
+ LookupArrayInfo jtable[4];
+ unsigned char* mlib_lookupTable[4];
int i;
int retStatus = 1;
mlib_status status;
@@ -1452,6 +1553,11 @@
src_nbands = srcRasterP->numBands;
dst_nbands = dstRasterP->numBands;
+ /* adjust number of lookup bands */
+ if (lut_nbands > src_nbands) {
+ lut_nbands = src_nbands;
+ }
+
/* MediaLib can't do more than 4 bands */
if (src_nbands <= 0 || src_nbands > 4 ||
dst_nbands <= 0 || dst_nbands > 4 ||
@@ -1516,22 +1622,37 @@
/* Get references to the lookup table arrays */
/* Need to grab these pointers before we lock down arrays */
for (i=0; i < lut_nbands; i++) {
- jtable[i] = (*env)->GetObjectArrayElement(env, jtableArrays, i);
- if (jtable[i] == NULL) {
+ jtable[i].jArray = (*env)->GetObjectArrayElement(env, jtableArrays, i);
+ jtable[i].table = NULL;
+ if (jtable[i].jArray != NULL) {
+ jtable[i].length = (*env)->GetArrayLength(env, jtable[i].jArray);
+ if (jtable[i].length < 256) {
+ /* we may read outside the table during lookup */
+ jtable[i].jArray = NULL;
+ }
+ }
+
+ if (jtable[i].jArray == NULL)
+ {
+ freeDataArray(env, srcRasterP->jdata, src, sdata,
+ dstRasterP->jdata, dst, ddata);
+
+ awt_freeParsedRaster(srcRasterP, TRUE);
+ awt_freeParsedRaster(dstRasterP, TRUE);
return 0;
}
}
for (i=0; i < lut_nbands; i++) {
- table[i] = (unsigned char *)
- (*env)->GetPrimitiveArrayCritical(env, jtable[i], NULL);
- if (table[i] == NULL) {
+ jtable[i].table = (unsigned char *)
+ (*env)->GetPrimitiveArrayCritical(env, jtable[i].jArray, NULL);
+ if (jtable[i].table == NULL) {
/* Free what we've got so far. */
int j;
for (j = 0; j < i; j++) {
(*env)->ReleasePrimitiveArrayCritical(env,
- jtable[j],
- (jbyte *) table[j],
+ jtable[j].jArray,
+ (jbyte *) jtable[j].table,
JNI_ABORT);
}
freeDataArray(env, srcRasterP->jdata, src, sdata,
@@ -1540,6 +1661,7 @@
awt_freeParsedRaster(dstRasterP, TRUE);
return 0;
}
+ mlib_lookupTable[i] = jtable[i].table;
}
/*
@@ -1548,107 +1670,28 @@
* contains single lookup array.
*/
for (i = lut_nbands; i < src_nbands; i++) {
- table[i] = table[0];
+ mlib_lookupTable[i] = jtable[0].table;
}
/*
* Setup lookup array for "extra" channels
*/
for ( ; i < src->channels; i++) {
- table[i] = ilut;
+ mlib_lookupTable[i] = ilut;
}
-#define NLUT 8
/* Mlib needs 16bit lookuptable and must be signed! */
if (src->type == MLIB_SHORT) {
- unsigned short *sdataP = (unsigned short *) src->data;
- unsigned short *sP;
if (dst->type == MLIB_BYTE) {
- unsigned char *cdataP = (unsigned char *) dst->data;
- unsigned char *cP;
if (lut_nbands > 1) {
retStatus = 0;
} else {
- int x, y;
- unsigned int mask = NLUT-1;
- unsigned char* pLut = table[0];
- unsigned int endianTest = 0xff000000;
- for (y=0; y < src->height; y++) {
- int nloop, nx;
- unsigned short* srcP;
- int* dstP;
- int npix = src->width;
- cP = cdataP;
- sP = sdataP;
- /* Get to 32 bit-aligned point */
- while(((uintptr_t)cP & 0x3) != 0 && npix>0) {
- *cP++ = pLut[*sP++];
- npix--;
- }
-
- /*
- * Do NLUT pixels per loop iteration.
- * Pack into ints and write out 2 at a time.
- */
- nloop = npix/NLUT;
- nx = npix%NLUT;
- srcP = sP;
- dstP = (int*)cP;
-
- if(((char*)(&endianTest))[0] != 0) {
- /* Big endian loop */
- for(x=nloop; x!=0; x--) {
- dstP[0] = (int)
- ((pLut[srcP[0]] << 24) |
- (pLut[srcP[1]] << 16) |
- (pLut[srcP[2]] << 8) |
- pLut[srcP[3]]);
- dstP[1] = (int)
- ((pLut[srcP[4]] << 24) |
- (pLut[srcP[5]] << 16) |
- (pLut[srcP[6]] << 8) |
- pLut[srcP[7]]);
- dstP += NLUT/4;
- srcP += NLUT;
- }
- } else {
- /* Little endian loop */
- for(x=nloop; x!=0; x--) {
- dstP[0] = (int)
- ((pLut[srcP[3]] << 24) |
- (pLut[srcP[2]] << 16) |
- (pLut[srcP[1]] << 8) |
- pLut[srcP[0]]);
- dstP[1] = (int)
- ((pLut[srcP[7]] << 24) |
- (pLut[srcP[6]] << 16) |
- (pLut[srcP[5]] << 8) |
- pLut[srcP[4]]);
- dstP += NLUT/4;
- srcP += NLUT;
- }
- }
- /*
- * Complete any remaining pixels
- */
- cP = cP + NLUT * nloop;
- sP = sP + NLUT * nloop;
- for(x=nx; x!=0; x--) {
- *cP++ = pLut[*sP++];
- }
-
- /*
- * 4554571: increment pointers using the scanline stride
- * in pixel units (not byte units)
- */
- cdataP += dstRasterP->scanlineStride;
- sdataP += srcRasterP->scanlineStride;
- }
+ retStatus = lookupShortData(src, dst, &jtable[0]);
}
}
/* How about ddata == null? */
} else if ((status = (*sMlibFns[MLIB_LOOKUP].fptr)(dst, src,
- (void **)table) != MLIB_SUCCESS)) {
+ (void **)mlib_lookupTable) != MLIB_SUCCESS)) {
printMedialibError(status);
retStatus = 0;
}
@@ -1677,8 +1720,8 @@
/* Release the LUT */
for (i=0; i < lut_nbands; i++) {
- (*env)->ReleasePrimitiveArrayCritical(env, jtable[i],
- (jbyte *) table[i], JNI_ABORT);
+ (*env)->ReleasePrimitiveArrayCritical(env, jtable[i].jArray,
+ (jbyte *) jtable[i].table, JNI_ABORT);
}
/* Release the pinned memory */
diff --git a/jdk/src/share/native/sun/awt/medialib/mlib_ImageCreate.c b/jdk/src/share/native/sun/awt/medialib/mlib_ImageCreate.c
index 97abea2..2e136df 100644
--- a/jdk/src/share/native/sun/awt/medialib/mlib_ImageCreate.c
+++ b/jdk/src/share/native/sun/awt/medialib/mlib_ImageCreate.c
@@ -160,27 +160,46 @@
/* Check if stride == width
* If it is then image can be treated as a 1-D vector
*/
+
+ if (!SAFE_TO_MULT(width, channels)) {
+ return NULL;
+ }
+
+ wb = width * channels;
+
switch (type) {
case MLIB_DOUBLE:
- wb = width * channels * 8;
+ if (!SAFE_TO_MULT(wb, 8)) {
+ return NULL;
+ }
+ wb *= 8;
mask = 7;
break;
case MLIB_FLOAT:
case MLIB_INT:
- wb = width * channels * 4;
+ if (!SAFE_TO_MULT(wb, 4)) {
+ return NULL;
+ }
+ wb *= 4;
mask = 3;
break;
case MLIB_USHORT:
case MLIB_SHORT:
- wb = width * channels * 2;
+ if (!SAFE_TO_MULT(wb, 2)) {
+ return NULL;
+ }
+ wb *= 2;
mask = 1;
break;
case MLIB_BYTE:
- wb = width * channels;
+ // wb is ready
mask = 0;
break;
case MLIB_BIT:
- wb = (width * channels + 7) / 8;
+ if (!SAFE_TO_ADD(7, wb)) {
+ return NULL;
+ }
+ wb = (wb + 7) / 8;
mask = 0;
break;
default:
@@ -270,7 +289,7 @@
break;
case MLIB_USHORT:
case MLIB_SHORT:
- if (!SAFE_TO_MULT(wb, 4)) {
+ if (!SAFE_TO_MULT(wb, 2)) {
return NULL;
}
wb *= 2;
diff --git a/jdk/src/share/native/sun/reflect/Reflection.c b/jdk/src/share/native/sun/reflect/Reflection.c
index 5a92d9e..cd26fee 100644
--- a/jdk/src/share/native/sun/reflect/Reflection.c
+++ b/jdk/src/share/native/sun/reflect/Reflection.c
@@ -27,9 +27,11 @@
#include "sun_reflect_Reflection.h"
JNIEXPORT jclass JNICALL Java_sun_reflect_Reflection_getCallerClass
-(JNIEnv *env, jclass unused, jint depth)
+(JNIEnv *env, jclass unused)
{
- return JVM_GetCallerClass(env, depth);
+ // Until there is hotspot @CallerSensitive support,
+ // depth must always be 2 to get the immediate caller
+ return JVM_GetCallerClass(env, 2);
}
JNIEXPORT jint JNICALL Java_sun_reflect_Reflection_getClassAccessFlags
diff --git a/jdk/src/windows/native/sun/windows/awt_Component.cpp b/jdk/src/windows/native/sun/windows/awt_Component.cpp
index eaaa7be..be29fe0 100644
--- a/jdk/src/windows/native/sun/windows/awt_Component.cpp
+++ b/jdk/src/windows/native/sun/windows/awt_Component.cpp
@@ -6131,7 +6131,7 @@
RGNDATA *pRgnData = (RGNDATA *) SAFE_SIZE_STRUCT_ALLOC(safe_Malloc,
sizeof(RGNDATAHEADER), sizeof(RECT_T), numrects);
- memcpy(pRgnData + sizeof(RGNDATAHEADER), pRect, sizeof(RECT_T) * numrects);
+ memcpy((BYTE*)pRgnData + sizeof(RGNDATAHEADER), pRect, sizeof(RECT_T) * numrects);
if (pRect != rects) {
free(pRect);
}
diff --git a/jdk/test/Makefile b/jdk/test/Makefile
index 1fe631b..83097aa 100644
--- a/jdk/test/Makefile
+++ b/jdk/test/Makefile
@@ -484,7 +484,7 @@
# Stable agentvm testruns (minus items from PROBLEM_LIST)
JDK_ALL_TARGETS += jdk_lang
-jdk_lang: $(call TestDirs, java/lang)
+jdk_lang: $(call TestDirs, java/lang sun/reflect)
$(call RunAgentvmBatch)
# Stable othervm testruns (minus items from PROBLEM_LIST)
@@ -513,7 +513,7 @@
jdk_misc: $(call TestDirs, \
demo/jvmti demo/zipfs javax/naming javax/script \
javax/smartcardio javax/xml com/sun/jndi com/sun/org/glassfish \
- com/sun/xml sun/misc)
+ com/sun/corba com/sun/xml sun/misc)
$(call RunAgentvmBatch)
# Stable samevm testruns (minus items from PROBLEM_LIST)
diff --git a/jdk/test/java/util/logging/bundlesearch/ClassPathTestBundle_en.properties b/jdk/test/java/util/logging/bundlesearch/ClassPathTestBundle_en.properties
new file mode 100644
index 0000000..7184870
--- /dev/null
+++ b/jdk/test/java/util/logging/bundlesearch/ClassPathTestBundle_en.properties
@@ -0,0 +1,25 @@
+#
+# Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+sample1=translation #2 for sample1
+sample2=translation #2 for sample2
+supports-test=ResourceBundleSearchTest
diff --git a/jdk/test/java/util/logging/bundlesearch/IndirectlyLoadABundle.java b/jdk/test/java/util/logging/bundlesearch/IndirectlyLoadABundle.java
new file mode 100644
index 0000000..47ae96b
--- /dev/null
+++ b/jdk/test/java/util/logging/bundlesearch/IndirectlyLoadABundle.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.net.URLClassLoader;
+
+/**
+ * This class is used to ensure that a resource bundle loadable by a classloader
+ * is on the caller's stack, but not on the classpath or TCCL to ensure that
+ * Logger.getLogger() can't load the bundle via a stack search
+ *
+ * @author Jim Gish
+ */
+public class IndirectlyLoadABundle {
+
+ private final static String rbName = "StackSearchableResource";
+
+ public boolean loadAndTest() throws Throwable {
+ // Find out where we are running from so we can setup the URLClassLoader URLs
+ // test.src and test.classes will be set if running in jtreg, but probably
+ // not otherwise
+ String testDir = System.getProperty("test.src", System.getProperty("user.dir"));
+ String testClassesDir = System.getProperty("test.classes",
+ System.getProperty("user.dir"));
+ String sep = System.getProperty("file.separator");
+ URL[] urls = new URL[2];
+
+ // Allow for both jtreg and standalone cases here
+ urls[0] = new URL("file://" + testDir + sep + "resources" + sep);
+ urls[1] = new URL("file://" + testClassesDir + sep );
+ System.out.println("INFO: urls[0] = " + urls[0]);
+ System.out.println("INFO: urls[1] = " + urls[1]);
+
+ // Make sure we can find it via the URLClassLoader
+ URLClassLoader yetAnotherResourceCL = new URLClassLoader(urls, null);
+ if (!testForValidResourceSetup(yetAnotherResourceCL)) {
+ throw new Exception("Couldn't directly load bundle " + rbName
+ + " as expected. Test config problem");
+ }
+ // But it shouldn't be available via the system classloader
+ ClassLoader myCL = this.getClass().getClassLoader();
+ if (testForValidResourceSetup(myCL)) {
+ throw new Exception("Was able to directly load bundle " + rbName
+ + " from " + myCL + " but shouldn't have been"
+ + " able to. Test config problem");
+ }
+
+ Class<?> loadItUpClazz = Class.forName("LoadItUp", true, yetAnotherResourceCL);
+ ClassLoader actual = loadItUpClazz.getClassLoader();
+ if (actual != yetAnotherResourceCL) {
+ throw new Exception("LoadItUp was loaded by an unexpected CL: " + actual);
+ }
+ Object loadItUp = loadItUpClazz.newInstance();
+ Method testMethod = loadItUpClazz.getMethod("test", String.class);
+ try {
+ return (Boolean) testMethod.invoke(loadItUp, rbName);
+ } catch (InvocationTargetException ex) {
+ throw ex.getTargetException();
+ }
+ }
+
+ private boolean testForValidResourceSetup(ClassLoader cl) {
+ // First make sure the test environment is setup properly and the bundle actually
+ // exists
+ return ResourceBundleSearchTest.isOnClassPath(rbName, cl);
+ }
+}
diff --git a/jdk/test/java/util/logging/bundlesearch/LoadItUp.java b/jdk/test/java/util/logging/bundlesearch/LoadItUp.java
new file mode 100644
index 0000000..d47b9a3
--- /dev/null
+++ b/jdk/test/java/util/logging/bundlesearch/LoadItUp.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+import java.util.MissingResourceException;
+import java.util.logging.Logger;
+
+/*
+ * This class is loaded onto the call stack when the test method is called
+ * and then its classloader can be used to find a property bundle in the same
+ * directory as the class. However, Logger is not allowed
+ * to find the bundle by looking up the stack for this classloader.
+ * We verify that this cannot happen.
+ *
+ * @author Jim Gish
+ */
+public class LoadItUp {
+
+ private final static boolean DEBUG = false;
+
+ public Boolean test(String rbName) throws Exception {
+ // we should not be able to find the resource in this directory via
+ // getLogger calls. The only way that would be possible given this setup
+ // is that if Logger.getLogger searched up the call stack
+ return lookupBundle(rbName);
+ }
+
+ private boolean lookupBundle(String rbName) {
+ // See if Logger.getLogger can find the resource in this directory
+ try {
+ Logger aLogger = Logger.getLogger("NestedLogger", rbName);
+ } catch (MissingResourceException re) {
+ if (DEBUG) {
+ System.out.println(
+ "As expected, LoadItUp.lookupBundle() did not find the bundle "
+ + rbName);
+ }
+ return false;
+ }
+ System.out.println("FAILED: LoadItUp.lookupBundle() found the bundle "
+ + rbName + " using a stack search.");
+ return true;
+ }
+}
diff --git a/jdk/test/java/util/logging/bundlesearch/ResourceBundleSearchTest.java b/jdk/test/java/util/logging/bundlesearch/ResourceBundleSearchTest.java
new file mode 100644
index 0000000..d652dfa
--- /dev/null
+++ b/jdk/test/java/util/logging/bundlesearch/ResourceBundleSearchTest.java
@@ -0,0 +1,249 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8010127
+ * @summary Remove the stack search for a resource bundle Logger to use
+ * @author Jim Gish
+ * @build ResourceBundleSearchTest IndirectlyLoadABundle LoadItUp
+ * @run main ResourceBundleSearchTest
+ */
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+import java.util.logging.Logger;
+
+public class ResourceBundleSearchTest {
+
+ private final static boolean DEBUG = false;
+ private final static String LOGGER_PREFIX = "myLogger.";
+ private static int loggerNum = 0;
+ private final static String PROP_RB_NAME = "ClassPathTestBundle";
+ private final static String TCCL_TEST_BUNDLE = "ContextClassLoaderTestBundle";
+
+ private static int numPass = 0;
+ private static int numFail = 0;
+ private static List<String> msgs = new ArrayList<String>();
+
+ public static void main(String[] args) throws Throwable {
+ ResourceBundleSearchTest test = new ResourceBundleSearchTest();
+ test.runTests();
+ }
+
+ private void runTests() throws Throwable {
+ // ensure we are using en as the default Locale so we can find the resource
+ Locale.setDefault(Locale.ENGLISH);
+
+ String testClasses = System.getProperty("test.classes");
+ System.out.println( "test.classes = " + testClasses );
+
+ ClassLoader myClassLoader = ClassLoader.getSystemClassLoader();
+
+ // Find out where we are running from so we can setup the URLClassLoader URL
+ String userDir = System.getProperty("user.dir");
+ String testDir = System.getProperty("test.src", userDir);
+ String sep = System.getProperty("file.separator");
+
+ URL[] urls = new URL[1];
+ urls[0] = new URL("file://" + testDir + sep + "resources" + sep);
+ URLClassLoader rbClassLoader = new URLClassLoader(urls);
+
+ // Test 1 - can we find a Logger bundle from doing a stack search?
+ // We shouldn't be able to
+ assertFalse(testGetBundleFromStackSearch(), "testGetBundleFromStackSearch");
+
+ // Test 2 - can we find a Logger bundle off of the Thread context class
+ // loader? We should be able to.
+ assertTrue(
+ testGetBundleFromTCCL(TCCL_TEST_BUNDLE, rbClassLoader),
+ "testGetBundleFromTCCL");
+
+ // Test 3 - Can we find a Logger bundle from the classpath? We should be
+ // able to, but ....
+ // We check to see if the bundle is on the classpath or not so that this
+ // will work standalone. In the case of jtreg/samevm,
+ // the resource bundles are not on the classpath. Running standalone
+ // (or othervm), they are
+ if (isOnClassPath(PROP_RB_NAME, myClassLoader)) {
+ debug("We should be able to see " + PROP_RB_NAME + " on the classpath");
+ assertTrue(testGetBundleFromSystemClassLoader(PROP_RB_NAME),
+ "testGetBundleFromSystemClassLoader");
+ } else {
+ debug("We should not be able to see " + PROP_RB_NAME + " on the classpath");
+ assertFalse(testGetBundleFromSystemClassLoader(PROP_RB_NAME),
+ "testGetBundleFromSystemClassLoader");
+ }
+
+ report();
+ }
+
+ private void report() throws Exception {
+ System.out.println("Num passed = " + numPass + " Num failed = " + numFail);
+ if (numFail > 0) {
+ // We only care about the messages if they were errors
+ for (String msg : msgs) {
+ System.out.println(msg);
+ }
+ throw new Exception(numFail + " out of " + (numPass + numFail)
+ + " tests failed.");
+ }
+ }
+
+ public void assertTrue(boolean testResult, String testName) {
+ if (testResult) {
+ numPass++;
+ } else {
+ numFail++;
+ System.out.println("FAILED: " + testName
+ + " was supposed to return true but did NOT!");
+ }
+ }
+
+ public void assertFalse(boolean testResult, String testName) {
+ if (!testResult) {
+ numPass++;
+ } else {
+ numFail++;
+ System.out.println("FAILED: " + testName
+ + " was supposed to return false but did NOT!");
+ }
+ }
+
+ public boolean testGetBundleFromStackSearch() throws Throwable {
+ // This should fail. This was the old functionality to search up the
+ // caller's call stack
+ IndirectlyLoadABundle indirectLoader = new IndirectlyLoadABundle();
+ return indirectLoader.loadAndTest();
+ }
+
+ public boolean testGetBundleFromTCCL(String bundleName,
+ ClassLoader setOnTCCL) throws InterruptedException {
+ // This should succeed. We should be able to get the bundle from the
+ // thread context class loader
+ debug("Looking for " + bundleName + " using TCCL");
+ LoggingThread lr = new LoggingThread(bundleName, setOnTCCL);
+ lr.start();
+ synchronized (lr) {
+ try {
+ lr.wait();
+ } catch (InterruptedException ex) {
+ throw ex;
+ }
+ }
+ msgs.add(lr.msg);
+ return lr.foundBundle;
+ }
+
+ /*
+ * @param String bundleClass
+ * @param ClassLoader to use for search
+ * @return true iff bundleClass is on system classpath
+ */
+ public static boolean isOnClassPath(String baseName, ClassLoader cl) {
+ ResourceBundle rb = null;
+ try {
+ rb = ResourceBundle.getBundle(baseName, Locale.getDefault(), cl);
+ System.out.println("INFO: Found bundle " + baseName + " on " + cl);
+ } catch (MissingResourceException e) {
+ System.out.println("INFO: Could not find bundle " + baseName + " on " + cl);
+ return false;
+ }
+ return (rb != null);
+ }
+
+ private static String newLoggerName() {
+ // we need a new logger name every time we attempt to find a bundle via
+ // the Logger.getLogger call, so we'll simply tack on an integer which
+ // we increment each time this is called
+ loggerNum++;
+ return LOGGER_PREFIX + loggerNum;
+ }
+
+ public boolean testGetBundleFromSystemClassLoader(String bundleName) {
+ // this should succeed if the bundle is on the system classpath.
+ try {
+ Logger aLogger = Logger.getLogger(ResourceBundleSearchTest.newLoggerName(),
+ bundleName);
+ } catch (MissingResourceException re) {
+ msgs.add("INFO: testGetBundleFromSystemClassLoader() did not find bundle "
+ + bundleName);
+ return false;
+ }
+ msgs.add("INFO: testGetBundleFromSystemClassLoader() found the bundle "
+ + bundleName);
+ return true;
+ }
+
+ public static class LoggingThread extends Thread {
+
+ boolean foundBundle = false;
+ String msg = null;
+ ClassLoader clToSetOnTCCL = null;
+ String bundleName = null;
+
+ public LoggingThread(String bundleName) {
+ this.bundleName = bundleName;
+ }
+
+ public LoggingThread(String bundleName, ClassLoader setOnTCCL) {
+ this.clToSetOnTCCL = setOnTCCL;
+ this.bundleName = bundleName;
+ }
+
+ public void run() {
+ boolean setTCCL = false;
+ try {
+ if (clToSetOnTCCL != null) {
+ Thread.currentThread().setContextClassLoader(clToSetOnTCCL);
+ setTCCL = true;
+ }
+ // this should succeed if the bundle is on the system classpath.
+ try {
+ Logger aLogger = Logger.getLogger(ResourceBundleSearchTest.newLoggerName(),
+ bundleName);
+ msg = "INFO: LoggingRunnable() found the bundle " + bundleName
+ + (setTCCL ? " with " : " without ") + "setting the TCCL";
+ foundBundle = true;
+ } catch (MissingResourceException re) {
+ msg = "INFO: LoggingRunnable() did not find the bundle " + bundleName
+ + (setTCCL ? " with " : " without ") + "setting the TCCL";
+ foundBundle = false;
+ }
+ } catch (Throwable e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ }
+ }
+
+ private void debug(String msg) {
+ if (DEBUG) {
+ System.out.println(msg);
+ }
+ }
+}
diff --git a/jdk/test/java/util/logging/bundlesearch/resources/ContextClassLoaderTestBundle_en.properties b/jdk/test/java/util/logging/bundlesearch/resources/ContextClassLoaderTestBundle_en.properties
new file mode 100644
index 0000000..ad4085a
--- /dev/null
+++ b/jdk/test/java/util/logging/bundlesearch/resources/ContextClassLoaderTestBundle_en.properties
@@ -0,0 +1,25 @@
+#
+# Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+sample1=translation #3 for sample1
+sample2=translation #3 for sample2
+supports-test=ResourceBundleSearchTest
diff --git a/jdk/test/java/util/logging/bundlesearch/resources/StackSearchableResource_en.properties b/jdk/test/java/util/logging/bundlesearch/resources/StackSearchableResource_en.properties
new file mode 100644
index 0000000..17ba443
--- /dev/null
+++ b/jdk/test/java/util/logging/bundlesearch/resources/StackSearchableResource_en.properties
@@ -0,0 +1,25 @@
+#
+# Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+sample1=translation #4 for sample1
+sample2=translation #4 for sample2
+supports-test=ResourceBundleSearchTest
diff --git a/jdk/test/sun/reflect/CallerSensitive/CallerSensitiveFinder.java b/jdk/test/sun/reflect/CallerSensitive/CallerSensitiveFinder.java
new file mode 100644
index 0000000..d19cee1
--- /dev/null
+++ b/jdk/test/sun/reflect/CallerSensitive/CallerSensitiveFinder.java
@@ -0,0 +1,248 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import com.sun.tools.classfile.*;
+import static com.sun.tools.classfile.ConstantPool.*;
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.FutureTask;
+
+/*
+ * @test
+ * @bug 8010117
+ * @summary Verify if CallerSensitive methods are annotated with
+ * sun.reflect.CallerSensitive annotation
+ * @build CallerSensitiveFinder MethodFinder ClassFileReader
+ * @run main/othervm/timeout=900 -mx800m CallerSensitiveFinder
+ */
+public class CallerSensitiveFinder extends MethodFinder {
+ private static int numThreads = 3;
+ private static boolean verbose = false;
+ public static void main(String[] args) throws Exception {
+ List<Path> classes = new ArrayList<>();
+ String testclasses = System.getProperty("test.classes", ".");
+ int i = 0;
+ while (i < args.length) {
+ String arg = args[i++];
+ if (arg.equals("-v")) {
+ verbose = true;
+ } else {
+ Path p = Paths.get(testclasses, arg);
+ if (!p.toFile().exists()) {
+ throw new IllegalArgumentException(arg + " does not exist");
+ }
+ classes.add(p);
+ }
+ }
+ if (classes.isEmpty()) {
+ classes.addAll(PlatformClassPath.getJREClasses());
+ }
+ final String method = "sun/reflect/Reflection.getCallerClass";
+ CallerSensitiveFinder csfinder = new CallerSensitiveFinder(method);
+
+ List<String> errors = csfinder.run(classes);
+ if (!errors.isEmpty()) {
+ throw new RuntimeException(errors.size() +
+ " caller-sensitive methods are missing @CallerSensitive annotation");
+ }
+ }
+
+ private final List<String> csMethodsMissingAnnotation = new ArrayList<>();
+ private final java.lang.reflect.Method mhnCallerSensitiveMethod;
+ public CallerSensitiveFinder(String... methods) throws Exception {
+ super(methods);
+ this.mhnCallerSensitiveMethod = getIsCallerSensitiveMethod();
+ }
+
+ static java.lang.reflect.Method getIsCallerSensitiveMethod()
+ throws ClassNotFoundException, NoSuchMethodException
+ {
+ Class<?> cls = Class.forName("java.lang.invoke.MethodHandleNatives");
+ java.lang.reflect.Method m = cls.getDeclaredMethod("isCallerSensitiveMethod", Class.class, String.class);
+ m.setAccessible(true);
+ return m;
+ }
+
+ boolean inMethodHandlesList(String classname, String method) {
+ Class<?> cls;
+ try {
+ cls = Class.forName(classname.replace('/', '.'),
+ false,
+ ClassLoader.getSystemClassLoader());
+ return (Boolean) mhnCallerSensitiveMethod.invoke(null, cls, method);
+ } catch (ClassNotFoundException|IllegalAccessException e) {
+ throw new RuntimeException(e);
+ } catch (InvocationTargetException e) {
+ throw new RuntimeException(e.getCause());
+ }
+ }
+
+ public List<String> run(List<Path> classes) throws IOException, InterruptedException,
+ ExecutionException, ConstantPoolException
+ {
+ ExecutorService pool = Executors.newFixedThreadPool(numThreads);
+ for (Path path : classes) {
+ ClassFileReader reader = ClassFileReader.newInstance(path.toFile());
+ for (ClassFile cf : reader.getClassFiles()) {
+ String classFileName = cf.getName();
+ // for each ClassFile
+ // parse constant pool to find matching method refs
+ // parse each method (caller)
+ // - visit and find method references matching the given method name
+ pool.submit(getTask(cf));
+ }
+ }
+ waitForCompletion();
+ pool.shutdown();
+ return csMethodsMissingAnnotation;
+ }
+
+ private static final String CALLER_SENSITIVE_ANNOTATION = "Lsun/reflect/CallerSensitive;";
+ private static boolean isCallerSensitive(Method m, ConstantPool cp)
+ throws ConstantPoolException
+ {
+ RuntimeAnnotations_attribute attr =
+ (RuntimeAnnotations_attribute)m.attributes.get(Attribute.RuntimeVisibleAnnotations);
+ int index = 0;
+ if (attr != null) {
+ for (int i = 0; i < attr.annotations.length; i++) {
+ Annotation ann = attr.annotations[i];
+ String annType = cp.getUTF8Value(ann.type_index);
+ if (CALLER_SENSITIVE_ANNOTATION.equals(annType)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ public void referenceFound(ClassFile cf, Method m, Set<Integer> refs)
+ throws ConstantPoolException
+ {
+ String name = String.format("%s#%s %s", cf.getName(),
+ m.getName(cf.constant_pool),
+ m.descriptor.getValue(cf.constant_pool));
+ if (!CallerSensitiveFinder.isCallerSensitive(m, cf.constant_pool)) {
+ csMethodsMissingAnnotation.add(name);
+ System.err.println(" Missing @CallerSensitive: " + name);
+ } else if (verbose) {
+ System.out.format("Caller found: %s%n", name);
+ }
+ if (m.access_flags.is(AccessFlags.ACC_PUBLIC)) {
+ if (!inMethodHandlesList(cf.getName(), m.getName(cf.constant_pool))) {
+ csMethodsMissingAnnotation.add(name);
+ System.err.println(" Missing in MethodHandleNatives list: " + name);
+ } else if (verbose) {
+ System.out.format("Caller found in MethodHandleNatives list: %s%n", name);
+
+ }
+ }
+ }
+
+ private final List<FutureTask<String>> tasks = new ArrayList<FutureTask<String>>();
+ private FutureTask<String> getTask(final ClassFile cf) {
+ FutureTask<String> task = new FutureTask<String>(new Callable<String>() {
+ public String call() throws Exception {
+ return parse(cf);
+ }
+ });
+ tasks.add(task);
+ return task;
+ }
+
+ private void waitForCompletion() throws InterruptedException, ExecutionException {
+ for (FutureTask<String> t : tasks) {
+ String s = t.get();
+ }
+ System.out.println("Parsed " + tasks.size() + " classfiles");
+ }
+
+ static class PlatformClassPath {
+ static List<Path> getJREClasses() throws IOException {
+ List<Path> result = new ArrayList<Path>();
+ Path home = Paths.get(System.getProperty("java.home"));
+
+ if (home.endsWith("jre")) {
+ // jar files in <javahome>/jre/lib
+ // skip <javahome>/lib
+ result.addAll(addJarFiles(home.resolve("lib")));
+ } else if (home.resolve("lib").toFile().exists()) {
+ // either a JRE or a jdk build image
+ File classes = home.resolve("classes").toFile();
+ if (classes.exists() && classes.isDirectory()) {
+ // jdk build outputdir
+ result.add(classes.toPath());
+ }
+ // add other JAR files
+ result.addAll(addJarFiles(home.resolve("lib")));
+ } else {
+ throw new RuntimeException("\"" + home + "\" not a JDK home");
+ }
+ return result;
+ }
+
+ static List<Path> addJarFiles(final Path root) throws IOException {
+ final List<Path> result = new ArrayList<Path>();
+ final Path ext = root.resolve("ext");
+ Files.walkFileTree(root, new SimpleFileVisitor<Path>() {
+ @Override
+ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
+ throws IOException {
+ if (dir.equals(root) || dir.equals(ext)) {
+ return FileVisitResult.CONTINUE;
+ } else {
+ // skip other cobundled JAR files
+ return FileVisitResult.SKIP_SUBTREE;
+ }
+ }
+
+ @Override
+ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
+ throws IOException {
+ File f = file.toFile();
+ String fn = f.getName();
+ // parse alt-rt.jar as well
+ if (fn.endsWith(".jar") && !fn.equals("jfxrt.jar")) {
+ result.add(file);
+ }
+ return FileVisitResult.CONTINUE;
+ }
+ });
+ return result;
+ }
+ }
+}
diff --git a/jdk/test/sun/reflect/CallerSensitive/ClassFileReader.java b/jdk/test/sun/reflect/CallerSensitive/ClassFileReader.java
new file mode 100644
index 0000000..fadd5ae
--- /dev/null
+++ b/jdk/test/sun/reflect/CallerSensitive/ClassFileReader.java
@@ -0,0 +1,338 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.ConstantPoolException;
+import java.io.*;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.*;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+/**
+ * ClassFileReader reads ClassFile(s) of a given path that can be
+ * a .class file, a directory, or a JAR file.
+ */
+public class ClassFileReader {
+ /**
+ * Returns a ClassFileReader instance of a given path.
+ */
+ public static ClassFileReader newInstance(File path) throws IOException {
+ if (!path.exists()) {
+ throw new FileNotFoundException(path.getAbsolutePath());
+ }
+
+ if (path.isDirectory()) {
+ return new DirectoryReader(path.toPath());
+ } else if (path.getName().endsWith(".jar")) {
+ return new JarFileReader(path.toPath());
+ } else {
+ return new ClassFileReader(path.toPath());
+ }
+ }
+
+ /**
+ * Returns a ClassFileReader instance of a given JarFile.
+ */
+ public static ClassFileReader newInstance(Path path, JarFile jf) throws IOException {
+ return new JarFileReader(path, jf);
+ }
+
+ protected final Path path;
+ protected final String baseFileName;
+ private ClassFileReader(Path path) {
+ this.path = path;
+ this.baseFileName = path.getFileName() != null
+ ? path.getFileName().toString()
+ : path.toString();
+ }
+
+ public String getFileName() {
+ return baseFileName;
+ }
+
+ /**
+ * Returns the ClassFile matching the given binary name
+ * or a fully-qualified class name.
+ */
+ public ClassFile getClassFile(String name) throws IOException {
+ if (name.indexOf('.') > 0) {
+ int i = name.lastIndexOf('.');
+ String pathname = name.replace('.', File.separatorChar) + ".class";
+ if (baseFileName.equals(pathname) ||
+ baseFileName.equals(pathname.substring(0, i) + "$" +
+ pathname.substring(i+1, pathname.length()))) {
+ return readClassFile(path);
+ }
+ } else {
+ if (baseFileName.equals(name.replace('/', File.separatorChar) + ".class")) {
+ return readClassFile(path);
+ }
+ }
+ return null;
+ }
+
+ public Iterable<ClassFile> getClassFiles() throws IOException {
+ return new Iterable<ClassFile>() {
+ public Iterator<ClassFile> iterator() {
+ return new FileIterator();
+ }
+ };
+ }
+
+ protected ClassFile readClassFile(Path p) throws IOException {
+ InputStream is = null;
+ try {
+ is = Files.newInputStream(p);
+ return ClassFile.read(is);
+ } catch (ConstantPoolException e) {
+ throw new ClassFileError(e);
+ } finally {
+ if (is != null) {
+ is.close();
+ }
+ }
+ }
+
+ class FileIterator implements Iterator<ClassFile> {
+ int count;
+ FileIterator() {
+ this.count = 0;
+ }
+ public boolean hasNext() {
+ return count == 0 && baseFileName.endsWith(".class");
+ }
+
+ public ClassFile next() {
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+ try {
+ ClassFile cf = readClassFile(path);
+ count++;
+ return cf;
+ } catch (IOException e) {
+ throw new ClassFileError(e);
+ }
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+ }
+
+ public String toString() {
+ return path.toString();
+ }
+
+ private static class DirectoryReader extends ClassFileReader {
+ DirectoryReader(Path path) throws IOException {
+ super(path);
+ }
+
+ public ClassFile getClassFile(String name) throws IOException {
+ if (name.indexOf('.') > 0) {
+ int i = name.lastIndexOf('.');
+ String pathname = name.replace('.', File.separatorChar) + ".class";
+ Path p = path.resolve(pathname);
+ if (!p.toFile().exists()) {
+ p = path.resolve(pathname.substring(0, i) + "$" +
+ pathname.substring(i+1, pathname.length()));
+ }
+ if (p.toFile().exists()) {
+ return readClassFile(p);
+ }
+ } else {
+ Path p = path.resolve(name + ".class");
+ if (p.toFile().exists()) {
+ return readClassFile(p);
+ }
+ }
+ return null;
+ }
+
+ public Iterable<ClassFile> getClassFiles() throws IOException {
+ final Iterator<ClassFile> iter = new DirectoryIterator();
+ return new Iterable<ClassFile>() {
+ public Iterator<ClassFile> iterator() {
+ return iter;
+ }
+ };
+ }
+
+ private List<Path> walkTree(Path dir) throws IOException {
+ final List<Path> files = new ArrayList<Path>();
+ Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
+ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
+ throws IOException {
+ if (file.toFile().getName().endsWith(".class")) {
+ files.add(file);
+ }
+ return FileVisitResult.CONTINUE;
+ }
+ });
+ return files;
+ }
+
+ class DirectoryIterator implements Iterator<ClassFile> {
+ private List<Path> entries;
+ private int index = 0;
+ DirectoryIterator() throws IOException {
+ entries = walkTree(path);
+ index = 0;
+ }
+
+ public boolean hasNext() {
+ return index != entries.size();
+ }
+
+ public ClassFile next() {
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+ Path path = entries.get(index++);
+ try {
+ return readClassFile(path);
+ } catch (IOException e) {
+ throw new ClassFileError(e);
+ }
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+ }
+ }
+
+ private static class JarFileReader extends ClassFileReader {
+ final JarFile jarfile;
+ JarFileReader(Path path) throws IOException {
+ this(path, new JarFile(path.toFile()));
+ }
+ JarFileReader(Path path, JarFile jf) throws IOException {
+ super(path);
+ this.jarfile = jf;
+ }
+
+ public ClassFile getClassFile(String name) throws IOException {
+ if (name.indexOf('.') > 0) {
+ int i = name.lastIndexOf('.');
+ String entryName = name.replace('.', '/') + ".class";
+ JarEntry e = jarfile.getJarEntry(entryName);
+ if (e == null) {
+ e = jarfile.getJarEntry(entryName.substring(0, i) + "$"
+ + entryName.substring(i + 1, entryName.length()));
+ }
+ if (e != null) {
+ return readClassFile(e);
+ }
+ } else {
+ JarEntry e = jarfile.getJarEntry(name + ".class");
+ if (e != null) {
+ return readClassFile(e);
+ }
+ }
+ return null;
+ }
+
+ private ClassFile readClassFile(JarEntry e) throws IOException {
+ InputStream is = null;
+ try {
+ is = jarfile.getInputStream(e);
+ return ClassFile.read(is);
+ } catch (ConstantPoolException ex) {
+ throw new IOException(ex);
+ } finally {
+ if (is != null)
+ is.close();
+ }
+ }
+
+ public Iterable<ClassFile> getClassFiles() throws IOException {
+ final Iterator<ClassFile> iter = new JarFileIterator();
+ return new Iterable<ClassFile>() {
+ public Iterator<ClassFile> iterator() {
+ return iter;
+ }
+ };
+ }
+
+ class JarFileIterator implements Iterator<ClassFile> {
+ private Enumeration<JarEntry> entries;
+ private JarEntry nextEntry;
+ JarFileIterator() {
+ this.entries = jarfile.entries();
+ while (entries.hasMoreElements()) {
+ JarEntry e = entries.nextElement();
+ String name = e.getName();
+ if (name.endsWith(".class")) {
+ this.nextEntry = e;
+ break;
+ }
+ }
+ }
+
+ public boolean hasNext() {
+ return nextEntry != null;
+ }
+
+ public ClassFile next() {
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+
+ ClassFile cf;
+ try {
+ cf = readClassFile(nextEntry);
+ } catch (IOException e) {
+ throw new ClassFileError(e);
+ }
+ JarEntry entry = nextEntry;
+ nextEntry = null;
+ while (entries.hasMoreElements()) {
+ JarEntry e = entries.nextElement();
+ String name = e.getName();
+ if (name.endsWith(".class")) {
+ nextEntry = e;
+ break;
+ }
+ }
+ return cf;
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+ }
+ }
+
+ public static class ClassFileError extends Error {
+ public ClassFileError(Throwable t) {
+ super(t);
+ }
+ }
+}
diff --git a/jdk/test/sun/reflect/CallerSensitive/MethodFinder.java b/jdk/test/sun/reflect/CallerSensitive/MethodFinder.java
new file mode 100644
index 0000000..8ea7886
--- /dev/null
+++ b/jdk/test/sun/reflect/CallerSensitive/MethodFinder.java
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.*;
+import com.sun.tools.classfile.*;
+import static com.sun.tools.classfile.ConstantPool.*;
+import com.sun.tools.classfile.Instruction.TypeKind;
+
+/**
+ * MethodFinder utility class to find references to the given methods.
+ */
+public abstract class MethodFinder {
+ final List<String> methods;
+ public MethodFinder(String... methods) {
+ this.methods = Arrays.asList(methods);
+ }
+
+ /**
+ * A callback method will be invoked when a method referencing
+ * any of the lookup methods.
+ *
+ * @param cf ClassFile
+ * @param m Method
+ * @param refs Set of constant pool indices that reference the methods
+ * matching the given lookup method names
+ */
+ public abstract void referenceFound(ClassFile cf, Method m, Set<Integer> refs)
+ throws ConstantPoolException;
+
+ public String parse(ClassFile cf) throws ConstantPoolException {
+ List<Integer> cprefs = new ArrayList<Integer>();
+ int index = 1;
+ for (ConstantPool.CPInfo cpInfo : cf.constant_pool.entries()) {
+ if (cpInfo.accept(cpVisitor, null)) {
+ cprefs.add(index);
+ }
+ index += cpInfo.size();
+ }
+
+ if (!cprefs.isEmpty()) {
+ for (Method m : cf.methods) {
+ Set<Integer> refs = new HashSet<Integer>();
+ Code_attribute c_attr = (Code_attribute) m.attributes.get(Attribute.Code);
+ if (c_attr != null) {
+ for (Instruction instr : c_attr.getInstructions()) {
+ int idx = instr.accept(codeVisitor, cprefs);
+ if (idx > 0) {
+ refs.add(idx);
+ }
+ }
+ }
+ if (refs.size() > 0) {
+ referenceFound(cf, m, refs);
+ }
+ }
+ }
+ return cprefs.isEmpty() ? "" : cf.getName();
+ }
+
+ private ConstantPool.Visitor<Boolean,Void> cpVisitor =
+ new ConstantPool.Visitor<Boolean,Void>()
+ {
+ private boolean matches(CPRefInfo info) {
+ try {
+ CONSTANT_NameAndType_info nat = info.getNameAndTypeInfo();
+ return matches(info.getClassName(), nat.getName(), nat.getType());
+ } catch (ConstantPoolException ex) {
+ return false;
+ }
+ }
+
+ private boolean matches(String cn, String name, String type) {
+ return methods.contains(cn + "." + name);
+ }
+
+ public Boolean visitClass(CONSTANT_Class_info info, Void p) {
+ return false;
+ }
+
+ public Boolean visitInterfaceMethodref(CONSTANT_InterfaceMethodref_info info, Void p) {
+ return matches(info);
+ }
+
+ public Boolean visitMethodref(CONSTANT_Methodref_info info, Void p) {
+ return matches(info);
+ }
+
+ public Boolean visitDouble(CONSTANT_Double_info info, Void p) {
+ return false;
+ }
+
+ public Boolean visitFieldref(CONSTANT_Fieldref_info info, Void p) {
+ return false;
+ }
+
+ public Boolean visitFloat(CONSTANT_Float_info info, Void p) {
+ return false;
+ }
+
+ public Boolean visitInteger(CONSTANT_Integer_info info, Void p) {
+ return false;
+ }
+
+ public Boolean visitInvokeDynamic(CONSTANT_InvokeDynamic_info info, Void p) {
+ return false;
+ }
+
+ public Boolean visitLong(CONSTANT_Long_info info, Void p) {
+ return false;
+ }
+
+ public Boolean visitNameAndType(CONSTANT_NameAndType_info info, Void p) {
+ return false;
+ }
+
+ public Boolean visitMethodHandle(CONSTANT_MethodHandle_info info, Void p) {
+ return false;
+ }
+
+ public Boolean visitMethodType(CONSTANT_MethodType_info info, Void p) {
+ return false;
+ }
+
+ public Boolean visitString(CONSTANT_String_info info, Void p) {
+ return false;
+ }
+
+ public Boolean visitUtf8(CONSTANT_Utf8_info info, Void p) {
+ return false;
+ }
+ };
+
+ private Instruction.KindVisitor<Integer, List<Integer>> codeVisitor =
+ new Instruction.KindVisitor<Integer, List<Integer>>()
+ {
+ public Integer visitNoOperands(Instruction instr, List<Integer> p) {
+ return 0;
+ }
+
+ public Integer visitArrayType(Instruction instr, TypeKind kind, List<Integer> p) {
+ return 0;
+ }
+
+ public Integer visitBranch(Instruction instr, int offset, List<Integer> p) {
+ return 0;
+ }
+
+ public Integer visitConstantPoolRef(Instruction instr, int index, List<Integer> p) {
+ return p.contains(index) ? index : 0;
+ }
+
+ public Integer visitConstantPoolRefAndValue(Instruction instr, int index, int value, List<Integer> p) {
+ return p.contains(index) ? index : 0;
+ }
+
+ public Integer visitLocal(Instruction instr, int index, List<Integer> p) {
+ return 0;
+ }
+
+ public Integer visitLocalAndValue(Instruction instr, int index, int value, List<Integer> p) {
+ return 0;
+ }
+
+ public Integer visitLookupSwitch(Instruction instr, int default_, int npairs, int[] matches, int[] offsets, List<Integer> p) {
+ return 0;
+ }
+
+ public Integer visitTableSwitch(Instruction instr, int default_, int low, int high, int[] offsets, List<Integer> p) {
+ return 0;
+ }
+
+ public Integer visitValue(Instruction instr, int value, List<Integer> p) {
+ return 0;
+ }
+
+ public Integer visitUnknown(Instruction instr, List<Integer> p) {
+ return 0;
+ }
+ };
+}
+
diff --git a/jdk/test/sun/reflect/CallerSensitive/MissingCallerSensitive.java b/jdk/test/sun/reflect/CallerSensitive/MissingCallerSensitive.java
new file mode 100644
index 0000000..d682eea
--- /dev/null
+++ b/jdk/test/sun/reflect/CallerSensitive/MissingCallerSensitive.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8010117
+ * @summary Test CallerSensitiveFinder to find missing annotation
+ * @compile -XDignore.symbol.file MissingCallerSensitive.java
+ * @build CallerSensitiveFinder MethodFinder ClassFileReader
+ * @run main/othervm MissingCallerSensitive
+ */
+
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.*;
+public class MissingCallerSensitive {
+ public static void main(String[] args) throws Exception {
+ String testclasses = System.getProperty("test.classes", ".");
+ List<Path> classes = new ArrayList<>();
+ classes.add(Paths.get(testclasses, "MissingCallerSensitive.class"));
+
+ final String method = "sun/reflect/Reflection.getCallerClass";
+ CallerSensitiveFinder csfinder = new CallerSensitiveFinder(method);
+ List<String> errors = csfinder.run(classes);
+ /*
+ * Expected 1 method missing @CallerSenitive and 2 methods not in
+ * the MethodHandleNatives CS list
+ */
+ if (errors.size() != 3) {
+ throw new RuntimeException("Unexpected number of methods found: " + errors.size());
+ }
+ int count=0;
+ for (String e : errors) {
+ if (e.startsWith("MissingCallerSensitive#missingCallerSensitiveAnnotation ")) {
+ count++;
+ }
+ }
+ if (count != 2) {
+ throw new RuntimeException("Error: expected 1 method missing annotation & missing in the list");
+ }
+ }
+
+ @sun.reflect.CallerSensitive
+ public ClassLoader getCallerLoader() {
+ Class<?> c = sun.reflect.Reflection.getCallerClass();
+ return c.getClassLoader();
+ }
+
+ public ClassLoader missingCallerSensitiveAnnotation() {
+ Class<?> c = sun.reflect.Reflection.getCallerClass();
+ return c.getClassLoader();
+ }
+}
diff --git a/langtools/.hgtags b/langtools/.hgtags
index bb3e9b0..9fcc0f9 100644
--- a/langtools/.hgtags
+++ b/langtools/.hgtags
@@ -251,6 +251,7 @@
2782a1c60faf7585dee0af0ef585aeed3288e521 jdk7u17-b02
0abc443a68676c7231b274a324d27204c735acac jdk7u17-b30
1a9b32d36ff86136549f20156cf3e821295228a0 jdk7u17-b31
+a91bdaf125d89b8b2c6ff86c8055aab3b7d2546c jdk7u17-b32
8a12629ea21378f96666628f472cd9a6936a4933 jdk7u21-b01
82103a284427a2512fe884d8f232f1a83d46beb6 jdk7u21-b02
9adfe6a84c3884d5c24f6655e89546a6e0a80129 jdk7u21-b03
@@ -259,6 +260,12 @@
5e0127eb56c3f70bdf67a5b2c57cf218838371ae jdk7u21-b06
08034557136e484b3a7c4d0ec9b21e57ea9cd30b jdk7u21-b07
f3c75c441d5623186e43de0b5a645e12fc360c29 jdk7u21-b08
+b6c7a18b668b85bdc41914b2b354c1928deb659e jdk7u21-b09
+de06078efe709392d7faf44803d54b74599f6bda jdk7u21-b10
+e120818fc321b5d9d8573a58bf5f6a6eb7471229 jdk7u21-b11
+ff6f8ab2635c6e0b0f6bb1a68dca48b4fc31b107 jdk7u21-b30
+a87ad97e80ae1861143b477d8a8990dc6ecc9173 jdk7u21-b12
884621bb9042cd4a06e230307f1e26f1c518346d jdk7u25-b01
1311e3618232058b09fe7ea25eda4af8d3fe6807 jdk7u25-b02
8dc40e209a12638ea18bb7ee436051768afa5d39 jdk7u25-b03
+d7f974b867c4cf771ab749871c2ff4d3f869f13f jdk7u25-b04