提交 2b4a508f 编写于 作者: E ewendeli

Merge

......@@ -66,7 +66,7 @@ int JLI_GetStdArgc();
#include <io.h>
#define JLI_StrCaseCmp(p1, p2) stricmp((p1), (p2))
#define JLI_StrNCaseCmp(p1, p2, p3) strnicmp((p1), (p2), (p3))
#define JLI_Snprintf _snprintf
int JLI_Snprintf(char *buffer, size_t size, const char *format, ...);
void JLI_CmdToArgs(char *cmdline);
#define JLI_Lseek _lseeki64
#else /* NIXES */
......
......@@ -568,9 +568,9 @@ JLI_ParseManifest(char *jarfile, manifest_info *info)
#ifdef O_BINARY
| O_BINARY /* use binary mode on windows */
#endif
)) == -1)
)) == -1) {
return (-1);
}
info->manifest_version = NULL;
info->main_class = NULL;
info->jre_version = NULL;
......@@ -617,12 +617,14 @@ JLI_JarUnpackFile(const char *jarfile, const char *filename, int *size) {
zentry entry;
void *data = NULL;
fd = open(jarfile, O_RDONLY
if ((fd = open(jarfile, O_RDONLY
#ifdef O_BINARY
| O_BINARY /* use binary mode on windows */
#endif
);
if (fd != -1 && find_file(fd, &entry, filename) == 0) {
)) == -1) {
return NULL;
}
if (find_file(fd, &entry, filename) == 0) {
data = inflate_file(fd, &entry, size);
}
close(fd);
......@@ -664,8 +666,9 @@ JLI_ManifestIterate(const char *jarfile, attribute_closure ac, void *user_data)
#ifdef O_BINARY
| O_BINARY /* use binary mode on windows */
#endif
)) == -1)
)) == -1) {
return (-1);
}
if (rc = find_file(fd, &entry, manifest_name) != 0) {
close(fd);
......
......@@ -66,11 +66,14 @@ public final class MethodFinder extends AbstractFinder<Method> {
Signature signature = new Signature(type, name, args);
Method method = CACHE.get(signature);
if (method != null) {
boolean cached = method != null;
if (cached && isPackageAccessible(method.getDeclaringClass())) {
return method;
}
method = findAccessibleMethod(new MethodFinder(name, args).find(type.getMethods()));
CACHE.put(signature, method);
if (!cached) {
CACHE.put(signature, method);
}
return method;
}
......
......@@ -41,6 +41,8 @@ import javax.crypto.ShortBufferException;
import javax.crypto.SecretKey;
import javax.crypto.spec.*;
import sun.security.util.KeyUtil;
/**
* This class implements the Diffie-Hellman key agreement protocol between
* any number of parties.
......@@ -200,6 +202,9 @@ extends KeyAgreementSpi {
throw new InvalidKeyException("Incompatible parameters");
}
// validate the Diffie-Hellman public key
KeyUtil.validate(dhPubKey);
// store the y value
this.y = dhPubKey.getY();
......
......@@ -1000,7 +1000,6 @@ class BandStructure {
/** Write a constant pool reference. */
public void putRef(Entry e) {
assert(index != null);
addValue(encodeRefOrNull(e, index));
}
public void putRef(Entry e, Index index) {
......@@ -1052,6 +1051,8 @@ class BandStructure {
int encodeRef(Entry e, Index ix) {
if (ix == null)
throw new RuntimeException("null index for " + e.stringValue());
int coding = ix.indexOf(e);
if (verbose > 2)
Utils.log.fine("putRef "+coding+" => "+e);
......
......@@ -1405,6 +1405,8 @@ class ConstantPool {
/** Index of all CP entries of a given tag and class. */
public Index getMemberIndex(byte tag, ClassEntry classRef) {
if (classRef == null)
throw new RuntimeException("missing class reference for " + tagName(tag));
if (indexByTagAndClass == null)
indexByTagAndClass = new Index[CONSTANT_Limit][];
Index allClasses = getIndexByTag(CONSTANT_Class);
......
......@@ -109,6 +109,10 @@ class NativeUnpack {
return (p200 == null)? null: p200._nunp;
}
private synchronized long getUnpackerPtr() {
return unpackerPtr;
}
// Callback from the unpacker engine to get more data.
private long readInputFn(ByteBuffer pbuf, long minlen) throws IOException {
if (in == null) return 0; // nothing is readable
......
......@@ -83,7 +83,7 @@ public class PackerImpl extends TLGlobals implements Pack200.Packer {
* @param out an OutputStream
* @exception IOException if an error is encountered.
*/
public void pack(JarFile in, OutputStream out) throws IOException {
public synchronized void pack(JarFile in, OutputStream out) throws IOException {
assert(Utils.currentInstance.get() == null);
TimeZone tz = (props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE))
? null
......@@ -118,7 +118,7 @@ public class PackerImpl extends TLGlobals implements Pack200.Packer {
* @param out an OutputStream
* @exception IOException if an error is encountered.
*/
public void pack(JarInputStream in, OutputStream out) throws IOException {
public synchronized void pack(JarInputStream in, OutputStream out) throws IOException {
assert(Utils.currentInstance.get() == null);
TimeZone tz = (props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE)) ? null :
TimeZone.getDefault();
......
/*
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 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
......@@ -106,7 +106,7 @@ public class UnpackerImpl extends TLGlobals implements Pack200.Unpacker {
* @param out a JarOutputStream.
* @exception IOException if an error is encountered.
*/
public void unpack(InputStream in, JarOutputStream out) throws IOException {
public synchronized void unpack(InputStream in, JarOutputStream out) throws IOException {
if (in == null) {
throw new NullPointerException("null input");
}
......@@ -151,7 +151,7 @@ public class UnpackerImpl extends TLGlobals implements Pack200.Unpacker {
* @param out a JarOutputStream.
* @exception IOException if an error is encountered.
*/
public void unpack(File in, JarOutputStream out) throws IOException {
public synchronized void unpack(File in, JarOutputStream out) throws IOException {
if (in == null) {
throw new NullPointerException("null input");
}
......
......@@ -54,6 +54,8 @@ import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
import javax.management.AttributeNotFoundException;
import javax.management.openmbean.CompositeData;
import sun.reflect.misc.MethodUtil;
import sun.reflect.misc.ReflectUtil;
/**
* This class contains the methods for performing all the tests needed to verify
......@@ -526,8 +528,10 @@ public class Introspector {
// to locate method
readMethod = SimpleIntrospector.getReadMethod(clazz, element);
}
if (readMethod != null)
return readMethod.invoke(complex);
if (readMethod != null) {
ReflectUtil.checkPackageAccess(readMethod.getDeclaringClass());
return MethodUtil.invoke(readMethod, complex, new Class[0]);
}
throw new AttributeNotFoundException(
"Could not find the getter method for the property " +
......
......@@ -39,6 +39,7 @@ import sun.awt.PeerEvent;
import sun.awt.util.IdentityArrayList;
import sun.awt.util.IdentityLinkedList;
import sun.security.util.SecurityConstants;
import java.security.AccessControlException;
/**
* A Dialog is a top-level window with a title and a border
......@@ -128,6 +129,8 @@ public class Dialog extends Window {
*/
boolean undecorated = false;
private transient boolean initialized = false;
/**
* Modal dialogs block all input to some top-level windows.
* Whether a particular window is blocked depends on dialog's type
......@@ -671,6 +674,7 @@ public class Dialog extends Window {
this.title = title;
setModalityType(modalityType);
SunToolkit.checkAndSetPolicy(this);
initialized = true;
}
/**
......@@ -722,6 +726,7 @@ public class Dialog extends Window {
this.title = title;
setModalityType(modalityType);
SunToolkit.checkAndSetPolicy(this);
initialized = true;
}
/**
......@@ -851,12 +856,9 @@ public class Dialog extends Window {
if (modalityType == type) {
return;
}
if (type == ModalityType.TOOLKIT_MODAL) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(SecurityConstants.AWT.TOOLKIT_MODALITY_PERMISSION);
}
}
checkModalityPermission(type);
modalityType = type;
modal = (modalityType != ModalityType.MODELESS);
}
......@@ -1025,6 +1027,11 @@ public class Dialog extends Window {
*/
@Deprecated
public void show() {
if (!initialized) {
throw new IllegalStateException("The dialog component " +
"has not been initialized properly");
}
beforeFirstShow = false;
if (!isModal()) {
conditionalShow(null, null);
......@@ -1600,18 +1607,51 @@ public class Dialog extends Window {
}
}
private void checkModalityPermission(ModalityType mt) {
if (mt == ModalityType.TOOLKIT_MODAL) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(
SecurityConstants.AWT.TOOLKIT_MODALITY_PERMISSION
);
}
}
}
private void readObject(ObjectInputStream s)
throws ClassNotFoundException, IOException, HeadlessException
{
GraphicsEnvironment.checkHeadless();
s.defaultReadObject();
java.io.ObjectInputStream.GetField fields =
s.readFields();
ModalityType localModalityType = (ModalityType)fields.get("modalityType", null);
try {
checkModalityPermission(localModalityType);
} catch (AccessControlException ace) {
localModalityType = DEFAULT_MODALITY_TYPE;
}
// in 1.5 or earlier modalityType was absent, so use "modal" instead
if (modalityType == null) {
if (localModalityType == null) {
this.modal = fields.get("modal", false);
setModal(modal);
} else {
this.modalityType = localModalityType;
}
this.resizable = fields.get("resizable", true);
this.undecorated = fields.get("undecorated", false);
this.title = (String)fields.get("title", "");
blockedWindows = new IdentityArrayList<>();
SunToolkit.checkAndSetPolicy(this);
initialized = true;
}
/*
......
......@@ -194,7 +194,8 @@ public class EventQueue {
}
public void removeSourceEvents(EventQueue eventQueue,
Object source,
boolean removeAllEvents) {
boolean removeAllEvents)
{
eventQueue.removeSourceEvents(source, removeAllEvents);
}
public boolean noEvents(EventQueue eventQueue) {
......@@ -203,6 +204,11 @@ public class EventQueue {
public void wakeup(EventQueue eventQueue, boolean isShutdown) {
eventQueue.wakeup(isShutdown);
}
public void invokeAndWait(Object source, Runnable r)
throws InterruptedException, InvocationTargetException
{
EventQueue.invokeAndWait(source, r);
}
});
}
......@@ -1245,8 +1251,14 @@ public class EventQueue {
* @since 1.2
*/
public static void invokeAndWait(Runnable runnable)
throws InterruptedException, InvocationTargetException {
throws InterruptedException, InvocationTargetException
{
invokeAndWait(Toolkit.getDefaultToolkit(), runnable);
}
static void invokeAndWait(Object source, Runnable runnable)
throws InterruptedException, InvocationTargetException
{
if (EventQueue.isDispatchThread()) {
throw new Error("Cannot call invokeAndWait from the event dispatcher thread");
}
......@@ -1255,8 +1267,7 @@ public class EventQueue {
Object lock = new AWTInvocationLock();
InvocationEvent event =
new InvocationEvent(Toolkit.getDefaultToolkit(), runnable, lock,
true);
new InvocationEvent(source, runnable, lock, true);
synchronized (lock) {
Toolkit.getEventQueue().postEvent(event);
......
......@@ -109,12 +109,6 @@ public class TextComponent extends Component implements Accessible {
// the background color of non-editable TextComponents.
boolean backgroundSetByClientCode = false;
/**
* True if this <code>TextComponent</code> has access
* to the System clipboard.
*/
transient private boolean canAccessClipboard;
transient protected TextListener textListener;
/*
......@@ -139,7 +133,6 @@ public class TextComponent extends Component implements Accessible {
GraphicsEnvironment.checkHeadless();
this.text = (text != null) ? text : "";
setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR));
checkSystemClipboardAccess();
}
private void enableInputMethodsIfNecessary() {
......@@ -734,17 +727,14 @@ public class TextComponent extends Component implements Accessible {
/**
* Assigns a valid value to the canAccessClipboard instance variable.
*/
private void checkSystemClipboardAccess() {
canAccessClipboard = true;
private boolean canAccessClipboard() {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
try {
sm.checkSystemClipboardAccess();
}
catch (SecurityException e) {
canAccessClipboard = false;
}
}
if (sm == null) return true;
try {
sm.checkSystemClipboardAccess();
return true;
} catch (SecurityException e) {}
return false;
}
/*
......@@ -827,7 +817,6 @@ public class TextComponent extends Component implements Accessible {
}
}
enableInputMethodsIfNecessary();
checkSystemClipboardAccess();
}
......
......@@ -1206,7 +1206,7 @@ public class Window extends Container implements Accessible {
}
else {
try {
EventQueue.invokeAndWait(action);
EventQueue.invokeAndWait(this, action);
}
catch (InterruptedException e) {
System.err.println("Disposal was interrupted:");
......
......@@ -1752,6 +1752,12 @@ public class ObjectInputStream
ObjectStreamClass desc = readClassDesc(false);
desc.checkDeserialize();
Class<?> cl = desc.forClass();
if (cl == String.class || cl == Class.class
|| cl == ObjectStreamClass.class) {
throw new InvalidClassException("invalid class descriptor");
}
Object obj;
try {
obj = desc.isInstantiable() ? desc.newInstance() : null;
......
......@@ -63,7 +63,9 @@ import sun.reflect.generics.repository.ConstructorRepository;
import sun.reflect.generics.scope.ClassScope;
import sun.security.util.SecurityConstants;
import java.lang.annotation.Annotation;
import java.lang.reflect.Proxy;
import sun.reflect.annotation.*;
import sun.reflect.misc.ReflectUtil;
/**
* Instances of the class {@code Class} represent classes and
......@@ -250,11 +252,11 @@ public final
ClassLoader loader)
throws ClassNotFoundException
{
if (loader == null) {
if (sun.misc.VM.isSystemDomainLoader(loader)) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
ClassLoader ccl = ClassLoader.getCallerClassLoader();
if (ccl != null) {
if (!sun.misc.VM.isSystemDomainLoader(ccl)) {
sm.checkPermission(
SecurityConstants.GET_CLASSLOADER_PERMISSION);
}
......@@ -319,7 +321,7 @@ public final
throws InstantiationException, IllegalAccessException
{
if (System.getSecurityManager() != null) {
checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), false);
}
return newInstance0();
}
......@@ -1299,7 +1301,7 @@ public final
// 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());
checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), false);
// Privileged so this implementation can look at DECLARED classes,
// something the caller might not have privilege to do. The code here
......@@ -1374,7 +1376,7 @@ public final
// 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());
checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
return copyFields(privateGetPublicFields(null));
}
......@@ -1425,7 +1427,7 @@ public final
// 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());
checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
return copyMethods(privateGetPublicMethods());
}
......@@ -1474,7 +1476,7 @@ public final
// 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());
checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
return copyConstructors(privateGetDeclaredConstructors(true));
}
......@@ -1533,7 +1535,7 @@ public final
// 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());
checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
Field field = getField0(name);
if (field == null) {
throw new NoSuchFieldException(name);
......@@ -1618,7 +1620,7 @@ public final
// 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());
checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
Method method = getMethod0(name, parameterTypes);
if (method == null) {
throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes));
......@@ -1672,7 +1674,7 @@ public final
// 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());
checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
return getConstructor0(parameterTypes, Member.PUBLIC);
}
......@@ -1714,7 +1716,7 @@ public final
// 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());
checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), false);
return getDeclaredClasses0();
}
......@@ -1758,7 +1760,7 @@ public final
// 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());
checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
return copyFields(privateGetDeclaredFields(false));
}
......@@ -1806,7 +1808,7 @@ public final
// 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());
checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
return copyMethods(privateGetDeclaredMethods(false));
}
......@@ -1851,7 +1853,7 @@ public final
// 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());
checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
return copyConstructors(privateGetDeclaredConstructors(false));
}
......@@ -1895,7 +1897,7 @@ public final
// 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());
checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
Field field = searchFields(privateGetDeclaredFields(false), name);
if (field == null) {
throw new NoSuchFieldException(name);
......@@ -1950,7 +1952,7 @@ public final
// 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());
checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
Method method = searchMethods(privateGetDeclaredMethods(false), name, parameterTypes);
if (method == null) {
throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes));
......@@ -2000,7 +2002,7 @@ public final
// 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());
checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
return getConstructor0(parameterTypes, Member.DECLARED);
}
......@@ -2170,18 +2172,26 @@ public final
* <p> Default policy: allow all clients access with normal Java access
* control.
*/
private void checkMemberAccess(int which, ClassLoader ccl) {
private void checkMemberAccess(int which, ClassLoader ccl, boolean checkProxyInterfaces) {
SecurityManager s = System.getSecurityManager();
if (s != null) {
s.checkMemberAccess(this, which);
ClassLoader cl = getClassLoader0();
if (sun.reflect.misc.ReflectUtil.needsPackageAccessCheck(ccl, cl)) {
if (ReflectUtil.needsPackageAccessCheck(ccl, cl)) {
String name = this.getName();
int i = name.lastIndexOf('.');
if (i != -1) {
s.checkPackageAccess(name.substring(0, i));
// 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)) {
s.checkPackageAccess(pkg);
}
}
}
// check package access on the proxy interfaces
if (checkProxyInterfaces && Proxy.isProxyClass(this)) {
ReflectUtil.checkProxyPackageAccess(ccl, this.getInterfaces());
}
}
}
......
......@@ -26,8 +26,12 @@
package java.lang.invoke;
import java.lang.reflect.*;
import java.security.AccessController;
import java.security.PrivilegedAction;
import sun.invoke.WrapperInstance;
import java.util.ArrayList;
import sun.reflect.Reflection;
import sun.reflect.misc.ReflectUtil;
/**
* This class consists exclusively of static methods that help adapt
......@@ -137,6 +141,18 @@ public class MethodHandleProxies {
<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());
SecurityManager smgr = System.getSecurityManager();
if (smgr != null) {
final int CALLER_FRAME = 2; // 0: Reflection, 1: asInterfaceInstance, 2: caller
final Class<?> caller = Reflection.getCallerClass(CALLER_FRAME);
final ClassLoader ccl = caller.getClassLoader();
ReflectUtil.checkProxyPackageAccess(ccl, intfc);
}
ClassLoader proxyLoader = intfc.getClassLoader();
if (proxyLoader == null) {
ClassLoader cl = Thread.currentThread().getContextClassLoader(); // avoid use of BCP
proxyLoader = cl != null ? cl : ClassLoader.getSystemClassLoader();
}
final Method[] methods = getSingleNameMethods(intfc);
if (methods == null)
throw new IllegalArgumentException("not a single-method interface: "+intfc.getName());
......@@ -148,27 +164,44 @@ public class MethodHandleProxies {
checkTarget = checkTarget.asType(checkTarget.type().changeReturnType(Object.class));
vaTargets[i] = checkTarget.asSpreader(Object[].class, smMT.parameterCount());
}
return intfc.cast(Proxy.newProxyInstance(
intfc.getClassLoader(),
new Class<?>[]{ intfc, WrapperInstance.class },
new InvocationHandler() {
private Object getArg(String name) {
if ((Object)name == "getWrapperInstanceTarget") return target;
if ((Object)name == "getWrapperInstanceType") return intfc;
throw new AssertionError();
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
for (int i = 0; i < methods.length; i++) {
if (method.equals(methods[i]))
return vaTargets[i].invokeExact(args);
}
if (method.getDeclaringClass() == WrapperInstance.class)
return getArg(method.getName());
if (isObjectMethod(method))
return callObjectMethod(proxy, method, args);
throw new InternalError("bad proxy method: "+method);
final InvocationHandler ih = new InvocationHandler() {
private Object getArg(String name) {
if ((Object)name == "getWrapperInstanceTarget") return target;
if ((Object)name == "getWrapperInstanceType") return intfc;
throw new AssertionError();
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
for (int i = 0; i < methods.length; i++) {
if (method.equals(methods[i]))
return vaTargets[i].invokeExact(args);
}
}));
if (method.getDeclaringClass() == WrapperInstance.class)
return getArg(method.getName());
if (isObjectMethod(method))
return callObjectMethod(proxy, method, args);
throw new InternalError("bad proxy method: "+method);
}
};
Object proxy;
if (smgr != null) {
// sun.invoke.WrapperInstance is a restricted interface not accessible
// by any non-null class loader.
final ClassLoader loader = proxyLoader;
proxy = AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
return Proxy.newProxyInstance(
loader,
new Class<?>[]{ intfc, WrapperInstance.class },
ih);
}
});
} else {
proxy = Proxy.newProxyInstance(proxyLoader,
new Class<?>[]{ intfc, WrapperInstance.class },
ih);
}
return intfc.cast(proxy);
}
/**
......
......@@ -27,6 +27,9 @@ package java.lang.reflect;
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import java.security.AccessController;
import java.security.Permission;
import java.security.PrivilegedAction;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
......@@ -36,6 +39,9 @@ import java.util.Set;
import java.util.List;
import java.util.WeakHashMap;
import sun.misc.ProxyGenerator;
import sun.reflect.Reflection;
import sun.reflect.misc.ReflectUtil;
import sun.security.util.SecurityConstants;
/**
* {@code Proxy} provides static methods for creating dynamic proxy
......@@ -265,9 +271,69 @@ public class Proxy implements java.io.Serializable {
* @param h the invocation handler for this proxy instance
*/
protected Proxy(InvocationHandler h) {
doNewInstanceCheck();
this.h = h;
}
private static class ProxyAccessHelper {
// The permission is implementation specific.
static final Permission PROXY_PERMISSION =
new ReflectPermission("proxyConstructorNewInstance");
// These system properties are defined to provide a short-term
// workaround if customers need to disable the new security checks.
static final boolean allowNewInstance;
static final boolean allowNullLoader;
static {
allowNewInstance = getBooleanProperty("sun.reflect.proxy.allowsNewInstance");
allowNullLoader = getBooleanProperty("sun.reflect.proxy.allowsNullLoader");
}
private static boolean getBooleanProperty(final String key) {
String s = AccessController.doPrivileged(new PrivilegedAction<String>() {
public String run() {
return System.getProperty(key);
}
});
return Boolean.valueOf(s);
}
static boolean needsNewInstanceCheck(Class<?> proxyClass) {
if (!Proxy.isProxyClass(proxyClass) || allowNewInstance) {
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;
}
}
return false;
}
}
/*
* Access check on a proxy class that implements any non-public interface.
*
* @throws SecurityException if a security manager exists, and
* the caller does not have the permission.
*/
private void doNewInstanceCheck() {
SecurityManager sm = System.getSecurityManager();
Class<?> proxyClass = this.getClass();
if (sm != null && ProxyAccessHelper.needsNewInstanceCheck(proxyClass)) {
try {
sm.checkPermission(ProxyAccessHelper.PROXY_PERMISSION);
} catch (SecurityException e) {
throw new SecurityException("Not allowed to construct a Proxy "
+ "instance that implements a non-public interface", e);
}
}
}
/**
* Returns the {@code java.lang.Class} object for a proxy class
* given a class loader and an array of interfaces. The proxy class
......@@ -346,6 +412,51 @@ public class Proxy implements java.io.Serializable {
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);
}
}
}
}
/*
* Generate a proxy class (caller-sensitive).
*
* To define a proxy class, it performs the access checks as in
* Class.forName (VM will invoke ClassLoader.checkPackageAccess):
* 1. "getClassLoader" permission check if loader == null
* 2. checkPackageAccess on the interfaces it implements
*
* To get a constructor and new instance of a proxy class, it performs
* the package access check on the interfaces it implements
* as in Class.getConstructor.
*
* If an interface is non-public, the proxy class must be defined by
* the defining loader of the interface. If the caller's class loader
* is not the same as the defining loader of the interface, the VM
* will throw IllegalAccessError when the generated proxy class is
* being defined via the defineClass0 method.
*/
private static Class<?> getProxyClass0(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);
ReflectUtil.checkProxyPackageAccess(ccl, interfaces);
}
if (interfaces.length > 65535) {
throw new IllegalArgumentException("interface limit exceeded");
}
......@@ -497,8 +608,9 @@ public class Proxy implements java.io.Serializable {
}
}
if (proxyPkg == null) { // if no non-public proxy interfaces,
proxyPkg = ""; // use the unnamed package
if (proxyPkg == null) {
// if no non-public proxy interfaces, use sun.proxy package
proxyPkg = ReflectUtil.PROXY_PACKAGE + ".";
}
{
......@@ -598,19 +710,43 @@ public class Proxy implements java.io.Serializable {
/*
* Look up or generate the designated proxy class.
*/
Class<?> cl = getProxyClass(loader, interfaces);
Class<?> cl = getProxyClass0(loader, interfaces); // stack walk magic: do not refactor
/*
* Invoke its constructor with the designated invocation handler.
*/
try {
Constructor<?> cons = cl.getConstructor(constructorParams);
return cons.newInstance(new Object[] { h });
} catch (NoSuchMethodException |
IllegalAccessException |
InstantiationException |
InvocationTargetException e) {
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
return AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
return newInstance(cons, ih);
}
});
} else {
return newInstance(cons, ih);
}
} catch (NoSuchMethodException e) {
throw new InternalError(e.toString(), e);
}
}
private static Object newInstance(Constructor<?> cons, InvocationHandler h) {
try {
return cons.newInstance(new Object[] {h} );
} catch (IllegalAccessException | InstantiationException e) {
throw new InternalError(e.toString(), e);
} catch (InvocationTargetException e) {
Throwable t = e.getCause();
if (t instanceof RuntimeException) {
throw (RuntimeException) t;
} else {
throw new InternalError(t.toString(), t);
}
}
}
......
/*
* Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 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
......@@ -24,9 +24,12 @@
*/
package java.net;
import java.io.ObjectInputStream;
import java.io.IOException;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamException;
import java.io.ObjectStreamField;
/**
*
......@@ -46,23 +49,105 @@ import java.io.InvalidObjectException;
* @see java.net.ServerSocket
* @since 1.4
*/
public class InetSocketAddress extends SocketAddress {
/* The hostname of the Socket Address
* @serial
*/
private String hostname = null;
/* The IP address of the Socket Address
* @serial
*/
private InetAddress addr = null;
/* The port number of the Socket Address
* @serial
*/
private int port;
public class InetSocketAddress
extends SocketAddress
{
// Private implementation class pointed to by all public methods.
private static class InetSocketAddressHolder {
// The hostname of the Socket Address
private String hostname;
// The IP address of the Socket Address
private InetAddress addr;
// The port number of the Socket Address
private int port;
private InetSocketAddressHolder(String hostname, InetAddress addr, int port) {
this.hostname = hostname;
this.addr = addr;
this.port = port;
}
private int getPort() {
return port;
}
private InetAddress getAddress() {
return addr;
}
private String getHostName() {
if (hostname != null)
return hostname;
if (addr != null)
return addr.getHostName();
return null;
}
private String getHostString() {
if (hostname != null)
return hostname;
if (addr != null) {
if (addr.hostName != null)
return addr.hostName;
else
return addr.getHostAddress();
}
return null;
}
private boolean isUnresolved() {
return addr == null;
}
@Override
public String toString() {
if (isUnresolved()) {
return hostname + ":" + port;
} else {
return addr.toString() + ":" + port;
}
}
@Override
public final boolean equals(Object obj) {
if (obj == null || !(obj instanceof InetSocketAddressHolder))
return false;
InetSocketAddressHolder that = (InetSocketAddressHolder)obj;
boolean sameIP;
if (addr != null)
sameIP = addr.equals(that.addr);
else if (hostname != null)
sameIP = (that.addr == null) &&
hostname.equalsIgnoreCase(that.hostname);
else
sameIP = (that.addr == null) && (that.hostname == null);
return sameIP && (port == that.port);
}
@Override
public final int hashCode() {
if (addr != null)
return addr.hashCode() + port;
if (hostname != null)
return hostname.toLowerCase().hashCode() + port;
return port;
}
}
private final transient InetSocketAddressHolder holder;
private static final long serialVersionUID = 5076001401234631237L;
private InetSocketAddress() {
private static int checkPort(int port) {
if (port < 0 || port > 0xFFFF)
throw new IllegalArgumentException("port out of range:" + port);
return port;
}
private static String checkHost(String hostname) {
if (hostname == null)
throw new IllegalArgumentException("hostname can't be null");
return hostname;
}
/**
......@@ -97,14 +182,10 @@ public class InetSocketAddress extends SocketAddress {
* range of valid port values.
*/
public InetSocketAddress(InetAddress addr, int port) {
if (port < 0 || port > 0xFFFF) {
throw new IllegalArgumentException("port out of range:" + port);
}
this.port = port;
if (addr == null)
this.addr = InetAddress.anyLocalAddress();
else
this.addr = addr;
holder = new InetSocketAddressHolder(
null,
addr == null ? InetAddress.anyLocalAddress() : addr,
checkPort(port));
}
/**
......@@ -132,19 +213,20 @@ public class InetSocketAddress extends SocketAddress {
* @see #isUnresolved()
*/
public InetSocketAddress(String hostname, int port) {
if (port < 0 || port > 0xFFFF) {
throw new IllegalArgumentException("port out of range:" + port);
}
if (hostname == null) {
throw new IllegalArgumentException("hostname can't be null");
}
checkHost(hostname);
InetAddress addr = null;
String host = null;
try {
addr = InetAddress.getByName(hostname);
} catch(UnknownHostException e) {
this.hostname = hostname;
addr = null;
host = hostname;
}
this.port = port;
holder = new InetSocketAddressHolder(host, addr, checkPort(port));
}
// private constructor for creating unresolved instances
private InetSocketAddress(int port, String hostname) {
holder = new InetSocketAddressHolder(hostname, null, port);
}
/**
......@@ -169,31 +251,67 @@ public class InetSocketAddress extends SocketAddress {
* @since 1.5
*/
public static InetSocketAddress createUnresolved(String host, int port) {
if (port < 0 || port > 0xFFFF) {
throw new IllegalArgumentException("port out of range:" + port);
}
if (host == null) {
throw new IllegalArgumentException("hostname can't be null");
}
InetSocketAddress s = new InetSocketAddress();
s.port = port;
s.hostname = host;
s.addr = null;
return s;
return new InetSocketAddress(checkPort(port), checkHost(host));
}
private void readObject(ObjectInputStream s)
throws IOException, ClassNotFoundException {
s.defaultReadObject();
/**
* @serialField hostname String
* @serialField addr InetAddress
* @serialField port int
*/
private static final ObjectStreamField[] serialPersistentFields = {
new ObjectStreamField("hostname", String.class),
new ObjectStreamField("addr", InetAddress.class),
new ObjectStreamField("port", int.class)};
private void writeObject(ObjectOutputStream out)
throws IOException
{
// Don't call defaultWriteObject()
ObjectOutputStream.PutField pfields = out.putFields();
pfields.put("hostname", holder.hostname);
pfields.put("addr", holder.addr);
pfields.put("port", holder.port);
out.writeFields();
}
// Check that our invariants are satisfied
if (port < 0 || port > 0xFFFF) {
throw new InvalidObjectException("port out of range:" + port);
}
private void readObject(ObjectInputStream in)
throws IOException, ClassNotFoundException
{
// Don't call defaultReadObject()
ObjectInputStream.GetField oisFields = in.readFields();
final String oisHostname = (String)oisFields.get("hostname", null);
final InetAddress oisAddr = (InetAddress)oisFields.get("addr", null);
final int oisPort = oisFields.get("port", -1);
if (hostname == null && addr == null) {
// Check that our invariants are satisfied
checkPort(oisPort);
if (oisHostname == null && oisAddr == null)
throw new InvalidObjectException("hostname and addr " +
"can't both be null");
InetSocketAddressHolder h = new InetSocketAddressHolder(oisHostname,
oisAddr,
oisPort);
UNSAFE.putObject(this, FIELDS_OFFSET, h);
}
private void readObjectNoData()
throws ObjectStreamException
{
throw new InvalidObjectException("Stream data required");
}
private static final long FIELDS_OFFSET;
private static final sun.misc.Unsafe UNSAFE;
static {
try {
sun.misc.Unsafe unsafe = sun.misc.Unsafe.getUnsafe();
FIELDS_OFFSET = unsafe.objectFieldOffset(
InetSocketAddress.class.getDeclaredField("holder"));
UNSAFE = unsafe;
} catch (ReflectiveOperationException e) {
throw new Error(e);
}
}
......@@ -203,7 +321,7 @@ public class InetSocketAddress extends SocketAddress {
* @return the port number.
*/
public final int getPort() {
return port;
return holder.getPort();
}
/**
......@@ -213,7 +331,7 @@ public class InetSocketAddress extends SocketAddress {
* @return the InetAdress or <code>null</code> if it is unresolved.
*/
public final InetAddress getAddress() {
return addr;
return holder.getAddress();
}
/**
......@@ -224,31 +342,19 @@ public class InetSocketAddress extends SocketAddress {
* @return the hostname part of the address.
*/
public final String getHostName() {
if (hostname != null)
return hostname;
if (addr != null)
return addr.getHostName();
return null;
return holder.getHostName();
}
/**
* Returns the hostname, or the String form of the address if it
* doesn't have a hostname (it was created using a literal).
* This has the benefit of <b>not</b> attemptimg a reverse lookup.
* This has the benefit of <b>not</b> attempting a reverse lookup.
*
* @return the hostname, or String representation of the address.
* @since 1.7
*/
public final String getHostString() {
if (hostname != null)
return hostname;
if (addr != null) {
if (addr.hostName != null)
return addr.hostName;
else
return addr.getHostAddress();
}
return null;
return holder.getHostString();
}
/**
......@@ -258,7 +364,7 @@ public class InetSocketAddress extends SocketAddress {
* an <code>InetAddress</code>.
*/
public final boolean isUnresolved() {
return addr == null;
return holder.isUnresolved();
}
/**
......@@ -269,12 +375,9 @@ public class InetSocketAddress extends SocketAddress {
*
* @return a string representation of this object.
*/
@Override
public String toString() {
if (isUnresolved()) {
return hostname + ":" + port;
} else {
return addr.toString() + ":" + port;
}
return holder.toString();
}
/**
......@@ -297,19 +400,11 @@ public class InetSocketAddress extends SocketAddress {
* <code>false</code> otherwise.
* @see java.net.InetAddress#equals(java.lang.Object)
*/
@Override
public final boolean equals(Object obj) {
if (obj == null || !(obj instanceof InetSocketAddress))
return false;
InetSocketAddress sockAddr = (InetSocketAddress) obj;
boolean sameIP = false;
if (this.addr != null)
sameIP = this.addr.equals(sockAddr.addr);
else if (this.hostname != null)
sameIP = (sockAddr.addr == null) &&
this.hostname.equalsIgnoreCase(sockAddr.hostname);
else
sameIP = (sockAddr.addr == null) && (sockAddr.hostname == null);
return sameIP && (this.port == sockAddr.port);
return holder.equals(((InetSocketAddress) obj).holder);
}
/**
......@@ -317,11 +412,8 @@ public class InetSocketAddress extends SocketAddress {
*
* @return a hash code value for this socket address.
*/
@Override
public final int hashCode() {
if (addr != null)
return addr.hashCode() + port;
if (hostname != null)
return hostname.toLowerCase().hashCode() + port;
return port;
return holder.hashCode();
}
}
......@@ -34,8 +34,10 @@
*/
package java.util.concurrent;
import java.util.concurrent.locks.*;
import java.util.concurrent.atomic.*;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.*;
/**
......@@ -491,10 +493,15 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
* policy limiting the number of threads. Even though it is not
* treated as an error, failure to create threads may result in
* new tasks being rejected or existing ones remaining stuck in
* the queue. On the other hand, no special precautions exist to
* handle OutOfMemoryErrors that might be thrown while trying to
* create threads, since there is generally no recourse from
* within this class.
* the queue.
*
* We go further and preserve pool invariants even in the face of
* errors such as OutOfMemoryError, that might be thrown while
* trying to create threads. Such errors are rather common due to
* the need to allocate a native stack in Thread#start, and users
* will want to perform clean pool shutdown to clean up. There
* will likely be enough memory available for the cleanup code to
* complete without encountering yet another OutOfMemoryError.
*/
private volatile ThreadFactory threadFactory;
......@@ -568,9 +575,13 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
* task execution. This protects against interrupts that are
* intended to wake up a worker thread waiting for a task from
* instead interrupting a task being run. We implement a simple
* non-reentrant mutual exclusion lock rather than use ReentrantLock
* because we do not want worker tasks to be able to reacquire the
* lock when they invoke pool control methods like setCorePoolSize.
* non-reentrant mutual exclusion lock rather than use
* ReentrantLock because we do not want worker tasks to be able to
* reacquire the lock when they invoke pool control methods like
* setCorePoolSize. Additionally, to suppress interrupts until
* the thread actually starts running tasks, we initialize lock
* state to a negative value, and clear it upon start (in
* runWorker).
*/
private final class Worker
extends AbstractQueuedSynchronizer
......@@ -594,6 +605,7 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
* @param firstTask the first task (null if none)
*/
Worker(Runnable firstTask) {
setState(-1); // inhibit interrupts until runWorker
this.firstTask = firstTask;
this.thread = getThreadFactory().newThread(this);
}
......@@ -609,7 +621,7 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
// The value 1 represents the locked state.
protected boolean isHeldExclusively() {
return getState() == 1;
return getState() != 0;
}
protected boolean tryAcquire(int unused) {
......@@ -630,6 +642,16 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
public boolean tryLock() { return tryAcquire(1); }
public void unlock() { release(1); }
public boolean isLocked() { return isHeldExclusively(); }
void interruptIfStarted() {
Thread t;
if (getState() >= 0 && (t = thread) != null && !t.isInterrupted()) {
try {
t.interrupt();
} catch (SecurityException ignore) {
}
}
}
}
/*
......@@ -728,12 +750,8 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
for (Worker w : workers) {
try {
w.thread.interrupt();
} catch (SecurityException ignore) {
}
}
for (Worker w : workers)
w.interruptIfStarted();
} finally {
mainLock.unlock();
}
......@@ -790,19 +808,6 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
private static final boolean ONLY_ONE = true;
/**
* Ensures that unless the pool is stopping, the current thread
* does not have its interrupt set. This requires a double-check
* of state in case the interrupt was cleared concurrently with a
* shutdownNow -- if so, the interrupt is re-enabled.
*/
private void clearInterruptsForTaskRun() {
if (runStateLessThan(ctl.get(), STOP) &&
Thread.interrupted() &&
runStateAtLeast(ctl.get(), STOP))
Thread.currentThread().interrupt();
}
/*
* Misc utilities, most of which are also exported to
* ScheduledThreadPoolExecutor
......@@ -862,12 +867,13 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
* Checks if a new worker can be added with respect to current
* pool state and the given bound (either core or maximum). If so,
* the worker count is adjusted accordingly, and, if possible, a
* new worker is created and started running firstTask as its
* new worker is created and started, running firstTask as its
* first task. This method returns false if the pool is stopped or
* eligible to shut down. It also returns false if the thread
* factory fails to create a thread when asked, which requires a
* backout of workerCount, and a recheck for termination, in case
* the existence of this worker was holding up termination.
* factory fails to create a thread when asked. If the thread
* creation fails, either due to the thread factory returning
* null, or due to an exception (typically OutOfMemoryError in
* Thread#start), we roll back cleanly.
*
* @param firstTask the task the new thread should run first (or
* null if none). Workers are created with an initial first task
......@@ -910,46 +916,65 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
}
}
Worker w = new Worker(firstTask);
Thread t = w.thread;
boolean workerStarted = false;
boolean workerAdded = false;
Worker w = null;
try {
final ReentrantLock mainLock = this.mainLock;
w = new Worker(firstTask);
final Thread t = w.thread;
if (t != null) {
mainLock.lock();
try {
// Recheck while holding lock.
// Back out on ThreadFactory failure or if
// shut down before lock acquired.
int c = ctl.get();
int rs = runStateOf(c);
if (rs < SHUTDOWN ||
(rs == SHUTDOWN && firstTask == null)) {
if (t.isAlive()) // precheck that t is startable
throw new IllegalThreadStateException();
workers.add(w);
int s = workers.size();
if (s > largestPoolSize)
largestPoolSize = s;
workerAdded = true;
}
} finally {
mainLock.unlock();
}
if (workerAdded) {
t.start();
workerStarted = true;
}
}
} finally {
if (! workerStarted)
addWorkerFailed(w);
}
return workerStarted;
}
/**
* Rolls back the worker thread creation.
* - removes worker from workers, if present
* - decrements worker count
* - rechecks for termination, in case the existence of this
* worker was holding up termination
*/
private void addWorkerFailed(Worker w) {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
// Recheck while holding lock.
// Back out on ThreadFactory failure or if
// shut down before lock acquired.
int c = ctl.get();
int rs = runStateOf(c);
if (t == null ||
(rs >= SHUTDOWN &&
! (rs == SHUTDOWN &&
firstTask == null))) {
decrementWorkerCount();
tryTerminate();
return false;
}
workers.add(w);
int s = workers.size();
if (s > largestPoolSize)
largestPoolSize = s;
if (w != null)
workers.remove(w);
decrementWorkerCount();
tryTerminate();
} finally {
mainLock.unlock();
}
t.start();
// It is possible (but unlikely) for a thread to have been
// added to workers, but not yet started, during transition to
// STOP, which could result in a rare missed interrupt,
// because Thread.interrupt is not guaranteed to have any effect
// on a non-yet-started Thread (see Thread#interrupt).
if (runStateOf(ctl.get()) == STOP && ! t.isInterrupted())
t.interrupt();
return true;
}
/**
......@@ -1096,15 +1121,25 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
* @param w the worker
*/
final void runWorker(Worker w) {
Thread wt = Thread.currentThread();
Runnable task = w.firstTask;
w.firstTask = null;
w.unlock(); // allow interrupts
boolean completedAbruptly = true;
try {
while (task != null || (task = getTask()) != null) {
w.lock();
clearInterruptsForTaskRun();
// If pool is stopping, ensure thread is interrupted;
// if not, ensure thread is not interrupted. This
// requires a recheck in second case to deal with
// shutdownNow race while clearing interrupt
if ((runStateAtLeast(ctl.get(), STOP) ||
(Thread.interrupted() &&
runStateAtLeast(ctl.get(), STOP))) &&
!wt.isInterrupted())
wt.interrupt();
try {
beforeExecute(w.thread, task);
beforeExecute(wt, task);
Throwable thrown = null;
try {
task.run();
......@@ -2064,3 +2099,4 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
}
}
}
......@@ -34,6 +34,7 @@ import java.security.CodeSigner;
import java.security.cert.Certificate;
import java.security.AccessController;
import java.security.CodeSource;
import sun.misc.IOUtils;
import sun.security.action.GetPropertyAction;
import sun.security.util.ManifestEntryVerifier;
import sun.misc.SharedSecrets;
......@@ -329,6 +330,9 @@ class JarFile extends ZipFile {
if (names != null) {
for (int i = 0; i < names.length; i++) {
JarEntry e = getJarEntry(names[i]);
if (e == null) {
throw new JarException("corrupted jar file");
}
if (!e.isDirectory()) {
if (mev == null) {
mev = new ManifestEntryVerifier
......@@ -348,6 +352,10 @@ class JarFile extends ZipFile {
// treat the jar file as being unsigned
jv = null;
verify = false;
if (JarVerifier.debug != null) {
JarVerifier.debug.println("jarfile parsing error!");
ex.printStackTrace();
}
}
// if after initializing the verifier we have nothing
......@@ -375,11 +383,9 @@ class JarFile extends ZipFile {
* META-INF files.
*/
private byte[] getBytes(ZipEntry ze) throws IOException {
byte[] b = new byte[(int)ze.getSize()];
try (DataInputStream is = new DataInputStream(super.getInputStream(ze))) {
is.readFully(b, 0, b.length);
try (InputStream is = super.getInputStream(ze)) {
return IOUtils.readFully(is, (int)ze.getSize(), true);
}
return b;
}
/**
......@@ -479,12 +485,7 @@ class JarFile extends ZipFile {
if (!isKnownToNotHaveClassPathAttribute()) {
JarEntry manEntry = getManEntry();
if (manEntry != null) {
byte[] b = new byte[(int)manEntry.getSize()];
try (DataInputStream dis = new DataInputStream(
super.getInputStream(manEntry))) {
dis.readFully(b, 0, b.length);
}
byte[] b = getBytes(manEntry);
int last = b.length - src.length;
int i = 0;
next:
......
......@@ -24,6 +24,10 @@
*/
package java.util.logging;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;
/**
......@@ -59,7 +63,6 @@ import java.util.ResourceBundle;
*/
public class Level implements java.io.Serializable {
private static java.util.ArrayList<Level> known = new java.util.ArrayList<>();
private static String defaultBundle = "sun.util.logging.resources.logging";
/**
......@@ -77,6 +80,9 @@ public class Level implements java.io.Serializable {
*/
private final String resourceBundleName;
// localized level name
private String localizedLevelName;
/**
* OFF is a special level that can be used to turn off logging.
* This level is initialized to <CODE>Integer.MAX_VALUE</CODE>.
......@@ -202,9 +208,8 @@ public class Level implements java.io.Serializable {
this.name = name;
this.value = value;
this.resourceBundleName = resourceBundleName;
synchronized (Level.class) {
known.add(this);
}
this.localizedLevelName = resourceBundleName == null ? name : null;
KnownLevel.add(this);
}
/**
......@@ -236,12 +241,76 @@ public class Level implements java.io.Serializable {
* @return localized name
*/
public String getLocalizedName() {
return getLocalizedLevelName();
}
// package-private getLevelName() is used by the implementation
// instead of getName() to avoid calling the subclass's version
final String getLevelName() {
return this.name;
}
final synchronized String getLocalizedLevelName() {
if (localizedLevelName != null) {
return localizedLevelName;
}
try {
ResourceBundle rb = ResourceBundle.getBundle(resourceBundleName);
return rb.getString(name);
localizedLevelName = rb.getString(name);
} catch (Exception ex) {
return name;
localizedLevelName = name;
}
return localizedLevelName;
}
// Returns a mirrored Level object that matches the given name as
// specified in the Level.parse method. Returns null if not found.
//
// It returns the same Level object as the one returned by Level.parse
// method if the given name is a non-localized name or integer.
//
// If the name is a localized name, findLevel and parse method may
// return a different level value if there is a custom Level subclass
// that overrides Level.getLocalizedName() to return a different string
// than what's returned by the default implementation.
//
static Level findLevel(String name) {
if (name == null) {
throw new NullPointerException();
}
KnownLevel level;
// Look for a known Level with the given non-localized name.
level = KnownLevel.findByName(name);
if (level != null) {
return level.mirroredLevel;
}
// Now, check if the given name is an integer. If so,
// first look for a Level with the given value and then
// if necessary create one.
try {
int x = Integer.parseInt(name);
level = KnownLevel.findByValue(x);
if (level == null) {
// add new Level
Level levelObject = new Level(name, x);
level = KnownLevel.findByValue(x);
}
return level.mirroredLevel;
} catch (NumberFormatException ex) {
// Not an integer.
// Drop through.
}
level = KnownLevel.findByLocalizedLevelName(name);
if (level != null) {
return level.mirroredLevel;
}
return null;
}
/**
......@@ -268,21 +337,15 @@ public class Level implements java.io.Serializable {
// Serialization magic to prevent "doppelgangers".
// This is a performance optimization.
private Object readResolve() {
synchronized (Level.class) {
for (int i = 0; i < known.size(); i++) {
Level other = known.get(i);
if (this.name.equals(other.name) && this.value == other.value
&& (this.resourceBundleName == other.resourceBundleName ||
(this.resourceBundleName != null &&
this.resourceBundleName.equals(other.resourceBundleName)))) {
return other;
}
}
// Woops. Whoever sent us this object knows
// about a new log level. Add it to our list.
known.add(this);
return this;
KnownLevel o = KnownLevel.matches(this);
if (o != null) {
return o.levelObject;
}
// Woops. Whoever sent us this object knows
// about a new log level. Add it to our list.
Level level = new Level(this.name, this.value, this.resourceBundleName);
return level;
}
/**
......@@ -296,6 +359,7 @@ public class Level implements java.io.Serializable {
* <li> "SEVERE"
* <li> "1000"
* </ul>
*
* @param name string to be parsed
* @throws NullPointerException if the name is null
* @throws IllegalArgumentException if the value is not valid.
......@@ -315,12 +379,12 @@ public class Level implements java.io.Serializable {
// Check that name is not null.
name.length();
KnownLevel level;
// Look for a known Level with the given non-localized name.
for (int i = 0; i < known.size(); i++) {
Level l = known.get(i);
if (name.equals(l.name)) {
return l;
}
level = KnownLevel.findByName(name);
if (level != null) {
return level.levelObject;
}
// Now, check if the given name is an integer. If so,
......@@ -328,14 +392,13 @@ public class Level implements java.io.Serializable {
// if necessary create one.
try {
int x = Integer.parseInt(name);
for (int i = 0; i < known.size(); i++) {
Level l = known.get(i);
if (l.value == x) {
return l;
}
level = KnownLevel.findByValue(x);
if (level == null) {
// add new Level
Level levelObject = new Level(name, x);
level = KnownLevel.findByValue(x);
}
// Create a new Level.
return new Level(name, x);
return level.levelObject;
} catch (NumberFormatException ex) {
// Not an integer.
// Drop through.
......@@ -344,11 +407,9 @@ public class Level implements java.io.Serializable {
// Finally, look for a known level with the given localized name,
// in the current default locale.
// This is relatively expensive, but not excessively so.
for (int i = 0; i < known.size(); i++) {
Level l = known.get(i);
if (name.equals(l.getLocalizedName())) {
return l;
}
level = KnownLevel.findByLocalizedName(name);
if (level != null) {
return level.levelObject;
}
// OK, we've tried everything and failed
......@@ -375,4 +436,124 @@ public class Level implements java.io.Serializable {
public int hashCode() {
return this.value;
}
// KnownLevel class maintains the global list of all known levels.
// The API allows multiple custom Level instances of the same name/value
// be created. This class provides convenient methods to find a level
// by a given name, by a given value, or by a given localized name.
//
// KnownLevel wraps the following Level objects:
// 1. levelObject: standard Level object or custom Level object
// 2. mirroredLevel: Level object representing the level specified in the
// logging configuration.
//
// Level.getName, Level.getLocalizedName, Level.getResourceBundleName methods
// are non-final but the name and resource bundle name are parameters to
// the Level constructor. Use the mirroredLevel object instead of the
// levelObject to prevent the logging framework to execute foreign code
// implemented by untrusted Level subclass.
//
// Implementation Notes:
// If Level.getName, Level.getLocalizedName, Level.getResourceBundleName methods
// were final, the following KnownLevel implementation can be removed.
// Future API change should take this into consideration.
static final class KnownLevel {
private static Map<String, List<KnownLevel>> nameToLevels = new HashMap<>();
private static Map<Integer, List<KnownLevel>> intToLevels = new HashMap<>();
final Level levelObject; // instance of Level class or Level subclass
final Level mirroredLevel; // instance of Level class
KnownLevel(Level l) {
this.levelObject = l;
if (l.getClass() == Level.class) {
this.mirroredLevel = l;
} else {
this.mirroredLevel = new Level(l.name, l.value, l.resourceBundleName);
}
}
static synchronized void add(Level l) {
// the mirroredLevel object is always added to the list
// before the custom Level instance
KnownLevel o = new KnownLevel(l);
List<KnownLevel> list = nameToLevels.get(l.name);
if (list == null) {
list = new ArrayList<>();
nameToLevels.put(l.name, list);
}
list.add(o);
list = intToLevels.get(l.value);
if (list == null) {
list = new ArrayList<>();
intToLevels.put(l.value, list);
}
list.add(o);
}
// Returns a KnownLevel with the given non-localized name.
static synchronized KnownLevel findByName(String name) {
List<KnownLevel> list = nameToLevels.get(name);
if (list != null) {
return list.get(0);
}
return null;
}
// Returns a KnownLevel with the given value.
static synchronized KnownLevel findByValue(int value) {
List<KnownLevel> list = intToLevels.get(value);
if (list != null) {
return list.get(0);
}
return null;
}
// Returns a KnownLevel with the given localized name matching
// by calling the Level.getLocalizedLevelName() method (i.e. found
// from the resourceBundle associated with the Level object).
// This method does not call Level.getLocalizedName() that may
// be overridden in a subclass implementation
static synchronized KnownLevel findByLocalizedLevelName(String name) {
for (List<KnownLevel> levels : nameToLevels.values()) {
for (KnownLevel l : levels) {
String lname = l.levelObject.getLocalizedLevelName();
if (name.equals(lname)) {
return l;
}
}
}
return null;
}
// Returns a KnownLevel with the given localized name matching
// by calling the Level.getLocalizedName() method
static synchronized KnownLevel findByLocalizedName(String name) {
for (List<KnownLevel> levels : nameToLevels.values()) {
for (KnownLevel l : levels) {
String lname = l.levelObject.getLocalizedName();
if (name.equals(lname)) {
return l;
}
}
}
return null;
}
static synchronized KnownLevel matches(Level l) {
List<KnownLevel> list = nameToLevels.get(l.name);
if (list != null) {
for (KnownLevel level : list) {
Level other = level.mirroredLevel;
if (l.value == other.value &&
(l.resourceBundleName == other.resourceBundleName ||
(l.resourceBundleName != null &&
l.resourceBundleName.equals(other.resourceBundleName)))) {
return level;
}
}
}
return null;
}
}
}
......@@ -314,6 +314,40 @@ public class Logger {
}
}
// Until all JDK code converted to call sun.util.logging.PlatformLogger
// (see 7054233), we need to determine if Logger.getLogger is to add
// a system logger or user logger.
//
// As an interim solution, if the immediate caller whose caller loader is
// null, we assume it's a system logger and add it to the system context.
// These system loggers only set the resource bundle to the given
// resource bundle name (rather than the default system resource bundle).
private static class SystemLoggerHelper {
static boolean disableCallerCheck = getBooleanProperty("sun.util.logging.disableCallerCheck");
private static boolean getBooleanProperty(final String key) {
String s = AccessController.doPrivileged(new PrivilegedAction<String>() {
public String run() {
return System.getProperty(key);
}
});
return Boolean.valueOf(s);
}
}
private static Logger demandLogger(String name, String resourceBundleName) {
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);
}
}
return manager.demandLogger(name, resourceBundleName);
}
/**
* Find or create a logger for a named subsystem. If a logger has
* already been created with the given name it is returned. Otherwise
......@@ -355,8 +389,7 @@ public class Logger {
// would throw an IllegalArgumentException in the second call
// because the wrapper would result in an attempt to replace
// the existing "resourceBundleForFoo" with null.
LogManager manager = LogManager.getLogManager();
return manager.demandLogger(name);
return demandLogger(name, null);
}
/**
......@@ -403,8 +436,7 @@ public class Logger {
// Synchronization is not required here. All synchronization for
// adding a new Logger object is handled by LogManager.addLogger().
public static Logger getLogger(String name, String resourceBundleName) {
LogManager manager = LogManager.getLogManager();
Logger result = manager.demandLogger(name);
Logger result = demandLogger(name, resourceBundleName);
// MissingResourceException or IllegalArgumentException can be
// thrown by setupResourceInfo().
......@@ -412,6 +444,17 @@ public class Logger {
return result;
}
// package-private
// Add a platform logger to the system context.
// i.e. caller of sun.util.logging.PlatformLogger.getLogger
static Logger getPlatformLogger(String name) {
LogManager manager = LogManager.getLogManager();
// all loggers in the system context will default to
// the system logger's resource bundle
Logger result = manager.demandSystemLogger(name, SYSTEM_LOGGER_RB_NAME);
return result;
}
/**
* Create an anonymous Logger. The newly created Logger is not
......@@ -564,7 +607,7 @@ public class Logger {
private void doLog(LogRecord lr) {
lr.setLoggerName(name);
String ebname = getEffectiveResourceBundleName();
if (ebname != null) {
if (ebname != null && !ebname.equals(SYSTEM_LOGGER_RB_NAME)) {
lr.setResourceBundleName(ebname);
lr.setResourceBundle(findResourceBundle(ebname));
}
......@@ -1547,6 +1590,23 @@ public class Logger {
// 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) {
// the resource bundle is in a restricted package
return AccessController.doPrivileged(new PrivilegedAction<ResourceBundle>() {
public ResourceBundle run() {
try {
return ResourceBundle.getBundle(SYSTEM_LOGGER_RB_NAME,
locale,
ClassLoader.getSystemClassLoader());
} catch (MissingResourceException e) {
throw new InternalError(e.toString());
}
}
});
}
private synchronized ResourceBundle findResourceBundle(String name) {
// Return a null bundle for a null name.
if (name == null) {
......@@ -1561,6 +1621,13 @@ public class Logger {
return catalog;
}
if (name.equals(SYSTEM_LOGGER_RB_NAME)) {
catalog = findSystemResourceBundle(currentLocale);
catalogName = name;
catalogLocale = currentLocale;
return catalog;
}
// Use the thread's context ClassLoader. If there isn't one,
// use the SystemClassloader.
ClassLoader cl = Thread.currentThread().getContextClassLoader();
......@@ -1577,7 +1644,6 @@ public class Logger {
// ClassLoader. Drop through.
}
// Fall back to searching up the call stack and trying each
// calling ClassLoader.
for (int ix = 0; ; ix++) {
......
......@@ -34,7 +34,7 @@ import java.util.ArrayList;
*
* The <tt>LoggingMXBean</tt> interface provides a standard
* method for management access to the individual
* java.util.Logger objects available at runtime.
* {@code Logger} objects available at runtime.
*
* @author Ron Mann
* @author Mandy Chung
......@@ -75,7 +75,7 @@ class Logging implements LoggingMXBean {
if (level == null) {
return EMPTY_STRING;
} else {
return level.getName();
return level.getLevelName();
}
}
......@@ -85,7 +85,6 @@ class Logging implements LoggingMXBean {
}
Logger logger = logManager.getLogger(loggerName);
if (logger == null) {
throw new IllegalArgumentException("Logger " + loggerName +
"does not exist");
......@@ -94,7 +93,10 @@ class Logging implements LoggingMXBean {
Level level = null;
if (levelName != null) {
// parse will throw IAE if logLevel is invalid
level = Level.parse(levelName);
level = Level.findLevel(levelName);
if (level == null) {
throw new IllegalArgumentException("Unknown level \"" + levelName + "\"");
}
}
logger.setLevel(level);
......
......@@ -37,7 +37,8 @@ class LoggingProxyImpl implements LoggingProxy {
@Override
public Object getLogger(String name) {
return Logger.getLogger(name);
// always create a platform logger with the resource bundle name
return Logger.getPlatformLogger(name);
}
@Override
......@@ -92,12 +93,16 @@ class LoggingProxyImpl implements LoggingProxy {
@Override
public Object parseLevel(String levelName) {
return Level.parse(levelName);
Level level = Level.findLevel(levelName);
if (level == null) {
throw new IllegalArgumentException("Unknown level \"" + levelName + "\"");
}
return level;
}
@Override
public String getLevelName(Object level) {
return ((Level) level).getName();
return ((Level) level).getLevelName();
}
@Override
......
......@@ -162,7 +162,7 @@ public class SimpleFormatter extends Formatter {
dat,
source,
record.getLoggerName(),
record.getLevel().getLocalizedName(),
record.getLevel().getLocalizedLevelName(),
message,
throwable);
}
......
/*
* Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 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
......@@ -39,11 +39,13 @@ import java.io.PrintStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.logging.Level;
import java.util.Map;
import java.util.Set;
......@@ -78,6 +80,8 @@ import javax.management.RuntimeErrorException;
import javax.management.RuntimeOperationsException;
import javax.management.ServiceNotFoundException;
import javax.management.loading.ClassLoaderRepository;
import sun.misc.JavaSecurityAccess;
import sun.misc.SharedSecrets;
import sun.reflect.misc.MethodUtil;
import sun.reflect.misc.ReflectUtil;
......@@ -138,6 +142,9 @@ public class RequiredModelMBean
private boolean registered = false;
private transient MBeanServer server = null;
private final static JavaSecurityAccess javaSecurityAccess = SharedSecrets.getJavaSecurityAccess();
final private AccessControlContext acc = AccessController.getContext();
/*************************************/
/* constructors */
/*************************************/
......@@ -1025,10 +1032,31 @@ public class RequiredModelMBean
if (opClassName != null) {
try {
final ClassLoader targetClassLoader =
targetObject.getClass().getClassLoader();
targetClass = Class.forName(opClassName, false,
targetClassLoader);
AccessControlContext stack = AccessController.getContext();
final Object obj = targetObject;
final String className = opClassName;
final ClassNotFoundException[] caughtException = new ClassNotFoundException[1];
targetClass = javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Class<?>>() {
@Override
public Class<?> run() {
try {
ReflectUtil.checkPackageAccess(className);
final ClassLoader targetClassLoader =
obj.getClass().getClassLoader();
return Class.forName(className, false,
targetClassLoader);
} catch (ClassNotFoundException e) {
caughtException[0] = e;
}
return null;
}
}, stack, acc);
if (caughtException[0] != null) {
throw caughtException[0];
}
} catch (ClassNotFoundException e) {
final String msg =
"class for invoke " + opName + " not found";
......@@ -1061,9 +1089,9 @@ public class RequiredModelMBean
return result;
}
private static Method resolveMethod(Class<?> targetClass,
private Method resolveMethod(Class<?> targetClass,
String opMethodName,
String[] sig)
final String[] sig)
throws ReflectionException {
final boolean tracing = MODELMBEAN_LOGGER.isLoggable(Level.FINER);
......@@ -1078,30 +1106,45 @@ public class RequiredModelMBean
if (sig == null)
argClasses = null;
else {
final AccessControlContext stack = AccessController.getContext();
final ReflectionException[] caughtException = new ReflectionException[1];
final ClassLoader targetClassLoader = targetClass.getClassLoader();
argClasses = new Class<?>[sig.length];
for (int i = 0; i < sig.length; i++) {
if (tracing) {
MODELMBEAN_LOGGER.logp(Level.FINER,
RequiredModelMBean.class.getName(),"resolveMethod",
"resolve type " + sig[i]);
}
argClasses[i] = (Class<?>) primitiveClassMap.get(sig[i]);
if (argClasses[i] == null) {
try {
argClasses[i] =
Class.forName(sig[i], false, targetClassLoader);
} catch (ClassNotFoundException e) {
javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Void>() {
@Override
public Void run() {
for (int i = 0; i < sig.length; i++) {
if (tracing) {
MODELMBEAN_LOGGER.logp(Level.FINER,
RequiredModelMBean.class.getName(),
"resolveMethod",
"class not found");
RequiredModelMBean.class.getName(),"resolveMethod",
"resolve type " + sig[i]);
}
argClasses[i] = (Class<?>) primitiveClassMap.get(sig[i]);
if (argClasses[i] == null) {
try {
ReflectUtil.checkPackageAccess(sig[i]);
argClasses[i] =
Class.forName(sig[i], false, targetClassLoader);
} catch (ClassNotFoundException e) {
if (tracing) {
MODELMBEAN_LOGGER.logp(Level.FINER,
RequiredModelMBean.class.getName(),
"resolveMethod",
"class not found");
}
final String msg = "Parameter class not found";
caughtException[0] = new ReflectionException(e, msg);
}
}
final String msg = "Parameter class not found";
throw new ReflectionException(e, msg);
}
return null;
}
}, stack, acc);
if (caughtException[0] != null) {
throw caughtException[0];
}
}
......@@ -1133,7 +1176,7 @@ public class RequiredModelMBean
/* Find a method in RequiredModelMBean as determined by the given
parameters. Return null if there is none, or if the parameters
exclude using it. Called from invoke. */
private static Method findRMMBMethod(String opMethodName,
private Method findRMMBMethod(String opMethodName,
Object targetObjectField,
String opClassName,
String[] sig) {
......@@ -1155,19 +1198,29 @@ public class RequiredModelMBean
if (opClassName == null)
targetClass = rmmbClass;
else {
try {
final ClassLoader targetClassLoader =
rmmbClass.getClassLoader();
targetClass = Class.forName(opClassName, false,
targetClassLoader);
if (!rmmbClass.isAssignableFrom(targetClass))
return null;
} catch (ClassNotFoundException e) {
return null;
}
AccessControlContext stack = AccessController.getContext();
final String className = opClassName;
targetClass = javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Class<?>>() {
@Override
public Class<?> run() {
try {
ReflectUtil.checkPackageAccess(className);
final ClassLoader targetClassLoader =
rmmbClass.getClassLoader();
Class clz = Class.forName(className, false,
targetClassLoader);
if (!rmmbClass.isAssignableFrom(clz))
return null;
return clz;
} catch (ClassNotFoundException e) {
return null;
}
}
}, stack, acc);
}
try {
return resolveMethod(targetClass, opMethodName, sig);
return targetClass != null ? resolveMethod(targetClass, opMethodName, sig) : null;
} catch (ReflectionException e) {
return null;
}
......@@ -1177,12 +1230,35 @@ public class RequiredModelMBean
* Invoke the given method, and throw the somewhat unpredictable
* appropriate exception if the method itself gets an exception.
*/
private Object invokeMethod(String opName, Method method,
Object targetObject, Object[] opArgs)
private Object invokeMethod(String opName, final Method method,
final Object targetObject, final Object[] opArgs)
throws MBeanException, ReflectionException {
try {
ReflectUtil.checkPackageAccess(method.getDeclaringClass());
return MethodUtil.invoke(method, targetObject, opArgs);
final Throwable[] caughtException = new Throwable[1];
AccessControlContext stack = AccessController.getContext();
Object rslt = javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Object>() {
@Override
public Object run() {
try {
ReflectUtil.checkPackageAccess(method.getDeclaringClass());
return MethodUtil.invoke(method, targetObject, opArgs);
} catch (InvocationTargetException e) {
caughtException[0] = e;
} catch (IllegalAccessException e) {
caughtException[0] = e;
}
return null;
}
}, stack, acc);
if (caughtException[0] != null) {
if (caughtException[0] instanceof Exception) {
throw (Exception)caughtException[0];
} else if(caughtException[0] instanceof Error) {
throw (Error)caughtException[0];
}
}
return rslt;
} catch (RuntimeErrorException ree) {
throw new RuntimeOperationsException(ree,
"RuntimeException occurred in RequiredModelMBean "+
......@@ -1567,7 +1643,7 @@ public class RequiredModelMBean
}
// make sure response class matches type field
String respType = attrInfo.getType();
final String respType = attrInfo.getType();
if (response != null) {
String responseClass = response.getClass().getName();
if (!respType.equals(responseClass)) {
......@@ -1590,9 +1666,31 @@ public class RequiredModelMBean
// inequality may come from type subclassing
boolean subtype;
try {
ClassLoader cl =
response.getClass().getClassLoader();
Class<?> c = Class.forName(respType, true, cl);
final Class respClass = response.getClass();
final Exception[] caughException = new Exception[1];
AccessControlContext stack = AccessController.getContext();
Class c = javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Class<?>>() {
@Override
public Class<?> run() {
try {
ReflectUtil.checkPackageAccess(respType);
ClassLoader cl =
respClass.getClassLoader();
return Class.forName(respType, true, cl);
} catch (Exception e) {
caughException[0] = e;
}
return null;
}
}, stack, acc);
if (caughException[0] != null) {
throw caughException[0];
}
subtype = c.isInstance(response);
} catch (Exception e) {
subtype = false;
......@@ -2745,16 +2843,37 @@ public class RequiredModelMBean
return MBeanServerFactory.getClassLoaderRepository(server);
}
private Class<?> loadClass(String className)
private Class<?> loadClass(final String className)
throws ClassNotFoundException {
try {
return Class.forName(className);
} catch (ClassNotFoundException e) {
final ClassLoaderRepository clr =
getClassLoaderRepository();
if (clr == null) throw new ClassNotFoundException(className);
return clr.loadClass(className);
AccessControlContext stack = AccessController.getContext();
final ClassNotFoundException[] caughtException = new ClassNotFoundException[1];
Class c = javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Class<?>>() {
@Override
public Class<?> run() {
try {
ReflectUtil.checkPackageAccess(className);
return Class.forName(className);
} catch (ClassNotFoundException e) {
final ClassLoaderRepository clr =
getClassLoaderRepository();
try {
if (clr == null) throw new ClassNotFoundException(className);
return clr.loadClass(className);
} catch (ClassNotFoundException ex) {
caughtException[0] = ex;
}
}
return null;
}
}, stack, acc);
if (caughtException[0] != null) {
throw caughtException[0];
}
return c;
}
......
......@@ -781,15 +781,11 @@ public class JTable extends JComponent implements TableModelListener, Scrollable
scrollPane.getCorner(JScrollPane.UPPER_TRAILING_CORNER);
if (corner == null || corner instanceof UIResource){
corner = null;
Object componentClass = UIManager.get(
"Table.scrollPaneCornerComponent");
if (componentClass instanceof Class){
try {
corner = (Component)
((Class)componentClass).newInstance();
} catch (Exception e) {
// just ignore and don't set corner
}
try {
corner = (Component) UIManager.get(
"Table.scrollPaneCornerComponent");
} catch (Exception e) {
// just ignore and don't set corner
}
scrollPane.setCorner(JScrollPane.UPPER_TRAILING_CORNER,
corner);
......
......@@ -27,11 +27,12 @@ package javax.swing;
import java.awt.*;
import java.awt.event.*;
import java.awt.peer.ComponentPeer;
import java.awt.peer.ContainerPeer;
import java.awt.image.VolatileImage;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.applet.*;
import sun.awt.AWTAccessor;
......@@ -39,6 +40,8 @@ import sun.awt.AppContext;
import sun.awt.DisplayChangedListener;
import sun.awt.SunToolkit;
import sun.java2d.SunGraphicsEnvironment;
import sun.misc.JavaSecurityAccess;
import sun.misc.SharedSecrets;
import sun.security.action.GetPropertyAction;
import com.sun.java.swing.SwingUtilities3;
......@@ -176,6 +179,9 @@ public class RepaintManager
*/
private final ProcessingRunnable processingRunnable;
private final static JavaSecurityAccess javaSecurityAccess =
SharedSecrets.getJavaSecurityAccess();
static {
volatileImageBufferEnabled = "true".equals(AccessController.
......@@ -548,13 +554,26 @@ public class RepaintManager
// This is called from the toolkit thread when awt needs to run a
// Runnable before we paint.
//
void nativeQueueSurfaceDataRunnable(AppContext appContext, Component c,
Runnable r) {
void nativeQueueSurfaceDataRunnable(AppContext appContext,
final Component c, final Runnable r)
{
synchronized(this) {
if (runnableList == null) {
runnableList = new LinkedList<Runnable>();
}
runnableList.add(r);
runnableList.add(new Runnable() {
public void run() {
AccessControlContext stack = AccessController.getContext();
AccessControlContext acc =
AWTAccessor.getComponentAccessor().getAccessControlContext(c);
javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Void>() {
public Void run() {
r.run();
return null;
}
}, stack, acc);
}
});
}
scheduleProcessingRunnable(appContext);
}
......@@ -652,9 +671,9 @@ public class RepaintManager
* @see #addInvalidComponent
*/
public void validateInvalidComponents() {
java.util.List<Component> ic;
final java.util.List<Component> ic;
synchronized(this) {
if(invalidComponents == null) {
if (invalidComponents == null) {
return;
}
ic = invalidComponents;
......@@ -662,7 +681,17 @@ public class RepaintManager
}
int n = ic.size();
for(int i = 0; i < n; i++) {
ic.get(i).validate();
final Component c = ic.get(i);
AccessControlContext stack = AccessController.getContext();
AccessControlContext acc =
AWTAccessor.getComponentAccessor().getAccessControlContext(c);
javaSecurityAccess.doIntersectionPrivilege(
new PrivilegedAction<Void>() {
public Void run() {
c.validate();
return null;
}
}, stack, acc);
}
}
......@@ -740,78 +769,78 @@ public class RepaintManager
paintDirtyRegions(tmpDirtyComponents);
}
private void paintDirtyRegions(Map<Component,Rectangle>
tmpDirtyComponents){
int i, count;
java.util.List<Component> roots;
Component dirtyComponent;
count = tmpDirtyComponents.size();
if (count == 0) {
private void paintDirtyRegions(
final Map<Component,Rectangle> tmpDirtyComponents)
{
if (tmpDirtyComponents.isEmpty()) {
return;
}
Rectangle rect;
int localBoundsX = 0;
int localBoundsY = 0;
int localBoundsH;
int localBoundsW;
roots = new ArrayList<Component>(count);
final java.util.List<Component> roots =
new ArrayList<Component>(tmpDirtyComponents.size());
for (Component dirty : tmpDirtyComponents.keySet()) {
collectDirtyComponents(tmpDirtyComponents, dirty, roots);
}
count = roots.size();
final AtomicInteger count = new AtomicInteger(roots.size());
painting = true;
try {
for(i=0 ; i < count ; i++) {
dirtyComponent = roots.get(i);
rect = tmpDirtyComponents.get(dirtyComponent);
// Sometimes when RepaintManager is changed during the painting
// we may get null here, see #6995769 for details
if (rect == null) {
continue;
}
localBoundsH = dirtyComponent.getHeight();
localBoundsW = dirtyComponent.getWidth();
SwingUtilities.computeIntersection(localBoundsX,
localBoundsY,
localBoundsW,
localBoundsH,
rect);
if (dirtyComponent instanceof JComponent) {
((JComponent)dirtyComponent).paintImmediately(
rect.x,rect.y,rect.width, rect.height);
}
else if (dirtyComponent.isShowing()) {
Graphics g = JComponent.safelyGetGraphics(
dirtyComponent, dirtyComponent);
// If the Graphics goes away, it means someone disposed of
// the window, don't do anything.
if (g != null) {
g.setClip(rect.x, rect.y, rect.width, rect.height);
try {
dirtyComponent.paint(g);
} finally {
g.dispose();
for (int j=0 ; j < count.get(); j++) {
final int i = j;
final Component dirtyComponent = roots.get(j);
AccessControlContext stack = AccessController.getContext();
AccessControlContext acc =
AWTAccessor.getComponentAccessor().getAccessControlContext(dirtyComponent);
javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Void>() {
public Void run() {
Rectangle rect = tmpDirtyComponents.get(dirtyComponent);
// Sometimes when RepaintManager is changed during the painting
// we may get null here, see #6995769 for details
if (rect == null) {
return null;
}
int localBoundsH = dirtyComponent.getHeight();
int localBoundsW = dirtyComponent.getWidth();
SwingUtilities.computeIntersection(0,
0,
localBoundsW,
localBoundsH,
rect);
if (dirtyComponent instanceof JComponent) {
((JComponent)dirtyComponent).paintImmediately(
rect.x,rect.y,rect.width, rect.height);
}
else if (dirtyComponent.isShowing()) {
Graphics g = JComponent.safelyGetGraphics(
dirtyComponent, dirtyComponent);
// If the Graphics goes away, it means someone disposed of
// the window, don't do anything.
if (g != null) {
g.setClip(rect.x, rect.y, rect.width, rect.height);
try {
dirtyComponent.paint(g);
} finally {
g.dispose();
}
}
}
// If the repaintRoot has been set, service it now and
// remove any components that are children of repaintRoot.
if (repaintRoot != null) {
adjustRoots(repaintRoot, roots, i + 1);
count.set(roots.size());
paintManager.isRepaintingRoot = true;
repaintRoot.paintImmediately(0, 0, repaintRoot.getWidth(),
repaintRoot.getHeight());
paintManager.isRepaintingRoot = false;
// Only service repaintRoot once.
repaintRoot = null;
}
return null;
}
}
// If the repaintRoot has been set, service it now and
// remove any components that are children of repaintRoot.
if (repaintRoot != null) {
adjustRoots(repaintRoot, roots, i + 1);
count = roots.size();
paintManager.isRepaintingRoot = true;
repaintRoot.paintImmediately(0, 0, repaintRoot.getWidth(),
repaintRoot.getHeight());
paintManager.isRepaintingRoot = false;
// Only service repaintRoot once.
repaintRoot = null;
}
}, stack, acc);
}
} finally {
painting = false;
......
......@@ -677,6 +677,8 @@ public class UIDefaults extends Hashtable<Object,Object>
try {
String className = (String)get(uiClassID);
if (className != null) {
ReflectUtil.checkPackageAccess(className);
Class cls = (Class)get(className);
if (cls == null) {
if (uiClassLoader == null) {
......
......@@ -159,7 +159,12 @@ public class NimbusLookAndFeel extends SynthLookAndFeel {
// Store Table ScrollPane Corner Component
uiDefaults.put("Table.scrollPaneCornerComponent",
TableScrollPaneCorner.class);
new UIDefaults.ActiveValue() {
@Override
public Object createValue(UIDefaults table) {
return new TableScrollPaneCorner();
}
});
// Setup the settings for ToolBarSeparator which is custom
// installed for Nimbus
......
......@@ -45,6 +45,7 @@ import java.util.*;
import java.util.Collections;
import java.util.Locale;
import java.util.WeakHashMap;
import sun.awt.AWTAccessor;
import sun.awt.AppContext;
import sun.awt.EmbeddedFrame;
import sun.awt.SunToolkit;
......@@ -448,12 +449,12 @@ abstract class AppletPanel extends Panel implements AppletStub, Runnable {
// to avoid deadlock.
try {
final AppletPanel p = this;
EventQueue.invokeAndWait(new Runnable() {
public void run() {
p.validate();
}
});
Runnable r = new Runnable() {
public void run() {
p.validate();
}
};
AWTAccessor.getEventQueueAccessor().invokeAndWait(applet, r);
}
catch(InterruptedException ie) {
}
......@@ -478,18 +479,19 @@ abstract class AppletPanel extends Panel implements AppletStub, Runnable {
try {
final AppletPanel p = this;
final Applet a = applet;
EventQueue.invokeAndWait(new Runnable() {
public void run() {
p.validate();
a.setVisible(true);
// Fix for BugTraq ID 4041703.
// Set the default focus for an applet.
if (hasInitialFocus())
setDefaultFocus();
Runnable r = new Runnable() {
public void run() {
p.validate();
a.setVisible(true);
// Fix for BugTraq ID 4041703.
// Set the default focus for an applet.
if (hasInitialFocus()) {
setDefaultFocus();
}
});
}
};
AWTAccessor.getEventQueueAccessor().invokeAndWait(applet, r);
}
catch(InterruptedException ie) {
}
......@@ -512,13 +514,12 @@ abstract class AppletPanel extends Panel implements AppletStub, Runnable {
// to avoid deadlock.
try {
final Applet a = applet;
EventQueue.invokeAndWait(new Runnable() {
public void run()
{
a.setVisible(false);
}
});
Runnable r = new Runnable() {
public void run() {
a.setVisible(false);
}
};
AWTAccessor.getEventQueueAccessor().invokeAndWait(applet, r);
}
catch(InterruptedException ie) {
}
......@@ -570,17 +571,14 @@ abstract class AppletPanel extends Panel implements AppletStub, Runnable {
}
status = APPLET_DISPOSE;
try
{
try {
final Applet a = applet;
EventQueue.invokeAndWait(new Runnable()
{
public void run()
{
Runnable r = new Runnable() {
public void run() {
remove(a);
}
});
};
AWTAccessor.getEventQueueAccessor().invokeAndWait(applet, r);
}
catch(InterruptedException ie)
{
......
......@@ -34,6 +34,8 @@ import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.geom.Point2D;
import java.awt.peer.ComponentPeer;
import java.lang.reflect.InvocationTargetException;
import java.security.AccessControlContext;
import java.io.File;
......@@ -476,6 +478,12 @@ public final class AWTAccessor {
* appeared.
*/
void wakeup(EventQueue eventQueue, boolean isShutdown);
/**
* Static in EventQueue
*/
void invokeAndWait(Object source, Runnable r)
throws InterruptedException, InvocationTargetException;
}
/*
......
......@@ -327,21 +327,27 @@ public final class AppContext {
// Before we return the main "system" AppContext, check to
// see if there's an AWTSecurityManager installed. If so,
// allow it to choose the AppContext to return.
SecurityManager securityManager = System.getSecurityManager();
if ((securityManager != null) &&
(securityManager instanceof AWTSecurityManager))
{
AWTSecurityManager awtSecMgr = (AWTSecurityManager)securityManager;
AppContext secAppContext = awtSecMgr.getAppContext();
if (secAppContext != null) {
appContext = secAppContext; // Return what we're told
}
AppContext secAppContext = getExecutionAppContext();
if (secAppContext != null) {
appContext = secAppContext; // Return what we're told
}
}
return appContext;
}
private final static AppContext getExecutionAppContext() {
SecurityManager securityManager = System.getSecurityManager();
if ((securityManager != null) &&
(securityManager instanceof AWTSecurityManager))
{
AWTSecurityManager awtSecMgr = (AWTSecurityManager) securityManager;
AppContext secAppContext = awtSecMgr.getAppContext();
return secAppContext; // Return what we're told
}
return null;
}
/**
* Returns the main ("system") AppContext.
*
......@@ -806,6 +812,21 @@ public final class AppContext {
public boolean isMainAppContext() {
return (numAppContexts.get() == 1);
}
public Object getContext() {
return getAppContext();
}
public Object getExecutionContext() {
return getExecutionAppContext();
}
public Object get(Object context, Object key) {
return ((AppContext)context).get(key);
}
public void put(Object context, Object key, Object value) {
((AppContext)context).put(key, value);
}
public void remove(Object context, Object key) {
((AppContext)context).remove(key);
}
});
}
}
......
......@@ -198,7 +198,7 @@ public class ByteComponentRaster extends SunWritableRaster {
}
this.bandOffset = this.dataOffsets[0];
verify(false);
verify();
}
/**
......@@ -857,38 +857,68 @@ public class ByteComponentRaster extends SunWritableRaster {
}
/**
* 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.
*
* The method verifies whether scanline stride and pixel stride do not
* cause an integer overflow during calculation of a position of the pixel
* in data buffer. It also verifies whether the data buffer has enough data
* to correspond the raster layout attributes.
*
* @throws RasterFormatException if an integer overflow is detected,
* or if data buffer has not enough capacity.
*/
private void verify (boolean strictCheck) {
// Make sure data for Raster is in a legal range
for (int i=0; i < dataOffsets.length; i++) {
protected final void verify() {
for (int i = 0; i < dataOffsets.length; i++) {
if (dataOffsets[i] < 0) {
throw new RasterFormatException("Data offsets for band "+i+
"("+dataOffsets[i]+
") must be >= 0");
throw new RasterFormatException("Data offsets for band " + i
+ "(" + dataOffsets[i]
+ ") must be >= 0");
}
}
int maxSize = 0;
int size;
for (int i=0; i < numDataElements; i++) {
size = (height-1)*scanlineStride + (width-1)*pixelStride +
dataOffsets[i];
// we can be sure that width and height are greater than 0
if (scanlineStride < 0 ||
scanlineStride > (Integer.MAX_VALUE / height))
{
// integer overflow
throw new RasterFormatException("Incorrect scanline stride: "
+ scanlineStride);
}
int lastScanOffset = (height - 1) * scanlineStride;
if (pixelStride < 0 ||
pixelStride > (Integer.MAX_VALUE / width))
{
// integer overflow
throw new RasterFormatException("Incorrect pixel stride: "
+ pixelStride);
}
int lastPixelOffset = (width - 1) * pixelStride;
if (lastPixelOffset > (Integer.MAX_VALUE - lastScanOffset)) {
// integer overflow
throw new RasterFormatException("Incorrect raster attributes");
}
lastPixelOffset += lastScanOffset;
for (int i = 0; i < numDataElements; i++) {
size = lastPixelOffset + dataOffsets[i];
if (dataOffsets[i] > (Integer.MAX_VALUE - lastPixelOffset)) {
throw new RasterFormatException("Incorrect band offset: "
+ dataOffsets[i]);
}
if (size > maxSize) {
maxSize = size;
}
}
if (data.length < maxSize) {
throw new RasterFormatException("Data array too small (should be "+
maxSize+" )");
throw new RasterFormatException("Data array too small (should be "
+ maxSize + " )");
}
}
......
......@@ -250,7 +250,7 @@ public class ByteInterleavedRaster extends ByteComponentRaster {
}
}
verify(false);
verify();
}
/**
......@@ -1292,33 +1292,6 @@ public class ByteInterleavedRaster extends ByteComponentRaster {
return createCompatibleWritableRaster(width,height);
}
/**
* 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.
*/
private void verify (boolean strictCheck) {
int maxSize = 0;
int size;
for (int i=0; i < numDataElements; i++) {
size = (height-1)*scanlineStride + (width-1)*pixelStride +
dataOffsets[i];
if (size > maxSize) {
maxSize = size;
}
}
if (data.length < maxSize) {
throw new RasterFormatException("Data array too small (should be "+
maxSize+" )");
}
}
public String toString() {
return new String ("ByteInterleavedRaster: width = "+width+" height = "
+ height
......
......@@ -198,7 +198,7 @@ public class ShortComponentRaster extends SunWritableRaster {
}
this.bandOffset = this.dataOffsets[0];
verify(false);
verify();
}
/**
......@@ -791,38 +791,67 @@ public class ShortComponentRaster extends SunWritableRaster {
}
/**
* 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.
*
* The method verifies whether scanline stride and pixel stride do not
* cause an integer overflow during calculation of a position of the pixel
* in data buffer. It also verifies whether the data buffer has enough data
* to correspond the raster layout attributes.
*
* @throws RasterFormatException if an integer overflow is detected,
* or if data buffer has not enough capacity.
*/
private void verify (boolean strictCheck) {
// Make sure data for Raster is in a legal range
for (int i=0; i < dataOffsets.length; i++) {
protected final void verify() {
for (int i = 0; i < dataOffsets.length; i++) {
if (dataOffsets[i] < 0) {
throw new RasterFormatException("Data offsets for band "+i+
"("+dataOffsets[i]+
") must be >= 0");
throw new RasterFormatException("Data offsets for band " + i
+ "(" + dataOffsets[i]
+ ") must be >= 0");
}
}
int maxSize = 0;
int size;
for (int i=0; i < numDataElements; i++) {
size = (height-1)*scanlineStride + (width-1)*pixelStride +
dataOffsets[i];
// we can be sure that width and height are greater than 0
if (scanlineStride < 0 ||
scanlineStride > (Integer.MAX_VALUE / height))
{
// integer overflow
throw new RasterFormatException("Incorrect scanline stride: "
+ scanlineStride);
}
int lastScanOffset = (height - 1) * scanlineStride;
if (pixelStride < 0 ||
pixelStride > (Integer.MAX_VALUE / width))
{
// integer overflow
throw new RasterFormatException("Incorrect pixel stride: "
+ pixelStride);
}
int lastPixelOffset = (width - 1) * pixelStride;
if (lastPixelOffset > (Integer.MAX_VALUE - lastScanOffset)) {
// integer overflow
throw new RasterFormatException("Incorrect raster attributes");
}
lastPixelOffset += lastScanOffset;
for (int i = 0; i < numDataElements; i++) {
size = lastPixelOffset + dataOffsets[i];
if (dataOffsets[i] > (Integer.MAX_VALUE - lastPixelOffset)) {
throw new RasterFormatException("Incorrect band offset: "
+ dataOffsets[i]);
}
if (size > maxSize) {
maxSize = size;
}
}
if (data.length < maxSize) {
throw new RasterFormatException("Data array too small (should be "+
maxSize+" )");
throw new RasterFormatException("Data array too small (should be "
+ maxSize + " )");
}
}
......
......@@ -171,7 +171,7 @@ public class ShortInterleavedRaster extends ShortComponentRaster {
sampleModel);
}
this.bandOffset = this.dataOffsets[0];
verify(false);
verify();
}
/**
......@@ -762,33 +762,6 @@ public class ShortInterleavedRaster extends ShortComponentRaster {
return createCompatibleWritableRaster(width,height);
}
/**
* 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.
*/
private void verify (boolean strictCheck) {
int maxSize = 0;
int size;
for (int i=0; i < numDataElements; i++) {
size = (height-1)*scanlineStride + (width-1)*pixelStride +
dataOffsets[i];
if (size > maxSize) {
maxSize = size;
}
}
if (data.length < maxSize) {
throw new RasterFormatException("Data array too small (should be "+
maxSize+" )");
}
}
public String toString() {
return new String ("ShortInterleavedRaster: width = "+width
+" height = " + height
......
......@@ -26,6 +26,14 @@
package sun.misc;
public interface JavaAWTAccess {
public Object getContext();
public Object getExecutionContext();
public Object get(Object context, Object key);
public void put(Object context, Object key, Object value);
public void remove(Object context, Object key);
// convenience methods whose context is the object returned by getContext()
public Object get(Object key);
public void put(Object key, Object value);
public void remove(Object key);
......
......@@ -41,8 +41,12 @@ class ChunkedInputStream extends LeftOverInputStream {
private boolean needToReadHeader = true;
static char CR = '\r';
static char LF = '\n';
final static char CR = '\r';
final static char LF = '\n';
/*
* Maximum chunk header size of 2KB + 2 bytes for CRLF
*/
private final static int MAX_CHUNK_HEADER_SIZE = 2050;
private int numeric (char[] arr, int nchars) throws IOException {
assert arr.length >= nchars;
......@@ -73,10 +77,14 @@ class ChunkedInputStream extends LeftOverInputStream {
char[] len_arr = new char [16];
int len_size = 0;
boolean end_of_len = false;
int read = 0;
while ((c=in.read())!= -1) {
char ch = (char) c;
if (len_size == len_arr.length -1) {
read++;
if ((len_size == len_arr.length -1) ||
(read > MAX_CHUNK_HEADER_SIZE))
{
throw new IOException ("invalid chunk header");
}
if (gotCR) {
......
......@@ -125,6 +125,11 @@ class ChunkedInputStream extends InputStream implements Hurryable {
*/
private boolean closed;
/*
* Maximum chunk header size of 2KB + 2 bytes for CRLF
*/
private final static int MAX_CHUNK_HEADER_SIZE = 2050;
/**
* State to indicate that next field should be :-
* chunk-size [ chunk-extension ] CRLF
......@@ -290,6 +295,10 @@ class ChunkedInputStream extends InputStream implements Hurryable {
break;
}
pos++;
if ((pos - rawPos) >= MAX_CHUNK_HEADER_SIZE) {
error = true;
throw new IOException("Chunk header too long");
}
}
if (pos >= rawCount) {
return;
......
......@@ -421,7 +421,7 @@ class DatagramChannelImpl
synchronized (writeLock) {
ensureOpen();
InetSocketAddress isa = (InetSocketAddress)target;
InetSocketAddress isa = Net.checkAddress(target);
InetAddress ia = isa.getAddress();
if (ia == null)
throw new IOException("Target address not resolved");
......@@ -432,9 +432,9 @@ class DatagramChannelImpl
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
if (ia.isMulticastAddress()) {
sm.checkMulticast(isa.getAddress());
sm.checkMulticast(ia);
} else {
sm.checkConnect(isa.getAddress().getHostAddress(),
sm.checkConnect(ia.getHostAddress(),
isa.getPort());
}
}
......@@ -454,7 +454,7 @@ class DatagramChannelImpl
return 0;
writerThread = NativeThread.current();
do {
n = send(fd, src, target);
n = send(fd, src, isa);
} while ((n == IOStatus.INTERRUPTED) && isOpen());
synchronized (stateLock) {
......@@ -471,7 +471,7 @@ class DatagramChannelImpl
}
}
private int send(FileDescriptor fd, ByteBuffer src, SocketAddress target)
private int send(FileDescriptor fd, ByteBuffer src, InetSocketAddress target)
throws IOException
{
if (src instanceof DirectBuffer)
......@@ -502,7 +502,7 @@ class DatagramChannelImpl
}
private int sendFromNativeBuffer(FileDescriptor fd, ByteBuffer bb,
SocketAddress target)
InetSocketAddress target)
throws IOException
{
int pos = bb.position();
......@@ -514,7 +514,7 @@ class DatagramChannelImpl
int written;
try {
written = send0(preferIPv6, fd, ((DirectBuffer)bb).address() + pos,
rem, target);
rem, target.getAddress(), target.getPort());
} catch (PortUnreachableException pue) {
if (isConnected())
throw pue;
......@@ -1116,8 +1116,8 @@ class DatagramChannelImpl
boolean connected)
throws IOException;
private native int send0(boolean preferIPv6, FileDescriptor fd, long address, int len,
SocketAddress sa)
private native int send0(boolean preferIPv6, FileDescriptor fd, long address,
int len, InetAddress addr, int port)
throws IOException;
static {
......
......@@ -178,4 +178,29 @@ public final class ReflectUtil {
return !isAncestor(from, to);
}
/**
* Access check on the interfaces that a proxy class implements and throw
* {@code SecurityException} if it accesses a restricted package.
*
* @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)
{
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
for (Class<?> intf : interfaces) {
ClassLoader cl = intf.getClassLoader();
if (needsPackageAccessCheck(ccl, cl)) {
checkPackageAccess(intf);
}
}
}
}
public static final String PROXY_PACKAGE = "sun.proxy";
}
......@@ -153,7 +153,7 @@ public final class CGIHandler {
returnServerError(e.getMessage());
}
else
returnClientError("invalid command: " + command);
returnClientError("invalid command.");
} catch (Exception e) {
returnServerError("internal error: " + e.getMessage());
}
......@@ -225,7 +225,7 @@ final class CGIForwardCommand implements CGICommandHandler {
try {
port = Integer.parseInt(param);
} catch (NumberFormatException e) {
throw new CGIClientException("invalid port number: " + param);
throw new CGIClientException("invalid port number.");
}
if (port <= 0 || port > 0xFFFF)
throw new CGIClientException("invalid port: " + port);
......@@ -293,11 +293,14 @@ final class CGIForwardCommand implements CGICommandHandler {
"unexpected EOF reading server response");
if (line.toLowerCase().startsWith(key)) {
// if contentLengthFound is true
// we should probably do something here
responseContentLength =
Integer.parseInt(line.substring(key.length()).trim());
contentLengthFound = true;
if (contentLengthFound) {
throw new CGIServerException(
"Multiple Content-length entries found.");
} else {
responseContentLength =
Integer.parseInt(line.substring(key.length()).trim());
contentLengthFound = true;
}
}
} while ((line.length() != 0) &&
(line.charAt(0) != '\r') && (line.charAt(0) != '\n'));
......
......@@ -70,11 +70,14 @@ class HttpInputStream extends FilterInputStream {
throw new EOFException();
if (line.toLowerCase().startsWith(key)) {
// if contentLengthFound is true
// we should probably do something here
bytesLeft =
Integer.parseInt(line.substring(key.length()).trim());
contentLengthFound = true;
if (contentLengthFound) {
throw new IOException(
"Multiple Content-length entries found.");
} else {
bytesLeft =
Integer.parseInt(line.substring(key.length()).trim());
contentLengthFound = true;
}
}
// The idea here is to go past the first blank line.
......
......@@ -37,6 +37,7 @@ import javax.crypto.spec.*;
import static sun.security.pkcs11.TemplateManager.*;
import sun.security.pkcs11.wrapper.*;
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
import sun.security.util.KeyUtil;
/**
* KeyAgreement implementation class. This class currently supports
......@@ -134,6 +135,10 @@ final class P11KeyAgreement extends KeyAgreementSpi {
BigInteger p, g, y;
if (key instanceof DHPublicKey) {
DHPublicKey dhKey = (DHPublicKey)key;
// validate the Diffie-Hellman public key
KeyUtil.validate(dhKey);
y = dhKey.getY();
DHParameterSpec params = dhKey.getParams();
p = params.getP();
......@@ -145,6 +150,10 @@ final class P11KeyAgreement extends KeyAgreementSpi {
try {
DHPublicKeySpec spec = kf.engineGetKeySpec(
key, DHPublicKeySpec.class);
// validate the Diffie-Hellman public key
KeyUtil.validate(spec);
y = spec.getY();
p = spec.getP();
g = spec.getG();
......
......@@ -129,9 +129,8 @@ final class ClientHandshaker extends Handshaker {
*/
@Override
void processMessage(byte type, int messageLen) throws IOException {
if (state > type
&& (type != HandshakeMessage.ht_hello_request
&& state != HandshakeMessage.ht_client_hello)) {
if (state >= type
&& (type != HandshakeMessage.ht_hello_request)) {
throw new SSLProtocolException(
"Handshake message sequence violation, " + type);
}
......@@ -194,8 +193,12 @@ final class ClientHandshaker extends Handshaker {
}
break;
case K_DH_ANON:
this.serverKeyExchange(new DH_ServerKeyExchange(
try {
this.serverKeyExchange(new DH_ServerKeyExchange(
input, protocolVersion));
} catch (GeneralSecurityException e) {
throwSSLException("Server key", e);
}
break;
case K_DHE_DSS:
case K_DHE_RSA:
......@@ -921,7 +924,7 @@ final class ClientHandshaker extends Handshaker {
case K_DHE_RSA:
case K_DHE_DSS:
case K_DH_ANON:
preMasterSecret = dh.getAgreedSecret(serverDH);
preMasterSecret = dh.getAgreedSecret(serverDH, true);
break;
case K_ECDHE_RSA:
case K_ECDHE_ECDSA:
......
/*
* Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 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
......@@ -29,7 +29,7 @@ package sun.security.ssl;
import java.io.IOException;
import java.io.PrintStream;
import java.math.BigInteger;
import javax.net.ssl.SSLHandshakeException;
/*
* Message used by clients to send their Diffie-Hellman public
......@@ -51,7 +51,7 @@ final class DHClientKeyExchange extends HandshakeMessage {
private byte dh_Yc[]; // 1 to 2^16 -1 bytes
BigInteger getClientPublicKey() {
return new BigInteger(1, dh_Yc);
return dh_Yc == null ? null : new BigInteger(1, dh_Yc);
}
/*
......@@ -73,7 +73,14 @@ final class DHClientKeyExchange extends HandshakeMessage {
* but that's what the protocol spec requires.)
*/
DHClientKeyExchange(HandshakeInStream input) throws IOException {
dh_Yc = input.getBytes16();
if (input.available() >= 2) {
dh_Yc = input.getBytes16();
} else {
// currently, we don't support cipher suites that requires
// implicit public key of client.
throw new SSLHandshakeException(
"Unsupported implicit client DiffieHellman public key");
}
}
@Override
......@@ -87,7 +94,9 @@ final class DHClientKeyExchange extends HandshakeMessage {
@Override
void send(HandshakeOutStream s) throws IOException {
s.putBytes16(dh_Yc);
if (dh_Yc != null && dh_Yc.length != 0) {
s.putBytes16(dh_Yc);
}
}
@Override
......
/*
* Copyright (c) 1996, 2008, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 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
......@@ -28,12 +28,15 @@ package sun.security.ssl;
import java.math.BigInteger;
import java.security.*;
import java.io.IOException;
import javax.net.ssl.SSLHandshakeException;
import javax.crypto.SecretKey;
import javax.crypto.KeyAgreement;
import javax.crypto.interfaces.DHPublicKey;
import javax.crypto.spec.*;
import sun.security.util.KeyUtil;
/**
* This class implements the Diffie-Hellman key exchange algorithm.
* D-H means combining your private key with your partners public key to
......@@ -54,7 +57,8 @@ import javax.crypto.spec.*;
* . if we are server, call DHCrypt(keyLength,random). This generates
* an ephemeral keypair of the request length.
* . if we are client, call DHCrypt(modulus, base, random). This
* generates an ephemeral keypair using the parameters specified by the server.
* generates an ephemeral keypair using the parameters specified by
* the server.
* . send parameters and public value to remote peer
* . receive peers ephemeral public key
* . call getAgreedSecret() to calculate the shared secret
......@@ -83,6 +87,9 @@ final class DHCrypt {
// public component of our key, X = (g ^ x) mod p
private BigInteger publicValue; // X (aka y)
// the times to recove from failure if public key validation
private static int MAX_FAILOVER_TIMES = 2;
/**
* Generate a Diffie-Hellman keypair of the specified size.
*/
......@@ -90,9 +97,12 @@ final class DHCrypt {
try {
KeyPairGenerator kpg = JsseJce.getKeyPairGenerator("DiffieHellman");
kpg.initialize(keyLength, random);
KeyPair kp = kpg.generateKeyPair();
privateKey = kp.getPrivate();
DHPublicKeySpec spec = getDHPublicKeySpec(kp.getPublic());
DHPublicKeySpec spec = generateDHPublicKeySpec(kpg);
if (spec == null) {
throw new RuntimeException("Could not generate DH keypair");
}
publicValue = spec.getY();
modulus = spec.getP();
base = spec.getG();
......@@ -115,20 +125,25 @@ final class DHCrypt {
KeyPairGenerator kpg = JsseJce.getKeyPairGenerator("DiffieHellman");
DHParameterSpec params = new DHParameterSpec(modulus, base);
kpg.initialize(params, random);
KeyPair kp = kpg.generateKeyPair();
privateKey = kp.getPrivate();
DHPublicKeySpec spec = getDHPublicKeySpec(kp.getPublic());
DHPublicKeySpec spec = generateDHPublicKeySpec(kpg);
if (spec == null) {
throw new RuntimeException("Could not generate DH keypair");
}
publicValue = spec.getY();
} catch (GeneralSecurityException e) {
throw new RuntimeException("Could not generate DH keypair", e);
}
}
static DHPublicKeySpec getDHPublicKeySpec(PublicKey key) {
if (key instanceof DHPublicKey) {
DHPublicKey dhKey = (DHPublicKey)key;
DHParameterSpec params = dhKey.getParams();
return new DHPublicKeySpec(dhKey.getY(), params.getP(), params.getG());
return new DHPublicKeySpec(dhKey.getY(),
params.getP(), params.getG());
}
try {
KeyFactory factory = JsseJce.getKeyFactory("DH");
......@@ -166,17 +181,32 @@ final class DHCrypt {
* <P>It is illegal to call this member function if the private key
* has not been set (or generated).
*
* @param peerPublicKey the peer's public key.
* @returns the secret, which is an unsigned big-endian integer
* the same size as the Diffie-Hellman modulus.
* @param peerPublicKey the peer's public key.
* @param keyIsValidated whether the {@code peerPublicKey} has beed
* validated
* @return the secret, which is an unsigned big-endian integer
* the same size as the Diffie-Hellman modulus.
*/
SecretKey getAgreedSecret(BigInteger peerPublicValue) {
SecretKey getAgreedSecret(BigInteger peerPublicValue,
boolean keyIsValidated) throws IOException {
try {
KeyFactory kf = JsseJce.getKeyFactory("DiffieHellman");
DHPublicKeySpec spec =
new DHPublicKeySpec(peerPublicValue, modulus, base);
PublicKey publicKey = kf.generatePublic(spec);
KeyAgreement ka = JsseJce.getKeyAgreement("DiffieHellman");
// validate the Diffie-Hellman public key
if (!keyIsValidated &&
!KeyUtil.isOracleJCEProvider(ka.getProvider().getName())) {
try {
KeyUtil.validate(spec);
} catch (InvalidKeyException ike) {
// prefer handshake_failure alert to internal_error alert
throw new SSLHandshakeException(ike.getMessage());
}
}
ka.init(privateKey);
ka.doPhase(publicKey, true);
return ka.generateSecret("TlsPremasterSecret");
......@@ -185,4 +215,33 @@ final class DHCrypt {
}
}
// Generate and validate DHPublicKeySpec
private DHPublicKeySpec generateDHPublicKeySpec(KeyPairGenerator kpg)
throws GeneralSecurityException {
boolean doExtraValiadtion =
(!KeyUtil.isOracleJCEProvider(kpg.getProvider().getName()));
for (int i = 0; i <= MAX_FAILOVER_TIMES; i++) {
KeyPair kp = kpg.generateKeyPair();
privateKey = kp.getPrivate();
DHPublicKeySpec spec = getDHPublicKeySpec(kp.getPublic());
// validate the Diffie-Hellman public key
if (doExtraValiadtion) {
try {
KeyUtil.validate(spec);
} catch (InvalidKeyException ivke) {
if (i == MAX_FAILOVER_TIMES) {
throw ivke;
}
// otherwise, ignore the exception and try the next one
continue;
}
}
return spec;
}
return null;
}
}
......@@ -41,12 +41,14 @@ import javax.security.auth.x500.X500Principal;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.DHPublicKeySpec;
import javax.net.ssl.*;
import sun.security.internal.spec.TlsPrfParameterSpec;
import sun.security.ssl.CipherSuite.*;
import static sun.security.ssl.CipherSuite.PRF.*;
import sun.security.util.KeyUtil;
/**
* Many data structures are involved in the handshake messages. These
......@@ -712,6 +714,7 @@ class DH_ServerKeyExchange extends ServerKeyExchange
this.protocolVersion = protocolVersion;
this.preferableSignatureAlgorithm = null;
// The DH key has been validated in the constructor of DHCrypt.
setValues(obj);
signature = null;
}
......@@ -728,6 +731,7 @@ class DH_ServerKeyExchange extends ServerKeyExchange
this.protocolVersion = protocolVersion;
// The DH key has been validated in the constructor of DHCrypt.
setValues(obj);
Signature sig;
......@@ -754,7 +758,8 @@ class DH_ServerKeyExchange extends ServerKeyExchange
* DH_anon key exchange
*/
DH_ServerKeyExchange(HandshakeInStream input,
ProtocolVersion protocolVersion) throws IOException {
ProtocolVersion protocolVersion)
throws IOException, GeneralSecurityException {
this.protocolVersion = protocolVersion;
this.preferableSignatureAlgorithm = null;
......@@ -762,6 +767,10 @@ class DH_ServerKeyExchange extends ServerKeyExchange
dh_p = input.getBytes16();
dh_g = input.getBytes16();
dh_Ys = input.getBytes16();
KeyUtil.validate(new DHPublicKeySpec(new BigInteger(1, dh_Ys),
new BigInteger(1, dh_p),
new BigInteger(1, dh_g)));
signature = null;
}
......@@ -782,6 +791,9 @@ class DH_ServerKeyExchange extends ServerKeyExchange
dh_p = input.getBytes16();
dh_g = input.getBytes16();
dh_Ys = input.getBytes16();
KeyUtil.validate(new DHPublicKeySpec(new BigInteger(1, dh_Ys),
new BigInteger(1, dh_p),
new BigInteger(1, dh_g)));
// read the signature and hash algorithm
if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
......
......@@ -34,7 +34,7 @@ import javax.crypto.*;
import javax.net.ssl.*;
import sun.security.internal.spec.TlsRsaPremasterSecretParameterSpec;
import sun.security.util.KeyLength;
import sun.security.util.KeyUtil;
/**
* This is the client key exchange message (CLIENT --> SERVER) used with
......@@ -191,7 +191,7 @@ final class RSAClientKeyExchange extends HandshakeMessage {
"unable to get the plaintext of the premaster secret");
}
int keySize = KeyLength.getKeySize(secretKey);
int keySize = KeyUtil.getKeySize(secretKey);
if (keySize > 0 && keySize != 384) { // 384 = 48 * 8
if (debug != null && Debug.isOn("handshake")) {
System.out.println(
......
......@@ -150,7 +150,7 @@ final class ServerHandshaker extends Handshaker {
// In SSLv3 and TLS, messages follow strictly increasing
// numerical order _except_ for one annoying special case.
//
if ((state > type)
if ((state >= type)
&& (state != HandshakeMessage.ht_client_key_exchange
&& type != HandshakeMessage.ht_certificate_verify)) {
throw new SSLProtocolException(
......@@ -250,13 +250,15 @@ final class ServerHandshaker extends Handshaker {
}
//
// Move the state machine forward except for that annoying
// special case. This means that clients could send extra
// cert verify messages; not a problem so long as all of
// them actually check out.
// Move state machine forward if the message handling
// code didn't already do so
//
if (state < type && type != HandshakeMessage.ht_certificate_verify) {
state = type;
if (state < type) {
if(type == HandshakeMessage.ht_certificate_verify) {
state = type + 2; // an annoying special case
} else {
state = type;
}
}
}
......@@ -1406,7 +1408,7 @@ final class ServerHandshaker extends Handshaker {
if (debug != null && Debug.isOn("handshake")) {
mesg.print(System.out);
}
return dh.getAgreedSecret(mesg.getClientPublicKey());
return dh.getAgreedSecret(mesg.getClientPublicKey(), false);
}
private SecretKey clientKeyExchange(ECDHClientKeyExchange mesg)
......
......@@ -38,7 +38,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.ArrayList;
import sun.security.util.KeyLength;
import sun.security.util.KeyUtil;
/**
* Signature and hash algorithm.
......@@ -274,7 +274,7 @@ final class SignatureAndHashAlgorithm {
* If key size is less than 512, the digest length should be
* less than or equal to 20 bytes.
*/
int keySize = KeyLength.getKeySize(signingKey);
int keySize = KeyUtil.getKeySize(signingKey);
if (keySize >= 768) {
maxDigestLength = HashAlgorithm.SHA512.length;
} else if ((keySize >= 512) && (keySize < 768)) {
......
......@@ -325,6 +325,10 @@ class DerIndefLenConverter {
}
}
if (unresolved != 0) {
throw new IOException("not all indef len BER resolved");
}
newData = new byte[dataSize + numOfTotalLenBytes + unused];
dataPos=0; newDataPos=0; index=0;
......
......@@ -440,7 +440,7 @@ public class DisabledAlgorithmConstraints implements AlgorithmConstraints {
// Does this key constraint disable the specified key?
public boolean disables(Key key) {
int size = KeyLength.getKeySize(key);
int size = KeyUtil.getKeySize(key);
if (size == 0) {
return true; // we don't allow any key of size 0.
......
......@@ -28,16 +28,22 @@ package sun.security.util;
import java.security.Key;
import java.security.PrivilegedAction;
import java.security.AccessController;
import java.security.InvalidKeyException;
import java.security.interfaces.ECKey;
import java.security.interfaces.RSAKey;
import java.security.interfaces.DSAKey;
import java.security.spec.KeySpec;
import javax.crypto.SecretKey;
import javax.crypto.interfaces.DHKey;
import javax.crypto.interfaces.DHPublicKey;
import javax.crypto.spec.DHParameterSpec;
import javax.crypto.spec.DHPublicKeySpec;
import java.math.BigInteger;
/**
* A utility class to get key length
* A utility class to get key length, valiate keys, etc.
*/
public final class KeyLength {
public final class KeyUtil {
/**
* Returns the key size of the given key object in bits.
......@@ -46,7 +52,7 @@ public final class KeyLength {
* @return the key size of the given key object in bits, or -1 if the
* key size is not accessible
*/
final public static int getKeySize(Key key) {
public static final int getKeySize(Key key) {
int size = -1;
if (key instanceof Length) {
......@@ -87,5 +93,112 @@ public final class KeyLength {
return size;
}
/**
* Returns whether the key is valid or not.
* <P>
* Note that this method is only apply to DHPublicKey at present.
*
* @param publicKey
* the key object, cannot be null
*
* @throws NullPointerException if {@code publicKey} is null
* @throws InvalidKeyException if {@code publicKey} is invalid
*/
public static final void validate(Key key)
throws InvalidKeyException {
if (key == null) {
throw new NullPointerException(
"The key to be validated cannot be null");
}
if (key instanceof DHPublicKey) {
validateDHPublicKey((DHPublicKey)key);
}
}
/**
* Returns whether the key spec is valid or not.
* <P>
* Note that this method is only apply to DHPublicKeySpec at present.
*
* @param keySpec
* the key spec object, cannot be null
*
* @throws NullPointerException if {@code keySpec} is null
* @throws InvalidKeyException if {@code keySpec} is invalid
*/
public static final void validate(KeySpec keySpec)
throws InvalidKeyException {
if (keySpec == null) {
throw new NullPointerException(
"The key spec to be validated cannot be null");
}
if (keySpec instanceof DHPublicKeySpec) {
validateDHPublicKey((DHPublicKeySpec)keySpec);
}
}
/**
* Returns whether the specified provider is Oracle provider or not.
* <P>
* Note that this method is only apply to SunJCE and SunPKCS11 at present.
*
* @param providerName
* the provider name
* @return true if, and only if, the provider of the specified
* {@code providerName} is Oracle provider
*/
public static final boolean isOracleJCEProvider(String providerName) {
return providerName != null && (providerName.equals("SunJCE") ||
providerName.startsWith("SunPKCS11"));
}
/**
* Returns whether the Diffie-Hellman public key is valid or not.
*
* Per RFC 2631 and NIST SP800-56A, the following algorithm is used to
* validate Diffie-Hellman public keys:
* 1. Verify that y lies within the interval [2,p-1]. If it does not,
* the key is invalid.
* 2. Compute y^q mod p. If the result == 1, the key is valid.
* Otherwise the key is invalid.
*/
private static void validateDHPublicKey(DHPublicKey publicKey)
throws InvalidKeyException {
DHParameterSpec paramSpec = publicKey.getParams();
BigInteger p = paramSpec.getP();
BigInteger g = paramSpec.getG();
BigInteger y = publicKey.getY();
validateDHPublicKey(p, g, y);
}
private static void validateDHPublicKey(DHPublicKeySpec publicKeySpec)
throws InvalidKeyException {
validateDHPublicKey(publicKeySpec.getP(),
publicKeySpec.getG(), publicKeySpec.getY());
}
private static void validateDHPublicKey(BigInteger p,
BigInteger g, BigInteger y) throws InvalidKeyException {
// For better interoperability, the interval is limited to [2, p-2].
BigInteger leftOpen = BigInteger.ONE;
BigInteger rightOpen = p.subtract(BigInteger.ONE);
if (y.compareTo(leftOpen) <= 0) {
throw new InvalidKeyException(
"Diffie-Hellman public key is too small");
}
if (y.compareTo(rightOpen) >= 0) {
throw new InvalidKeyException(
"Diffie-Hellman public key is too large");
}
// Don't bother to check against the y^q mod p if safe primes are used.
}
}
......@@ -145,7 +145,19 @@ keystore.type=jks
# passed to checkPackageAccess unless the
# corresponding RuntimePermission ("accessClassInPackage."+package) has
# been granted.
package.access=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.,com.sun.org.glassfish.external.,com.sun.org.glassfish.gmbal.,jdk.internal.
package.access=sun.,\
com.sun.xml.internal.bind.,\
com.sun.xml.internal.org.jvnet.staxex.,\
com.sun.xml.internal.ws.,\
com.sun.imageio.,\
com.sun.istack.internal.,\
com.sun.jmx.defaults.,\
com.sun.jmx.remote.util.,\
com.sun.org.apache.xerces.internal.utils.,\
com.sun.org.apache.xalan.internal.utils.,\
com.sun.org.glassfish.external.,\
com.sun.org.glassfish.gmbal.,\
jdk.internal.
#
# List of comma-separated packages that start with or equal this string
......@@ -157,7 +169,19 @@ package.access=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.
# by default, none of the class loaders supplied with the JDK call
# checkPackageDefinition.
#
package.definition=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.,com.sun.org.glassfish.external.,com.sun.org.glassfish.gmbal.,jdk.internal.
package.definition=sun.,\
com.sun.xml.internal.bind.,\
com.sun.xml.internal.org.jvnet.staxex.,\
com.sun.xml.internal.ws.,\
com.sun.imageio.,\
com.sun.istack.internal.,\
com.sun.jmx.defaults.,\
com.sun.jmx.remote.util.,\
com.sun.org.apache.xerces.internal.utils.,\
com.sun.org.apache.xalan.internal.utils.,\
com.sun.org.glassfish.external.,\
com.sun.org.glassfish.gmbal.,\
jdk.internal.
#
# Determines whether this properties file can be appended to
......
......@@ -146,7 +146,20 @@ keystore.type=jks
# passed to checkPackageAccess unless the
# corresponding RuntimePermission ("accessClassInPackage."+package) has
# been granted.
package.access=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,apple.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.,com.sun.org.glassfish.external.,com.sun.org.glassfish.gmbal.,jdk.internal.
package.access=sun.,\
com.sun.xml.internal.bind.,\
com.sun.xml.internal.org.jvnet.staxex.,\
com.sun.xml.internal.ws.,\
com.sun.imageio.,\
com.sun.istack.internal.,\
com.sun.jmx.defaults.,\
com.sun.jmx.remote.util.,\
com.sun.org.apache.xerces.internal.utils.,\
com.sun.org.apache.xalan.internal.utils.,\
com.sun.org.glassfish.external.,\
com.sun.org.glassfish.gmbal.,\
jdk.internal.,\
apple.
#
# List of comma-separated packages that start with or equal this string
......@@ -158,7 +171,20 @@ package.access=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.
# by default, none of the class loaders supplied with the JDK call
# checkPackageDefinition.
#
package.definition=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,apple.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.,com.sun.org.glassfish.external.,com.sun.org.glassfish.gmbal.,jdk.internal.
package.definition=sun.,\
com.sun.xml.internal.bind.,\
com.sun.xml.internal.org.jvnet.staxex.,\
com.sun.xml.internal.ws.,\
com.sun.imageio.,\
com.sun.istack.internal.,\
com.sun.jmx.defaults.,\
com.sun.jmx.remote.util.,\
com.sun.org.apache.xerces.internal.utils.,\
com.sun.org.apache.xalan.internal.utils.,\
com.sun.org.glassfish.external.,\
com.sun.org.glassfish.gmbal.,\
jdk.internal.,\
apple.
#
# Determines whether this properties file can be appended to
......
......@@ -147,7 +147,19 @@ keystore.type=jks
# passed to checkPackageAccess unless the
# corresponding RuntimePermission ("accessClassInPackage."+package) has
# been granted.
package.access=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.,com.sun.org.glassfish.external.,com.sun.org.glassfish.gmbal.,jdk.internal.
package.access=sun.,\
com.sun.xml.internal.bind.,\
com.sun.xml.internal.org.jvnet.staxex.,\
com.sun.xml.internal.ws.,\
com.sun.imageio.,\
com.sun.istack.internal.,\
com.sun.jmx.defaults.,\
com.sun.jmx.remote.util.,\
com.sun.org.apache.xerces.internal.utils.,\
com.sun.org.apache.xalan.internal.utils.,\
com.sun.org.glassfish.external.,\
com.sun.org.glassfish.gmbal.,\
jdk.internal.
#
# List of comma-separated packages that start with or equal this string
......@@ -159,7 +171,19 @@ package.access=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.
# by default, none of the class loaders supplied with the JDK call
# checkPackageDefinition.
#
package.definition=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.,com.sun.org.glassfish.external.,com.sun.org.glassfish.gmbal.,jdk.internal.
package.definition=sun.,\
com.sun.xml.internal.bind.,\
com.sun.xml.internal.org.jvnet.staxex.,\
com.sun.xml.internal.ws.,\
com.sun.imageio.,\
com.sun.istack.internal.,\
com.sun.jmx.defaults.,\
com.sun.jmx.remote.util.,\
com.sun.org.apache.xerces.internal.utils.,\
com.sun.org.apache.xalan.internal.utils.,\
com.sun.org.glassfish.external.,\
com.sun.org.glassfish.gmbal.,\
jdk.internal.
#
# Determines whether this properties file can be appended to
......
......@@ -146,7 +146,19 @@ keystore.type=jks
# passed to checkPackageAccess unless the
# corresponding RuntimePermission ("accessClassInPackage."+package) has
# been granted.
package.access=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.,com.sun.org.glassfish.external.,com.sun.org.glassfish.gmbal.,jdk.internal.
package.access=sun.,\
com.sun.xml.internal.bind.,\
com.sun.xml.internal.org.jvnet.staxex.,\
com.sun.xml.internal.ws.,\
com.sun.imageio.,\
com.sun.istack.internal.,\
com.sun.jmx.defaults.,\
com.sun.jmx.remote.util.,\
com.sun.org.apache.xerces.internal.utils.,\
com.sun.org.apache.xalan.internal.utils.,\
com.sun.org.glassfish.external.,\
com.sun.org.glassfish.gmbal.,\
jdk.internal.
#
# List of comma-separated packages that start with or equal this string
......@@ -158,7 +170,19 @@ package.access=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.
# by default, none of the class loaders supplied with the JDK call
# checkPackageDefinition.
#
package.definition=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.,com.sun.org.glassfish.external.,com.sun.org.glassfish.gmbal.,jdk.internal.
package.definition=sun.,\
com.sun.xml.internal.bind.,\
com.sun.xml.internal.org.jvnet.staxex.,\
com.sun.xml.internal.ws.,\
com.sun.imageio.,\
com.sun.istack.internal.,\
com.sun.jmx.defaults.,\
com.sun.jmx.remote.util.,\
com.sun.org.apache.xerces.internal.utils.,\
com.sun.org.apache.xalan.internal.utils.,\
com.sun.org.glassfish.external.,\
com.sun.org.glassfish.gmbal.,\
jdk.internal.
#
# Determines whether this properties file can be appended to
......
......@@ -187,6 +187,10 @@ void band::setIndexByTag(byte tag) {
entry* band::getRefCommon(cpindex* ix_, bool nullOKwithCaller) {
CHECK_0;
if (ix_ == NULL) {
abort("no index");
return NULL;
}
assert(ix_->ixTag == ixTag
|| ((ixTag == CONSTANT_All ||
ixTag == CONSTANT_LoadableValue ||
......
......@@ -99,8 +99,8 @@ struct band {
int getByte() { assert(ix == null); return vs[0].getByte(); }
int getInt() { assert(ix == null); return vs[0].getInt(); }
entry* getRefN() { assert(ix != null); return getRefCommon(ix, true); }
entry* getRef() { assert(ix != null); return getRefCommon(ix, false); }
entry* getRefN() { return getRefCommon(ix, true); }
entry* getRef() { return getRefCommon(ix, false); }
entry* getRefUsing(cpindex* ix2)
{ assert(ix == null); return getRefCommon(ix2, true); }
entry* getRefCommon(cpindex* ix, bool nullOK);
......
......@@ -50,6 +50,7 @@ static jfieldID unpackerPtrFID;
static jmethodID currentInstMID;
static jmethodID readInputMID;
static jclass NIclazz;
static jmethodID getUnpackerPtrMID;
static char* dbg = null;
......@@ -60,8 +61,8 @@ static jlong read_input_via_jni(unpacker* self,
static unpacker* get_unpacker(JNIEnv *env, jobject pObj, bool noCreate=false) {
unpacker* uPtr;
uPtr = (unpacker*)jlong2ptr(env->GetLongField(pObj, unpackerPtrFID));
//fprintf(stderr, "get_unpacker(%p) uPtr=%p\n", pObj, uPtr);
jlong p = env->CallLongMethod(pObj, getUnpackerPtrMID);
uPtr = (unpacker*)jlong2ptr(p);
if (uPtr == null) {
if (noCreate) return null;
uPtr = new unpacker();
......@@ -94,11 +95,15 @@ static unpacker* get_unpacker() {
if (env == null)
return null;
jobject pObj = env->CallStaticObjectMethod(NIclazz, currentInstMID);
//fprintf(stderr, "get_unpacker() pObj=%p\n", pObj);
if (pObj == null)
return null;
// Got pObj and env; now do it the easy way.
return get_unpacker(env, pObj);
//fprintf(stderr, "get_unpacker0() pObj=%p\n", pObj);
if (pObj != null) {
// Got pObj and env; now do it the easy way.
return get_unpacker(env, pObj);
}
// this should really not happen, if it does something is seriously
// wrong throw an exception
THROW_IOE(ERROR_INTERNAL);
return null;
}
static void free_unpacker(JNIEnv *env, jobject pObj, unpacker* uPtr) {
......@@ -127,18 +132,23 @@ static jlong read_input_via_jni(unpacker* self,
JNIEXPORT void JNICALL
Java_com_sun_java_util_jar_pack_NativeUnpack_initIDs(JNIEnv *env, jclass clazz) {
#ifndef PRODUCT
dbg = getenv("DEBUG_ATTACH");
while( dbg != null) { sleep(10); }
#endif
NIclazz = (jclass) env->NewGlobalRef(clazz);
unpackerPtrFID = env->GetFieldID(clazz, "unpackerPtr", "J");
currentInstMID = env->GetStaticMethodID(clazz, "currentInstance",
"()Ljava/lang/Object;");
readInputMID = env->GetMethodID(clazz, "readInputFn",
"(Ljava/nio/ByteBuffer;J)J");
getUnpackerPtrMID = env->GetMethodID(clazz, "getUnpackerPtr", "()J");
if (unpackerPtrFID == null ||
currentInstMID == null ||
readInputMID == null ||
NIclazz == null) {
NIclazz == null ||
getUnpackerPtrMID == null) {
THROW_IOE("cannot init class members");
}
}
......@@ -146,8 +156,13 @@ Java_com_sun_java_util_jar_pack_NativeUnpack_initIDs(JNIEnv *env, jclass clazz)
JNIEXPORT jlong JNICALL
Java_com_sun_java_util_jar_pack_NativeUnpack_start(JNIEnv *env, jobject pObj,
jobject pBuf, jlong offset) {
unpacker* uPtr = get_unpacker(env, pObj);
// try to get the unpacker pointer the hard way first, we do this to ensure
// valid object pointers and env is intact, if not now is good time to bail.
unpacker* uPtr = get_unpacker();
//fprintf(stderr, "start(%p) uPtr=%p initializing\n", pObj, uPtr);
if (uPtr == null) {
return -1;
}
// redirect our io to the default log file or whatever.
uPtr->redirect_stdio();
......@@ -163,7 +178,12 @@ Java_com_sun_java_util_jar_pack_NativeUnpack_start(JNIEnv *env, jobject pObj,
else
{ buf = (char*)buf + (size_t)offset; buflen -= (size_t)offset; }
}
// before we start off we make sure there is no other error by the time we
// get here
if (uPtr->aborting()) {
THROW_IOE(uPtr->get_abort_message());
return 0;
}
uPtr->start(buf, buflen);
if (uPtr->aborting()) {
THROW_IOE(uPtr->get_abort_message());
......@@ -230,11 +250,14 @@ Java_com_sun_java_util_jar_pack_NativeUnpack_getUnusedInput(JNIEnv *env, jobject
// We have fetched all the files.
// Now swallow up any remaining input.
if (uPtr->input_remaining() == 0)
if (uPtr->input_remaining() == 0) {
return null;
else
return env->NewDirectByteBuffer(uPtr->input_scan(),
uPtr->input_remaining());
} else {
bytes remaining_bytes;
remaining_bytes.malloc(uPtr->input_remaining());
remaining_bytes.copyFrom(uPtr->input_scan(), uPtr->input_remaining());
return env->NewDirectByteBuffer(remaining_bytes.ptr, remaining_bytes.len);
}
}
JNIEXPORT jlong JNICALL
......
......@@ -281,11 +281,13 @@ int entry::typeSize() {
}
inline cpindex* cpool::getFieldIndex(entry* classRef) {
if (classRef == NULL) { abort("missing class reference"); return NULL; }
assert(classRef->tagMatches(CONSTANT_Class));
assert((uint)classRef->inord < (uint)tag_count[CONSTANT_Class]);
return &member_indexes[classRef->inord*2+0];
}
inline cpindex* cpool::getMethodIndex(entry* classRef) {
if (classRef == NULL) { abort("missing class reference"); return NULL; }
assert(classRef->tagMatches(CONSTANT_Class));
assert((uint)classRef->inord < (uint)tag_count[CONSTANT_Class]);
return &member_indexes[classRef->inord*2+1];
......@@ -1291,6 +1293,7 @@ void unpacker::read_double_refs(band& cp_band, byte ref1Tag, byte ref2Tag,
entry& e = cpMap[i];
e.refs = U_NEW(entry*, e.nrefs = 2);
e.refs[0] = cp_band1.getRef();
CHECK;
e.refs[1] = cp_band2.getRef();
CHECK;
}
......@@ -1371,6 +1374,7 @@ void unpacker::read_method_type(entry* cpMap, int len) {
entry& e = cpMap[i];
e.refs = U_NEW(entry*, e.nrefs = 1);
e.refs[0] = cp_MethodType.getRef();
CHECK;
}
}
......@@ -2106,6 +2110,7 @@ void unpacker::read_attr_defs() {
int attrc = ADH_BYTE_CONTEXT(header);
int idx = ADH_BYTE_INDEX(header);
entry* name = attr_definition_name.getRef();
CHECK;
entry* layout = attr_definition_layout.getRef();
CHECK;
attr_defs[attrc].defineLayout(idx, name, layout->value.b.strval());
......@@ -2210,7 +2215,9 @@ void unpacker::read_ics() {
if (ics[i].name == NO_ENTRY_YET) {
// Long form.
ics[i].outer = ic_outer_class.getRefN();
CHECK;
ics[i].name = ic_name.getRefN();
CHECK;
} else {
// Fill in outer and name based on inner.
bytes& n = ics[i].inner->value.b;
......@@ -2733,6 +2740,7 @@ void unpacker::putlayout(band** body) {
e = b.getRefUsing(cp.getKQIndex());
else
e = b.getRefN();
CHECK;
switch (b.le_len) {
case 0: break;
case 1: putu1ref(e); break;
......@@ -3118,7 +3126,7 @@ void unpacker::read_bcs() {
void unpacker::read_bands() {
byte* rp0 = rp;
CHECK;
read_file_header();
CHECK;
......@@ -3880,10 +3888,12 @@ void unpacker::dump_options() {
// packed file and len is the length of the buffer.
// If null, the callback is used to fill an internal buffer.
void unpacker::start(void* packptr, size_t len) {
CHECK;
NOT_PRODUCT(debug_u = this);
if (packptr != null && len != 0) {
inbytes.set((byte*) packptr, len);
}
CHECK;
read_bands();
}
......@@ -4015,6 +4025,7 @@ void unpacker::write_bc_ops() {
NOT_PRODUCT(bc_superfield.setIndex(null));
NOT_PRODUCT(bc_supermethod.setIndex(null));
}
CHECK;
for (int curIP = 0; ; curIP++) {
int curPC = (int)(wpoffset() - codeBase);
......@@ -4128,7 +4139,8 @@ void unpacker::write_bc_ops() {
int coding = bc_initref.getInt();
// Find the nth overloading of <init> in classRef.
entry* ref = null;
cpindex* ix = (classRef == null)? null: cp.getMethodIndex(classRef);
cpindex* ix = cp.getMethodIndex(classRef);
CHECK;
for (int j = 0, which_init = 0; ; j++) {
ref = (ix == null)? null: ix->get(j);
if (ref == null) break; // oops, bad input
......@@ -4405,6 +4417,7 @@ int unpacker::write_attrs(int attrc, julong indexBits) {
case ADH_BYTE(ATTR_CONTEXT_CLASS, CLASS_ATTR_EnclosingMethod):
aname = cp.sym[cpool::s_EnclosingMethod];
putref(class_EnclosingMethod_RC.getRefN());
CHECK_0;
putref(class_EnclosingMethod_RDN.getRefN());
break;
......@@ -4423,6 +4436,7 @@ int unpacker::write_attrs(int attrc, julong indexBits) {
putu2(count = method_Exceptions_N.getInt());
for (j = 0; j < count; j++) {
putref(method_Exceptions_RC.getRefN());
CHECK_0;
}
break;
......@@ -4455,16 +4469,18 @@ int unpacker::write_attrs(int attrc, julong indexBits) {
// (253) [(1)(2)(2)]
// (254) [(1)(2)(2)(2)]
putu2(code_StackMapTable_offset.getInt());
CHECK_0;
for (int k = (tag - 251); k > 0; k--) {
put_stackmap_type();
CHECK_0;
}
} else {
// (255) [(1)NH[(2)]NH[(2)]]
putu2(code_StackMapTable_offset.getInt());
putu2(j2 = code_StackMapTable_local_N.getInt());
while (j2-- > 0) put_stackmap_type();
while (j2-- > 0) {put_stackmap_type(); CHECK_0;}
putu2(j2 = code_StackMapTable_stack_N.getInt());
while (j2-- > 0) put_stackmap_type();
while (j2-- > 0) {put_stackmap_type(); CHECK_0;}
}
}
break;
......@@ -4488,7 +4504,9 @@ int unpacker::write_attrs(int attrc, julong indexBits) {
bii += code_LocalVariableTable_span_O.getInt();
putu2(to_bci(bii) - bci);
putref(code_LocalVariableTable_name_RU.getRefN());
CHECK_0;
putref(code_LocalVariableTable_type_RS.getRefN());
CHECK_0;
putu2(code_LocalVariableTable_slot.getInt());
}
break;
......@@ -4503,7 +4521,9 @@ int unpacker::write_attrs(int attrc, julong indexBits) {
bii += code_LocalVariableTypeTable_span_O.getInt();
putu2(to_bci(bii) - bci);
putref(code_LocalVariableTypeTable_name_RU.getRefN());
CHECK_0;
putref(code_LocalVariableTypeTable_type_RS.getRefN());
CHECK_0;
putu2(code_LocalVariableTypeTable_slot.getInt());
}
break;
......@@ -4531,7 +4551,7 @@ int unpacker::write_attrs(int attrc, julong indexBits) {
break;
}
}
CHECK_0;
if (aname == null) {
// Unparse a compressor-defined attribute.
layout_definition* lo = ad.getLayout(idx);
......@@ -4687,7 +4707,9 @@ int unpacker::write_ics(int naOffset, int na) {
flags &= ~ACC_IC_LONG_FORM; // clear high bit if set to get clean zero
extra_ic.flags = flags;
extra_ic.outer = class_InnerClasses_outer_RCN.getRefN();
CHECK_0;
extra_ic.name = class_InnerClasses_name_RUN.getRefN();
CHECK_0;
// Detect if this is an exact copy of the global tuple.
if (global_ic != null) {
if (global_ic->flags != extra_ic.flags ||
......@@ -4796,6 +4818,7 @@ void unpacker::write_classfile_tail() {
julong indexMask = ad.flagIndexMask();
cur_class = class_this.getRef();
CHECK;
cur_super = class_super.getRef();
CHECK;
......@@ -4809,6 +4832,7 @@ void unpacker::write_classfile_tail() {
putu2(num = class_interface_count.getInt());
for (i = 0; i < num; i++) {
putref(class_interface.getRef());
CHECK;
}
write_members(class_field_count.getInt(), ATTR_CONTEXT_FIELD);
......
......@@ -95,6 +95,7 @@ typedef struct {
jint offsets[MAX_NUMBANDS];
jint nBits[MAX_NUMBANDS];
jint maxBitSize;
jint isUsed; // flag to indicate whether the raster sample model is SPPSM
} SPPSampleModelS_t;
/* Struct that holds information for the Raster object */
......
......@@ -41,5 +41,10 @@
(((w) > 0) && ((h) > 0) && ((sz) > 0) && \
(((0xffffffffu / ((juint)(w))) / ((juint)(h))) > ((juint)(sz))))
#define SAFE_TO_MULT(a, b) \
(((a) > 0) && ((b) >= 0) && ((0x7fffffff / (a)) > (b)))
#define SAFE_TO_ADD(a, b) \
(((a) >= 0) && ((b) >= 0) && ((0x7fffffff - (a)) > (b)))
#endif // __SAFE_ALLOC_H__
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册