This commit is contained in:
Edvard Wendelin 2013-02-05 15:35:35 +01:00
commit 11036fb4d5
89 changed files with 2945 additions and 1025 deletions

View File

@ -66,7 +66,7 @@ int JLI_GetStdArgc();
#include <io.h> #include <io.h>
#define JLI_StrCaseCmp(p1, p2) stricmp((p1), (p2)) #define JLI_StrCaseCmp(p1, p2) stricmp((p1), (p2))
#define JLI_StrNCaseCmp(p1, p2, p3) strnicmp((p1), (p2), (p3)) #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); void JLI_CmdToArgs(char *cmdline);
#define JLI_Lseek _lseeki64 #define JLI_Lseek _lseeki64
#else /* NIXES */ #else /* NIXES */

View File

@ -568,9 +568,9 @@ JLI_ParseManifest(char *jarfile, manifest_info *info)
#ifdef O_BINARY #ifdef O_BINARY
| O_BINARY /* use binary mode on windows */ | O_BINARY /* use binary mode on windows */
#endif #endif
)) == -1) )) == -1) {
return (-1); return (-1);
}
info->manifest_version = NULL; info->manifest_version = NULL;
info->main_class = NULL; info->main_class = NULL;
info->jre_version = NULL; info->jre_version = NULL;
@ -617,12 +617,14 @@ JLI_JarUnpackFile(const char *jarfile, const char *filename, int *size) {
zentry entry; zentry entry;
void *data = NULL; void *data = NULL;
fd = open(jarfile, O_RDONLY if ((fd = open(jarfile, O_RDONLY
#ifdef O_BINARY #ifdef O_BINARY
| O_BINARY /* use binary mode on windows */ | O_BINARY /* use binary mode on windows */
#endif #endif
); )) == -1) {
if (fd != -1 && find_file(fd, &entry, filename) == 0) { return NULL;
}
if (find_file(fd, &entry, filename) == 0) {
data = inflate_file(fd, &entry, size); data = inflate_file(fd, &entry, size);
} }
close(fd); close(fd);
@ -664,8 +666,9 @@ JLI_ManifestIterate(const char *jarfile, attribute_closure ac, void *user_data)
#ifdef O_BINARY #ifdef O_BINARY
| O_BINARY /* use binary mode on windows */ | O_BINARY /* use binary mode on windows */
#endif #endif
)) == -1) )) == -1) {
return (-1); return (-1);
}
if (rc = find_file(fd, &entry, manifest_name) != 0) { if (rc = find_file(fd, &entry, manifest_name) != 0) {
close(fd); close(fd);

View File

@ -66,11 +66,14 @@ public final class MethodFinder extends AbstractFinder<Method> {
Signature signature = new Signature(type, name, args); Signature signature = new Signature(type, name, args);
Method method = CACHE.get(signature); Method method = CACHE.get(signature);
if (method != null) { boolean cached = method != null;
if (cached && isPackageAccessible(method.getDeclaringClass())) {
return method; return method;
} }
method = findAccessibleMethod(new MethodFinder(name, args).find(type.getMethods())); method = findAccessibleMethod(new MethodFinder(name, args).find(type.getMethods()));
CACHE.put(signature, method); if (!cached) {
CACHE.put(signature, method);
}
return method; return method;
} }

View File

@ -41,6 +41,8 @@ import javax.crypto.ShortBufferException;
import javax.crypto.SecretKey; import javax.crypto.SecretKey;
import javax.crypto.spec.*; import javax.crypto.spec.*;
import sun.security.util.KeyUtil;
/** /**
* This class implements the Diffie-Hellman key agreement protocol between * This class implements the Diffie-Hellman key agreement protocol between
* any number of parties. * any number of parties.
@ -200,6 +202,9 @@ extends KeyAgreementSpi {
throw new InvalidKeyException("Incompatible parameters"); throw new InvalidKeyException("Incompatible parameters");
} }
// validate the Diffie-Hellman public key
KeyUtil.validate(dhPubKey);
// store the y value // store the y value
this.y = dhPubKey.getY(); this.y = dhPubKey.getY();

View File

@ -1000,7 +1000,6 @@ class BandStructure {
/** Write a constant pool reference. */ /** Write a constant pool reference. */
public void putRef(Entry e) { public void putRef(Entry e) {
assert(index != null);
addValue(encodeRefOrNull(e, index)); addValue(encodeRefOrNull(e, index));
} }
public void putRef(Entry e, Index index) { public void putRef(Entry e, Index index) {
@ -1052,6 +1051,8 @@ class BandStructure {
int encodeRef(Entry e, Index ix) { int encodeRef(Entry e, Index ix) {
if (ix == null)
throw new RuntimeException("null index for " + e.stringValue());
int coding = ix.indexOf(e); int coding = ix.indexOf(e);
if (verbose > 2) if (verbose > 2)
Utils.log.fine("putRef "+coding+" => "+e); Utils.log.fine("putRef "+coding+" => "+e);

View File

@ -1405,6 +1405,8 @@ class ConstantPool {
/** Index of all CP entries of a given tag and class. */ /** Index of all CP entries of a given tag and class. */
public Index getMemberIndex(byte tag, ClassEntry classRef) { public Index getMemberIndex(byte tag, ClassEntry classRef) {
if (classRef == null)
throw new RuntimeException("missing class reference for " + tagName(tag));
if (indexByTagAndClass == null) if (indexByTagAndClass == null)
indexByTagAndClass = new Index[CONSTANT_Limit][]; indexByTagAndClass = new Index[CONSTANT_Limit][];
Index allClasses = getIndexByTag(CONSTANT_Class); Index allClasses = getIndexByTag(CONSTANT_Class);

View File

@ -109,6 +109,10 @@ class NativeUnpack {
return (p200 == null)? null: p200._nunp; return (p200 == null)? null: p200._nunp;
} }
private synchronized long getUnpackerPtr() {
return unpackerPtr;
}
// Callback from the unpacker engine to get more data. // Callback from the unpacker engine to get more data.
private long readInputFn(ByteBuffer pbuf, long minlen) throws IOException { private long readInputFn(ByteBuffer pbuf, long minlen) throws IOException {
if (in == null) return 0; // nothing is readable if (in == null) return 0; // nothing is readable

View File

@ -83,7 +83,7 @@ public class PackerImpl extends TLGlobals implements Pack200.Packer {
* @param out an OutputStream * @param out an OutputStream
* @exception IOException if an error is encountered. * @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); assert(Utils.currentInstance.get() == null);
TimeZone tz = (props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE)) TimeZone tz = (props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE))
? null ? null
@ -118,7 +118,7 @@ public class PackerImpl extends TLGlobals implements Pack200.Packer {
* @param out an OutputStream * @param out an OutputStream
* @exception IOException if an error is encountered. * @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); assert(Utils.currentInstance.get() == null);
TimeZone tz = (props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE)) ? null : TimeZone tz = (props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE)) ? null :
TimeZone.getDefault(); TimeZone.getDefault();

View File

@ -1,5 +1,5 @@
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -106,7 +106,7 @@ public class UnpackerImpl extends TLGlobals implements Pack200.Unpacker {
* @param out a JarOutputStream. * @param out a JarOutputStream.
* @exception IOException if an error is encountered. * @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) { if (in == null) {
throw new NullPointerException("null input"); throw new NullPointerException("null input");
} }
@ -151,7 +151,7 @@ public class UnpackerImpl extends TLGlobals implements Pack200.Unpacker {
* @param out a JarOutputStream. * @param out a JarOutputStream.
* @exception IOException if an error is encountered. * @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) { if (in == null) {
throw new NullPointerException("null input"); throw new NullPointerException("null input");
} }

View File

@ -54,6 +54,8 @@ import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import javax.management.AttributeNotFoundException; import javax.management.AttributeNotFoundException;
import javax.management.openmbean.CompositeData; 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 * This class contains the methods for performing all the tests needed to verify
@ -526,8 +528,10 @@ public class Introspector {
// to locate method // to locate method
readMethod = SimpleIntrospector.getReadMethod(clazz, element); readMethod = SimpleIntrospector.getReadMethod(clazz, element);
} }
if (readMethod != null) if (readMethod != null) {
return readMethod.invoke(complex); ReflectUtil.checkPackageAccess(readMethod.getDeclaringClass());
return MethodUtil.invoke(readMethod, complex, new Class[0]);
}
throw new AttributeNotFoundException( throw new AttributeNotFoundException(
"Could not find the getter method for the property " + "Could not find the getter method for the property " +

View File

@ -39,6 +39,7 @@ import sun.awt.PeerEvent;
import sun.awt.util.IdentityArrayList; import sun.awt.util.IdentityArrayList;
import sun.awt.util.IdentityLinkedList; import sun.awt.util.IdentityLinkedList;
import sun.security.util.SecurityConstants; import sun.security.util.SecurityConstants;
import java.security.AccessControlException;
/** /**
* A Dialog is a top-level window with a title and a border * 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; boolean undecorated = false;
private transient boolean initialized = false;
/** /**
* Modal dialogs block all input to some top-level windows. * Modal dialogs block all input to some top-level windows.
* Whether a particular window is blocked depends on dialog's type * Whether a particular window is blocked depends on dialog's type
@ -671,6 +674,7 @@ public class Dialog extends Window {
this.title = title; this.title = title;
setModalityType(modalityType); setModalityType(modalityType);
SunToolkit.checkAndSetPolicy(this); SunToolkit.checkAndSetPolicy(this);
initialized = true;
} }
/** /**
@ -722,6 +726,7 @@ public class Dialog extends Window {
this.title = title; this.title = title;
setModalityType(modalityType); setModalityType(modalityType);
SunToolkit.checkAndSetPolicy(this); SunToolkit.checkAndSetPolicy(this);
initialized = true;
} }
/** /**
@ -851,12 +856,9 @@ public class Dialog extends Window {
if (modalityType == type) { if (modalityType == type) {
return; return;
} }
if (type == ModalityType.TOOLKIT_MODAL) {
SecurityManager sm = System.getSecurityManager(); checkModalityPermission(type);
if (sm != null) {
sm.checkPermission(SecurityConstants.AWT.TOOLKIT_MODALITY_PERMISSION);
}
}
modalityType = type; modalityType = type;
modal = (modalityType != ModalityType.MODELESS); modal = (modalityType != ModalityType.MODELESS);
} }
@ -1025,6 +1027,11 @@ public class Dialog extends Window {
*/ */
@Deprecated @Deprecated
public void show() { public void show() {
if (!initialized) {
throw new IllegalStateException("The dialog component " +
"has not been initialized properly");
}
beforeFirstShow = false; beforeFirstShow = false;
if (!isModal()) { if (!isModal()) {
conditionalShow(null, null); 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) private void readObject(ObjectInputStream s)
throws ClassNotFoundException, IOException, HeadlessException throws ClassNotFoundException, IOException, HeadlessException
{ {
GraphicsEnvironment.checkHeadless(); GraphicsEnvironment.checkHeadless();
s.defaultReadObject();
// in 1.5 or earlier modalityType was absent, so use "modal" instead java.io.ObjectInputStream.GetField fields =
if (modalityType == null) { s.readFields();
setModal(modal);
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 (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<>(); blockedWindows = new IdentityArrayList<>();
SunToolkit.checkAndSetPolicy(this);
initialized = true;
} }
/* /*

View File

@ -194,7 +194,8 @@ public class EventQueue {
} }
public void removeSourceEvents(EventQueue eventQueue, public void removeSourceEvents(EventQueue eventQueue,
Object source, Object source,
boolean removeAllEvents) { boolean removeAllEvents)
{
eventQueue.removeSourceEvents(source, removeAllEvents); eventQueue.removeSourceEvents(source, removeAllEvents);
} }
public boolean noEvents(EventQueue eventQueue) { public boolean noEvents(EventQueue eventQueue) {
@ -203,6 +204,11 @@ public class EventQueue {
public void wakeup(EventQueue eventQueue, boolean isShutdown) { public void wakeup(EventQueue eventQueue, boolean isShutdown) {
eventQueue.wakeup(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 * @since 1.2
*/ */
public static void invokeAndWait(Runnable runnable) 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()) { if (EventQueue.isDispatchThread()) {
throw new Error("Cannot call invokeAndWait from the event dispatcher thread"); throw new Error("Cannot call invokeAndWait from the event dispatcher thread");
} }
@ -1255,8 +1267,7 @@ public class EventQueue {
Object lock = new AWTInvocationLock(); Object lock = new AWTInvocationLock();
InvocationEvent event = InvocationEvent event =
new InvocationEvent(Toolkit.getDefaultToolkit(), runnable, lock, new InvocationEvent(source, runnable, lock, true);
true);
synchronized (lock) { synchronized (lock) {
Toolkit.getEventQueue().postEvent(event); Toolkit.getEventQueue().postEvent(event);

View File

@ -109,12 +109,6 @@ public class TextComponent extends Component implements Accessible {
// the background color of non-editable TextComponents. // the background color of non-editable TextComponents.
boolean backgroundSetByClientCode = false; boolean backgroundSetByClientCode = false;
/**
* True if this <code>TextComponent</code> has access
* to the System clipboard.
*/
transient private boolean canAccessClipboard;
transient protected TextListener textListener; transient protected TextListener textListener;
/* /*
@ -139,7 +133,6 @@ public class TextComponent extends Component implements Accessible {
GraphicsEnvironment.checkHeadless(); GraphicsEnvironment.checkHeadless();
this.text = (text != null) ? text : ""; this.text = (text != null) ? text : "";
setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR)); setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR));
checkSystemClipboardAccess();
} }
private void enableInputMethodsIfNecessary() { private void enableInputMethodsIfNecessary() {
@ -734,17 +727,14 @@ public class TextComponent extends Component implements Accessible {
/** /**
* Assigns a valid value to the canAccessClipboard instance variable. * Assigns a valid value to the canAccessClipboard instance variable.
*/ */
private void checkSystemClipboardAccess() { private boolean canAccessClipboard() {
canAccessClipboard = true;
SecurityManager sm = System.getSecurityManager(); SecurityManager sm = System.getSecurityManager();
if (sm != null) { if (sm == null) return true;
try { try {
sm.checkSystemClipboardAccess(); sm.checkSystemClipboardAccess();
} return true;
catch (SecurityException e) { } catch (SecurityException e) {}
canAccessClipboard = false; return false;
}
}
} }
/* /*
@ -827,7 +817,6 @@ public class TextComponent extends Component implements Accessible {
} }
} }
enableInputMethodsIfNecessary(); enableInputMethodsIfNecessary();
checkSystemClipboardAccess();
} }

View File

@ -1206,7 +1206,7 @@ public class Window extends Container implements Accessible {
} }
else { else {
try { try {
EventQueue.invokeAndWait(action); EventQueue.invokeAndWait(this, action);
} }
catch (InterruptedException e) { catch (InterruptedException e) {
System.err.println("Disposal was interrupted:"); System.err.println("Disposal was interrupted:");

View File

@ -1752,6 +1752,12 @@ public class ObjectInputStream
ObjectStreamClass desc = readClassDesc(false); ObjectStreamClass desc = readClassDesc(false);
desc.checkDeserialize(); desc.checkDeserialize();
Class<?> cl = desc.forClass();
if (cl == String.class || cl == Class.class
|| cl == ObjectStreamClass.class) {
throw new InvalidClassException("invalid class descriptor");
}
Object obj; Object obj;
try { try {
obj = desc.isInstantiable() ? desc.newInstance() : null; obj = desc.isInstantiable() ? desc.newInstance() : null;

View File

@ -63,7 +63,9 @@ import sun.reflect.generics.repository.ConstructorRepository;
import sun.reflect.generics.scope.ClassScope; import sun.reflect.generics.scope.ClassScope;
import sun.security.util.SecurityConstants; import sun.security.util.SecurityConstants;
import java.lang.annotation.Annotation; import java.lang.annotation.Annotation;
import java.lang.reflect.Proxy;
import sun.reflect.annotation.*; import sun.reflect.annotation.*;
import sun.reflect.misc.ReflectUtil;
/** /**
* Instances of the class {@code Class} represent classes and * Instances of the class {@code Class} represent classes and
@ -250,11 +252,11 @@ public final
ClassLoader loader) ClassLoader loader)
throws ClassNotFoundException throws ClassNotFoundException
{ {
if (loader == null) { if (sun.misc.VM.isSystemDomainLoader(loader)) {
SecurityManager sm = System.getSecurityManager(); SecurityManager sm = System.getSecurityManager();
if (sm != null) { if (sm != null) {
ClassLoader ccl = ClassLoader.getCallerClassLoader(); ClassLoader ccl = ClassLoader.getCallerClassLoader();
if (ccl != null) { if (!sun.misc.VM.isSystemDomainLoader(ccl)) {
sm.checkPermission( sm.checkPermission(
SecurityConstants.GET_CLASSLOADER_PERMISSION); SecurityConstants.GET_CLASSLOADER_PERMISSION);
} }
@ -319,7 +321,7 @@ public final
throws InstantiationException, IllegalAccessException throws InstantiationException, IllegalAccessException
{ {
if (System.getSecurityManager() != null) { if (System.getSecurityManager() != null) {
checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader()); checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), false);
} }
return newInstance0(); return newInstance0();
} }
@ -1299,7 +1301,7 @@ public final
// be very careful not to change the stack depth of this // be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons // checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess // 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, // Privileged so this implementation can look at DECLARED classes,
// something the caller might not have privilege to do. The code here // 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 // be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons // checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess // see java.lang.SecurityManager.checkMemberAccess
checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader()); checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
return copyFields(privateGetPublicFields(null)); return copyFields(privateGetPublicFields(null));
} }
@ -1425,7 +1427,7 @@ public final
// be very careful not to change the stack depth of this // be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons // checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess // see java.lang.SecurityManager.checkMemberAccess
checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader()); checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
return copyMethods(privateGetPublicMethods()); return copyMethods(privateGetPublicMethods());
} }
@ -1474,7 +1476,7 @@ public final
// be very careful not to change the stack depth of this // be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons // checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess // see java.lang.SecurityManager.checkMemberAccess
checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader()); checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
return copyConstructors(privateGetDeclaredConstructors(true)); return copyConstructors(privateGetDeclaredConstructors(true));
} }
@ -1533,7 +1535,7 @@ public final
// be very careful not to change the stack depth of this // be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons // checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess // see java.lang.SecurityManager.checkMemberAccess
checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader()); checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
Field field = getField0(name); Field field = getField0(name);
if (field == null) { if (field == null) {
throw new NoSuchFieldException(name); throw new NoSuchFieldException(name);
@ -1618,7 +1620,7 @@ public final
// be very careful not to change the stack depth of this // be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons // checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess // see java.lang.SecurityManager.checkMemberAccess
checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader()); checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
Method method = getMethod0(name, parameterTypes); Method method = getMethod0(name, parameterTypes);
if (method == null) { if (method == null) {
throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes)); throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes));
@ -1672,7 +1674,7 @@ public final
// be very careful not to change the stack depth of this // be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons // checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess // see java.lang.SecurityManager.checkMemberAccess
checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader()); checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
return getConstructor0(parameterTypes, Member.PUBLIC); return getConstructor0(parameterTypes, Member.PUBLIC);
} }
@ -1714,7 +1716,7 @@ public final
// be very careful not to change the stack depth of this // be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons // checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess // see java.lang.SecurityManager.checkMemberAccess
checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader()); checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), false);
return getDeclaredClasses0(); return getDeclaredClasses0();
} }
@ -1758,7 +1760,7 @@ public final
// be very careful not to change the stack depth of this // be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons // checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess // see java.lang.SecurityManager.checkMemberAccess
checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader()); checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
return copyFields(privateGetDeclaredFields(false)); return copyFields(privateGetDeclaredFields(false));
} }
@ -1806,7 +1808,7 @@ public final
// be very careful not to change the stack depth of this // be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons // checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess // see java.lang.SecurityManager.checkMemberAccess
checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader()); checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
return copyMethods(privateGetDeclaredMethods(false)); return copyMethods(privateGetDeclaredMethods(false));
} }
@ -1851,7 +1853,7 @@ public final
// be very careful not to change the stack depth of this // be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons // checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess // see java.lang.SecurityManager.checkMemberAccess
checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader()); checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
return copyConstructors(privateGetDeclaredConstructors(false)); return copyConstructors(privateGetDeclaredConstructors(false));
} }
@ -1895,7 +1897,7 @@ public final
// be very careful not to change the stack depth of this // be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons // checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess // see java.lang.SecurityManager.checkMemberAccess
checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader()); checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
Field field = searchFields(privateGetDeclaredFields(false), name); Field field = searchFields(privateGetDeclaredFields(false), name);
if (field == null) { if (field == null) {
throw new NoSuchFieldException(name); throw new NoSuchFieldException(name);
@ -1950,7 +1952,7 @@ public final
// be very careful not to change the stack depth of this // be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons // checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess // see java.lang.SecurityManager.checkMemberAccess
checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader()); checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
Method method = searchMethods(privateGetDeclaredMethods(false), name, parameterTypes); Method method = searchMethods(privateGetDeclaredMethods(false), name, parameterTypes);
if (method == null) { if (method == null) {
throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes)); throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes));
@ -2000,7 +2002,7 @@ public final
// be very careful not to change the stack depth of this // be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons // checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess // see java.lang.SecurityManager.checkMemberAccess
checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader()); checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
return getConstructor0(parameterTypes, Member.DECLARED); return getConstructor0(parameterTypes, Member.DECLARED);
} }
@ -2170,18 +2172,26 @@ public final
* <p> Default policy: allow all clients access with normal Java access * <p> Default policy: allow all clients access with normal Java access
* control. * control.
*/ */
private void checkMemberAccess(int which, ClassLoader ccl) { private void checkMemberAccess(int which, ClassLoader ccl, boolean checkProxyInterfaces) {
SecurityManager s = System.getSecurityManager(); SecurityManager s = System.getSecurityManager();
if (s != null) { if (s != null) {
s.checkMemberAccess(this, which); s.checkMemberAccess(this, which);
ClassLoader cl = getClassLoader0(); ClassLoader cl = getClassLoader0();
if (sun.reflect.misc.ReflectUtil.needsPackageAccessCheck(ccl, cl)) { if (ReflectUtil.needsPackageAccessCheck(ccl, cl)) {
String name = this.getName(); String name = this.getName();
int i = name.lastIndexOf('.'); int i = name.lastIndexOf('.');
if (i != -1) { 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());
}
} }
} }

View File

@ -26,8 +26,12 @@
package java.lang.invoke; package java.lang.invoke;
import java.lang.reflect.*; import java.lang.reflect.*;
import java.security.AccessController;
import java.security.PrivilegedAction;
import sun.invoke.WrapperInstance; import sun.invoke.WrapperInstance;
import java.util.ArrayList; import java.util.ArrayList;
import sun.reflect.Reflection;
import sun.reflect.misc.ReflectUtil;
/** /**
* This class consists exclusively of static methods that help adapt * 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) { <T> T asInterfaceInstance(final Class<T> intfc, final MethodHandle target) {
if (!intfc.isInterface() || !Modifier.isPublic(intfc.getModifiers())) if (!intfc.isInterface() || !Modifier.isPublic(intfc.getModifiers()))
throw new IllegalArgumentException("not a public interface: "+intfc.getName()); 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); final Method[] methods = getSingleNameMethods(intfc);
if (methods == null) if (methods == null)
throw new IllegalArgumentException("not a single-method interface: "+intfc.getName()); 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)); checkTarget = checkTarget.asType(checkTarget.type().changeReturnType(Object.class));
vaTargets[i] = checkTarget.asSpreader(Object[].class, smMT.parameterCount()); vaTargets[i] = checkTarget.asSpreader(Object[].class, smMT.parameterCount());
} }
return intfc.cast(Proxy.newProxyInstance( final InvocationHandler ih = new InvocationHandler() {
intfc.getClassLoader(), private Object getArg(String name) {
new Class<?>[]{ intfc, WrapperInstance.class }, if ((Object)name == "getWrapperInstanceTarget") return target;
new InvocationHandler() { if ((Object)name == "getWrapperInstanceType") return intfc;
private Object getArg(String name) { throw new AssertionError();
if ((Object)name == "getWrapperInstanceTarget") return target; }
if ((Object)name == "getWrapperInstanceType") return intfc; public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
throw new AssertionError(); for (int i = 0; i < methods.length; i++) {
if (method.equals(methods[i]))
return vaTargets[i].invokeExact(args);
} }
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if (method.getDeclaringClass() == WrapperInstance.class)
for (int i = 0; i < methods.length; i++) { return getArg(method.getName());
if (method.equals(methods[i])) if (isObjectMethod(method))
return vaTargets[i].invokeExact(args); return callObjectMethod(proxy, method, args);
} throw new InternalError("bad proxy method: "+method);
if (method.getDeclaringClass() == WrapperInstance.class) }
return getArg(method.getName()); };
if (isObjectMethod(method))
return callObjectMethod(proxy, method, args); Object proxy;
throw new InternalError("bad proxy method: "+method); 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);
} }
/** /**

View File

@ -27,6 +27,9 @@ package java.lang.reflect;
import java.lang.ref.Reference; import java.lang.ref.Reference;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.security.AccessController;
import java.security.Permission;
import java.security.PrivilegedAction;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
@ -36,6 +39,9 @@ import java.util.Set;
import java.util.List; import java.util.List;
import java.util.WeakHashMap; import java.util.WeakHashMap;
import sun.misc.ProxyGenerator; 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 * {@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 * @param h the invocation handler for this proxy instance
*/ */
protected Proxy(InvocationHandler h) { protected Proxy(InvocationHandler h) {
doNewInstanceCheck();
this.h = h; 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 * Returns the {@code java.lang.Class} object for a proxy class
* given a class loader and an array of interfaces. The 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) Class<?>... interfaces)
throws IllegalArgumentException 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) { if (interfaces.length > 65535) {
throw new IllegalArgumentException("interface limit exceeded"); 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, if (proxyPkg == null) {
proxyPkg = ""; // use the unnamed package // if no non-public proxy interfaces, use sun.proxy package
proxyPkg = ReflectUtil.PROXY_PACKAGE + ".";
} }
{ {
@ -598,22 +710,46 @@ public class Proxy implements java.io.Serializable {
/* /*
* Look up or generate the designated proxy class. * 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. * Invoke its constructor with the designated invocation handler.
*/ */
try { try {
Constructor<?> cons = cl.getConstructor(constructorParams); final Constructor<?> cons = cl.getConstructor(constructorParams);
return cons.newInstance(new Object[] { h }); final InvocationHandler ih = h;
} catch (NoSuchMethodException | SecurityManager sm = System.getSecurityManager();
IllegalAccessException | if (sm != null && ProxyAccessHelper.needsNewInstanceCheck(cl)) {
InstantiationException | // create proxy instance with doPrivilege as the proxy class may
InvocationTargetException e) { // 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); 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);
}
}
}
/** /**
* Returns true if and only if the specified class was dynamically * Returns true if and only if the specified class was dynamically
* generated to be a proxy class using the {@code getProxyClass} * generated to be a proxy class using the {@code getProxyClass}

View File

@ -1,5 +1,5 @@
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -24,9 +24,12 @@
*/ */
package java.net; package java.net;
import java.io.ObjectInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InvalidObjectException; 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 * @see java.net.ServerSocket
* @since 1.4 * @since 1.4
*/ */
public class InetSocketAddress extends SocketAddress { public class InetSocketAddress
/* The hostname of the Socket Address extends SocketAddress
* @serial {
*/ // Private implementation class pointed to by all public methods.
private String hostname = null; private static class InetSocketAddressHolder {
/* The IP address of the Socket Address // The hostname of the Socket Address
* @serial private String hostname;
*/ // The IP address of the Socket Address
private InetAddress addr = null; private InetAddress addr;
/* The port number of the Socket Address // The port number of the Socket Address
* @serial private int port;
*/
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 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. * range of valid port values.
*/ */
public InetSocketAddress(InetAddress addr, int port) { public InetSocketAddress(InetAddress addr, int port) {
if (port < 0 || port > 0xFFFF) { holder = new InetSocketAddressHolder(
throw new IllegalArgumentException("port out of range:" + port); null,
} addr == null ? InetAddress.anyLocalAddress() : addr,
this.port = port; checkPort(port));
if (addr == null)
this.addr = InetAddress.anyLocalAddress();
else
this.addr = addr;
} }
/** /**
@ -132,19 +213,20 @@ public class InetSocketAddress extends SocketAddress {
* @see #isUnresolved() * @see #isUnresolved()
*/ */
public InetSocketAddress(String hostname, int port) { public InetSocketAddress(String hostname, int port) {
if (port < 0 || port > 0xFFFF) { checkHost(hostname);
throw new IllegalArgumentException("port out of range:" + port); InetAddress addr = null;
} String host = null;
if (hostname == null) {
throw new IllegalArgumentException("hostname can't be null");
}
try { try {
addr = InetAddress.getByName(hostname); addr = InetAddress.getByName(hostname);
} catch(UnknownHostException e) { } catch(UnknownHostException e) {
this.hostname = hostname; host = hostname;
addr = null;
} }
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 * @since 1.5
*/ */
public static InetSocketAddress createUnresolved(String host, int port) { public static InetSocketAddress createUnresolved(String host, int port) {
if (port < 0 || port > 0xFFFF) { return new InetSocketAddress(checkPort(port), checkHost(host));
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;
} }
private void readObject(ObjectInputStream s) /**
throws IOException, ClassNotFoundException { * @serialField hostname String
s.defaultReadObject(); * @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();
}
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);
// Check that our invariants are satisfied // Check that our invariants are satisfied
if (port < 0 || port > 0xFFFF) { checkPort(oisPort);
throw new InvalidObjectException("port out of range:" + port); if (oisHostname == null && oisAddr == null)
}
if (hostname == null && addr == null) {
throw new InvalidObjectException("hostname and addr " + throw new InvalidObjectException("hostname and addr " +
"can't both be null"); "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. * @return the port number.
*/ */
public final int getPort() { 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. * @return the InetAdress or <code>null</code> if it is unresolved.
*/ */
public final InetAddress getAddress() { 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. * @return the hostname part of the address.
*/ */
public final String getHostName() { public final String getHostName() {
if (hostname != null) return holder.getHostName();
return hostname;
if (addr != null)
return addr.getHostName();
return null;
} }
/** /**
* Returns the hostname, or the String form of the address if it * Returns the hostname, or the String form of the address if it
* doesn't have a hostname (it was created using a literal). * 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. * @return the hostname, or String representation of the address.
* @since 1.7 * @since 1.7
*/ */
public final String getHostString() { public final String getHostString() {
if (hostname != null) return holder.getHostString();
return hostname;
if (addr != null) {
if (addr.hostName != null)
return addr.hostName;
else
return addr.getHostAddress();
}
return null;
} }
/** /**
@ -258,7 +364,7 @@ public class InetSocketAddress extends SocketAddress {
* an <code>InetAddress</code>. * an <code>InetAddress</code>.
*/ */
public final boolean isUnresolved() { 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. * @return a string representation of this object.
*/ */
@Override
public String toString() { public String toString() {
if (isUnresolved()) { return holder.toString();
return hostname + ":" + port;
} else {
return addr.toString() + ":" + port;
}
} }
/** /**
@ -297,19 +400,11 @@ public class InetSocketAddress extends SocketAddress {
* <code>false</code> otherwise. * <code>false</code> otherwise.
* @see java.net.InetAddress#equals(java.lang.Object) * @see java.net.InetAddress#equals(java.lang.Object)
*/ */
@Override
public final boolean equals(Object obj) { public final boolean equals(Object obj) {
if (obj == null || !(obj instanceof InetSocketAddress)) if (obj == null || !(obj instanceof InetSocketAddress))
return false; return false;
InetSocketAddress sockAddr = (InetSocketAddress) obj; return holder.equals(((InetSocketAddress) obj).holder);
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);
} }
/** /**
@ -317,11 +412,8 @@ public class InetSocketAddress extends SocketAddress {
* *
* @return a hash code value for this socket address. * @return a hash code value for this socket address.
*/ */
@Override
public final int hashCode() { public final int hashCode() {
if (addr != null) return holder.hashCode();
return addr.hashCode() + port;
if (hostname != null)
return hostname.toLowerCase().hashCode() + port;
return port;
} }
} }

View File

@ -34,8 +34,10 @@
*/ */
package java.util.concurrent; package java.util.concurrent;
import java.util.concurrent.locks.*; import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.atomic.*; import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.*; import java.util.*;
/** /**
@ -491,10 +493,15 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
* policy limiting the number of threads. Even though it is not * policy limiting the number of threads. Even though it is not
* treated as an error, failure to create threads may result in * treated as an error, failure to create threads may result in
* new tasks being rejected or existing ones remaining stuck in * new tasks being rejected or existing ones remaining stuck in
* the queue. On the other hand, no special precautions exist to * the queue.
* handle OutOfMemoryErrors that might be thrown while trying to *
* create threads, since there is generally no recourse from * We go further and preserve pool invariants even in the face of
* within this class. * 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; private volatile ThreadFactory threadFactory;
@ -568,9 +575,13 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
* task execution. This protects against interrupts that are * task execution. This protects against interrupts that are
* intended to wake up a worker thread waiting for a task from * intended to wake up a worker thread waiting for a task from
* instead interrupting a task being run. We implement a simple * instead interrupting a task being run. We implement a simple
* non-reentrant mutual exclusion lock rather than use ReentrantLock * non-reentrant mutual exclusion lock rather than use
* because we do not want worker tasks to be able to reacquire the * ReentrantLock because we do not want worker tasks to be able to
* lock when they invoke pool control methods like setCorePoolSize. * 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 private final class Worker
extends AbstractQueuedSynchronizer extends AbstractQueuedSynchronizer
@ -594,6 +605,7 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
* @param firstTask the first task (null if none) * @param firstTask the first task (null if none)
*/ */
Worker(Runnable firstTask) { Worker(Runnable firstTask) {
setState(-1); // inhibit interrupts until runWorker
this.firstTask = firstTask; this.firstTask = firstTask;
this.thread = getThreadFactory().newThread(this); this.thread = getThreadFactory().newThread(this);
} }
@ -609,7 +621,7 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
// The value 1 represents the locked state. // The value 1 represents the locked state.
protected boolean isHeldExclusively() { protected boolean isHeldExclusively() {
return getState() == 1; return getState() != 0;
} }
protected boolean tryAcquire(int unused) { protected boolean tryAcquire(int unused) {
@ -630,6 +642,16 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
public boolean tryLock() { return tryAcquire(1); } public boolean tryLock() { return tryAcquire(1); }
public void unlock() { release(1); } public void unlock() { release(1); }
public boolean isLocked() { return isHeldExclusively(); } 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; final ReentrantLock mainLock = this.mainLock;
mainLock.lock(); mainLock.lock();
try { try {
for (Worker w : workers) { for (Worker w : workers)
try { w.interruptIfStarted();
w.thread.interrupt();
} catch (SecurityException ignore) {
}
}
} finally { } finally {
mainLock.unlock(); mainLock.unlock();
} }
@ -790,19 +808,6 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
private static final boolean ONLY_ONE = true; 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 * Misc utilities, most of which are also exported to
* ScheduledThreadPoolExecutor * ScheduledThreadPoolExecutor
@ -862,12 +867,13 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
* Checks if a new worker can be added with respect to current * Checks if a new worker can be added with respect to current
* pool state and the given bound (either core or maximum). If so, * pool state and the given bound (either core or maximum). If so,
* the worker count is adjusted accordingly, and, if possible, a * 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 * first task. This method returns false if the pool is stopped or
* eligible to shut down. It also returns false if the thread * eligible to shut down. It also returns false if the thread
* factory fails to create a thread when asked, which requires a * factory fails to create a thread when asked. If the thread
* backout of workerCount, and a recheck for termination, in case * creation fails, either due to the thread factory returning
* the existence of this worker was holding up termination. * 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 * @param firstTask the task the new thread should run first (or
* null if none). Workers are created with an initial first task * 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); boolean workerStarted = false;
Thread t = w.thread; 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; final ReentrantLock mainLock = this.mainLock;
mainLock.lock(); mainLock.lock();
try { try {
// Recheck while holding lock. if (w != null)
// Back out on ThreadFactory failure or if workers.remove(w);
// shut down before lock acquired. decrementWorkerCount();
int c = ctl.get(); tryTerminate();
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;
} finally { } finally {
mainLock.unlock(); 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 * @param w the worker
*/ */
final void runWorker(Worker w) { final void runWorker(Worker w) {
Thread wt = Thread.currentThread();
Runnable task = w.firstTask; Runnable task = w.firstTask;
w.firstTask = null; w.firstTask = null;
w.unlock(); // allow interrupts
boolean completedAbruptly = true; boolean completedAbruptly = true;
try { try {
while (task != null || (task = getTask()) != null) { while (task != null || (task = getTask()) != null) {
w.lock(); 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 { try {
beforeExecute(w.thread, task); beforeExecute(wt, task);
Throwable thrown = null; Throwable thrown = null;
try { try {
task.run(); task.run();
@ -2064,3 +2099,4 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
} }
} }
} }

View File

@ -34,6 +34,7 @@ import java.security.CodeSigner;
import java.security.cert.Certificate; import java.security.cert.Certificate;
import java.security.AccessController; import java.security.AccessController;
import java.security.CodeSource; import java.security.CodeSource;
import sun.misc.IOUtils;
import sun.security.action.GetPropertyAction; import sun.security.action.GetPropertyAction;
import sun.security.util.ManifestEntryVerifier; import sun.security.util.ManifestEntryVerifier;
import sun.misc.SharedSecrets; import sun.misc.SharedSecrets;
@ -329,6 +330,9 @@ class JarFile extends ZipFile {
if (names != null) { if (names != null) {
for (int i = 0; i < names.length; i++) { for (int i = 0; i < names.length; i++) {
JarEntry e = getJarEntry(names[i]); JarEntry e = getJarEntry(names[i]);
if (e == null) {
throw new JarException("corrupted jar file");
}
if (!e.isDirectory()) { if (!e.isDirectory()) {
if (mev == null) { if (mev == null) {
mev = new ManifestEntryVerifier mev = new ManifestEntryVerifier
@ -348,6 +352,10 @@ class JarFile extends ZipFile {
// treat the jar file as being unsigned // treat the jar file as being unsigned
jv = null; jv = null;
verify = false; verify = false;
if (JarVerifier.debug != null) {
JarVerifier.debug.println("jarfile parsing error!");
ex.printStackTrace();
}
} }
// if after initializing the verifier we have nothing // if after initializing the verifier we have nothing
@ -375,11 +383,9 @@ class JarFile extends ZipFile {
* META-INF files. * META-INF files.
*/ */
private byte[] getBytes(ZipEntry ze) throws IOException { private byte[] getBytes(ZipEntry ze) throws IOException {
byte[] b = new byte[(int)ze.getSize()]; try (InputStream is = super.getInputStream(ze)) {
try (DataInputStream is = new DataInputStream(super.getInputStream(ze))) { return IOUtils.readFully(is, (int)ze.getSize(), true);
is.readFully(b, 0, b.length);
} }
return b;
} }
/** /**
@ -479,12 +485,7 @@ class JarFile extends ZipFile {
if (!isKnownToNotHaveClassPathAttribute()) { if (!isKnownToNotHaveClassPathAttribute()) {
JarEntry manEntry = getManEntry(); JarEntry manEntry = getManEntry();
if (manEntry != null) { if (manEntry != null) {
byte[] b = new byte[(int)manEntry.getSize()]; byte[] b = getBytes(manEntry);
try (DataInputStream dis = new DataInputStream(
super.getInputStream(manEntry))) {
dis.readFully(b, 0, b.length);
}
int last = b.length - src.length; int last = b.length - src.length;
int i = 0; int i = 0;
next: next:

View File

@ -24,6 +24,10 @@
*/ */
package java.util.logging; package java.util.logging;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle; import java.util.ResourceBundle;
/** /**
@ -59,7 +63,6 @@ import java.util.ResourceBundle;
*/ */
public class Level implements java.io.Serializable { 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"; private static String defaultBundle = "sun.util.logging.resources.logging";
/** /**
@ -77,6 +80,9 @@ public class Level implements java.io.Serializable {
*/ */
private final String resourceBundleName; private final String resourceBundleName;
// localized level name
private String localizedLevelName;
/** /**
* OFF is a special level that can be used to turn off logging. * OFF is a special level that can be used to turn off logging.
* This level is initialized to <CODE>Integer.MAX_VALUE</CODE>. * 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.name = name;
this.value = value; this.value = value;
this.resourceBundleName = resourceBundleName; this.resourceBundleName = resourceBundleName;
synchronized (Level.class) { this.localizedLevelName = resourceBundleName == null ? name : null;
known.add(this); KnownLevel.add(this);
}
} }
/** /**
@ -236,12 +241,76 @@ public class Level implements java.io.Serializable {
* @return localized name * @return localized name
*/ */
public String getLocalizedName() { 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 { try {
ResourceBundle rb = ResourceBundle.getBundle(resourceBundleName); ResourceBundle rb = ResourceBundle.getBundle(resourceBundleName);
return rb.getString(name); localizedLevelName = rb.getString(name);
} catch (Exception ex) { } 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". // Serialization magic to prevent "doppelgangers".
// This is a performance optimization. // This is a performance optimization.
private Object readResolve() { private Object readResolve() {
synchronized (Level.class) { KnownLevel o = KnownLevel.matches(this);
for (int i = 0; i < known.size(); i++) { if (o != null) {
Level other = known.get(i); return o.levelObject;
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;
} }
// 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> "SEVERE"
* <li> "1000" * <li> "1000"
* </ul> * </ul>
*
* @param name string to be parsed * @param name string to be parsed
* @throws NullPointerException if the name is null * @throws NullPointerException if the name is null
* @throws IllegalArgumentException if the value is not valid. * @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. // Check that name is not null.
name.length(); name.length();
KnownLevel level;
// Look for a known Level with the given non-localized name. // Look for a known Level with the given non-localized name.
for (int i = 0; i < known.size(); i++) { level = KnownLevel.findByName(name);
Level l = known.get(i); if (level != null) {
if (name.equals(l.name)) { return level.levelObject;
return l;
}
} }
// Now, check if the given name is an integer. If so, // 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. // if necessary create one.
try { try {
int x = Integer.parseInt(name); int x = Integer.parseInt(name);
for (int i = 0; i < known.size(); i++) { level = KnownLevel.findByValue(x);
Level l = known.get(i); if (level == null) {
if (l.value == x) { // add new Level
return l; Level levelObject = new Level(name, x);
} level = KnownLevel.findByValue(x);
} }
// Create a new Level. return level.levelObject;
return new Level(name, x);
} catch (NumberFormatException ex) { } catch (NumberFormatException ex) {
// Not an integer. // Not an integer.
// Drop through. // Drop through.
@ -344,11 +407,9 @@ public class Level implements java.io.Serializable {
// Finally, look for a known level with the given localized name, // Finally, look for a known level with the given localized name,
// in the current default locale. // in the current default locale.
// This is relatively expensive, but not excessively so. // This is relatively expensive, but not excessively so.
for (int i = 0; i < known.size(); i++) { level = KnownLevel.findByLocalizedName(name);
Level l = known.get(i); if (level != null) {
if (name.equals(l.getLocalizedName())) { return level.levelObject;
return l;
}
} }
// OK, we've tried everything and failed // OK, we've tried everything and failed
@ -375,4 +436,124 @@ public class Level implements java.io.Serializable {
public int hashCode() { public int hashCode() {
return this.value; 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;
}
}
} }

View File

@ -35,6 +35,10 @@ import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.beans.PropertyChangeListener; import java.beans.PropertyChangeListener;
import java.net.URL;
import sun.misc.JavaAWTAccess;
import sun.misc.SharedSecrets;
import sun.security.action.GetPropertyAction;
/** /**
* There is a single global LogManager object that is used to * There is a single global LogManager object that is used to
@ -152,10 +156,9 @@ public class LogManager {
// count to allow for cases where the same listener is registered many times. // count to allow for cases where the same listener is registered many times.
private final Map<Object,Integer> listenerMap = new HashMap<>(); private final Map<Object,Integer> listenerMap = new HashMap<>();
// Table of named Loggers that maps names to Loggers. // LoggerContext for system loggers and user loggers
private Hashtable<String,LoggerWeakRef> namedLoggers = new Hashtable<>(); private final LoggerContext systemContext = new SystemLoggerContext();
// Tree of named Loggers private final LoggerContext userContext = new LoggerContext();
private LogNode root = new LogNode(null);
private Logger rootLogger; private Logger rootLogger;
// Have we done the primordial reading of the configuration file? // Have we done the primordial reading of the configuration file?
@ -194,11 +197,12 @@ public class LogManager {
// Create and retain Logger for the root of the namespace. // Create and retain Logger for the root of the namespace.
manager.rootLogger = manager.new RootLogger(); manager.rootLogger = manager.new RootLogger();
manager.addLogger(manager.rootLogger); manager.addLogger(manager.rootLogger);
manager.systemContext.addLocalLogger(manager.rootLogger);
// Adding the global Logger. Doing so in the Logger.<clinit> // Adding the global Logger. Doing so in the Logger.<clinit>
// would deadlock with the LogManager.<clinit>. // would deadlock with the LogManager.<clinit>.
Logger.getGlobal().setLogManager(manager); Logger.global.setLogManager(manager);
manager.addLogger(Logger.getGlobal()); manager.addLogger(Logger.global);
// We don't call readConfiguration() here, as we may be running // We don't call readConfiguration() here, as we may be running
// very early in the JVM startup sequence. Instead readConfiguration // very early in the JVM startup sequence. Instead readConfiguration
@ -276,14 +280,14 @@ public class LogManager {
return; return;
} }
readPrimordialConfiguration = true; readPrimordialConfiguration = true;
try { try {
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() { AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
public Object run() throws Exception { public Void run() throws Exception {
readConfiguration(); readConfiguration();
// Platform loggers begin to delegate to java.util.logging.Logger // Platform loggers begin to delegate to java.util.logging.Logger
sun.util.logging.PlatformLogger.redirectPlatformLoggers(); sun.util.logging.PlatformLogger.redirectPlatformLoggers();
return null; return null;
} }
}); });
@ -367,20 +371,65 @@ public class LogManager {
} }
} }
// Package-level method. // Returns the LoggerContext for the user code (i.e. application or AppContext).
// Loggers are isolated from each AppContext.
private LoggerContext getUserContext() {
LoggerContext context = null;
SecurityManager sm = System.getSecurityManager();
JavaAWTAccess javaAwtAccess = SharedSecrets.getJavaAWTAccess();
if (sm != null && javaAwtAccess != null) {
synchronized (javaAwtAccess) {
// AppContext.getAppContext() returns the system AppContext if called
// from a system thread but Logger.getLogger might be called from
// an applet code. Instead, find the AppContext of the applet code
// from the execution stack.
Object ecx = javaAwtAccess.getExecutionContext();
if (ecx == null) {
// fall back to AppContext.getAppContext()
ecx = javaAwtAccess.getContext();
}
context = (LoggerContext)javaAwtAccess.get(ecx, LoggerContext.class);
if (context == null) {
if (javaAwtAccess.isMainAppContext()) {
context = userContext;
} else {
context = new LoggerContext();
context.addLocalLogger(manager.rootLogger);
}
javaAwtAccess.put(ecx, LoggerContext.class, context);
}
}
} else {
context = userContext;
}
return context;
}
private List<LoggerContext> contexts() {
List<LoggerContext> cxs = new ArrayList<>();
cxs.add(systemContext);
cxs.add(getUserContext());
return cxs;
}
// Find or create a specified logger instance. If a logger has // Find or create a specified logger instance. If a logger has
// already been created with the given name it is returned. // already been created with the given name it is returned.
// Otherwise a new logger instance is created and registered // Otherwise a new logger instance is created and registered
// in the LogManager global namespace. // in the LogManager global namespace.
// This method will always return a non-null Logger object. // This method will always return a non-null Logger object.
// Synchronization is not required here. All synchronization for // Synchronization is not required here. All synchronization for
// adding a new Logger object is handled by addLogger(). // adding a new Logger object is handled by addLogger().
Logger demandLogger(String name) { //
// This method must delegate to the LogManager implementation to
// add a new Logger or return the one that has been added previously
// as a LogManager subclass may override the addLogger, getLogger,
// readConfiguration, and other methods.
Logger demandLogger(String name, String resourceBundleName) {
Logger result = getLogger(name); Logger result = getLogger(name);
if (result == null) { if (result == null) {
// only allocate the new logger once // only allocate the new logger once
Logger newLogger = new Logger(name, null); Logger newLogger = new Logger(name, resourceBundleName);
do { do {
if (addLogger(newLogger)) { if (addLogger(newLogger)) {
// We successfully added the new Logger that we // We successfully added the new Logger that we
@ -405,24 +454,231 @@ public class LogManager {
return result; return result;
} }
// If logger.getUseParentHandlers() returns 'true' and any of the logger's Logger demandSystemLogger(String name, String resourceBundleName) {
// parents have levels or handlers defined, make sure they are instantiated. return systemContext.demandLogger(name, resourceBundleName);
private void processParentHandlers(Logger logger, String name) { }
int ix = 1;
for (;;) {
int ix2 = name.indexOf(".", ix);
if (ix2 < 0) {
break;
}
String pname = name.substring(0,ix2);
if (getProperty(pname+".level") != null || // LoggerContext maintains the logger namespace per context.
getProperty(pname+".handlers") != null) { // The default LogManager implementation has one system context and user
// This pname has a level/handlers definition. // context. The system context is used to maintain the namespace for
// Make sure it exists. // all system loggers and is queried by the system code. If a system logger
demandLogger(pname); // doesn't exist in the user context, it'll also be added to the user context.
// The user context is queried by the user code and all other loggers are
// added in the user context.
static class LoggerContext {
// Table of named Loggers that maps names to Loggers.
private final Hashtable<String,LoggerWeakRef> namedLoggers = new Hashtable<>();
// Tree of named Loggers
private final LogNode root;
private LoggerContext() {
this.root = new LogNode(null, this);
}
Logger demandLogger(String name, String resourceBundleName) {
// a LogManager subclass may have its own implementation to add and
// get a Logger. So delegate to the LogManager to do the work.
return manager.demandLogger(name, resourceBundleName);
}
synchronized Logger findLogger(String name) {
LoggerWeakRef ref = namedLoggers.get(name);
if (ref == null) {
return null;
} }
ix = ix2+1; Logger logger = ref.get();
if (logger == null) {
// Hashtable holds stale weak reference
// to a logger which has been GC-ed.
removeLogger(name);
}
return logger;
}
// Add a logger to this context. This method will only set its level
// and process parent loggers. It doesn't set its handlers.
synchronized boolean addLocalLogger(Logger logger) {
final String name = logger.getName();
if (name == null) {
throw new NullPointerException();
}
// cleanup some Loggers that have been GC'ed
manager.drainLoggerRefQueueBounded();
LoggerWeakRef ref = namedLoggers.get(name);
if (ref != null) {
if (ref.get() == null) {
// It's possible that the Logger was GC'ed after the
// drainLoggerRefQueueBounded() call above so allow
// a new one to be registered.
removeLogger(name);
} else {
// We already have a registered logger with the given name.
return false;
}
}
// We're adding a new logger.
// Note that we are creating a weak reference here.
ref = manager.new LoggerWeakRef(logger);
namedLoggers.put(name, ref);
// Apply any initial level defined for the new logger.
Level level = manager.getLevelProperty(name + ".level", null);
if (level != null) {
doSetLevel(logger, level);
}
// instantiation of the handler is done in the LogManager.addLogger
// implementation as a handler class may be only visible to LogManager
// subclass for the custom log manager case
processParentHandlers(logger, name);
// Find the new node and its parent.
LogNode node = getNode(name);
node.loggerRef = ref;
Logger parent = null;
LogNode nodep = node.parent;
while (nodep != null) {
LoggerWeakRef nodeRef = nodep.loggerRef;
if (nodeRef != null) {
parent = nodeRef.get();
if (parent != null) {
break;
}
}
nodep = nodep.parent;
}
if (parent != null) {
doSetParent(logger, parent);
}
// Walk over the children and tell them we are their new parent.
node.walkAndSetParent(logger);
// new LogNode is ready so tell the LoggerWeakRef about it
ref.setNode(node);
return true;
}
void removeLogger(String name) {
namedLoggers.remove(name);
}
synchronized Enumeration<String> getLoggerNames() {
return namedLoggers.keys();
}
// If logger.getUseParentHandlers() returns 'true' and any of the logger's
// parents have levels or handlers defined, make sure they are instantiated.
private void processParentHandlers(final Logger logger, final String name) {
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
if (logger != manager.rootLogger) {
boolean useParent = manager.getBooleanProperty(name + ".useParentHandlers", true);
if (!useParent) {
logger.setUseParentHandlers(false);
}
}
return null;
}
});
int ix = 1;
for (;;) {
int ix2 = name.indexOf(".", ix);
if (ix2 < 0) {
break;
}
String pname = name.substring(0, ix2);
if (manager.getProperty(pname + ".level") != null ||
manager.getProperty(pname + ".handlers") != null) {
// This pname has a level/handlers definition.
// Make sure it exists.
demandLogger(pname, null);
}
ix = ix2+1;
}
}
// Gets a node in our tree of logger nodes.
// If necessary, create it.
LogNode getNode(String name) {
if (name == null || name.equals("")) {
return root;
}
LogNode node = root;
while (name.length() > 0) {
int ix = name.indexOf(".");
String head;
if (ix > 0) {
head = name.substring(0, ix);
name = name.substring(ix + 1);
} else {
head = name;
name = "";
}
if (node.children == null) {
node.children = new HashMap<>();
}
LogNode child = node.children.get(head);
if (child == null) {
child = new LogNode(node, this);
node.children.put(head, child);
}
node = child;
}
return node;
}
}
static class SystemLoggerContext extends LoggerContext {
// Add a system logger in the system context's namespace as well as
// in the LogManager's namespace if not exist so that there is only
// one single logger of the given name. System loggers are visible
// to applications unless a logger of the same name has been added.
Logger demandLogger(String name, String resourceBundleName) {
Logger result = findLogger(name);
if (result == null) {
// only allocate the new system logger once
Logger newLogger = new Logger(name, resourceBundleName);
do {
if (addLocalLogger(newLogger)) {
// We successfully added the new Logger that we
// created above so return it without refetching.
result = newLogger;
} else {
// We didn't add the new Logger that we created above
// because another thread added a Logger with the same
// name after our null check above and before our call
// to addLogger(). We have to refetch the Logger because
// addLogger() returns a boolean instead of the Logger
// reference itself. However, if the thread that created
// the other Logger is not holding a strong reference to
// the other Logger, then it is possible for the other
// Logger to be GC'ed after we saw it in addLogger() and
// before we can refetch it. If it has been GC'ed then
// we'll just loop around and try again.
result = findLogger(name);
}
} while (result == null);
}
// Add the system logger to the LogManager's namespace if not exists
// The LogManager will set its handlers via the LogManager.addLogger method.
if (!manager.addLogger(result) && result.getHandlers().length == 0) {
// if logger already exists but handlers not set
final Logger l = manager.getLogger(name);
final Logger logger = result;
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
for (Handler hdl : l.getHandlers()) {
logger.addHandler(hdl);
}
return null;
}
});
}
return result;
} }
} }
@ -431,32 +687,27 @@ public class LogManager {
// be made based on the logging configuration, which can // be made based on the logging configuration, which can
// only be modified by trusted code. // only be modified by trusted code.
private void loadLoggerHandlers(final Logger logger, final String name, private void loadLoggerHandlers(final Logger logger, final String name,
final String handlersPropertyName) { final String handlersPropertyName)
{
AccessController.doPrivileged(new PrivilegedAction<Object>() { AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() { public Object run() {
if (logger != rootLogger) {
boolean useParent = getBooleanProperty(name + ".useParentHandlers", true);
if (!useParent) {
logger.setUseParentHandlers(false);
}
}
String names[] = parseClassNames(handlersPropertyName); String names[] = parseClassNames(handlersPropertyName);
for (int i = 0; i < names.length; i++) { for (int i = 0; i < names.length; i++) {
String word = names[i]; String word = names[i];
try { try {
Class<?> clz = ClassLoader.getSystemClassLoader().loadClass(word); Class<?> clz = ClassLoader.getSystemClassLoader().loadClass(word);
Handler hdl = (Handler) clz.newInstance(); Handler hdl = (Handler) clz.newInstance();
try { // Check if there is a property defining the
// Check if there is a property defining the // this handler's level.
// this handler's level. String levs = getProperty(word + ".level");
String levs = getProperty(word + ".level"); if (levs != null) {
if (levs != null) { Level l = Level.findLevel(levs);
hdl.setLevel(Level.parse(levs)); if (l != null) {
hdl.setLevel(l);
} else {
// Probably a bad level. Drop through.
System.err.println("Can't set level for " + word);
} }
} catch (Exception ex) {
System.err.println("Can't set level for " + word);
// Probably a bad level. Drop through.
} }
// Add this Handler to the logger // Add this Handler to the logger
logger.addHandler(hdl); logger.addHandler(hdl);
@ -467,7 +718,8 @@ public class LogManager {
} }
} }
return null; return null;
}}); }
});
} }
@ -512,7 +764,7 @@ public class LogManager {
if (node != null) { if (node != null) {
// if we have a LogNode, then we were a named Logger // if we have a LogNode, then we were a named Logger
// so clear namedLoggers weak ref to us // so clear namedLoggers weak ref to us
manager.namedLoggers.remove(name); node.context.removeLogger(name);
name = null; // clear our ref to the Logger's name name = null; // clear our ref to the Logger's name
node.loggerRef = null; // clear LogNode's weak ref to us node.loggerRef = null; // clear LogNode's weak ref to us
@ -601,73 +853,22 @@ public class LogManager {
* false if a logger of that name already exists. * false if a logger of that name already exists.
* @exception NullPointerException if the logger name is null. * @exception NullPointerException if the logger name is null.
*/ */
public synchronized boolean addLogger(Logger logger) { public boolean addLogger(Logger logger) {
final String name = logger.getName(); final String name = logger.getName();
if (name == null) { if (name == null) {
throw new NullPointerException(); throw new NullPointerException();
} }
LoggerContext cx = getUserContext();
// cleanup some Loggers that have been GC'ed if (cx.addLocalLogger(logger)) {
drainLoggerRefQueueBounded(); // Do we have a per logger handler too?
// Note: this will add a 200ms penalty
LoggerWeakRef ref = namedLoggers.get(name); loadLoggerHandlers(logger, name, name + ".handlers");
if (ref != null) { return true;
if (ref.get() == null) { } else {
// It's possible that the Logger was GC'ed after the return false;
// drainLoggerRefQueueBounded() call above so allow
// a new one to be registered.
namedLoggers.remove(name);
} else {
// We already have a registered logger with the given name.
return false;
}
} }
// We're adding a new logger.
// Note that we are creating a weak reference here.
ref = new LoggerWeakRef(logger);
namedLoggers.put(name, ref);
// Apply any initial level defined for the new logger.
Level level = getLevelProperty(name+".level", null);
if (level != null) {
doSetLevel(logger, level);
}
// Do we have a per logger handler too?
// Note: this will add a 200ms penalty
loadLoggerHandlers(logger, name, name+".handlers");
processParentHandlers(logger, name);
// Find the new node and its parent.
LogNode node = findNode(name);
node.loggerRef = ref;
Logger parent = null;
LogNode nodep = node.parent;
while (nodep != null) {
LoggerWeakRef nodeRef = nodep.loggerRef;
if (nodeRef != null) {
parent = nodeRef.get();
if (parent != null) {
break;
}
}
nodep = nodep.parent;
}
if (parent != null) {
doSetParent(logger, parent);
}
// Walk over the children and tell them we are their new parent.
node.walkAndSetParent(logger);
// new LogNode is ready so tell the LoggerWeakRef about it
ref.setNode(node);
return true;
} }
// Private method to set a level on a logger. // Private method to set a level on a logger.
// If necessary, we raise privilege before doing the call. // If necessary, we raise privilege before doing the call.
private static void doSetLevel(final Logger logger, final Level level) { private static void doSetLevel(final Logger logger, final Level level) {
@ -686,8 +887,6 @@ public class LogManager {
}}); }});
} }
// Private method to set a parent on a logger. // Private method to set a parent on a logger.
// If necessary, we raise privilege before doing the setParent call. // If necessary, we raise privilege before doing the setParent call.
private static void doSetParent(final Logger logger, final Logger parent) { private static void doSetParent(final Logger logger, final Logger parent) {
@ -706,36 +905,6 @@ public class LogManager {
}}); }});
} }
// Find a node in our tree of logger nodes.
// If necessary, create it.
private LogNode findNode(String name) {
if (name == null || name.equals("")) {
return root;
}
LogNode node = root;
while (name.length() > 0) {
int ix = name.indexOf(".");
String head;
if (ix > 0) {
head = name.substring(0,ix);
name = name.substring(ix+1);
} else {
head = name;
name = "";
}
if (node.children == null) {
node.children = new HashMap<>();
}
LogNode child = node.children.get(head);
if (child == null) {
child = new LogNode(node);
node.children.put(head, child);
}
node = child;
}
return node;
}
/** /**
* Method to find a named logger. * Method to find a named logger.
* <p> * <p>
@ -751,18 +920,8 @@ public class LogManager {
* @param name name of the logger * @param name name of the logger
* @return matching logger or null if none is found * @return matching logger or null if none is found
*/ */
public synchronized Logger getLogger(String name) { public Logger getLogger(String name) {
LoggerWeakRef ref = namedLoggers.get(name); return getUserContext().findLogger(name);
if (ref == null) {
return null;
}
Logger logger = ref.get();
if (logger == null) {
// Hashtable holds stale weak reference
// to a logger which has been GC-ed.
namedLoggers.remove(name);
}
return logger;
} }
/** /**
@ -781,8 +940,8 @@ public class LogManager {
* <p> * <p>
* @return enumeration of logger name strings * @return enumeration of logger name strings
*/ */
public synchronized Enumeration<String> getLoggerNames() { public Enumeration<String> getLoggerNames() {
return namedLoggers.keys(); return getUserContext().getLoggerNames();
} }
/** /**
@ -867,20 +1026,20 @@ public class LogManager {
// the global handlers, if they haven't been initialized yet. // the global handlers, if they haven't been initialized yet.
initializedGlobalHandlers = true; initializedGlobalHandlers = true;
} }
Enumeration<String> enum_ = getLoggerNames(); for (LoggerContext cx : contexts()) {
while (enum_.hasMoreElements()) { Enumeration<String> enum_ = cx.getLoggerNames();
String name = enum_.nextElement(); while (enum_.hasMoreElements()) {
resetLogger(name); String name = enum_.nextElement();
Logger logger = cx.findLogger(name);
if (logger != null) {
resetLogger(logger);
}
}
} }
} }
// Private method to reset an individual target logger. // Private method to reset an individual target logger.
private void resetLogger(String name) { private void resetLogger(Logger logger) {
Logger logger = getLogger(name);
if (logger == null) {
return;
}
// Close all the Logger's handlers. // Close all the Logger's handlers.
Handler[] targets = logger.getHandlers(); Handler[] targets = logger.getHandlers();
for (int i = 0; i < targets.length; i++) { for (int i = 0; i < targets.length; i++) {
@ -892,6 +1051,7 @@ public class LogManager {
// Problems closing a handler? Keep going... // Problems closing a handler? Keep going...
} }
} }
String name = logger.getName();
if (name != null && name.equals("")) { if (name != null && name.equals("")) {
// This is the root logger. // This is the root logger.
logger.setLevel(defaultLevel); logger.setLevel(defaultLevel);
@ -1057,11 +1217,8 @@ public class LogManager {
if (val == null) { if (val == null) {
return defaultValue; return defaultValue;
} }
try { Level l = Level.findLevel(val.trim());
return Level.parse(val.trim()); return l != null ? l : defaultValue;
} catch (Exception ex) {
return defaultValue;
}
} }
// Package private method to get a filter property. // Package private method to get a filter property.
@ -1151,9 +1308,11 @@ public class LogManager {
HashMap<String,LogNode> children; HashMap<String,LogNode> children;
LoggerWeakRef loggerRef; LoggerWeakRef loggerRef;
LogNode parent; LogNode parent;
final LoggerContext context;
LogNode(LogNode parent) { LogNode(LogNode parent, LoggerContext context) {
this.parent = parent; this.parent = parent;
this.context = context;
} }
// Recursive method to walk the tree below a node and set // Recursive method to walk the tree below a node and set
@ -1180,7 +1339,6 @@ public class LogManager {
// that we only instantiate the global handlers when they // that we only instantiate the global handlers when they
// are first needed. // are first needed.
private class RootLogger extends Logger { private class RootLogger extends Logger {
private RootLogger() { private RootLogger() {
super("", null); super("", null);
setLevel(defaultLevel); setLevel(defaultLevel);
@ -1226,11 +1384,13 @@ public class LogManager {
System.err.println("Bad level value for property: " + key); System.err.println("Bad level value for property: " + key);
continue; continue;
} }
Logger l = getLogger(name); for (LoggerContext cx : contexts()) {
if (l == null) { Logger l = cx.findLogger(name);
continue; if (l == null) {
continue;
}
l.setLevel(level);
} }
l.setLevel(level);
} }
} }

View File

@ -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 * Find or create a logger for a named subsystem. If a logger has
* already been created with the given name it is returned. Otherwise * 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 // would throw an IllegalArgumentException in the second call
// because the wrapper would result in an attempt to replace // because the wrapper would result in an attempt to replace
// the existing "resourceBundleForFoo" with null. // the existing "resourceBundleForFoo" with null.
LogManager manager = LogManager.getLogManager(); return demandLogger(name, null);
return manager.demandLogger(name);
} }
/** /**
@ -403,8 +436,7 @@ public class Logger {
// Synchronization is not required here. All synchronization for // Synchronization is not required here. All synchronization for
// adding a new Logger object is handled by LogManager.addLogger(). // adding a new Logger object is handled by LogManager.addLogger().
public static Logger getLogger(String name, String resourceBundleName) { public static Logger getLogger(String name, String resourceBundleName) {
LogManager manager = LogManager.getLogManager(); Logger result = demandLogger(name, resourceBundleName);
Logger result = manager.demandLogger(name);
// MissingResourceException or IllegalArgumentException can be // MissingResourceException or IllegalArgumentException can be
// thrown by setupResourceInfo(). // thrown by setupResourceInfo().
@ -412,6 +444,17 @@ public class Logger {
return result; 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 * Create an anonymous Logger. The newly created Logger is not
@ -564,7 +607,7 @@ public class Logger {
private void doLog(LogRecord lr) { private void doLog(LogRecord lr) {
lr.setLoggerName(name); lr.setLoggerName(name);
String ebname = getEffectiveResourceBundleName(); String ebname = getEffectiveResourceBundleName();
if (ebname != null) { if (ebname != null && !ebname.equals(SYSTEM_LOGGER_RB_NAME)) {
lr.setResourceBundleName(ebname); lr.setResourceBundleName(ebname);
lr.setResourceBundle(findResourceBundle(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 // May also return null if we can't find the resource bundle and
// there is no suitable previous cached value. // 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) { private synchronized ResourceBundle findResourceBundle(String name) {
// Return a null bundle for a null name. // Return a null bundle for a null name.
if (name == null) { if (name == null) {
@ -1561,6 +1621,13 @@ public class Logger {
return catalog; 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 thread's context ClassLoader. If there isn't one,
// use the SystemClassloader. // use the SystemClassloader.
ClassLoader cl = Thread.currentThread().getContextClassLoader(); ClassLoader cl = Thread.currentThread().getContextClassLoader();
@ -1577,7 +1644,6 @@ public class Logger {
// ClassLoader. Drop through. // ClassLoader. Drop through.
} }
// Fall back to searching up the call stack and trying each // Fall back to searching up the call stack and trying each
// calling ClassLoader. // calling ClassLoader.
for (int ix = 0; ; ix++) { for (int ix = 0; ; ix++) {

View File

@ -34,7 +34,7 @@ import java.util.ArrayList;
* *
* The <tt>LoggingMXBean</tt> interface provides a standard * The <tt>LoggingMXBean</tt> interface provides a standard
* method for management access to the individual * method for management access to the individual
* java.util.Logger objects available at runtime. * {@code Logger} objects available at runtime.
* *
* @author Ron Mann * @author Ron Mann
* @author Mandy Chung * @author Mandy Chung
@ -75,7 +75,7 @@ class Logging implements LoggingMXBean {
if (level == null) { if (level == null) {
return EMPTY_STRING; return EMPTY_STRING;
} else { } else {
return level.getName(); return level.getLevelName();
} }
} }
@ -85,7 +85,6 @@ class Logging implements LoggingMXBean {
} }
Logger logger = logManager.getLogger(loggerName); Logger logger = logManager.getLogger(loggerName);
if (logger == null) { if (logger == null) {
throw new IllegalArgumentException("Logger " + loggerName + throw new IllegalArgumentException("Logger " + loggerName +
"does not exist"); "does not exist");
@ -94,7 +93,10 @@ class Logging implements LoggingMXBean {
Level level = null; Level level = null;
if (levelName != null) { if (levelName != null) {
// parse will throw IAE if logLevel is invalid // 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); logger.setLevel(level);

View File

@ -37,7 +37,8 @@ class LoggingProxyImpl implements LoggingProxy {
@Override @Override
public Object getLogger(String name) { public Object getLogger(String name) {
return Logger.getLogger(name); // always create a platform logger with the resource bundle name
return Logger.getPlatformLogger(name);
} }
@Override @Override
@ -92,12 +93,16 @@ class LoggingProxyImpl implements LoggingProxy {
@Override @Override
public Object parseLevel(String levelName) { 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 @Override
public String getLevelName(Object level) { public String getLevelName(Object level) {
return ((Level) level).getName(); return ((Level) level).getLevelName();
} }
@Override @Override

View File

@ -162,7 +162,7 @@ public class SimpleFormatter extends Formatter {
dat, dat,
source, source,
record.getLoggerName(), record.getLoggerName(),
record.getLevel().getLocalizedName(), record.getLevel().getLocalizedLevelName(),
message, message,
throwable); throwable);
} }

View File

@ -1,5 +1,5 @@
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -39,11 +39,13 @@ import java.io.PrintStream;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -78,6 +80,8 @@ import javax.management.RuntimeErrorException;
import javax.management.RuntimeOperationsException; import javax.management.RuntimeOperationsException;
import javax.management.ServiceNotFoundException; import javax.management.ServiceNotFoundException;
import javax.management.loading.ClassLoaderRepository; import javax.management.loading.ClassLoaderRepository;
import sun.misc.JavaSecurityAccess;
import sun.misc.SharedSecrets;
import sun.reflect.misc.MethodUtil; import sun.reflect.misc.MethodUtil;
import sun.reflect.misc.ReflectUtil; import sun.reflect.misc.ReflectUtil;
@ -138,6 +142,9 @@ public class RequiredModelMBean
private boolean registered = false; private boolean registered = false;
private transient MBeanServer server = null; private transient MBeanServer server = null;
private final static JavaSecurityAccess javaSecurityAccess = SharedSecrets.getJavaSecurityAccess();
final private AccessControlContext acc = AccessController.getContext();
/*************************************/ /*************************************/
/* constructors */ /* constructors */
/*************************************/ /*************************************/
@ -1025,10 +1032,31 @@ public class RequiredModelMBean
if (opClassName != null) { if (opClassName != null) {
try { try {
final ClassLoader targetClassLoader = AccessControlContext stack = AccessController.getContext();
targetObject.getClass().getClassLoader(); final Object obj = targetObject;
targetClass = Class.forName(opClassName, false, final String className = opClassName;
targetClassLoader); 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) { } catch (ClassNotFoundException e) {
final String msg = final String msg =
"class for invoke " + opName + " not found"; "class for invoke " + opName + " not found";
@ -1061,9 +1089,9 @@ public class RequiredModelMBean
return result; return result;
} }
private static Method resolveMethod(Class<?> targetClass, private Method resolveMethod(Class<?> targetClass,
String opMethodName, String opMethodName,
String[] sig) final String[] sig)
throws ReflectionException { throws ReflectionException {
final boolean tracing = MODELMBEAN_LOGGER.isLoggable(Level.FINER); final boolean tracing = MODELMBEAN_LOGGER.isLoggable(Level.FINER);
@ -1078,30 +1106,45 @@ public class RequiredModelMBean
if (sig == null) if (sig == null)
argClasses = null; argClasses = null;
else { else {
final AccessControlContext stack = AccessController.getContext();
final ReflectionException[] caughtException = new ReflectionException[1];
final ClassLoader targetClassLoader = targetClass.getClassLoader(); final ClassLoader targetClassLoader = targetClass.getClassLoader();
argClasses = new Class<?>[sig.length]; argClasses = new Class<?>[sig.length];
for (int i = 0; i < sig.length; i++) {
if (tracing) { javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Void>() {
MODELMBEAN_LOGGER.logp(Level.FINER,
RequiredModelMBean.class.getName(),"resolveMethod", @Override
"resolve type " + sig[i]); public Void run() {
} for (int i = 0; i < sig.length; i++) {
argClasses[i] = (Class<?>) primitiveClassMap.get(sig[i]);
if (argClasses[i] == null) {
try {
argClasses[i] =
Class.forName(sig[i], false, targetClassLoader);
} catch (ClassNotFoundException e) {
if (tracing) { if (tracing) {
MODELMBEAN_LOGGER.logp(Level.FINER, MODELMBEAN_LOGGER.logp(Level.FINER,
RequiredModelMBean.class.getName(), RequiredModelMBean.class.getName(),"resolveMethod",
"resolveMethod", "resolve type " + sig[i]);
"class not found"); }
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 /* Find a method in RequiredModelMBean as determined by the given
parameters. Return null if there is none, or if the parameters parameters. Return null if there is none, or if the parameters
exclude using it. Called from invoke. */ exclude using it. Called from invoke. */
private static Method findRMMBMethod(String opMethodName, private Method findRMMBMethod(String opMethodName,
Object targetObjectField, Object targetObjectField,
String opClassName, String opClassName,
String[] sig) { String[] sig) {
@ -1155,19 +1198,29 @@ public class RequiredModelMBean
if (opClassName == null) if (opClassName == null)
targetClass = rmmbClass; targetClass = rmmbClass;
else { else {
try { AccessControlContext stack = AccessController.getContext();
final ClassLoader targetClassLoader = final String className = opClassName;
rmmbClass.getClassLoader(); targetClass = javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Class<?>>() {
targetClass = Class.forName(opClassName, false,
targetClassLoader); @Override
if (!rmmbClass.isAssignableFrom(targetClass)) public Class<?> run() {
return null; try {
} catch (ClassNotFoundException e) { ReflectUtil.checkPackageAccess(className);
return null; 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 { try {
return resolveMethod(targetClass, opMethodName, sig); return targetClass != null ? resolveMethod(targetClass, opMethodName, sig) : null;
} catch (ReflectionException e) { } catch (ReflectionException e) {
return null; return null;
} }
@ -1177,12 +1230,35 @@ public class RequiredModelMBean
* Invoke the given method, and throw the somewhat unpredictable * Invoke the given method, and throw the somewhat unpredictable
* appropriate exception if the method itself gets an exception. * appropriate exception if the method itself gets an exception.
*/ */
private Object invokeMethod(String opName, Method method, private Object invokeMethod(String opName, final Method method,
Object targetObject, Object[] opArgs) final Object targetObject, final Object[] opArgs)
throws MBeanException, ReflectionException { throws MBeanException, ReflectionException {
try { try {
ReflectUtil.checkPackageAccess(method.getDeclaringClass()); final Throwable[] caughtException = new Throwable[1];
return MethodUtil.invoke(method, targetObject, opArgs); 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) { } catch (RuntimeErrorException ree) {
throw new RuntimeOperationsException(ree, throw new RuntimeOperationsException(ree,
"RuntimeException occurred in RequiredModelMBean "+ "RuntimeException occurred in RequiredModelMBean "+
@ -1567,7 +1643,7 @@ public class RequiredModelMBean
} }
// make sure response class matches type field // make sure response class matches type field
String respType = attrInfo.getType(); final String respType = attrInfo.getType();
if (response != null) { if (response != null) {
String responseClass = response.getClass().getName(); String responseClass = response.getClass().getName();
if (!respType.equals(responseClass)) { if (!respType.equals(responseClass)) {
@ -1590,9 +1666,31 @@ public class RequiredModelMBean
// inequality may come from type subclassing // inequality may come from type subclassing
boolean subtype; boolean subtype;
try { try {
ClassLoader cl = final Class respClass = response.getClass();
response.getClass().getClassLoader(); final Exception[] caughException = new Exception[1];
Class<?> c = Class.forName(respType, true, cl);
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); subtype = c.isInstance(response);
} catch (Exception e) { } catch (Exception e) {
subtype = false; subtype = false;
@ -2745,16 +2843,37 @@ public class RequiredModelMBean
return MBeanServerFactory.getClassLoaderRepository(server); return MBeanServerFactory.getClassLoaderRepository(server);
} }
private Class<?> loadClass(String className) private Class<?> loadClass(final String className)
throws ClassNotFoundException { throws ClassNotFoundException {
try { AccessControlContext stack = AccessController.getContext();
return Class.forName(className); final ClassNotFoundException[] caughtException = new ClassNotFoundException[1];
} catch (ClassNotFoundException e) {
final ClassLoaderRepository clr = Class c = javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Class<?>>() {
getClassLoaderRepository();
if (clr == null) throw new ClassNotFoundException(className); @Override
return clr.loadClass(className); 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;
} }

View File

@ -781,15 +781,11 @@ public class JTable extends JComponent implements TableModelListener, Scrollable
scrollPane.getCorner(JScrollPane.UPPER_TRAILING_CORNER); scrollPane.getCorner(JScrollPane.UPPER_TRAILING_CORNER);
if (corner == null || corner instanceof UIResource){ if (corner == null || corner instanceof UIResource){
corner = null; corner = null;
Object componentClass = UIManager.get( try {
"Table.scrollPaneCornerComponent"); corner = (Component) UIManager.get(
if (componentClass instanceof Class){ "Table.scrollPaneCornerComponent");
try { } catch (Exception e) {
corner = (Component) // just ignore and don't set corner
((Class)componentClass).newInstance();
} catch (Exception e) {
// just ignore and don't set corner
}
} }
scrollPane.setCorner(JScrollPane.UPPER_TRAILING_CORNER, scrollPane.setCorner(JScrollPane.UPPER_TRAILING_CORNER,
corner); corner);

View File

@ -27,11 +27,12 @@ package javax.swing;
import java.awt.*; import java.awt.*;
import java.awt.event.*; import java.awt.event.*;
import java.awt.peer.ComponentPeer;
import java.awt.peer.ContainerPeer;
import java.awt.image.VolatileImage; import java.awt.image.VolatileImage;
import java.security.AccessControlContext;
import java.security.AccessController; import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.*; import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.applet.*; import java.applet.*;
import sun.awt.AWTAccessor; import sun.awt.AWTAccessor;
@ -39,6 +40,8 @@ import sun.awt.AppContext;
import sun.awt.DisplayChangedListener; import sun.awt.DisplayChangedListener;
import sun.awt.SunToolkit; import sun.awt.SunToolkit;
import sun.java2d.SunGraphicsEnvironment; import sun.java2d.SunGraphicsEnvironment;
import sun.misc.JavaSecurityAccess;
import sun.misc.SharedSecrets;
import sun.security.action.GetPropertyAction; import sun.security.action.GetPropertyAction;
import com.sun.java.swing.SwingUtilities3; import com.sun.java.swing.SwingUtilities3;
@ -176,6 +179,9 @@ public class RepaintManager
*/ */
private final ProcessingRunnable processingRunnable; private final ProcessingRunnable processingRunnable;
private final static JavaSecurityAccess javaSecurityAccess =
SharedSecrets.getJavaSecurityAccess();
static { static {
volatileImageBufferEnabled = "true".equals(AccessController. volatileImageBufferEnabled = "true".equals(AccessController.
@ -548,13 +554,26 @@ public class RepaintManager
// This is called from the toolkit thread when awt needs to run a // This is called from the toolkit thread when awt needs to run a
// Runnable before we paint. // Runnable before we paint.
// //
void nativeQueueSurfaceDataRunnable(AppContext appContext, Component c, void nativeQueueSurfaceDataRunnable(AppContext appContext,
Runnable r) { final Component c, final Runnable r)
{
synchronized(this) { synchronized(this) {
if (runnableList == null) { if (runnableList == null) {
runnableList = new LinkedList<Runnable>(); 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); scheduleProcessingRunnable(appContext);
} }
@ -652,9 +671,9 @@ public class RepaintManager
* @see #addInvalidComponent * @see #addInvalidComponent
*/ */
public void validateInvalidComponents() { public void validateInvalidComponents() {
java.util.List<Component> ic; final java.util.List<Component> ic;
synchronized(this) { synchronized(this) {
if(invalidComponents == null) { if (invalidComponents == null) {
return; return;
} }
ic = invalidComponents; ic = invalidComponents;
@ -662,7 +681,17 @@ public class RepaintManager
} }
int n = ic.size(); int n = ic.size();
for(int i = 0; i < n; i++) { 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); paintDirtyRegions(tmpDirtyComponents);
} }
private void paintDirtyRegions(Map<Component,Rectangle> private void paintDirtyRegions(
tmpDirtyComponents){ final Map<Component,Rectangle> tmpDirtyComponents)
int i, count; {
java.util.List<Component> roots; if (tmpDirtyComponents.isEmpty()) {
Component dirtyComponent;
count = tmpDirtyComponents.size();
if (count == 0) {
return; return;
} }
Rectangle rect; final java.util.List<Component> roots =
int localBoundsX = 0; new ArrayList<Component>(tmpDirtyComponents.size());
int localBoundsY = 0;
int localBoundsH;
int localBoundsW;
roots = new ArrayList<Component>(count);
for (Component dirty : tmpDirtyComponents.keySet()) { for (Component dirty : tmpDirtyComponents.keySet()) {
collectDirtyComponents(tmpDirtyComponents, dirty, roots); collectDirtyComponents(tmpDirtyComponents, dirty, roots);
} }
count = roots.size(); final AtomicInteger count = new AtomicInteger(roots.size());
painting = true; painting = true;
try { try {
for(i=0 ; i < count ; i++) { for (int j=0 ; j < count.get(); j++) {
dirtyComponent = roots.get(i); final int i = j;
rect = tmpDirtyComponents.get(dirtyComponent); final Component dirtyComponent = roots.get(j);
// Sometimes when RepaintManager is changed during the painting AccessControlContext stack = AccessController.getContext();
// we may get null here, see #6995769 for details AccessControlContext acc =
if (rect == null) { AWTAccessor.getComponentAccessor().getAccessControlContext(dirtyComponent);
continue; javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Void>() {
} public Void run() {
localBoundsH = dirtyComponent.getHeight(); Rectangle rect = tmpDirtyComponents.get(dirtyComponent);
localBoundsW = dirtyComponent.getWidth(); // Sometimes when RepaintManager is changed during the painting
// we may get null here, see #6995769 for details
SwingUtilities.computeIntersection(localBoundsX, if (rect == null) {
localBoundsY, return null;
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();
} }
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;
} }
} }, stack, acc);
// 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;
}
} }
} finally { } finally {
painting = false; painting = false;

View File

@ -677,6 +677,8 @@ public class UIDefaults extends Hashtable<Object,Object>
try { try {
String className = (String)get(uiClassID); String className = (String)get(uiClassID);
if (className != null) { if (className != null) {
ReflectUtil.checkPackageAccess(className);
Class cls = (Class)get(className); Class cls = (Class)get(className);
if (cls == null) { if (cls == null) {
if (uiClassLoader == null) { if (uiClassLoader == null) {

View File

@ -159,7 +159,12 @@ public class NimbusLookAndFeel extends SynthLookAndFeel {
// Store Table ScrollPane Corner Component // Store Table ScrollPane Corner Component
uiDefaults.put("Table.scrollPaneCornerComponent", 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 // Setup the settings for ToolBarSeparator which is custom
// installed for Nimbus // installed for Nimbus

View File

@ -45,6 +45,7 @@ import java.util.*;
import java.util.Collections; import java.util.Collections;
import java.util.Locale; import java.util.Locale;
import java.util.WeakHashMap; import java.util.WeakHashMap;
import sun.awt.AWTAccessor;
import sun.awt.AppContext; import sun.awt.AppContext;
import sun.awt.EmbeddedFrame; import sun.awt.EmbeddedFrame;
import sun.awt.SunToolkit; import sun.awt.SunToolkit;
@ -448,12 +449,12 @@ abstract class AppletPanel extends Panel implements AppletStub, Runnable {
// to avoid deadlock. // to avoid deadlock.
try { try {
final AppletPanel p = this; final AppletPanel p = this;
Runnable r = new Runnable() {
EventQueue.invokeAndWait(new Runnable() { public void run() {
public void run() { p.validate();
p.validate(); }
} };
}); AWTAccessor.getEventQueueAccessor().invokeAndWait(applet, r);
} }
catch(InterruptedException ie) { catch(InterruptedException ie) {
} }
@ -478,18 +479,19 @@ abstract class AppletPanel extends Panel implements AppletStub, Runnable {
try { try {
final AppletPanel p = this; final AppletPanel p = this;
final Applet a = applet; final Applet a = applet;
Runnable r = new Runnable() {
public void run() {
p.validate();
a.setVisible(true);
EventQueue.invokeAndWait(new Runnable() { // Fix for BugTraq ID 4041703.
public void run() { // Set the default focus for an applet.
p.validate(); if (hasInitialFocus()) {
a.setVisible(true); setDefaultFocus();
// Fix for BugTraq ID 4041703.
// Set the default focus for an applet.
if (hasInitialFocus())
setDefaultFocus();
} }
}); }
};
AWTAccessor.getEventQueueAccessor().invokeAndWait(applet, r);
} }
catch(InterruptedException ie) { catch(InterruptedException ie) {
} }
@ -512,13 +514,12 @@ abstract class AppletPanel extends Panel implements AppletStub, Runnable {
// to avoid deadlock. // to avoid deadlock.
try { try {
final Applet a = applet; final Applet a = applet;
Runnable r = new Runnable() {
EventQueue.invokeAndWait(new Runnable() { public void run() {
public void run() a.setVisible(false);
{ }
a.setVisible(false); };
} AWTAccessor.getEventQueueAccessor().invokeAndWait(applet, r);
});
} }
catch(InterruptedException ie) { catch(InterruptedException ie) {
} }
@ -570,17 +571,14 @@ abstract class AppletPanel extends Panel implements AppletStub, Runnable {
} }
status = APPLET_DISPOSE; status = APPLET_DISPOSE;
try try {
{
final Applet a = applet; final Applet a = applet;
Runnable r = new Runnable() {
EventQueue.invokeAndWait(new Runnable() public void run() {
{
public void run()
{
remove(a); remove(a);
} }
}); };
AWTAccessor.getEventQueueAccessor().invokeAndWait(applet, r);
} }
catch(InterruptedException ie) catch(InterruptedException ie)
{ {

View File

@ -34,6 +34,8 @@ import java.awt.event.InputEvent;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import java.awt.geom.Point2D; import java.awt.geom.Point2D;
import java.awt.peer.ComponentPeer; import java.awt.peer.ComponentPeer;
import java.lang.reflect.InvocationTargetException;
import java.security.AccessControlContext; import java.security.AccessControlContext;
import java.io.File; import java.io.File;
@ -476,6 +478,12 @@ public final class AWTAccessor {
* appeared. * appeared.
*/ */
void wakeup(EventQueue eventQueue, boolean isShutdown); void wakeup(EventQueue eventQueue, boolean isShutdown);
/**
* Static in EventQueue
*/
void invokeAndWait(Object source, Runnable r)
throws InterruptedException, InvocationTargetException;
} }
/* /*

View File

@ -327,21 +327,27 @@ public final class AppContext {
// Before we return the main "system" AppContext, check to // Before we return the main "system" AppContext, check to
// see if there's an AWTSecurityManager installed. If so, // see if there's an AWTSecurityManager installed. If so,
// allow it to choose the AppContext to return. // allow it to choose the AppContext to return.
SecurityManager securityManager = System.getSecurityManager(); AppContext secAppContext = getExecutionAppContext();
if ((securityManager != null) && if (secAppContext != null) {
(securityManager instanceof AWTSecurityManager)) appContext = secAppContext; // Return what we're told
{
AWTSecurityManager awtSecMgr = (AWTSecurityManager)securityManager;
AppContext secAppContext = awtSecMgr.getAppContext();
if (secAppContext != null) {
appContext = secAppContext; // Return what we're told
}
} }
} }
return appContext; 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. * Returns the main ("system") AppContext.
* *
@ -806,6 +812,21 @@ public final class AppContext {
public boolean isMainAppContext() { public boolean isMainAppContext() {
return (numAppContexts.get() == 1); 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);
}
}); });
} }
} }

View File

@ -198,7 +198,7 @@ public class ByteComponentRaster extends SunWritableRaster {
} }
this.bandOffset = this.dataOffsets[0]; 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 * Verify that the layout parameters are consistent with the data.
* the data. If strictCheck *
* is false, this method will check for ArrayIndexOutOfBounds conditions. If * The method verifies whether scanline stride and pixel stride do not
* strictCheck is true, this method will check for additional error * cause an integer overflow during calculation of a position of the pixel
* conditions such as line wraparound (width of a line greater than * in data buffer. It also verifies whether the data buffer has enough data
* the scanline stride). * to correspond the raster layout attributes.
* @return String Error string, if the layout is incompatible with *
* the data. Otherwise returns null. * @throws RasterFormatException if an integer overflow is detected,
* or if data buffer has not enough capacity.
*/ */
private void verify (boolean strictCheck) { protected final void verify() {
// Make sure data for Raster is in a legal range for (int i = 0; i < dataOffsets.length; i++) {
for (int i=0; i < dataOffsets.length; i++) {
if (dataOffsets[i] < 0) { if (dataOffsets[i] < 0) {
throw new RasterFormatException("Data offsets for band "+i+ throw new RasterFormatException("Data offsets for band " + i
"("+dataOffsets[i]+ + "(" + dataOffsets[i]
") must be >= 0"); + ") must be >= 0");
} }
} }
int maxSize = 0; int maxSize = 0;
int size; int size;
for (int i=0; i < numDataElements; i++) { // we can be sure that width and height are greater than 0
size = (height-1)*scanlineStride + (width-1)*pixelStride + if (scanlineStride < 0 ||
dataOffsets[i]; 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) { if (size > maxSize) {
maxSize = size; maxSize = size;
} }
} }
if (data.length < maxSize) { if (data.length < maxSize) {
throw new RasterFormatException("Data array too small (should be "+ throw new RasterFormatException("Data array too small (should be "
maxSize+" )"); + maxSize + " )");
} }
} }

View File

@ -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); 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() { public String toString() {
return new String ("ByteInterleavedRaster: width = "+width+" height = " return new String ("ByteInterleavedRaster: width = "+width+" height = "
+ height + height

View File

@ -198,7 +198,7 @@ public class ShortComponentRaster extends SunWritableRaster {
} }
this.bandOffset = this.dataOffsets[0]; 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 * Verify that the layout parameters are consistent with the data.
* the data. If strictCheck *
* is false, this method will check for ArrayIndexOutOfBounds conditions. If * The method verifies whether scanline stride and pixel stride do not
* strictCheck is true, this method will check for additional error * cause an integer overflow during calculation of a position of the pixel
* conditions such as line wraparound (width of a line greater than * in data buffer. It also verifies whether the data buffer has enough data
* the scanline stride). * to correspond the raster layout attributes.
* @return String Error string, if the layout is incompatible with *
* the data. Otherwise returns null. * @throws RasterFormatException if an integer overflow is detected,
* or if data buffer has not enough capacity.
*/ */
private void verify (boolean strictCheck) { protected final void verify() {
// Make sure data for Raster is in a legal range for (int i = 0; i < dataOffsets.length; i++) {
for (int i=0; i < dataOffsets.length; i++) {
if (dataOffsets[i] < 0) { if (dataOffsets[i] < 0) {
throw new RasterFormatException("Data offsets for band "+i+ throw new RasterFormatException("Data offsets for band " + i
"("+dataOffsets[i]+ + "(" + dataOffsets[i]
") must be >= 0"); + ") must be >= 0");
} }
} }
int maxSize = 0; int maxSize = 0;
int size; int size;
for (int i=0; i < numDataElements; i++) { // we can be sure that width and height are greater than 0
size = (height-1)*scanlineStride + (width-1)*pixelStride + if (scanlineStride < 0 ||
dataOffsets[i]; 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) { if (size > maxSize) {
maxSize = size; maxSize = size;
} }
} }
if (data.length < maxSize) { if (data.length < maxSize) {
throw new RasterFormatException("Data array too small (should be "+ throw new RasterFormatException("Data array too small (should be "
maxSize+" )"); + maxSize + " )");
} }
} }

View File

@ -171,7 +171,7 @@ public class ShortInterleavedRaster extends ShortComponentRaster {
sampleModel); sampleModel);
} }
this.bandOffset = this.dataOffsets[0]; this.bandOffset = this.dataOffsets[0];
verify(false); verify();
} }
/** /**
@ -762,33 +762,6 @@ public class ShortInterleavedRaster extends ShortComponentRaster {
return createCompatibleWritableRaster(width,height); 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() { public String toString() {
return new String ("ShortInterleavedRaster: width = "+width return new String ("ShortInterleavedRaster: width = "+width
+" height = " + height +" height = " + height

View File

@ -26,6 +26,14 @@
package sun.misc; package sun.misc;
public interface JavaAWTAccess { 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 Object get(Object key);
public void put(Object key, Object value); public void put(Object key, Object value);
public void remove(Object key); public void remove(Object key);

View File

@ -41,8 +41,12 @@ class ChunkedInputStream extends LeftOverInputStream {
private boolean needToReadHeader = true; private boolean needToReadHeader = true;
static char CR = '\r'; final static char CR = '\r';
static char LF = '\n'; 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 { private int numeric (char[] arr, int nchars) throws IOException {
assert arr.length >= nchars; assert arr.length >= nchars;
@ -73,10 +77,14 @@ class ChunkedInputStream extends LeftOverInputStream {
char[] len_arr = new char [16]; char[] len_arr = new char [16];
int len_size = 0; int len_size = 0;
boolean end_of_len = false; boolean end_of_len = false;
int read = 0;
while ((c=in.read())!= -1) { while ((c=in.read())!= -1) {
char ch = (char) c; 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"); throw new IOException ("invalid chunk header");
} }
if (gotCR) { if (gotCR) {

View File

@ -125,6 +125,11 @@ class ChunkedInputStream extends InputStream implements Hurryable {
*/ */
private boolean closed; 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 :- * State to indicate that next field should be :-
* chunk-size [ chunk-extension ] CRLF * chunk-size [ chunk-extension ] CRLF
@ -290,6 +295,10 @@ class ChunkedInputStream extends InputStream implements Hurryable {
break; break;
} }
pos++; pos++;
if ((pos - rawPos) >= MAX_CHUNK_HEADER_SIZE) {
error = true;
throw new IOException("Chunk header too long");
}
} }
if (pos >= rawCount) { if (pos >= rawCount) {
return; return;

View File

@ -421,7 +421,7 @@ class DatagramChannelImpl
synchronized (writeLock) { synchronized (writeLock) {
ensureOpen(); ensureOpen();
InetSocketAddress isa = (InetSocketAddress)target; InetSocketAddress isa = Net.checkAddress(target);
InetAddress ia = isa.getAddress(); InetAddress ia = isa.getAddress();
if (ia == null) if (ia == null)
throw new IOException("Target address not resolved"); throw new IOException("Target address not resolved");
@ -432,9 +432,9 @@ class DatagramChannelImpl
SecurityManager sm = System.getSecurityManager(); SecurityManager sm = System.getSecurityManager();
if (sm != null) { if (sm != null) {
if (ia.isMulticastAddress()) { if (ia.isMulticastAddress()) {
sm.checkMulticast(isa.getAddress()); sm.checkMulticast(ia);
} else { } else {
sm.checkConnect(isa.getAddress().getHostAddress(), sm.checkConnect(ia.getHostAddress(),
isa.getPort()); isa.getPort());
} }
} }
@ -454,7 +454,7 @@ class DatagramChannelImpl
return 0; return 0;
writerThread = NativeThread.current(); writerThread = NativeThread.current();
do { do {
n = send(fd, src, target); n = send(fd, src, isa);
} while ((n == IOStatus.INTERRUPTED) && isOpen()); } while ((n == IOStatus.INTERRUPTED) && isOpen());
synchronized (stateLock) { 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 throws IOException
{ {
if (src instanceof DirectBuffer) if (src instanceof DirectBuffer)
@ -502,7 +502,7 @@ class DatagramChannelImpl
} }
private int sendFromNativeBuffer(FileDescriptor fd, ByteBuffer bb, private int sendFromNativeBuffer(FileDescriptor fd, ByteBuffer bb,
SocketAddress target) InetSocketAddress target)
throws IOException throws IOException
{ {
int pos = bb.position(); int pos = bb.position();
@ -514,7 +514,7 @@ class DatagramChannelImpl
int written; int written;
try { try {
written = send0(preferIPv6, fd, ((DirectBuffer)bb).address() + pos, written = send0(preferIPv6, fd, ((DirectBuffer)bb).address() + pos,
rem, target); rem, target.getAddress(), target.getPort());
} catch (PortUnreachableException pue) { } catch (PortUnreachableException pue) {
if (isConnected()) if (isConnected())
throw pue; throw pue;
@ -1116,8 +1116,8 @@ class DatagramChannelImpl
boolean connected) boolean connected)
throws IOException; throws IOException;
private native int send0(boolean preferIPv6, FileDescriptor fd, long address, int len, private native int send0(boolean preferIPv6, FileDescriptor fd, long address,
SocketAddress sa) int len, InetAddress addr, int port)
throws IOException; throws IOException;
static { static {

View File

@ -178,4 +178,29 @@ public final class ReflectUtil {
return !isAncestor(from, to); 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";
} }

View File

@ -153,7 +153,7 @@ public final class CGIHandler {
returnServerError(e.getMessage()); returnServerError(e.getMessage());
} }
else else
returnClientError("invalid command: " + command); returnClientError("invalid command.");
} catch (Exception e) { } catch (Exception e) {
returnServerError("internal error: " + e.getMessage()); returnServerError("internal error: " + e.getMessage());
} }
@ -225,7 +225,7 @@ final class CGIForwardCommand implements CGICommandHandler {
try { try {
port = Integer.parseInt(param); port = Integer.parseInt(param);
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
throw new CGIClientException("invalid port number: " + param); throw new CGIClientException("invalid port number.");
} }
if (port <= 0 || port > 0xFFFF) if (port <= 0 || port > 0xFFFF)
throw new CGIClientException("invalid port: " + port); throw new CGIClientException("invalid port: " + port);
@ -293,11 +293,14 @@ final class CGIForwardCommand implements CGICommandHandler {
"unexpected EOF reading server response"); "unexpected EOF reading server response");
if (line.toLowerCase().startsWith(key)) { if (line.toLowerCase().startsWith(key)) {
// if contentLengthFound is true if (contentLengthFound) {
// we should probably do something here throw new CGIServerException(
responseContentLength = "Multiple Content-length entries found.");
Integer.parseInt(line.substring(key.length()).trim()); } else {
contentLengthFound = true; responseContentLength =
Integer.parseInt(line.substring(key.length()).trim());
contentLengthFound = true;
}
} }
} while ((line.length() != 0) && } while ((line.length() != 0) &&
(line.charAt(0) != '\r') && (line.charAt(0) != '\n')); (line.charAt(0) != '\r') && (line.charAt(0) != '\n'));

View File

@ -70,11 +70,14 @@ class HttpInputStream extends FilterInputStream {
throw new EOFException(); throw new EOFException();
if (line.toLowerCase().startsWith(key)) { if (line.toLowerCase().startsWith(key)) {
// if contentLengthFound is true if (contentLengthFound) {
// we should probably do something here throw new IOException(
bytesLeft = "Multiple Content-length entries found.");
Integer.parseInt(line.substring(key.length()).trim()); } else {
contentLengthFound = true; bytesLeft =
Integer.parseInt(line.substring(key.length()).trim());
contentLengthFound = true;
}
} }
// The idea here is to go past the first blank line. // The idea here is to go past the first blank line.

View File

@ -37,6 +37,7 @@ import javax.crypto.spec.*;
import static sun.security.pkcs11.TemplateManager.*; import static sun.security.pkcs11.TemplateManager.*;
import sun.security.pkcs11.wrapper.*; import sun.security.pkcs11.wrapper.*;
import static sun.security.pkcs11.wrapper.PKCS11Constants.*; import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
import sun.security.util.KeyUtil;
/** /**
* KeyAgreement implementation class. This class currently supports * KeyAgreement implementation class. This class currently supports
@ -134,6 +135,10 @@ final class P11KeyAgreement extends KeyAgreementSpi {
BigInteger p, g, y; BigInteger p, g, y;
if (key instanceof DHPublicKey) { if (key instanceof DHPublicKey) {
DHPublicKey dhKey = (DHPublicKey)key; DHPublicKey dhKey = (DHPublicKey)key;
// validate the Diffie-Hellman public key
KeyUtil.validate(dhKey);
y = dhKey.getY(); y = dhKey.getY();
DHParameterSpec params = dhKey.getParams(); DHParameterSpec params = dhKey.getParams();
p = params.getP(); p = params.getP();
@ -145,6 +150,10 @@ final class P11KeyAgreement extends KeyAgreementSpi {
try { try {
DHPublicKeySpec spec = kf.engineGetKeySpec( DHPublicKeySpec spec = kf.engineGetKeySpec(
key, DHPublicKeySpec.class); key, DHPublicKeySpec.class);
// validate the Diffie-Hellman public key
KeyUtil.validate(spec);
y = spec.getY(); y = spec.getY();
p = spec.getP(); p = spec.getP();
g = spec.getG(); g = spec.getG();

View File

@ -129,9 +129,8 @@ final class ClientHandshaker extends Handshaker {
*/ */
@Override @Override
void processMessage(byte type, int messageLen) throws IOException { void processMessage(byte type, int messageLen) throws IOException {
if (state > type if (state >= type
&& (type != HandshakeMessage.ht_hello_request && (type != HandshakeMessage.ht_hello_request)) {
&& state != HandshakeMessage.ht_client_hello)) {
throw new SSLProtocolException( throw new SSLProtocolException(
"Handshake message sequence violation, " + type); "Handshake message sequence violation, " + type);
} }
@ -194,8 +193,12 @@ final class ClientHandshaker extends Handshaker {
} }
break; break;
case K_DH_ANON: case K_DH_ANON:
this.serverKeyExchange(new DH_ServerKeyExchange( try {
this.serverKeyExchange(new DH_ServerKeyExchange(
input, protocolVersion)); input, protocolVersion));
} catch (GeneralSecurityException e) {
throwSSLException("Server key", e);
}
break; break;
case K_DHE_DSS: case K_DHE_DSS:
case K_DHE_RSA: case K_DHE_RSA:
@ -921,7 +924,7 @@ final class ClientHandshaker extends Handshaker {
case K_DHE_RSA: case K_DHE_RSA:
case K_DHE_DSS: case K_DHE_DSS:
case K_DH_ANON: case K_DH_ANON:
preMasterSecret = dh.getAgreedSecret(serverDH); preMasterSecret = dh.getAgreedSecret(serverDH, true);
break; break;
case K_ECDHE_RSA: case K_ECDHE_RSA:
case K_ECDHE_ECDSA: case K_ECDHE_ECDSA:

View File

@ -1,5 +1,5 @@
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -29,7 +29,7 @@ package sun.security.ssl;
import java.io.IOException; import java.io.IOException;
import java.io.PrintStream; import java.io.PrintStream;
import java.math.BigInteger; import java.math.BigInteger;
import javax.net.ssl.SSLHandshakeException;
/* /*
* Message used by clients to send their Diffie-Hellman public * 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 private byte dh_Yc[]; // 1 to 2^16 -1 bytes
BigInteger getClientPublicKey() { 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.) * but that's what the protocol spec requires.)
*/ */
DHClientKeyExchange(HandshakeInStream input) throws IOException { 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 @Override
@ -87,7 +94,9 @@ final class DHClientKeyExchange extends HandshakeMessage {
@Override @Override
void send(HandshakeOutStream s) throws IOException { void send(HandshakeOutStream s) throws IOException {
s.putBytes16(dh_Yc); if (dh_Yc != null && dh_Yc.length != 0) {
s.putBytes16(dh_Yc);
}
} }
@Override @Override

View File

@ -1,5 +1,5 @@
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -28,12 +28,15 @@ package sun.security.ssl;
import java.math.BigInteger; import java.math.BigInteger;
import java.security.*; import java.security.*;
import java.io.IOException;
import javax.net.ssl.SSLHandshakeException;
import javax.crypto.SecretKey; import javax.crypto.SecretKey;
import javax.crypto.KeyAgreement; import javax.crypto.KeyAgreement;
import javax.crypto.interfaces.DHPublicKey; import javax.crypto.interfaces.DHPublicKey;
import javax.crypto.spec.*; import javax.crypto.spec.*;
import sun.security.util.KeyUtil;
/** /**
* This class implements the Diffie-Hellman key exchange algorithm. * This class implements the Diffie-Hellman key exchange algorithm.
* D-H means combining your private key with your partners public key to * 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 * . if we are server, call DHCrypt(keyLength,random). This generates
* an ephemeral keypair of the request length. * an ephemeral keypair of the request length.
* . if we are client, call DHCrypt(modulus, base, random). This * . 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 * . send parameters and public value to remote peer
* . receive peers ephemeral public key * . receive peers ephemeral public key
* . call getAgreedSecret() to calculate the shared secret * . call getAgreedSecret() to calculate the shared secret
@ -83,6 +87,9 @@ final class DHCrypt {
// public component of our key, X = (g ^ x) mod p // public component of our key, X = (g ^ x) mod p
private BigInteger publicValue; // X (aka y) 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. * Generate a Diffie-Hellman keypair of the specified size.
*/ */
@ -90,9 +97,12 @@ final class DHCrypt {
try { try {
KeyPairGenerator kpg = JsseJce.getKeyPairGenerator("DiffieHellman"); KeyPairGenerator kpg = JsseJce.getKeyPairGenerator("DiffieHellman");
kpg.initialize(keyLength, random); kpg.initialize(keyLength, random);
KeyPair kp = kpg.generateKeyPair();
privateKey = kp.getPrivate(); DHPublicKeySpec spec = generateDHPublicKeySpec(kpg);
DHPublicKeySpec spec = getDHPublicKeySpec(kp.getPublic()); if (spec == null) {
throw new RuntimeException("Could not generate DH keypair");
}
publicValue = spec.getY(); publicValue = spec.getY();
modulus = spec.getP(); modulus = spec.getP();
base = spec.getG(); base = spec.getG();
@ -115,20 +125,25 @@ final class DHCrypt {
KeyPairGenerator kpg = JsseJce.getKeyPairGenerator("DiffieHellman"); KeyPairGenerator kpg = JsseJce.getKeyPairGenerator("DiffieHellman");
DHParameterSpec params = new DHParameterSpec(modulus, base); DHParameterSpec params = new DHParameterSpec(modulus, base);
kpg.initialize(params, random); kpg.initialize(params, random);
KeyPair kp = kpg.generateKeyPair();
privateKey = kp.getPrivate(); DHPublicKeySpec spec = generateDHPublicKeySpec(kpg);
DHPublicKeySpec spec = getDHPublicKeySpec(kp.getPublic()); if (spec == null) {
throw new RuntimeException("Could not generate DH keypair");
}
publicValue = spec.getY(); publicValue = spec.getY();
} catch (GeneralSecurityException e) { } catch (GeneralSecurityException e) {
throw new RuntimeException("Could not generate DH keypair", e); throw new RuntimeException("Could not generate DH keypair", e);
} }
} }
static DHPublicKeySpec getDHPublicKeySpec(PublicKey key) { static DHPublicKeySpec getDHPublicKeySpec(PublicKey key) {
if (key instanceof DHPublicKey) { if (key instanceof DHPublicKey) {
DHPublicKey dhKey = (DHPublicKey)key; DHPublicKey dhKey = (DHPublicKey)key;
DHParameterSpec params = dhKey.getParams(); DHParameterSpec params = dhKey.getParams();
return new DHPublicKeySpec(dhKey.getY(), params.getP(), params.getG()); return new DHPublicKeySpec(dhKey.getY(),
params.getP(), params.getG());
} }
try { try {
KeyFactory factory = JsseJce.getKeyFactory("DH"); 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 * <P>It is illegal to call this member function if the private key
* has not been set (or generated). * has not been set (or generated).
* *
* @param peerPublicKey the peer's public key. * @param peerPublicKey the peer's public key.
* @returns the secret, which is an unsigned big-endian integer * @param keyIsValidated whether the {@code peerPublicKey} has beed
* the same size as the Diffie-Hellman modulus. * 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 { try {
KeyFactory kf = JsseJce.getKeyFactory("DiffieHellman"); KeyFactory kf = JsseJce.getKeyFactory("DiffieHellman");
DHPublicKeySpec spec = DHPublicKeySpec spec =
new DHPublicKeySpec(peerPublicValue, modulus, base); new DHPublicKeySpec(peerPublicValue, modulus, base);
PublicKey publicKey = kf.generatePublic(spec); PublicKey publicKey = kf.generatePublic(spec);
KeyAgreement ka = JsseJce.getKeyAgreement("DiffieHellman"); 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.init(privateKey);
ka.doPhase(publicKey, true); ka.doPhase(publicKey, true);
return ka.generateSecret("TlsPremasterSecret"); 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;
}
} }

View File

@ -41,12 +41,14 @@ import javax.security.auth.x500.X500Principal;
import javax.crypto.KeyGenerator; import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey; import javax.crypto.SecretKey;
import javax.crypto.spec.DHPublicKeySpec;
import javax.net.ssl.*; import javax.net.ssl.*;
import sun.security.internal.spec.TlsPrfParameterSpec; import sun.security.internal.spec.TlsPrfParameterSpec;
import sun.security.ssl.CipherSuite.*; import sun.security.ssl.CipherSuite.*;
import static sun.security.ssl.CipherSuite.PRF.*; import static sun.security.ssl.CipherSuite.PRF.*;
import sun.security.util.KeyUtil;
/** /**
* Many data structures are involved in the handshake messages. These * Many data structures are involved in the handshake messages. These
@ -712,6 +714,7 @@ class DH_ServerKeyExchange extends ServerKeyExchange
this.protocolVersion = protocolVersion; this.protocolVersion = protocolVersion;
this.preferableSignatureAlgorithm = null; this.preferableSignatureAlgorithm = null;
// The DH key has been validated in the constructor of DHCrypt.
setValues(obj); setValues(obj);
signature = null; signature = null;
} }
@ -728,6 +731,7 @@ class DH_ServerKeyExchange extends ServerKeyExchange
this.protocolVersion = protocolVersion; this.protocolVersion = protocolVersion;
// The DH key has been validated in the constructor of DHCrypt.
setValues(obj); setValues(obj);
Signature sig; Signature sig;
@ -754,7 +758,8 @@ class DH_ServerKeyExchange extends ServerKeyExchange
* DH_anon key exchange * DH_anon key exchange
*/ */
DH_ServerKeyExchange(HandshakeInStream input, DH_ServerKeyExchange(HandshakeInStream input,
ProtocolVersion protocolVersion) throws IOException { ProtocolVersion protocolVersion)
throws IOException, GeneralSecurityException {
this.protocolVersion = protocolVersion; this.protocolVersion = protocolVersion;
this.preferableSignatureAlgorithm = null; this.preferableSignatureAlgorithm = null;
@ -762,6 +767,10 @@ class DH_ServerKeyExchange extends ServerKeyExchange
dh_p = input.getBytes16(); dh_p = input.getBytes16();
dh_g = input.getBytes16(); dh_g = input.getBytes16();
dh_Ys = 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; signature = null;
} }
@ -782,6 +791,9 @@ class DH_ServerKeyExchange extends ServerKeyExchange
dh_p = input.getBytes16(); dh_p = input.getBytes16();
dh_g = input.getBytes16(); dh_g = input.getBytes16();
dh_Ys = 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 // read the signature and hash algorithm
if (protocolVersion.v >= ProtocolVersion.TLS12.v) { if (protocolVersion.v >= ProtocolVersion.TLS12.v) {

View File

@ -34,7 +34,7 @@ import javax.crypto.*;
import javax.net.ssl.*; import javax.net.ssl.*;
import sun.security.internal.spec.TlsRsaPremasterSecretParameterSpec; 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 * 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"); "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 (keySize > 0 && keySize != 384) { // 384 = 48 * 8
if (debug != null && Debug.isOn("handshake")) { if (debug != null && Debug.isOn("handshake")) {
System.out.println( System.out.println(

View File

@ -150,7 +150,7 @@ final class ServerHandshaker extends Handshaker {
// In SSLv3 and TLS, messages follow strictly increasing // In SSLv3 and TLS, messages follow strictly increasing
// numerical order _except_ for one annoying special case. // numerical order _except_ for one annoying special case.
// //
if ((state > type) if ((state >= type)
&& (state != HandshakeMessage.ht_client_key_exchange && (state != HandshakeMessage.ht_client_key_exchange
&& type != HandshakeMessage.ht_certificate_verify)) { && type != HandshakeMessage.ht_certificate_verify)) {
throw new SSLProtocolException( throw new SSLProtocolException(
@ -250,13 +250,15 @@ final class ServerHandshaker extends Handshaker {
} }
// //
// Move the state machine forward except for that annoying // Move state machine forward if the message handling
// special case. This means that clients could send extra // code didn't already do so
// cert verify messages; not a problem so long as all of
// them actually check out.
// //
if (state < type && type != HandshakeMessage.ht_certificate_verify) { if (state < type) {
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")) { if (debug != null && Debug.isOn("handshake")) {
mesg.print(System.out); mesg.print(System.out);
} }
return dh.getAgreedSecret(mesg.getClientPublicKey()); return dh.getAgreedSecret(mesg.getClientPublicKey(), false);
} }
private SecretKey clientKeyExchange(ECDHClientKeyExchange mesg) private SecretKey clientKeyExchange(ECDHClientKeyExchange mesg)

View File

@ -38,7 +38,7 @@ import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.ArrayList; import java.util.ArrayList;
import sun.security.util.KeyLength; import sun.security.util.KeyUtil;
/** /**
* Signature and hash algorithm. * Signature and hash algorithm.
@ -274,7 +274,7 @@ final class SignatureAndHashAlgorithm {
* If key size is less than 512, the digest length should be * If key size is less than 512, the digest length should be
* less than or equal to 20 bytes. * less than or equal to 20 bytes.
*/ */
int keySize = KeyLength.getKeySize(signingKey); int keySize = KeyUtil.getKeySize(signingKey);
if (keySize >= 768) { if (keySize >= 768) {
maxDigestLength = HashAlgorithm.SHA512.length; maxDigestLength = HashAlgorithm.SHA512.length;
} else if ((keySize >= 512) && (keySize < 768)) { } else if ((keySize >= 512) && (keySize < 768)) {

View File

@ -325,6 +325,10 @@ class DerIndefLenConverter {
} }
} }
if (unresolved != 0) {
throw new IOException("not all indef len BER resolved");
}
newData = new byte[dataSize + numOfTotalLenBytes + unused]; newData = new byte[dataSize + numOfTotalLenBytes + unused];
dataPos=0; newDataPos=0; index=0; dataPos=0; newDataPos=0; index=0;

View File

@ -440,7 +440,7 @@ public class DisabledAlgorithmConstraints implements AlgorithmConstraints {
// Does this key constraint disable the specified key? // Does this key constraint disable the specified key?
public boolean disables(Key key) { public boolean disables(Key key) {
int size = KeyLength.getKeySize(key); int size = KeyUtil.getKeySize(key);
if (size == 0) { if (size == 0) {
return true; // we don't allow any key of size 0. return true; // we don't allow any key of size 0.

View File

@ -1,91 +0,0 @@
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.util;
import java.security.Key;
import java.security.PrivilegedAction;
import java.security.AccessController;
import java.security.interfaces.ECKey;
import java.security.interfaces.RSAKey;
import java.security.interfaces.DSAKey;
import javax.crypto.SecretKey;
import javax.crypto.interfaces.DHKey;
/**
* A utility class to get key length
*/
public final class KeyLength {
/**
* Returns the key size of the given key object in bits.
*
* @param key the key object, cannot be null
* @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) {
int size = -1;
if (key instanceof Length) {
try {
Length ruler = (Length)key;
size = ruler.length();
} catch (UnsupportedOperationException usoe) {
// ignore the exception
}
if (size >= 0) {
return size;
}
}
// try to parse the length from key specification
if (key instanceof SecretKey) {
SecretKey sk = (SecretKey)key;
String format = sk.getFormat();
if ("RAW".equals(format) && sk.getEncoded() != null) {
size = (sk.getEncoded().length * 8);
} // Otherwise, it may be a unextractable key of PKCS#11, or
// a key we are not able to handle.
} else if (key instanceof RSAKey) {
RSAKey pubk = (RSAKey)key;
size = pubk.getModulus().bitLength();
} else if (key instanceof ECKey) {
ECKey pubk = (ECKey)key;
size = pubk.getParams().getOrder().bitLength();
} else if (key instanceof DSAKey) {
DSAKey pubk = (DSAKey)key;
size = pubk.getParams().getP().bitLength();
} else if (key instanceof DHKey) {
DHKey pubk = (DHKey)key;
size = pubk.getParams().getP().bitLength();
} // Otherwise, it may be a unextractable key of PKCS#11, or
// a key we are not able to handle.
return size;
}
}

View File

@ -0,0 +1,204 @@
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.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, valiate keys, etc.
*/
public final class KeyUtil {
/**
* Returns the key size of the given key object in bits.
*
* @param key the key object, cannot be null
* @return the key size of the given key object in bits, or -1 if the
* key size is not accessible
*/
public static final int getKeySize(Key key) {
int size = -1;
if (key instanceof Length) {
try {
Length ruler = (Length)key;
size = ruler.length();
} catch (UnsupportedOperationException usoe) {
// ignore the exception
}
if (size >= 0) {
return size;
}
}
// try to parse the length from key specification
if (key instanceof SecretKey) {
SecretKey sk = (SecretKey)key;
String format = sk.getFormat();
if ("RAW".equals(format) && sk.getEncoded() != null) {
size = (sk.getEncoded().length * 8);
} // Otherwise, it may be a unextractable key of PKCS#11, or
// a key we are not able to handle.
} else if (key instanceof RSAKey) {
RSAKey pubk = (RSAKey)key;
size = pubk.getModulus().bitLength();
} else if (key instanceof ECKey) {
ECKey pubk = (ECKey)key;
size = pubk.getParams().getOrder().bitLength();
} else if (key instanceof DSAKey) {
DSAKey pubk = (DSAKey)key;
size = pubk.getParams().getP().bitLength();
} else if (key instanceof DHKey) {
DHKey pubk = (DHKey)key;
size = pubk.getParams().getP().bitLength();
} // Otherwise, it may be a unextractable key of PKCS#11, or
// a key we are not able to handle.
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.
}
}

View File

@ -145,7 +145,19 @@ keystore.type=jks
# passed to checkPackageAccess unless the # passed to checkPackageAccess unless the
# corresponding RuntimePermission ("accessClassInPackage."+package) has # corresponding RuntimePermission ("accessClassInPackage."+package) has
# been granted. # 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 # 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 # by default, none of the class loaders supplied with the JDK call
# checkPackageDefinition. # 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 # Determines whether this properties file can be appended to

View File

@ -146,7 +146,20 @@ keystore.type=jks
# passed to checkPackageAccess unless the # passed to checkPackageAccess unless the
# corresponding RuntimePermission ("accessClassInPackage."+package) has # corresponding RuntimePermission ("accessClassInPackage."+package) has
# been granted. # 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 # 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 # by default, none of the class loaders supplied with the JDK call
# checkPackageDefinition. # 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 # Determines whether this properties file can be appended to

View File

@ -147,7 +147,19 @@ keystore.type=jks
# passed to checkPackageAccess unless the # passed to checkPackageAccess unless the
# corresponding RuntimePermission ("accessClassInPackage."+package) has # corresponding RuntimePermission ("accessClassInPackage."+package) has
# been granted. # 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 # 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 # by default, none of the class loaders supplied with the JDK call
# checkPackageDefinition. # 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 # Determines whether this properties file can be appended to

View File

@ -146,7 +146,19 @@ keystore.type=jks
# passed to checkPackageAccess unless the # passed to checkPackageAccess unless the
# corresponding RuntimePermission ("accessClassInPackage."+package) has # corresponding RuntimePermission ("accessClassInPackage."+package) has
# been granted. # 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 # 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 # by default, none of the class loaders supplied with the JDK call
# checkPackageDefinition. # 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 # Determines whether this properties file can be appended to

View File

@ -187,6 +187,10 @@ void band::setIndexByTag(byte tag) {
entry* band::getRefCommon(cpindex* ix_, bool nullOKwithCaller) { entry* band::getRefCommon(cpindex* ix_, bool nullOKwithCaller) {
CHECK_0; CHECK_0;
if (ix_ == NULL) {
abort("no index");
return NULL;
}
assert(ix_->ixTag == ixTag assert(ix_->ixTag == ixTag
|| ((ixTag == CONSTANT_All || || ((ixTag == CONSTANT_All ||
ixTag == CONSTANT_LoadableValue || ixTag == CONSTANT_LoadableValue ||

View File

@ -99,8 +99,8 @@ struct band {
int getByte() { assert(ix == null); return vs[0].getByte(); } int getByte() { assert(ix == null); return vs[0].getByte(); }
int getInt() { assert(ix == null); return vs[0].getInt(); } int getInt() { assert(ix == null); return vs[0].getInt(); }
entry* getRefN() { assert(ix != null); return getRefCommon(ix, true); } entry* getRefN() { return getRefCommon(ix, true); }
entry* getRef() { assert(ix != null); return getRefCommon(ix, false); } entry* getRef() { return getRefCommon(ix, false); }
entry* getRefUsing(cpindex* ix2) entry* getRefUsing(cpindex* ix2)
{ assert(ix == null); return getRefCommon(ix2, true); } { assert(ix == null); return getRefCommon(ix2, true); }
entry* getRefCommon(cpindex* ix, bool nullOK); entry* getRefCommon(cpindex* ix, bool nullOK);

View File

@ -50,6 +50,7 @@ static jfieldID unpackerPtrFID;
static jmethodID currentInstMID; static jmethodID currentInstMID;
static jmethodID readInputMID; static jmethodID readInputMID;
static jclass NIclazz; static jclass NIclazz;
static jmethodID getUnpackerPtrMID;
static char* dbg = null; 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) { static unpacker* get_unpacker(JNIEnv *env, jobject pObj, bool noCreate=false) {
unpacker* uPtr; unpacker* uPtr;
uPtr = (unpacker*)jlong2ptr(env->GetLongField(pObj, unpackerPtrFID)); jlong p = env->CallLongMethod(pObj, getUnpackerPtrMID);
//fprintf(stderr, "get_unpacker(%p) uPtr=%p\n", pObj, uPtr); uPtr = (unpacker*)jlong2ptr(p);
if (uPtr == null) { if (uPtr == null) {
if (noCreate) return null; if (noCreate) return null;
uPtr = new unpacker(); uPtr = new unpacker();
@ -94,11 +95,15 @@ static unpacker* get_unpacker() {
if (env == null) if (env == null)
return null; return null;
jobject pObj = env->CallStaticObjectMethod(NIclazz, currentInstMID); jobject pObj = env->CallStaticObjectMethod(NIclazz, currentInstMID);
//fprintf(stderr, "get_unpacker() pObj=%p\n", pObj); //fprintf(stderr, "get_unpacker0() pObj=%p\n", pObj);
if (pObj == null) if (pObj != null) {
return null; // Got pObj and env; now do it the easy way.
// Got pObj and env; now do it the easy way. return get_unpacker(env, pObj);
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) { 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 JNIEXPORT void JNICALL
Java_com_sun_java_util_jar_pack_NativeUnpack_initIDs(JNIEnv *env, jclass clazz) { Java_com_sun_java_util_jar_pack_NativeUnpack_initIDs(JNIEnv *env, jclass clazz) {
#ifndef PRODUCT
dbg = getenv("DEBUG_ATTACH"); dbg = getenv("DEBUG_ATTACH");
while( dbg != null) { sleep(10); } while( dbg != null) { sleep(10); }
#endif
NIclazz = (jclass) env->NewGlobalRef(clazz); NIclazz = (jclass) env->NewGlobalRef(clazz);
unpackerPtrFID = env->GetFieldID(clazz, "unpackerPtr", "J"); unpackerPtrFID = env->GetFieldID(clazz, "unpackerPtr", "J");
currentInstMID = env->GetStaticMethodID(clazz, "currentInstance", currentInstMID = env->GetStaticMethodID(clazz, "currentInstance",
"()Ljava/lang/Object;"); "()Ljava/lang/Object;");
readInputMID = env->GetMethodID(clazz, "readInputFn", readInputMID = env->GetMethodID(clazz, "readInputFn",
"(Ljava/nio/ByteBuffer;J)J"); "(Ljava/nio/ByteBuffer;J)J");
getUnpackerPtrMID = env->GetMethodID(clazz, "getUnpackerPtr", "()J");
if (unpackerPtrFID == null || if (unpackerPtrFID == null ||
currentInstMID == null || currentInstMID == null ||
readInputMID == null || readInputMID == null ||
NIclazz == null) { NIclazz == null ||
getUnpackerPtrMID == null) {
THROW_IOE("cannot init class members"); 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 JNIEXPORT jlong JNICALL
Java_com_sun_java_util_jar_pack_NativeUnpack_start(JNIEnv *env, jobject pObj, Java_com_sun_java_util_jar_pack_NativeUnpack_start(JNIEnv *env, jobject pObj,
jobject pBuf, jlong offset) { 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. // redirect our io to the default log file or whatever.
uPtr->redirect_stdio(); uPtr->redirect_stdio();
@ -163,7 +178,12 @@ Java_com_sun_java_util_jar_pack_NativeUnpack_start(JNIEnv *env, jobject pObj,
else else
{ buf = (char*)buf + (size_t)offset; buflen -= (size_t)offset; } { 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); uPtr->start(buf, buflen);
if (uPtr->aborting()) { if (uPtr->aborting()) {
THROW_IOE(uPtr->get_abort_message()); 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. // We have fetched all the files.
// Now swallow up any remaining input. // Now swallow up any remaining input.
if (uPtr->input_remaining() == 0) if (uPtr->input_remaining() == 0) {
return null; return null;
else } else {
return env->NewDirectByteBuffer(uPtr->input_scan(), bytes remaining_bytes;
uPtr->input_remaining()); 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 JNIEXPORT jlong JNICALL

View File

@ -281,11 +281,13 @@ int entry::typeSize() {
} }
inline cpindex* cpool::getFieldIndex(entry* classRef) { inline cpindex* cpool::getFieldIndex(entry* classRef) {
if (classRef == NULL) { abort("missing class reference"); return NULL; }
assert(classRef->tagMatches(CONSTANT_Class)); assert(classRef->tagMatches(CONSTANT_Class));
assert((uint)classRef->inord < (uint)tag_count[CONSTANT_Class]); assert((uint)classRef->inord < (uint)tag_count[CONSTANT_Class]);
return &member_indexes[classRef->inord*2+0]; return &member_indexes[classRef->inord*2+0];
} }
inline cpindex* cpool::getMethodIndex(entry* classRef) { inline cpindex* cpool::getMethodIndex(entry* classRef) {
if (classRef == NULL) { abort("missing class reference"); return NULL; }
assert(classRef->tagMatches(CONSTANT_Class)); assert(classRef->tagMatches(CONSTANT_Class));
assert((uint)classRef->inord < (uint)tag_count[CONSTANT_Class]); assert((uint)classRef->inord < (uint)tag_count[CONSTANT_Class]);
return &member_indexes[classRef->inord*2+1]; 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]; entry& e = cpMap[i];
e.refs = U_NEW(entry*, e.nrefs = 2); e.refs = U_NEW(entry*, e.nrefs = 2);
e.refs[0] = cp_band1.getRef(); e.refs[0] = cp_band1.getRef();
CHECK;
e.refs[1] = cp_band2.getRef(); e.refs[1] = cp_band2.getRef();
CHECK; CHECK;
} }
@ -1371,6 +1374,7 @@ void unpacker::read_method_type(entry* cpMap, int len) {
entry& e = cpMap[i]; entry& e = cpMap[i];
e.refs = U_NEW(entry*, e.nrefs = 1); e.refs = U_NEW(entry*, e.nrefs = 1);
e.refs[0] = cp_MethodType.getRef(); e.refs[0] = cp_MethodType.getRef();
CHECK;
} }
} }
@ -2106,6 +2110,7 @@ void unpacker::read_attr_defs() {
int attrc = ADH_BYTE_CONTEXT(header); int attrc = ADH_BYTE_CONTEXT(header);
int idx = ADH_BYTE_INDEX(header); int idx = ADH_BYTE_INDEX(header);
entry* name = attr_definition_name.getRef(); entry* name = attr_definition_name.getRef();
CHECK;
entry* layout = attr_definition_layout.getRef(); entry* layout = attr_definition_layout.getRef();
CHECK; CHECK;
attr_defs[attrc].defineLayout(idx, name, layout->value.b.strval()); 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) { if (ics[i].name == NO_ENTRY_YET) {
// Long form. // Long form.
ics[i].outer = ic_outer_class.getRefN(); ics[i].outer = ic_outer_class.getRefN();
CHECK;
ics[i].name = ic_name.getRefN(); ics[i].name = ic_name.getRefN();
CHECK;
} else { } else {
// Fill in outer and name based on inner. // Fill in outer and name based on inner.
bytes& n = ics[i].inner->value.b; bytes& n = ics[i].inner->value.b;
@ -2733,6 +2740,7 @@ void unpacker::putlayout(band** body) {
e = b.getRefUsing(cp.getKQIndex()); e = b.getRefUsing(cp.getKQIndex());
else else
e = b.getRefN(); e = b.getRefN();
CHECK;
switch (b.le_len) { switch (b.le_len) {
case 0: break; case 0: break;
case 1: putu1ref(e); break; case 1: putu1ref(e); break;
@ -3118,7 +3126,7 @@ void unpacker::read_bcs() {
void unpacker::read_bands() { void unpacker::read_bands() {
byte* rp0 = rp; byte* rp0 = rp;
CHECK;
read_file_header(); read_file_header();
CHECK; CHECK;
@ -3880,10 +3888,12 @@ void unpacker::dump_options() {
// packed file and len is the length of the buffer. // packed file and len is the length of the buffer.
// If null, the callback is used to fill an internal buffer. // If null, the callback is used to fill an internal buffer.
void unpacker::start(void* packptr, size_t len) { void unpacker::start(void* packptr, size_t len) {
CHECK;
NOT_PRODUCT(debug_u = this); NOT_PRODUCT(debug_u = this);
if (packptr != null && len != 0) { if (packptr != null && len != 0) {
inbytes.set((byte*) packptr, len); inbytes.set((byte*) packptr, len);
} }
CHECK;
read_bands(); read_bands();
} }
@ -4015,6 +4025,7 @@ void unpacker::write_bc_ops() {
NOT_PRODUCT(bc_superfield.setIndex(null)); NOT_PRODUCT(bc_superfield.setIndex(null));
NOT_PRODUCT(bc_supermethod.setIndex(null)); NOT_PRODUCT(bc_supermethod.setIndex(null));
} }
CHECK;
for (int curIP = 0; ; curIP++) { for (int curIP = 0; ; curIP++) {
int curPC = (int)(wpoffset() - codeBase); int curPC = (int)(wpoffset() - codeBase);
@ -4128,7 +4139,8 @@ void unpacker::write_bc_ops() {
int coding = bc_initref.getInt(); int coding = bc_initref.getInt();
// Find the nth overloading of <init> in classRef. // Find the nth overloading of <init> in classRef.
entry* ref = null; 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++) { for (int j = 0, which_init = 0; ; j++) {
ref = (ix == null)? null: ix->get(j); ref = (ix == null)? null: ix->get(j);
if (ref == null) break; // oops, bad input 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): case ADH_BYTE(ATTR_CONTEXT_CLASS, CLASS_ATTR_EnclosingMethod):
aname = cp.sym[cpool::s_EnclosingMethod]; aname = cp.sym[cpool::s_EnclosingMethod];
putref(class_EnclosingMethod_RC.getRefN()); putref(class_EnclosingMethod_RC.getRefN());
CHECK_0;
putref(class_EnclosingMethod_RDN.getRefN()); putref(class_EnclosingMethod_RDN.getRefN());
break; break;
@ -4423,6 +4436,7 @@ int unpacker::write_attrs(int attrc, julong indexBits) {
putu2(count = method_Exceptions_N.getInt()); putu2(count = method_Exceptions_N.getInt());
for (j = 0; j < count; j++) { for (j = 0; j < count; j++) {
putref(method_Exceptions_RC.getRefN()); putref(method_Exceptions_RC.getRefN());
CHECK_0;
} }
break; break;
@ -4455,16 +4469,18 @@ int unpacker::write_attrs(int attrc, julong indexBits) {
// (253) [(1)(2)(2)] // (253) [(1)(2)(2)]
// (254) [(1)(2)(2)(2)] // (254) [(1)(2)(2)(2)]
putu2(code_StackMapTable_offset.getInt()); putu2(code_StackMapTable_offset.getInt());
CHECK_0;
for (int k = (tag - 251); k > 0; k--) { for (int k = (tag - 251); k > 0; k--) {
put_stackmap_type(); put_stackmap_type();
CHECK_0;
} }
} else { } else {
// (255) [(1)NH[(2)]NH[(2)]] // (255) [(1)NH[(2)]NH[(2)]]
putu2(code_StackMapTable_offset.getInt()); putu2(code_StackMapTable_offset.getInt());
putu2(j2 = code_StackMapTable_local_N.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()); putu2(j2 = code_StackMapTable_stack_N.getInt());
while (j2-- > 0) put_stackmap_type(); while (j2-- > 0) {put_stackmap_type(); CHECK_0;}
} }
} }
break; break;
@ -4488,7 +4504,9 @@ int unpacker::write_attrs(int attrc, julong indexBits) {
bii += code_LocalVariableTable_span_O.getInt(); bii += code_LocalVariableTable_span_O.getInt();
putu2(to_bci(bii) - bci); putu2(to_bci(bii) - bci);
putref(code_LocalVariableTable_name_RU.getRefN()); putref(code_LocalVariableTable_name_RU.getRefN());
CHECK_0;
putref(code_LocalVariableTable_type_RS.getRefN()); putref(code_LocalVariableTable_type_RS.getRefN());
CHECK_0;
putu2(code_LocalVariableTable_slot.getInt()); putu2(code_LocalVariableTable_slot.getInt());
} }
break; break;
@ -4503,7 +4521,9 @@ int unpacker::write_attrs(int attrc, julong indexBits) {
bii += code_LocalVariableTypeTable_span_O.getInt(); bii += code_LocalVariableTypeTable_span_O.getInt();
putu2(to_bci(bii) - bci); putu2(to_bci(bii) - bci);
putref(code_LocalVariableTypeTable_name_RU.getRefN()); putref(code_LocalVariableTypeTable_name_RU.getRefN());
CHECK_0;
putref(code_LocalVariableTypeTable_type_RS.getRefN()); putref(code_LocalVariableTypeTable_type_RS.getRefN());
CHECK_0;
putu2(code_LocalVariableTypeTable_slot.getInt()); putu2(code_LocalVariableTypeTable_slot.getInt());
} }
break; break;
@ -4531,7 +4551,7 @@ int unpacker::write_attrs(int attrc, julong indexBits) {
break; break;
} }
} }
CHECK_0;
if (aname == null) { if (aname == null) {
// Unparse a compressor-defined attribute. // Unparse a compressor-defined attribute.
layout_definition* lo = ad.getLayout(idx); 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 flags &= ~ACC_IC_LONG_FORM; // clear high bit if set to get clean zero
extra_ic.flags = flags; extra_ic.flags = flags;
extra_ic.outer = class_InnerClasses_outer_RCN.getRefN(); extra_ic.outer = class_InnerClasses_outer_RCN.getRefN();
CHECK_0;
extra_ic.name = class_InnerClasses_name_RUN.getRefN(); extra_ic.name = class_InnerClasses_name_RUN.getRefN();
CHECK_0;
// Detect if this is an exact copy of the global tuple. // Detect if this is an exact copy of the global tuple.
if (global_ic != null) { if (global_ic != null) {
if (global_ic->flags != extra_ic.flags || if (global_ic->flags != extra_ic.flags ||
@ -4796,6 +4818,7 @@ void unpacker::write_classfile_tail() {
julong indexMask = ad.flagIndexMask(); julong indexMask = ad.flagIndexMask();
cur_class = class_this.getRef(); cur_class = class_this.getRef();
CHECK;
cur_super = class_super.getRef(); cur_super = class_super.getRef();
CHECK; CHECK;
@ -4809,6 +4832,7 @@ void unpacker::write_classfile_tail() {
putu2(num = class_interface_count.getInt()); putu2(num = class_interface_count.getInt());
for (i = 0; i < num; i++) { for (i = 0; i < num; i++) {
putref(class_interface.getRef()); putref(class_interface.getRef());
CHECK;
} }
write_members(class_field_count.getInt(), ATTR_CONTEXT_FIELD); write_members(class_field_count.getInt(), ATTR_CONTEXT_FIELD);

View File

@ -114,6 +114,62 @@ int awt_parseImage(JNIEnv *env, jobject jimage, BufImageS_t **imagePP,
return status; return status;
} }
/* Verifies whether the channel offsets are sane and correspond to the type of
* the raster.
*
* Return value:
* 0: Failure: channel offsets are invalid
* 1: Success
*/
static int checkChannelOffsets(RasterS_t *rasterP, int dataArrayLength) {
int i, lastPixelOffset, lastScanOffset;
switch (rasterP->rasterType) {
case COMPONENT_RASTER_TYPE:
if (!SAFE_TO_MULT(rasterP->height, rasterP->scanlineStride)) {
return 0;
}
if (!SAFE_TO_MULT(rasterP->width, rasterP->pixelStride)) {
return 0;
}
lastScanOffset = (rasterP->height - 1) * rasterP->scanlineStride;
lastPixelOffset = (rasterP->width - 1) * rasterP->pixelStride;
if (!SAFE_TO_ADD(lastPixelOffset, lastScanOffset)) {
return 0;
}
lastPixelOffset += lastScanOffset;
for (i = 0; i < rasterP->numDataElements; i++) {
int off = rasterP->chanOffsets[i];
int size = lastPixelOffset + off;
if (off < 0 || !SAFE_TO_ADD(lastPixelOffset, off)) {
return 0;
}
if (size < lastPixelOffset || size >= dataArrayLength) {
// an overflow, or insufficient buffer capacity
return 0;
}
}
return 1;
case BANDED_RASTER_TYPE:
// NB:caller does not support the banded rasters yet,
// so this branch of the code must be re-defined in
// order to provide valid criteria for the data offsets
// verification, when/if banded rasters will be supported.
// At the moment, we prohibit banded rasters as well.
return 0;
default:
// PACKED_RASTER_TYPE: does not support channel offsets
// UNKNOWN_RASTER_TYPE: should not be used, likely indicates an error
return 0;
}
}
/* Parse the raster. All of the raster information is returned in the /* Parse the raster. All of the raster information is returned in the
* rasterP structure. * rasterP structure.
* *
@ -125,7 +181,6 @@ int awt_parseImage(JNIEnv *env, jobject jimage, BufImageS_t **imagePP,
int awt_parseRaster(JNIEnv *env, jobject jraster, RasterS_t *rasterP) { int awt_parseRaster(JNIEnv *env, jobject jraster, RasterS_t *rasterP) {
jobject joffs = NULL; jobject joffs = NULL;
/* int status;*/ /* int status;*/
int isDiscrete = TRUE;
if (JNU_IsNull(env, jraster)) { if (JNU_IsNull(env, jraster)) {
JNU_ThrowNullPointerException(env, "null Raster object"); JNU_ThrowNullPointerException(env, "null Raster object");
@ -155,6 +210,9 @@ int awt_parseRaster(JNIEnv *env, jobject jraster, RasterS_t *rasterP) {
return -1; return -1;
} }
// make sure that the raster type is initialized
rasterP->rasterType = UNKNOWN_RASTER_TYPE;
if (rasterP->numBands <= 0 || if (rasterP->numBands <= 0 ||
rasterP->numBands > MAX_NUMBANDS) rasterP->numBands > MAX_NUMBANDS)
{ {
@ -165,9 +223,14 @@ int awt_parseRaster(JNIEnv *env, jobject jraster, RasterS_t *rasterP) {
return 0; return 0;
} }
rasterP->sppsm.isUsed = 0;
if ((*env)->IsInstanceOf(env, rasterP->jsampleModel, if ((*env)->IsInstanceOf(env, rasterP->jsampleModel,
(*env)->FindClass(env,"java/awt/image/SinglePixelPackedSampleModel"))) { (*env)->FindClass(env,"java/awt/image/SinglePixelPackedSampleModel"))) {
jobject jmask, joffs, jnbits; jobject jmask, joffs, jnbits;
rasterP->sppsm.isUsed = 1;
rasterP->sppsm.maxBitSize = (*env)->GetIntField(env, rasterP->sppsm.maxBitSize = (*env)->GetIntField(env,
rasterP->jsampleModel, rasterP->jsampleModel,
g_SPPSMmaxBitID); g_SPPSMmaxBitID);
@ -254,7 +317,6 @@ int awt_parseRaster(JNIEnv *env, jobject jraster, RasterS_t *rasterP) {
} }
rasterP->chanOffsets[0] = (*env)->GetIntField(env, jraster, g_BPRdataBitOffsetID); rasterP->chanOffsets[0] = (*env)->GetIntField(env, jraster, g_BPRdataBitOffsetID);
rasterP->dataType = BYTE_DATA_TYPE; rasterP->dataType = BYTE_DATA_TYPE;
isDiscrete = FALSE;
} }
else { else {
rasterP->type = sun_awt_image_IntegerComponentRaster_TYPE_CUSTOM; rasterP->type = sun_awt_image_IntegerComponentRaster_TYPE_CUSTOM;
@ -265,7 +327,19 @@ int awt_parseRaster(JNIEnv *env, jobject jraster, RasterS_t *rasterP) {
return 0; return 0;
} }
if (isDiscrete) { // do basic validation of the raster structure
if (rasterP->width <= 0 || rasterP->height <= 0 ||
rasterP->pixelStride <= 0 || rasterP->scanlineStride <= 0)
{
// invalid raster
return -1;
}
// channel (data) offsets
switch (rasterP->rasterType) {
case COMPONENT_RASTER_TYPE:
case BANDED_RASTER_TYPE: // note that this routine does not support banded rasters at the moment
// get channel (data) offsets
rasterP->chanOffsets = NULL; rasterP->chanOffsets = NULL;
if (SAFE_TO_ALLOC_2(rasterP->numDataElements, sizeof(jint))) { if (SAFE_TO_ALLOC_2(rasterP->numDataElements, sizeof(jint))) {
rasterP->chanOffsets = rasterP->chanOffsets =
@ -278,10 +352,21 @@ int awt_parseRaster(JNIEnv *env, jobject jraster, RasterS_t *rasterP) {
} }
(*env)->GetIntArrayRegion(env, joffs, 0, rasterP->numDataElements, (*env)->GetIntArrayRegion(env, joffs, 0, rasterP->numDataElements,
rasterP->chanOffsets); rasterP->chanOffsets);
if (rasterP->jdata == NULL) {
// unable to verify the raster
return -1;
}
// verify whether channel offsets look sane
if (!checkChannelOffsets(rasterP, (*env)->GetArrayLength(env, rasterP->jdata))) {
return -1;
}
break;
default:
; // PACKED_RASTER_TYPE does not use the channel offsets.
} }
/* additioanl check for sppsm fields validity: make sure that /* additional check for sppsm fields validity: make sure that
* size of raster samples doesn't exceed the data type cpacity. * size of raster samples doesn't exceed the data type capacity.
*/ */
if (rasterP->dataType > UNKNOWN_DATA_TYPE && /* data type has been recognized */ if (rasterP->dataType > UNKNOWN_DATA_TYPE && /* data type has been recognized */
rasterP->sppsm.maxBitSize > 0 && /* raster has SPP sample model */ rasterP->sppsm.maxBitSize > 0 && /* raster has SPP sample model */
@ -631,6 +716,21 @@ setHints(JNIEnv *env, BufImageS_t *imageP) {
} }
else if (cmodelP->cmType == DIRECT_CM_TYPE || cmodelP->cmType == PACKED_CM_TYPE) { else if (cmodelP->cmType == DIRECT_CM_TYPE || cmodelP->cmType == PACKED_CM_TYPE) {
int i; int i;
/* do some sanity check first: make sure that
* - sample model is SinglePixelPackedSampleModel
* - number of bands in the raster corresponds to the number
* of color components in the color model
*/
if (!rasterP->sppsm.isUsed ||
rasterP->numBands != cmodelP->numComponents)
{
/* given raster is not compatible with the color model,
* so the operation has to be aborted.
*/
return -1;
}
if (cmodelP->maxNbits > 8) { if (cmodelP->maxNbits > 8) {
hintP->needToExpand = TRUE; hintP->needToExpand = TRUE;
hintP->expandToNbits = cmodelP->maxNbits; hintP->expandToNbits = cmodelP->maxNbits;

View File

@ -95,6 +95,7 @@ typedef struct {
jint offsets[MAX_NUMBANDS]; jint offsets[MAX_NUMBANDS];
jint nBits[MAX_NUMBANDS]; jint nBits[MAX_NUMBANDS];
jint maxBitSize; jint maxBitSize;
jint isUsed; // flag to indicate whether the raster sample model is SPPSM
} SPPSampleModelS_t; } SPPSampleModelS_t;
/* Struct that holds information for the Raster object */ /* Struct that holds information for the Raster object */

View File

@ -41,5 +41,10 @@
(((w) > 0) && ((h) > 0) && ((sz) > 0) && \ (((w) > 0) && ((h) > 0) && ((sz) > 0) && \
(((0xffffffffu / ((juint)(w))) / ((juint)(h))) > ((juint)(sz)))) (((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__ #endif // __SAFE_ALLOC_H__

View File

@ -133,6 +133,10 @@ SplashDecodeJpeg(Splash * splash, struct jpeg_decompress_struct *cinfo)
ImageFormat srcFormat; ImageFormat srcFormat;
jpeg_read_header(cinfo, TRUE); jpeg_read_header(cinfo, TRUE);
// SplashScreen jpeg converter expects data in RGB format only
cinfo->out_color_space = JCS_RGB;
jpeg_start_decompress(cinfo); jpeg_start_decompress(cinfo);
SplashCleanup(splash); SplashCleanup(splash);

View File

@ -1026,13 +1026,21 @@ public class SctpChannelImpl extends SctpChannel
boolean unordered, boolean unordered,
int ppid) int ppid)
throws IOException { throws IOException {
InetAddress addr = null; // no preferred address
int port = 0;
if (target != null) {
InetSocketAddress isa = Net.checkAddress(target);
addr = isa.getAddress();
port = isa.getPort();
}
int pos = bb.position(); int pos = bb.position();
int lim = bb.limit(); int lim = bb.limit();
assert (pos <= lim); assert (pos <= lim);
int rem = (pos <= lim ? lim - pos : 0); int rem = (pos <= lim ? lim - pos : 0);
int written = send0(fd, ((DirectBuffer)bb).address() + pos, int written = send0(fd, ((DirectBuffer)bb).address() + pos, rem, addr,
rem, target, -1 /*121*/, streamNumber, unordered, ppid); port, -1 /*121*/, streamNumber, unordered, ppid);
if (written > 0) if (written > 0)
bb.position(pos + written); bb.position(pos + written);
return written; return written;
@ -1091,7 +1099,7 @@ public class SctpChannelImpl extends SctpChannel
long address, int length, boolean peek) throws IOException; long address, int length, boolean peek) throws IOException;
static native int send0(int fd, long address, int length, static native int send0(int fd, long address, int length,
SocketAddress target, int assocId, int streamNumber, InetAddress addr, int port, int assocId, int streamNumber,
boolean unordered, int ppid) throws IOException; boolean unordered, int ppid) throws IOException;
private static native int checkConnect(FileDescriptor fd, boolean block, private static native int checkConnect(FileDescriptor fd, boolean block,

View File

@ -889,13 +889,20 @@ public class SctpMultiChannelImpl extends SctpMultiChannel
boolean unordered, boolean unordered,
int ppid) int ppid)
throws IOException { throws IOException {
InetAddress addr = null; // no preferred address
int port = 0;
if (target != null) {
InetSocketAddress isa = Net.checkAddress(target);
addr = isa.getAddress();
port = isa.getPort();
}
int pos = bb.position(); int pos = bb.position();
int lim = bb.limit(); int lim = bb.limit();
assert (pos <= lim); assert (pos <= lim);
int rem = (pos <= lim ? lim - pos : 0); int rem = (pos <= lim ? lim - pos : 0);
int written = send0(fd, ((DirectBuffer)bb).address() + pos, int written = send0(fd, ((DirectBuffer)bb).address() + pos, rem, addr,
rem, target, assocId, streamNumber, unordered, ppid); port, assocId, streamNumber, unordered, ppid);
if (written > 0) if (written > 0)
bb.position(pos + written); bb.position(pos + written);
return written; return written;
@ -976,13 +983,14 @@ public class SctpMultiChannelImpl extends SctpMultiChannel
private static int send0(int fd, private static int send0(int fd,
long address, long address,
int length, int length,
SocketAddress target, InetAddress addr,
int port,
int assocId, int assocId,
int streamNumber, int streamNumber,
boolean unordered, boolean unordered,
int ppid) int ppid)
throws IOException { throws IOException {
return SctpChannelImpl.send0(fd, address, length, target, assocId, return SctpChannelImpl.send0(fd, address, length, addr, port, assocId,
streamNumber, unordered, ppid); streamNumber, unordered, ppid);
} }

View File

@ -46,8 +46,6 @@
#include "sun_nio_ch_DatagramChannelImpl.h" #include "sun_nio_ch_DatagramChannelImpl.h"
static jfieldID isa_addrID; /* address in java.net.InetSocketAddress */
static jfieldID isa_portID; /* port in java.net.InetSocketAddress */
static jfieldID dci_senderID; /* sender in sun.nio.ch.DatagramChannelImpl */ static jfieldID dci_senderID; /* sender in sun.nio.ch.DatagramChannelImpl */
static jfieldID dci_senderAddrID; /* sender InetAddress in sun.nio.ch.DatagramChannelImpl */ static jfieldID dci_senderAddrID; /* sender InetAddress in sun.nio.ch.DatagramChannelImpl */
static jfieldID dci_senderPortID; /* sender port in sun.nio.ch.DatagramChannelImpl */ static jfieldID dci_senderPortID; /* sender port in sun.nio.ch.DatagramChannelImpl */
@ -61,9 +59,6 @@ Java_sun_nio_ch_DatagramChannelImpl_initIDs(JNIEnv *env, jclass clazz)
isa_class = (*env)->NewGlobalRef(env, clazz); isa_class = (*env)->NewGlobalRef(env, clazz);
isa_ctorID = (*env)->GetMethodID(env, clazz, "<init>", isa_ctorID = (*env)->GetMethodID(env, clazz, "<init>",
"(Ljava/net/InetAddress;I)V"); "(Ljava/net/InetAddress;I)V");
isa_addrID = (*env)->GetFieldID(env, clazz, "addr",
"Ljava/net/InetAddress;");
isa_portID = (*env)->GetFieldID(env, clazz, "port", "I");
clazz = (*env)->FindClass(env, "sun/nio/ch/DatagramChannelImpl"); clazz = (*env)->FindClass(env, "sun/nio/ch/DatagramChannelImpl");
dci_senderID = (*env)->GetFieldID(env, clazz, "sender", dci_senderID = (*env)->GetFieldID(env, clazz, "sender",
@ -212,15 +207,13 @@ Java_sun_nio_ch_DatagramChannelImpl_receive0(JNIEnv *env, jobject this,
JNIEXPORT jint JNICALL JNIEXPORT jint JNICALL
Java_sun_nio_ch_DatagramChannelImpl_send0(JNIEnv *env, jobject this, Java_sun_nio_ch_DatagramChannelImpl_send0(JNIEnv *env, jobject this,
jboolean preferIPv6, jobject fdo, jlong address, jboolean preferIPv6, jobject fdo, jlong address,
jint len, jobject dest) jint len, jobject destAddress, jint destPort)
{ {
jint fd = fdval(env, fdo); jint fd = fdval(env, fdo);
void *buf = (void *)jlong_to_ptr(address); void *buf = (void *)jlong_to_ptr(address);
SOCKADDR sa; SOCKADDR sa;
int sa_len = SOCKADDR_LEN; int sa_len = SOCKADDR_LEN;
jint n = 0; jint n = 0;
jobject destAddress = (*env)->GetObjectField(env, dest, isa_addrID);
jint destPort = (*env)->GetIntField(env, dest, isa_portID);
if (len > MAX_PACKET_LEN) { if (len > MAX_PACKET_LEN) {
len = MAX_PACKET_LEN; len = MAX_PACKET_LEN;

View File

@ -67,8 +67,6 @@ static jclass spc_class; /* sun.nio.ch.sctp.PeerAddressChanged */
static jmethodID spc_ctrID; /* sun.nio.ch.sctp.PeerAddressChanged.<init> */ static jmethodID spc_ctrID; /* sun.nio.ch.sctp.PeerAddressChanged.<init> */
static jclass ss_class; /* sun.nio.ch.sctp.Shutdown */ static jclass ss_class; /* sun.nio.ch.sctp.Shutdown */
static jmethodID ss_ctrID; /* sun.nio.ch.sctp.Shutdown.<init> */ static jmethodID ss_ctrID; /* sun.nio.ch.sctp.Shutdown.<init> */
static jfieldID isa_addrID; /* java.net.InetSocketAddress.addr */
static jfieldID isa_portID; /* java.net.InetSocketAddress.port */
/* defined in SctpNet.c */ /* defined in SctpNet.c */
jobject SockAddrToInetSocketAddress(JNIEnv* env, struct sockaddr* addr); jobject SockAddrToInetSocketAddress(JNIEnv* env, struct sockaddr* addr);
@ -138,13 +136,6 @@ JNIEXPORT void JNICALL Java_sun_nio_ch_sctp_SctpChannelImpl_initIDs
CHECK_NULL(ss_class); CHECK_NULL(ss_class);
ss_ctrID = (*env)->GetMethodID(env, cls, "<init>", "(I)V"); ss_ctrID = (*env)->GetMethodID(env, cls, "<init>", "(I)V");
CHECK_NULL(ss_ctrID); CHECK_NULL(ss_ctrID);
/* InetSocketAddress */
cls = (*env)->FindClass(env, "java/net/InetSocketAddress");
CHECK_NULL(cls);
isa_addrID = (*env)->GetFieldID(env, cls, "addr", "Ljava/net/InetAddress;");
CHECK_NULL(isa_addrID);
isa_portID = (*env)->GetFieldID(env, cls, "port", "I");
} }
void getControlData void getControlData
@ -509,12 +500,12 @@ JNIEXPORT jint JNICALL Java_sun_nio_ch_sctp_SctpChannelImpl_receive0
/* /*
* Class: sun_nio_ch_sctp_SctpChannelImpl * Class: sun_nio_ch_sctp_SctpChannelImpl
* Method: send0 * Method: send0
* Signature: (IJILjava/net/SocketAddress;IIZI)I * Signature: (IJILjava/net/InetAddress;IIIZI)I
*/ */
JNIEXPORT jint JNICALL Java_sun_nio_ch_sctp_SctpChannelImpl_send0 JNIEXPORT jint JNICALL Java_sun_nio_ch_sctp_SctpChannelImpl_send0
(JNIEnv *env, jclass klass, jint fd, jlong address, jint length, (JNIEnv *env, jclass klass, jint fd, jlong address, jint length,
jobject saTarget, jint assocId, jint streamNumber, jboolean unordered, jobject targetAddress, jint targetPort, jint assocId, jint streamNumber,
jint ppid) { jboolean unordered, jint ppid) {
SOCKADDR sa; SOCKADDR sa;
int sa_len = sizeof(sa); int sa_len = sizeof(sa);
ssize_t rv = 0; ssize_t rv = 0;
@ -526,17 +517,13 @@ JNIEXPORT jint JNICALL Java_sun_nio_ch_sctp_SctpChannelImpl_send0
struct controlData cdata[1]; struct controlData cdata[1];
/* SctpChannel: /* SctpChannel:
* saTarget may contain the preferred address or NULL to use primary, * targetAddress may contain the preferred address or NULL to use primary,
* assocId will always be -1 * assocId will always be -1
* SctpMultiChannell: * SctpMultiChannell:
* Setup new association, saTarget will contain address, assocId = -1 * Setup new association, targetAddress will contain address, assocId = -1
* Association already existing, assocId != -1, saTarget = preferred addr * Association already existing, assocId != -1, targetAddress = preferred addr
*/ */
if (saTarget != NULL /*&& assocId <= 0*/) { if (targetAddress != NULL /*&& assocId <= 0*/) {
jobject targetAddress = (*env)->GetObjectField(env, saTarget, isa_addrID);
jint targetPort = (*env)->GetIntField(env, saTarget, isa_portID);
if (NET_InetAddressToSockaddr(env, targetAddress, targetPort, if (NET_InetAddressToSockaddr(env, targetAddress, targetPort,
(struct sockaddr *)&sa, (struct sockaddr *)&sa,
&sa_len, JNI_TRUE) != 0) { &sa_len, JNI_TRUE) != 0) {

View File

@ -101,7 +101,6 @@ int awtPreloadD3D = -1;
/* funtion in awt.dll (src/windows/native/sun/java2d/d3d/D3DPipelineManager.cpp) */ /* funtion in awt.dll (src/windows/native/sun/java2d/d3d/D3DPipelineManager.cpp) */
#define D3D_PRELOAD_FUNC "preloadD3D" #define D3D_PRELOAD_FUNC "preloadD3D"
/* Extracts value of a parameter with the specified name /* Extracts value of a parameter with the specified name
* from command line argument (returns pointer in the argument). * from command line argument (returns pointer in the argument).
* Returns NULL if the argument does not contains the parameter. * Returns NULL if the argument does not contains the parameter.
@ -276,7 +275,8 @@ LoadMSVCRT()
#endif #endif
#ifdef CRT_DLL #ifdef CRT_DLL
if (GetJREPath(crtpath, MAXPATHLEN)) { if (GetJREPath(crtpath, MAXPATHLEN)) {
if (JLI_StrLen(crtpath) + JLI_StrLen("\\bin\\") + JLI_StrLen(CRT_DLL) >= MAXPATHLEN) { if (JLI_StrLen(crtpath) + JLI_StrLen("\\bin\\") +
JLI_StrLen(CRT_DLL) >= MAXPATHLEN) {
JLI_ReportErrorMessage(JRE_ERROR11); JLI_ReportErrorMessage(JRE_ERROR11);
return JNI_FALSE; return JNI_FALSE;
} }
@ -347,7 +347,8 @@ GetJVMPath(const char *jrepath, const char *jvmtype,
if (JLI_StrChr(jvmtype, '/') || JLI_StrChr(jvmtype, '\\')) { if (JLI_StrChr(jvmtype, '/') || JLI_StrChr(jvmtype, '\\')) {
JLI_Snprintf(jvmpath, jvmpathsize, "%s\\" JVM_DLL, jvmtype); JLI_Snprintf(jvmpath, jvmpathsize, "%s\\" JVM_DLL, jvmtype);
} else { } else {
JLI_Snprintf(jvmpath, jvmpathsize, "%s\\bin\\%s\\" JVM_DLL, jrepath, jvmtype); JLI_Snprintf(jvmpath, jvmpathsize, "%s\\bin\\%s\\" JVM_DLL,
jrepath, jvmtype);
} }
if (stat(jvmpath, &s) == 0) { if (stat(jvmpath, &s) == 0) {
return JNI_TRUE; return JNI_TRUE;
@ -525,6 +526,37 @@ jlong Counter2Micros(jlong counts)
} }
return (counts * 1000 * 1000)/counterFrequency.QuadPart; return (counts * 1000 * 1000)/counterFrequency.QuadPart;
} }
/*
* windows snprintf does not guarantee a null terminator in the buffer,
* if the computed size is equal to or greater than the buffer size,
* as well as error conditions. This function guarantees a null terminator
* under all these conditions. An unreasonable buffer or size will return
* an error value. Under all other conditions this function will return the
* size of the bytes actually written minus the null terminator, similar
* to ansi snprintf api. Thus when calling this function the caller must
* ensure storage for the null terminator.
*/
int
JLI_Snprintf(char* buffer, size_t size, const char* format, ...) {
int rc;
va_list vl;
if (size == 0 || buffer == NULL)
return -1;
buffer[0] = '\0';
va_start(vl, format);
rc = vsnprintf(buffer, size, format, vl);
va_end(vl);
/* force a null terminator, if something is amiss */
if (rc < 0) {
/* apply ansi semantics */
buffer[size - 1] = '\0';
return size;
} else if (rc == size) {
/* force a null terminator */
buffer[size - 1] = '\0';
}
return rc;
}
void void
JLI_ReportErrorMessage(const char* fmt, ...) { JLI_ReportErrorMessage(const char* fmt, ...) {
@ -880,7 +912,7 @@ unquote(const char *s) {
*/ */
void void
ExecJRE(char *jre, char **argv) { ExecJRE(char *jre, char **argv) {
int len; jint len;
char path[MAXPATHLEN + 1]; char path[MAXPATHLEN + 1];
const char *progname = GetProgramName(); const char *progname = GetProgramName();
@ -1417,7 +1449,10 @@ CreateApplicationArgs(JNIEnv *env, char **strv, int argc)
// we add the indicator // we add the indicator
tlen = 1 + JLI_StrLen(strv[i]) + 1; tlen = 1 + JLI_StrLen(strv[i]) + 1;
nargv[i] = (char *) JLI_MemAlloc(tlen); nargv[i] = (char *) JLI_MemAlloc(tlen);
JLI_Snprintf(nargv[i], tlen, "%c%s", arg_expand ? 'T' : 'F', strv[i]); if (JLI_Snprintf(nargv[i], tlen, "%c%s", arg_expand ? 'T' : 'F',
strv[i]) < 0) {
return NULL;
}
JLI_TraceLauncher("%s\n", nargv[i]); JLI_TraceLauncher("%s\n", nargv[i]);
} }

View File

@ -488,14 +488,15 @@ public abstract class WComponentPeer extends WObjectPeer
try { try {
replaceSurfaceData(); replaceSurfaceData();
} catch (InvalidPipeException e) { } catch (InvalidPipeException e) {
// REMIND : what do we do if our surface creation failed? // REMIND : what do we do if our surface creation failed?
} }
} }
} }
}; };
Component c = (Component)target;
// Fix 6255371. // Fix 6255371.
if (!PaintEventDispatcher.getPaintEventDispatcher().queueSurfaceDataReplacing((Component)target, r)) { if (!PaintEventDispatcher.getPaintEventDispatcher().queueSurfaceDataReplacing(c, r)) {
postEvent(new InvocationEvent(Toolkit.getDefaultToolkit(), r)); postEvent(new InvocationEvent(c, r));
} }
} }
@ -618,7 +619,7 @@ public abstract class WComponentPeer extends WObjectPeer
} }
public void disposeLater() { public void disposeLater() {
postEvent(new InvocationEvent(Toolkit.getDefaultToolkit(), new Runnable() { postEvent(new InvocationEvent(target, new Runnable() {
public void run() { public void run() {
dispose(); dispose();
} }

View File

@ -27,6 +27,7 @@ package sun.awt.windows;
import sun.awt.*; import sun.awt.*;
import java.awt.*; import java.awt.*;
import java.awt.event.InvocationEvent;
import java.awt.peer.ComponentPeer; import java.awt.peer.ComponentPeer;
import java.awt.image.*; import java.awt.image.*;
import sun.awt.image.ByteInterleavedRaster; import sun.awt.image.ByteInterleavedRaster;
@ -232,11 +233,13 @@ public class WEmbeddedFrame extends EmbeddedFrame {
} else { } else {
// To avoid focus concurrence b/w IE and EmbeddedFrame // To avoid focus concurrence b/w IE and EmbeddedFrame
// activation is postponed by means of posting it to EDT. // activation is postponed by means of posting it to EDT.
EventQueue.invokeLater(new Runnable() { Runnable r = new Runnable() {
public void run() { public void run() {
((WEmbeddedFramePeer)getPeer()).synthesizeWmActivate(true); ((WEmbeddedFramePeer)getPeer()).synthesizeWmActivate(true);
} }
}); };
WToolkit.postEvent(WToolkit.targetToAppContext(this),
new InvocationEvent(this, r));
} }
} }

View File

@ -34,8 +34,6 @@
#include "net_util.h" #include "net_util.h"
#include <winsock2.h> #include <winsock2.h>
static jfieldID isa_addrID; /* address in java.net.InetSocketAddress */
static jfieldID isa_portID; /* port in java.net.InetSocketAddress */
static jfieldID dci_senderID; /* sender in sun.nio.ch.DatagramChannelImpl */ static jfieldID dci_senderID; /* sender in sun.nio.ch.DatagramChannelImpl */
static jfieldID dci_senderAddrID; /* sender InetAddress in sun.nio.ch.DatagramChannelImpl */ static jfieldID dci_senderAddrID; /* sender InetAddress in sun.nio.ch.DatagramChannelImpl */
static jfieldID dci_senderPortID; /* sender port in sun.nio.ch.DatagramChannelImpl */ static jfieldID dci_senderPortID; /* sender port in sun.nio.ch.DatagramChannelImpl */
@ -50,9 +48,6 @@ Java_sun_nio_ch_DatagramChannelImpl_initIDs(JNIEnv *env, jclass clazz)
isa_class = (*env)->NewGlobalRef(env, clazz); isa_class = (*env)->NewGlobalRef(env, clazz);
isa_ctorID = (*env)->GetMethodID(env, clazz, "<init>", isa_ctorID = (*env)->GetMethodID(env, clazz, "<init>",
"(Ljava/net/InetAddress;I)V"); "(Ljava/net/InetAddress;I)V");
isa_addrID = (*env)->GetFieldID(env, clazz, "addr",
"Ljava/net/InetAddress;");
isa_portID = (*env)->GetFieldID(env, clazz, "port", "I");
clazz = (*env)->FindClass(env, "sun/nio/ch/DatagramChannelImpl"); clazz = (*env)->FindClass(env, "sun/nio/ch/DatagramChannelImpl");
dci_senderID = (*env)->GetFieldID(env, clazz, "sender", dci_senderID = (*env)->GetFieldID(env, clazz, "sender",
@ -214,15 +209,14 @@ Java_sun_nio_ch_DatagramChannelImpl_receive0(JNIEnv *env, jobject this,
JNIEXPORT jint JNICALL JNIEXPORT jint JNICALL
Java_sun_nio_ch_DatagramChannelImpl_send0(JNIEnv *env, jobject this, Java_sun_nio_ch_DatagramChannelImpl_send0(JNIEnv *env, jobject this,
jboolean preferIPv6, jobject fdo, jboolean preferIPv6, jobject fdo,
jlong address, jint len, jobject dest) jlong address, jint len,
jobject destAddress, jint destPort)
{ {
jint fd = fdval(env, fdo); jint fd = fdval(env, fdo);
void *buf = (void *)jlong_to_ptr(address); void *buf = (void *)jlong_to_ptr(address);
SOCKETADDRESS sa; SOCKETADDRESS sa;
int sa_len; int sa_len;
jint rv = 0; jint rv = 0;
jobject destAddress = (*env)->GetObjectField(env, dest, isa_addrID);
jint destPort = (*env)->GetIntField(env, dest, isa_portID);
if (NET_InetAddressToSockaddr(env, destAddress, destPort, if (NET_InetAddressToSockaddr(env, destAddress, destPort,
(struct sockaddr *)&sa, (struct sockaddr *)&sa,

View File

@ -53,14 +53,12 @@ struct EnableEditingStruct {
* AwtTextComponent fields * AwtTextComponent fields
*/ */
/* java.awt.TextComponent fields */
jfieldID AwtTextComponent::canAccessClipboardID;
/************************************************************************ /************************************************************************
* AwtTextComponent methods * AwtTextComponent methods
*/ */
jmethodID AwtTextComponent::canAccessClipboardMID;
AwtTextComponent::AwtTextComponent() { AwtTextComponent::AwtTextComponent() {
m_synthetic = FALSE; m_synthetic = FALSE;
m_lStartPos = -1; m_lStartPos = -1;
@ -367,8 +365,7 @@ AwtTextComponent::WmPaste()
} }
jobject target = GetTarget(env); jobject target = GetTarget(env);
jboolean canAccessClipboard = jboolean canAccessClipboard =
env->GetBooleanField(target, env->CallBooleanMethod (target, AwtTextComponent::canAccessClipboardMID);
AwtTextComponent::canAccessClipboardID);
env->DeleteLocalRef(target); env->DeleteLocalRef(target);
return (canAccessClipboard) ? mrDoDefault : mrConsume; return (canAccessClipboard) ? mrDoDefault : mrConsume;
} }
@ -854,12 +851,13 @@ Java_sun_awt_windows_WTextComponentPeer_initIDs(JNIEnv *env, jclass cls)
{ {
TRY; TRY;
cls = env->FindClass("java/awt/TextComponent"); jclass textComponentClassID = env->FindClass("java/awt/TextComponent");
if (cls != NULL) { AwtTextComponent::canAccessClipboardMID =
AwtTextComponent::canAccessClipboardID = env->GetMethodID(textComponentClassID,
env->GetFieldID(cls, "canAccessClipboard", "Z"); "canAccessClipboard", "()Z");
DASSERT(AwtTextComponent::canAccessClipboardID != NULL); env->DeleteLocalRef(textComponentClassID);
}
DASSERT(AwtTextComponent::canAccessClipboardMID != NULL);
CATCH_BAD_ALLOC; CATCH_BAD_ALLOC;
} }

View File

@ -42,8 +42,7 @@
class AwtTextComponent : public AwtComponent { class AwtTextComponent : public AwtComponent {
public: public:
/* java.awt.TextComponent canAccessClipboard field ID */ static jmethodID canAccessClipboardMID;
static jfieldID canAccessClipboardID;
AwtTextComponent(); AwtTextComponent();

View File

@ -512,6 +512,7 @@ jdk_other: $(call TestDirs, \
javax/script \ javax/script \
java/sql javax/sql \ java/sql javax/sql \
javax/smartcardio \ javax/smartcardio \
javax/xml/soap \
javax/xml/ws com/sun/internal/ws \ javax/xml/ws com/sun/internal/ws \
jdk/asm \ jdk/asm \
com/sun/org/apache/xerces \ com/sun/org/apache/xerces \

View File

@ -42,7 +42,7 @@ public class SendToUnresolved {
try { try {
dc.send(bb, sa); dc.send(bb, sa);
throw new RuntimeException("Expected exception not thrown"); throw new RuntimeException("Expected exception not thrown");
} catch (IOException e) { } catch (IOException | UnresolvedAddressException e) {
// Correct result // Correct result
} }
dc.close(); dc.close();

View File

@ -13,6 +13,7 @@ grant {
permission java.io.FilePermission ".${/}-", "read,write,delete"; permission java.io.FilePermission ".${/}-", "read,write,delete";
permission java.lang.RuntimePermission "createClassLoader"; permission java.lang.RuntimePermission "createClassLoader";
permission java.lang.RuntimePermission "getClassLoader";
permission java.lang.RuntimePermission "setContextClassLoader"; permission java.lang.RuntimePermission "setContextClassLoader";
// used by TestLibrary to determine test environment // used by TestLibrary to determine test environment

View File

@ -110,6 +110,14 @@ public class JavaVM {
return TestLibrary.getExtraProperty("jcov.options",""); return TestLibrary.getExtraProperty("jcov.options","");
} }
public void start(Runnable runnable) throws IOException {
if (runnable == null) {
throw new NullPointerException("Runnable cannot be null.");
}
start();
new JavaVMCallbackHandler(runnable).start();
}
/** /**
* Exec the VM as specified in this object's constructor. * Exec the VM as specified in this object's constructor.
@ -183,4 +191,35 @@ public class JavaVM {
start(); start();
return waitFor(); return waitFor();
} }
/**
* Handles calling the callback.
*/
private class JavaVMCallbackHandler extends Thread {
Runnable runnable;
JavaVMCallbackHandler(Runnable runnable) {
this.runnable = runnable;
}
/**
* Wait for the Process to terminate and notify the callback.
*/
@Override
public void run() {
if (vm != null) {
try {
vm.waitFor();
} catch(InterruptedException ie) {
// Restore the interrupted status
Thread.currentThread().interrupt();
}
}
if (runnable != null) {
runnable.run();
}
}
}
} }

View File

@ -0,0 +1,177 @@
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.io.*;
import java.util.*;
import java.util.logging.*;
/*
* Custom LogManager implementation to verify that the implementation delegates
* to the LogManager subclass to register both system logger and user logger.
*
* The LogManager implementation is the one configuring the logger's property
* such as level, handler, etc.
*/
public class CustomLogManager extends LogManager {
static LogManager INSTANCE;
Map<String,Logger> namedLoggers = new HashMap<>();
Properties props = initConfig();
public CustomLogManager() {
if (INSTANCE != null) {
throw new RuntimeException("CustomLogManager already created");
}
INSTANCE = this;
}
public synchronized boolean addLogger(Logger logger) {
String name = logger.getName();
if (namedLoggers.containsKey(name)) {
return false;
}
namedLoggers.put(name, logger);
// set level
if (props.get(name + ".level") != null) {
logger.setLevel(Level.parse(props.getProperty(name + ".level")));
}
// add handlers
if (props.get(name + ".handlers") != null && logger.getHandlers().length == 0) {
logger.addHandler(new CustomHandler());
}
// add parent loggers
int ix = 1;
for (;;) {
int ix2 = name.indexOf(".", ix);
if (ix2 < 0) {
break;
}
String pname = name.substring(0, ix2);
if (props.get(pname + ".level") != null ||
props.get(pname + ".handlers") != null) {
// This pname has a level/handlers definition.
// Make sure it exists.
//
// The test doesn't set the parent for simplicity.
if (!namedLoggers.containsKey(pname)) {
Logger.getLogger(pname);
}
}
ix = ix2 + 1;
}
return true;
}
public synchronized Logger getLogger(String name) {
return namedLoggers.get(name);
}
public synchronized Enumeration<String> getLoggerNames() {
return Collections.enumeration(namedLoggers.keySet());
}
public String getProperty(String name) {
return props.getProperty(name);
}
public void readConfiguration() {
// do nothing
}
public void readConfiguration(InputStream ins) {
// do nothing
}
private Properties initConfig() {
Properties props = new Properties();
props.put(".level", "CONFIG");
props.put("CustomLogManagerTest.level", "WARNING");
props.put("CustomLogManagerTest.handlers", "CustomLogManager$CustomHandler");
props.put("SimpleLogManager.level", "INFO");
props.put("SimpleLogManager.handlers", "CustomLogManager$CustomHandler");
props.put("CustomLogManager$CustomHandler.level", "WARNING");
props.put(".handlers", "CustomLogManager$CustomHandler");
props.put("org.foo.bar.level", "SEVERE");
props.put("org.foo.handlers", "CustomLogManager$CustomHandler");
props.put("org.openjdk.level", "SEVERE");
props.put("org.openjdk.handlers", "CustomLogManager$CustomHandler");
props.put("org.openjdk.core.level", "INFO");
return props;
}
public static void checkLogger(String name) {
checkLogger(name, null);
}
public static void checkLogger(String name, String resourceBundleName) {
Logger logger = INSTANCE.getLogger(name);
if (logger == null) {
throw new RuntimeException("Logger \"" + name + "\" not exist");
}
System.out.format("Logger \"%s\" level=%s handlers=%s resourcebundle=%s%n",
name, logger.getLevel(),
Arrays.toString(logger.getHandlers()),
logger.getResourceBundleName());
String rb = logger.getResourceBundleName();
if (rb != resourceBundleName && (rb == null || rb.equals(resourceBundleName))) {
throw new RuntimeException("Logger \"" + name +
"\" unexpected resource bundle: " + rb);
}
String value = INSTANCE.getProperty(name + ".level");
String level = logger.getLevel() != null ? logger.getLevel().getName() : null;
if (level != value && (level == null || level.equals(value))) {
throw new RuntimeException("Logger \"" + name + "\" unexpected level: " + level);
}
Handler[] handlers = logger.getHandlers();
String hdl = INSTANCE.getProperty(name + ".handlers");
if ((hdl == null && handlers.length != 0) ||
(hdl != null && handlers.length != 1)) {
throw new RuntimeException("Logger \"" + name + "\" unexpected handler: " +
Arrays.toString(handlers));
}
checkParents(name);
}
private static void checkParents(String name) {
int ix = 1;
for (;;) {
int ix2 = name.indexOf(".", ix);
if (ix2 < 0) {
break;
}
String pname = name.substring(0, ix2);
if (INSTANCE.getProperty(pname + ".level") != null ||
INSTANCE.getProperty(pname + ".handlers") != null) {
// This pname has a level/handlers definition.
// Make sure it exists.
checkLogger(pname);
}
ix = ix2 + 1;
}
}
// only CustomLogManager can create an instance of CustomHandler
private class CustomHandler extends StreamHandler {
}
}

View File

@ -0,0 +1,63 @@
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.io.*;
import java.util.*;
import java.util.logging.*;
import sun.util.logging.PlatformLogger;
/*
* @test
* @bug 8005615
* @summary Add loggers to custom log manager
*
* @compile -XDignore.symbol.file CustomLogManagerTest.java CustomLogManager.java
* @run main/othervm -Djava.util.logging.manager=CustomLogManager CustomLogManagerTest
*/
public class CustomLogManagerTest {
private static final String RESOURCE_BUNDLE = "sun.util.logging.resources.logging";
public static void main(String[] args) {
String mgr = System.getProperty("java.util.logging.manager");
if (!mgr.equals("CustomLogManager")) {
throw new RuntimeException("java.util.logging.manager not set");
}
Logger.getLogger(CustomLogManagerTest.class.getName());
Logger.getLogger("org.foo.Foo");
Logger.getLogger("org.foo.bar.Foo", RESOURCE_BUNDLE);
// platform logger will be set with the default system resource bundle
PlatformLogger.getLogger("org.openjdk.core.logger");
if (LogManager.getLogManager() != CustomLogManager.INSTANCE) {
throw new RuntimeException(LogManager.getLogManager() + " not CustomLogManager");
}
CustomLogManager.checkLogger(CustomLogManagerTest.class.getName());
CustomLogManager.checkLogger("org.foo.Foo");
CustomLogManager.checkLogger("org.foo.bar.Foo", RESOURCE_BUNDLE);
CustomLogManager.checkLogger(Logger.GLOBAL_LOGGER_NAME);
CustomLogManager.checkLogger("");
CustomLogManager.checkLogger("org.openjdk.core.logger", RESOURCE_BUNDLE);
}
}

View File

@ -0,0 +1,113 @@
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.util.*;
import java.util.logging.*;
import sun.util.logging.PlatformLogger;
/*
* @test
* @bug 8005615
* @summary A LogManager subclass overrides its own implementation of named
* logger (see the subclassing information in the Logger class specification)
*
* @compile -XDignore.symbol.file CustomLogManager.java SimpleLogManager.java
* @run main/othervm -Djava.util.logging.manager=SimpleLogManager SimpleLogManager
*/
public class SimpleLogManager extends CustomLogManager {
public static void main(String[] args) {
String classname = System.getProperty("java.util.logging.manager");
if (!classname.equals("SimpleLogManager")) {
throw new RuntimeException("java.util.logging.manager not set");
}
Logger logger = Logger.getLogger(SimpleLogManager.class.getName());
Logger.getLogger("org.foo.bar.Foo");
// a platform logger used by the system code is just a Logger instance.
PlatformLogger.getLogger("org.openjdk.core.logger");
LogManager mgr = LogManager.getLogManager();
if (mgr != CustomLogManager.INSTANCE || !(mgr instanceof SimpleLogManager)) {
throw new RuntimeException(LogManager.getLogManager() + " not SimpleLogManager");
}
checkCustomLogger(SimpleLogManager.class.getName(), null);
checkCustomLogger("org.foo.bar.Foo", null);
checkCustomLogger("org.openjdk.core.logger", "sun.util.logging.resources.logging");
// ## The LogManager.demandLogger method does not handle custom log manager
// ## that overrides the getLogger method to return a custom logger
// ## (see the test case in 8005640). Logger.getLogger may return
// ## a Logger instance but LogManager overrides it with a custom Logger
// ## instance like this case.
//
// However, the specification of LogManager and Logger subclassing is
// not clear whether this is supported or not. The following check
// just captures the current behavior.
if (logger instanceof CustomLogger) {
throw new RuntimeException(logger + " not CustomLogger");
}
}
private static void checkCustomLogger(String name, String resourceBundleName) {
CustomLogManager.checkLogger(name, resourceBundleName);
Logger logger1 = Logger.getLogger(name);
Logger logger2 = LogManager.getLogManager().getLogger(name);
if (logger1 != logger2) {
throw new RuntimeException(logger1 + " != " + logger2);
}
if (!(logger1 instanceof CustomLogger)) {
throw new RuntimeException(logger1 + " not CustomLogger");
}
}
/*
* This SimpleLogManager overrides the addLogger method to replace
* the given logger with a custom logger.
*
* It's unclear what the recommended way to use custom logger is.
* A LogManager subclass might override the getLogger method to return
* a custom Logger and create a new custom logger if not exist so that
* Logger.getLogger() can return a custom Logger instance but that violates
* the LogManager.getLogger() spec which should return null if not found.
*/
public synchronized boolean addLogger(Logger logger) {
String name = logger.getName();
if (namedLoggers.containsKey(name)) {
return false;
}
CustomLogger newLogger = new CustomLogger(logger);
super.addLogger(newLogger);
return true;
}
public class CustomLogger extends Logger {
CustomLogger(Logger logger) {
super(logger.getName(), logger.getResourceBundleName());
}
CustomLogger(String name) {
super(name, null);
}
}
}

View File

@ -29,7 +29,7 @@ import javax.net.*;
import javax.net.ssl.*; import javax.net.ssl.*;
import java.lang.reflect.*; import java.lang.reflect.*;
import sun.security.util.KeyLength; import sun.security.util.KeyUtil;
public class ShortRSAKeyWithinTLS { public class ShortRSAKeyWithinTLS {
@ -175,13 +175,13 @@ public class ShortRSAKeyWithinTLS {
privateKey = (PrivateKey)ks.getKey(keyAlias, null); privateKey = (PrivateKey)ks.getKey(keyAlias, null);
publicKey = (PublicKey)ks.getCertificate(keyAlias).getPublicKey(); publicKey = (PublicKey)ks.getCertificate(keyAlias).getPublicKey();
int privateKeySize = KeyLength.getKeySize(privateKey); int privateKeySize = KeyUtil.getKeySize(privateKey);
if (privateKeySize != keySize) { if (privateKeySize != keySize) {
throw new Exception("Expected key size is " + keySize + throw new Exception("Expected key size is " + keySize +
", but the private key size is " + privateKeySize); ", but the private key size is " + privateKeySize);
} }
int publicKeySize = KeyLength.getKeySize(publicKey); int publicKeySize = KeyUtil.getKeySize(publicKey);
if (publicKeySize != keySize) { if (publicKeySize != keySize) {
throw new Exception("Expected key size is " + keySize + throw new Exception("Expected key size is " + keySize +
", but the public key size is " + publicKeySize); ", but the public key size is " + publicKeySize);

View File

@ -23,6 +23,7 @@
/* /*
* @test * @test
* @bug 8002091
* @summary Test options patterns for javac,javah,javap and javadoc using * @summary Test options patterns for javac,javah,javap and javadoc using
* javac as a test launcher. Create a dummy javac and intercept options to check * javac as a test launcher. Create a dummy javac and intercept options to check
* reception of options as passed through the launcher without having to launch * reception of options as passed through the launcher without having to launch