mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-23 04:24:49 +02:00
Merge
This commit is contained in:
commit
32bc86d541
62 changed files with 2249 additions and 513 deletions
|
@ -50,6 +50,12 @@
|
|||
#define JAR_ERROR2 "Error: Unable to access jarfile %s"
|
||||
#define JAR_ERROR3 "Error: Invalid or corrupt jarfile %s"
|
||||
|
||||
#define CLS_ERROR1 "Error: Could not find the main class %s.\n" JNI_ERROR
|
||||
#define CLS_ERROR2 "Error: Failed to load Main Class: %s\n%s"
|
||||
#define CLS_ERROR3 "Error: No main method found in specified class.\n" GEN_ERROR
|
||||
#define CLS_ERROR4 "Error: Main method not public\n" GEN_ERROR
|
||||
#define CLS_ERROR5 "Error: main-class: attribute exceeds system limits of %d bytes\n" GEN_ERROR
|
||||
|
||||
#define CFG_WARN1 "Warning: %s VM not supported; %s VM will be used"
|
||||
#define CFG_WARN2 "Warning: No leading - on line %d of `%s'"
|
||||
#define CFG_WARN3 "Warning: Missing VM type on line %d of `%s'"
|
||||
|
|
|
@ -915,8 +915,14 @@ SelectVersion(int argc, char **argv, char **main_class)
|
|||
* to avoid locating, expanding and parsing the manifest extra
|
||||
* times.
|
||||
*/
|
||||
if (info.main_class != NULL)
|
||||
if (info.main_class != NULL) {
|
||||
if (JLI_StrLen(info.main_class) <= MAXNAMELEN) {
|
||||
(void)JLI_StrCat(env_entry, info.main_class);
|
||||
} else {
|
||||
JLI_ReportErrorMessage(CLS_ERROR5, MAXNAMELEN);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
(void)putenv(env_entry);
|
||||
ExecJRE(jre, new_argv);
|
||||
JLI_FreeManifest();
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
package com.sun.jmx.remote.internal;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -34,6 +33,7 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import java.security.AccessControlContext;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import javax.security.auth.Subject;
|
||||
|
@ -54,7 +54,10 @@ import com.sun.jmx.remote.util.EnvHelp;
|
|||
|
||||
|
||||
public abstract class ClientNotifForwarder {
|
||||
public ClientNotifForwarder(Map<String, ?> env) {
|
||||
|
||||
private final AccessControlContext acc;
|
||||
|
||||
public ClientNotifForwarder(Map env) {
|
||||
this(null, env);
|
||||
}
|
||||
|
||||
|
@ -87,6 +90,8 @@ public abstract class ClientNotifForwarder {
|
|||
this.command = command;
|
||||
if (thread == null) {
|
||||
thread = new Thread() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
while (true) {
|
||||
Runnable r;
|
||||
|
@ -130,6 +135,7 @@ public abstract class ClientNotifForwarder {
|
|||
|
||||
this.defaultClassLoader = defaultClassLoader;
|
||||
this.executor = ex;
|
||||
this.acc = AccessController.getContext();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -380,28 +386,85 @@ public abstract class ClientNotifForwarder {
|
|||
setState(TERMINATED);
|
||||
}
|
||||
|
||||
// -------------------------------------------------
|
||||
// private classes
|
||||
// -------------------------------------------------
|
||||
|
||||
// -------------------------------------------------
|
||||
// private classes
|
||||
// -------------------------------------------------
|
||||
//
|
||||
|
||||
private class NotifFetcher implements Runnable {
|
||||
|
||||
private volatile boolean alreadyLogged = false;
|
||||
|
||||
private void logOnce(String msg, SecurityException x) {
|
||||
if (alreadyLogged) return;
|
||||
// Log only once.
|
||||
logger.config("setContextClassLoader",msg);
|
||||
if (x != null) logger.fine("setContextClassLoader", x);
|
||||
alreadyLogged = true;
|
||||
}
|
||||
|
||||
// Set new context class loader, returns previous one.
|
||||
private final ClassLoader setContextClassLoader(final ClassLoader loader) {
|
||||
final AccessControlContext ctxt = ClientNotifForwarder.this.acc;
|
||||
// if ctxt is null, log a config message and throw a
|
||||
// SecurityException.
|
||||
if (ctxt == null) {
|
||||
logOnce("AccessControlContext must not be null.",null);
|
||||
throw new SecurityException("AccessControlContext must not be null");
|
||||
}
|
||||
return AccessController.doPrivileged(
|
||||
new PrivilegedAction<ClassLoader>() {
|
||||
public ClassLoader run() {
|
||||
try {
|
||||
// get context class loader - may throw
|
||||
// SecurityException - though unlikely.
|
||||
final ClassLoader previous =
|
||||
Thread.currentThread().getContextClassLoader();
|
||||
|
||||
// if nothing needs to be done, break here...
|
||||
if (loader == previous) return previous;
|
||||
|
||||
// reset context class loader - may throw
|
||||
// SecurityException
|
||||
Thread.currentThread().setContextClassLoader(loader);
|
||||
return previous;
|
||||
} catch (SecurityException x) {
|
||||
logOnce("Permission to set ContextClassLoader missing. " +
|
||||
"Notifications will not be dispatched. " +
|
||||
"Please check your Java policy configuration: " +
|
||||
x, x);
|
||||
throw x;
|
||||
}
|
||||
}
|
||||
}, ctxt);
|
||||
}
|
||||
|
||||
public void run() {
|
||||
final ClassLoader previous;
|
||||
if (defaultClassLoader != null) {
|
||||
previous = setContextClassLoader(defaultClassLoader);
|
||||
} else {
|
||||
previous = null;
|
||||
}
|
||||
try {
|
||||
doRun();
|
||||
} finally {
|
||||
if (defaultClassLoader != null) {
|
||||
setContextClassLoader(previous);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void doRun() {
|
||||
synchronized (ClientNotifForwarder.this) {
|
||||
currentFetchThread = Thread.currentThread();
|
||||
|
||||
if (state == STARTING)
|
||||
if (state == STARTING) {
|
||||
setState(STARTED);
|
||||
}
|
||||
}
|
||||
|
||||
if (defaultClassLoader != null) {
|
||||
AccessController.doPrivileged(new PrivilegedAction<Void>() {
|
||||
public Void run() {
|
||||
Thread.currentThread().
|
||||
setContextClassLoader(defaultClassLoader);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
NotificationResult nr = null;
|
||||
if (!shouldStop() && (nr = fetchNotifs()) != null) {
|
||||
|
@ -434,8 +497,9 @@ public abstract class ClientNotifForwarder {
|
|||
// check if an mbean unregistration notif
|
||||
if (!listenerID.equals(mbeanRemovedNotifID)) {
|
||||
final ClientListenerInfo li = infoList.get(listenerID);
|
||||
if (li != null)
|
||||
listeners.put(listenerID,li);
|
||||
if (li != null) {
|
||||
listeners.put(listenerID, li);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
final Notification notif = tn.getNotification();
|
||||
|
@ -799,9 +863,7 @@ public abstract class ClientNotifForwarder {
|
|||
private long clientSequenceNumber = -1;
|
||||
private final int maxNotifications;
|
||||
private final long timeout;
|
||||
|
||||
private Integer mbeanRemovedNotifID = null;
|
||||
|
||||
private Thread currentFetchThread;
|
||||
|
||||
// state
|
||||
|
|
|
@ -111,6 +111,22 @@ public abstract class MBeanServerAccessController
|
|||
*/
|
||||
protected abstract void checkWrite();
|
||||
|
||||
/**
|
||||
* Check if the caller can create the named class. The default
|
||||
* implementation of this method calls {@link #checkWrite()}.
|
||||
*/
|
||||
protected void checkCreate(String className) {
|
||||
checkWrite();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the caller can unregister the named MBean. The default
|
||||
* implementation of this method calls {@link #checkWrite()}.
|
||||
*/
|
||||
protected void checkUnregister(ObjectName name) {
|
||||
checkWrite();
|
||||
}
|
||||
|
||||
//--------------------------------------------
|
||||
//--------------------------------------------
|
||||
//
|
||||
|
@ -148,7 +164,7 @@ public abstract class MBeanServerAccessController
|
|||
}
|
||||
|
||||
/**
|
||||
* Call <code>checkWrite()</code>, then forward this method to the
|
||||
* Call <code>checkCreate(className)</code>, then forward this method to the
|
||||
* wrapped object.
|
||||
*/
|
||||
public ObjectInstance createMBean(String className, ObjectName name)
|
||||
|
@ -158,7 +174,7 @@ public abstract class MBeanServerAccessController
|
|||
MBeanRegistrationException,
|
||||
MBeanException,
|
||||
NotCompliantMBeanException {
|
||||
checkWrite();
|
||||
checkCreate(className);
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm == null) {
|
||||
Object object = getMBeanServer().instantiate(className);
|
||||
|
@ -170,7 +186,7 @@ public abstract class MBeanServerAccessController
|
|||
}
|
||||
|
||||
/**
|
||||
* Call <code>checkWrite()</code>, then forward this method to the
|
||||
* Call <code>checkCreate(className)</code>, then forward this method to the
|
||||
* wrapped object.
|
||||
*/
|
||||
public ObjectInstance createMBean(String className, ObjectName name,
|
||||
|
@ -181,7 +197,7 @@ public abstract class MBeanServerAccessController
|
|||
MBeanRegistrationException,
|
||||
MBeanException,
|
||||
NotCompliantMBeanException {
|
||||
checkWrite();
|
||||
checkCreate(className);
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm == null) {
|
||||
Object object = getMBeanServer().instantiate(className,
|
||||
|
@ -196,7 +212,7 @@ public abstract class MBeanServerAccessController
|
|||
}
|
||||
|
||||
/**
|
||||
* Call <code>checkWrite()</code>, then forward this method to the
|
||||
* Call <code>checkCreate(className)</code>, then forward this method to the
|
||||
* wrapped object.
|
||||
*/
|
||||
public ObjectInstance createMBean(String className,
|
||||
|
@ -209,7 +225,7 @@ public abstract class MBeanServerAccessController
|
|||
MBeanException,
|
||||
NotCompliantMBeanException,
|
||||
InstanceNotFoundException {
|
||||
checkWrite();
|
||||
checkCreate(className);
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm == null) {
|
||||
Object object = getMBeanServer().instantiate(className,
|
||||
|
@ -222,7 +238,7 @@ public abstract class MBeanServerAccessController
|
|||
}
|
||||
|
||||
/**
|
||||
* Call <code>checkWrite()</code>, then forward this method to the
|
||||
* Call <code>checkCreate(className)</code>, then forward this method to the
|
||||
* wrapped object.
|
||||
*/
|
||||
public ObjectInstance createMBean(String className,
|
||||
|
@ -237,7 +253,7 @@ public abstract class MBeanServerAccessController
|
|||
MBeanException,
|
||||
NotCompliantMBeanException,
|
||||
InstanceNotFoundException {
|
||||
checkWrite();
|
||||
checkCreate(className);
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm == null) {
|
||||
Object object = getMBeanServer().instantiate(className,
|
||||
|
@ -394,45 +410,45 @@ public abstract class MBeanServerAccessController
|
|||
}
|
||||
|
||||
/**
|
||||
* Call <code>checkWrite()</code>, then forward this method to the
|
||||
* Call <code>checkCreate(className)</code>, then forward this method to the
|
||||
* wrapped object.
|
||||
*/
|
||||
public Object instantiate(String className)
|
||||
throws ReflectionException, MBeanException {
|
||||
checkWrite();
|
||||
checkCreate(className);
|
||||
return getMBeanServer().instantiate(className);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call <code>checkWrite()</code>, then forward this method to the
|
||||
* Call <code>checkCreate(className)</code>, then forward this method to the
|
||||
* wrapped object.
|
||||
*/
|
||||
public Object instantiate(String className,
|
||||
Object params[],
|
||||
String signature[])
|
||||
throws ReflectionException, MBeanException {
|
||||
checkWrite();
|
||||
checkCreate(className);
|
||||
return getMBeanServer().instantiate(className, params, signature);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call <code>checkWrite()</code>, then forward this method to the
|
||||
* Call <code>checkCreate(className)</code>, then forward this method to the
|
||||
* wrapped object.
|
||||
*/
|
||||
public Object instantiate(String className, ObjectName loaderName)
|
||||
throws ReflectionException, MBeanException, InstanceNotFoundException {
|
||||
checkWrite();
|
||||
checkCreate(className);
|
||||
return getMBeanServer().instantiate(className, loaderName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call <code>checkWrite()</code>, then forward this method to the
|
||||
* Call <code>checkCreate(className)</code>, then forward this method to the
|
||||
* wrapped object.
|
||||
*/
|
||||
public Object instantiate(String className, ObjectName loaderName,
|
||||
Object params[], String signature[])
|
||||
throws ReflectionException, MBeanException, InstanceNotFoundException {
|
||||
checkWrite();
|
||||
checkCreate(className);
|
||||
return getMBeanServer().instantiate(className, loaderName,
|
||||
params, signature);
|
||||
}
|
||||
|
@ -579,12 +595,12 @@ public abstract class MBeanServerAccessController
|
|||
}
|
||||
|
||||
/**
|
||||
* Call <code>checkWrite()</code>, then forward this method to the
|
||||
* Call <code>checkUnregister()</code>, then forward this method to the
|
||||
* wrapped object.
|
||||
*/
|
||||
public void unregisterMBean(ObjectName name)
|
||||
throws InstanceNotFoundException, MBeanRegistrationException {
|
||||
checkWrite();
|
||||
checkUnregister(name);
|
||||
getMBeanServer().unregisterMBean(name);
|
||||
}
|
||||
|
||||
|
|
|
@ -31,11 +31,17 @@ import java.security.AccessControlContext;
|
|||
import java.security.AccessController;
|
||||
import java.security.Principal;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.Collection;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.management.MBeanServer;
|
||||
import javax.management.ObjectName;
|
||||
import javax.security.auth.Subject;
|
||||
|
||||
/**
|
||||
|
@ -46,7 +52,8 @@ import javax.security.auth.Subject;
|
|||
* not allowed; in this case the request is not forwarded to the
|
||||
* wrapped object.</p>
|
||||
*
|
||||
* <p>This class implements the {@link #checkRead()} and {@link #checkWrite()}
|
||||
* <p>This class implements the {@link #checkRead()}, {@link #checkWrite()},
|
||||
* {@link #checkCreate(String)}, and {@link #checkUnregister(ObjectName)}
|
||||
* methods based on an access level properties file containing username/access
|
||||
* level pairs. The set of username/access level pairs is passed either as a
|
||||
* filename which denotes a properties file on disk, or directly as an instance
|
||||
|
@ -56,14 +63,50 @@ import javax.security.auth.Subject;
|
|||
* has exactly one access level. The same access level can be shared by several
|
||||
* usernames.</p>
|
||||
*
|
||||
* <p>The supported access level values are <i>readonly</i> and
|
||||
* <i>readwrite</i>.</p>
|
||||
* <p>The supported access level values are {@code readonly} and
|
||||
* {@code readwrite}. The {@code readwrite} access level can be
|
||||
* qualified by one or more <i>clauses</i>, where each clause looks
|
||||
* like <code>create <i>classNamePattern</i></code> or {@code
|
||||
* unregister}. For example:</p>
|
||||
*
|
||||
* <pre>
|
||||
* monitorRole readonly
|
||||
* controlRole readwrite \
|
||||
* create javax.management.timer.*,javax.management.monitor.* \
|
||||
* unregister
|
||||
* </pre>
|
||||
*
|
||||
* <p>(The continuation lines with {@code \} come from the parser for
|
||||
* Properties files.)</p>
|
||||
*/
|
||||
public class MBeanServerFileAccessController
|
||||
extends MBeanServerAccessController {
|
||||
|
||||
public static final String READONLY = "readonly";
|
||||
public static final String READWRITE = "readwrite";
|
||||
static final String READONLY = "readonly";
|
||||
static final String READWRITE = "readwrite";
|
||||
|
||||
static final String CREATE = "create";
|
||||
static final String UNREGISTER = "unregister";
|
||||
|
||||
private enum AccessType {READ, WRITE, CREATE, UNREGISTER};
|
||||
|
||||
private static class Access {
|
||||
final boolean write;
|
||||
final String[] createPatterns;
|
||||
private boolean unregister;
|
||||
|
||||
Access(boolean write, boolean unregister, List<String> createPatternList) {
|
||||
this.write = write;
|
||||
int npats = (createPatternList == null) ? 0 : createPatternList.size();
|
||||
if (npats == 0)
|
||||
this.createPatterns = NO_STRINGS;
|
||||
else
|
||||
this.createPatterns = createPatternList.toArray(new String[npats]);
|
||||
this.unregister = unregister;
|
||||
}
|
||||
|
||||
private final String[] NO_STRINGS = new String[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Create a new MBeanServerAccessController that forwards all the
|
||||
|
@ -87,8 +130,8 @@ public class MBeanServerFileAccessController
|
|||
throws IOException {
|
||||
super();
|
||||
this.accessFileName = accessFileName;
|
||||
props = propertiesFromFile(accessFileName);
|
||||
checkValues(props);
|
||||
Properties props = propertiesFromFile(accessFileName);
|
||||
parseProperties(props);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -123,14 +166,14 @@ public class MBeanServerFileAccessController
|
|||
* #setMBeanServer} method after doing access checks based on read and
|
||||
* write permissions.</p>
|
||||
*
|
||||
* <p>This instance is initialized from the specified properties instance.
|
||||
* This constructor makes a copy of the properties instance using its
|
||||
* <code>clone</code> method and it is the copy that is consulted to check
|
||||
* the username and access level of an incoming connection. The original
|
||||
* properties object can be modified without affecting the copy. If the
|
||||
* {@link #refresh} method is then called, the
|
||||
* <code>MBeanServerFileAccessController</code> will make a new copy of the
|
||||
* properties object at that time.</p>
|
||||
* <p>This instance is initialized from the specified properties
|
||||
* instance. This constructor makes a copy of the properties
|
||||
* instance and it is the copy that is consulted to check the
|
||||
* username and access level of an incoming connection. The
|
||||
* original properties object can be modified without affecting
|
||||
* the copy. If the {@link #refresh} method is then called, the
|
||||
* <code>MBeanServerFileAccessController</code> will make a new
|
||||
* copy of the properties object at that time.</p>
|
||||
*
|
||||
* @param accessFileProps properties list containing the username/access
|
||||
* level entries.
|
||||
|
@ -145,8 +188,7 @@ public class MBeanServerFileAccessController
|
|||
if (accessFileProps == null)
|
||||
throw new IllegalArgumentException("Null properties");
|
||||
originalProps = accessFileProps;
|
||||
props = (Properties) accessFileProps.clone();
|
||||
checkValues(props);
|
||||
parseProperties(accessFileProps);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -155,14 +197,14 @@ public class MBeanServerFileAccessController
|
|||
* #setMBeanServer} method after doing access checks based on read and
|
||||
* write permissions.</p>
|
||||
*
|
||||
* <p>This instance is initialized from the specified properties instance.
|
||||
* This constructor makes a copy of the properties instance using its
|
||||
* <code>clone</code> method and it is the copy that is consulted to check
|
||||
* the username and access level of an incoming connection. The original
|
||||
* properties object can be modified without affecting the copy. If the
|
||||
* {@link #refresh} method is then called, the
|
||||
* <code>MBeanServerFileAccessController</code> will make a new copy of the
|
||||
* properties object at that time.</p>
|
||||
* <p>This instance is initialized from the specified properties
|
||||
* instance. This constructor makes a copy of the properties
|
||||
* instance and it is the copy that is consulted to check the
|
||||
* username and access level of an incoming connection. The
|
||||
* original properties object can be modified without affecting
|
||||
* the copy. If the {@link #refresh} method is then called, the
|
||||
* <code>MBeanServerFileAccessController</code> will make a new
|
||||
* copy of the properties object at that time.</p>
|
||||
*
|
||||
* @param accessFileProps properties list containing the username/access
|
||||
* level entries.
|
||||
|
@ -184,16 +226,36 @@ public class MBeanServerFileAccessController
|
|||
* Check if the caller can do read operations. This method does
|
||||
* nothing if so, otherwise throws SecurityException.
|
||||
*/
|
||||
@Override
|
||||
public void checkRead() {
|
||||
checkAccessLevel(READONLY);
|
||||
checkAccess(AccessType.READ, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the caller can do write operations. This method does
|
||||
* nothing if so, otherwise throws SecurityException.
|
||||
*/
|
||||
@Override
|
||||
public void checkWrite() {
|
||||
checkAccessLevel(READWRITE);
|
||||
checkAccess(AccessType.WRITE, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the caller can create MBeans or instances of the given class.
|
||||
* This method does nothing if so, otherwise throws SecurityException.
|
||||
*/
|
||||
@Override
|
||||
public void checkCreate(String className) {
|
||||
checkAccess(AccessType.CREATE, className);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the caller can do unregister operations. This method does
|
||||
* nothing if so, otherwise throws SecurityException.
|
||||
*/
|
||||
@Override
|
||||
public void checkUnregister(ObjectName name) {
|
||||
checkAccess(AccessType.UNREGISTER, null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -218,14 +280,13 @@ public class MBeanServerFileAccessController
|
|||
* @exception IllegalArgumentException if any of the supplied access
|
||||
* level values differs from "readonly" or "readwrite".
|
||||
*/
|
||||
public void refresh() throws IOException {
|
||||
synchronized (props) {
|
||||
public synchronized void refresh() throws IOException {
|
||||
Properties props;
|
||||
if (accessFileName == null)
|
||||
props = (Properties) originalProps.clone();
|
||||
props = (Properties) originalProps;
|
||||
else
|
||||
props = propertiesFromFile(accessFileName);
|
||||
checkValues(props);
|
||||
}
|
||||
parseProperties(props);
|
||||
}
|
||||
|
||||
private static Properties propertiesFromFile(String fname)
|
||||
|
@ -240,7 +301,7 @@ public class MBeanServerFileAccessController
|
|||
}
|
||||
}
|
||||
|
||||
private void checkAccessLevel(String accessLevel) {
|
||||
private synchronized void checkAccess(AccessType requiredAccess, String arg) {
|
||||
final AccessControlContext acc = AccessController.getContext();
|
||||
final Subject s =
|
||||
AccessController.doPrivileged(new PrivilegedAction<Subject>() {
|
||||
|
@ -249,39 +310,235 @@ public class MBeanServerFileAccessController
|
|||
}
|
||||
});
|
||||
if (s == null) return; /* security has not been enabled */
|
||||
final Set<Principal> principals = s.getPrincipals();
|
||||
for (Principal p : principals) {
|
||||
String grantedAccessLevel;
|
||||
synchronized (props) {
|
||||
grantedAccessLevel = props.getProperty(p.getName());
|
||||
final Set principals = s.getPrincipals();
|
||||
String newPropertyValue = null;
|
||||
for (Iterator i = principals.iterator(); i.hasNext(); ) {
|
||||
final Principal p = (Principal) i.next();
|
||||
Access access = accessMap.get(p.getName());
|
||||
if (access != null) {
|
||||
boolean ok;
|
||||
switch (requiredAccess) {
|
||||
case READ:
|
||||
ok = true; // all access entries imply read
|
||||
break;
|
||||
case WRITE:
|
||||
ok = access.write;
|
||||
break;
|
||||
case UNREGISTER:
|
||||
ok = access.unregister;
|
||||
if (!ok && access.write)
|
||||
newPropertyValue = "unregister";
|
||||
break;
|
||||
case CREATE:
|
||||
ok = checkCreateAccess(access, arg);
|
||||
if (!ok && access.write)
|
||||
newPropertyValue = "create " + arg;
|
||||
break;
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
if (grantedAccessLevel != null) {
|
||||
if (accessLevel.equals(READONLY) &&
|
||||
(grantedAccessLevel.equals(READONLY) ||
|
||||
grantedAccessLevel.equals(READWRITE)))
|
||||
return;
|
||||
if (accessLevel.equals(READWRITE) &&
|
||||
grantedAccessLevel.equals(READWRITE))
|
||||
if (ok)
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new SecurityException("Access denied! Invalid access level for " +
|
||||
"requested MBeanServer operation.");
|
||||
SecurityException se = new SecurityException("Access denied! Invalid " +
|
||||
"access level for requested MBeanServer operation.");
|
||||
// Add some more information to help people with deployments that
|
||||
// worked before we required explicit create clauses. We're not giving
|
||||
// any information to the bad guys, other than that the access control
|
||||
// is based on a file, which they could have worked out from the stack
|
||||
// trace anyway.
|
||||
if (newPropertyValue != null) {
|
||||
SecurityException se2 = new SecurityException("Access property " +
|
||||
"for this identity should be similar to: " + READWRITE +
|
||||
" " + newPropertyValue);
|
||||
se.initCause(se2);
|
||||
}
|
||||
throw se;
|
||||
}
|
||||
|
||||
private void checkValues(Properties props) {
|
||||
Collection<?> c = props.values();
|
||||
for (Iterator<?> i = c.iterator(); i.hasNext(); ) {
|
||||
final String accessLevel = (String) i.next();
|
||||
if (!accessLevel.equals(READONLY) &&
|
||||
!accessLevel.equals(READWRITE)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Syntax error in access level entry [" + accessLevel + "]");
|
||||
private static boolean checkCreateAccess(Access access, String className) {
|
||||
for (String classNamePattern : access.createPatterns) {
|
||||
if (classNameMatch(classNamePattern, className))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean classNameMatch(String pattern, String className) {
|
||||
// We studiously avoided regexes when parsing the properties file,
|
||||
// because that is done whenever the VM is started with the
|
||||
// appropriate -Dcom.sun.management options, even if nobody ever
|
||||
// creates an MBean. We don't want to incur the overhead of loading
|
||||
// all the regex code whenever those options are specified, but if we
|
||||
// get as far as here then the VM is already running and somebody is
|
||||
// doing the very unusual operation of remotely creating an MBean.
|
||||
// Because that operation is so unusual, we don't try to optimize
|
||||
// by hand-matching or by caching compiled Pattern objects.
|
||||
StringBuilder sb = new StringBuilder();
|
||||
StringTokenizer stok = new StringTokenizer(pattern, "*", true);
|
||||
while (stok.hasMoreTokens()) {
|
||||
String tok = stok.nextToken();
|
||||
if (tok.equals("*"))
|
||||
sb.append("[^.]*");
|
||||
else
|
||||
sb.append(Pattern.quote(tok));
|
||||
}
|
||||
return className.matches(sb.toString());
|
||||
}
|
||||
|
||||
private void parseProperties(Properties props) {
|
||||
this.accessMap = new HashMap<String, Access>();
|
||||
for (Map.Entry<Object, Object> entry : props.entrySet()) {
|
||||
String identity = (String) entry.getKey();
|
||||
String accessString = (String) entry.getValue();
|
||||
Access access = Parser.parseAccess(identity, accessString);
|
||||
accessMap.put(identity, access);
|
||||
}
|
||||
}
|
||||
|
||||
private Properties props;
|
||||
private static class Parser {
|
||||
private final static int EOS = -1; // pseudo-codepoint "end of string"
|
||||
static {
|
||||
assert !Character.isWhitespace(EOS);
|
||||
}
|
||||
|
||||
private final String identity; // just for better error messages
|
||||
private final String s; // the string we're parsing
|
||||
private final int len; // s.length()
|
||||
private int i;
|
||||
private int c;
|
||||
// At any point, either c is s.codePointAt(i), or i == len and
|
||||
// c is EOS. We use int rather than char because it is conceivable
|
||||
// (if unlikely) that a classname in a create clause might contain
|
||||
// "supplementary characters", the ones that don't fit in the original
|
||||
// 16 bits for Unicode.
|
||||
|
||||
private Parser(String identity, String s) {
|
||||
this.identity = identity;
|
||||
this.s = s;
|
||||
this.len = s.length();
|
||||
this.i = 0;
|
||||
if (i < len)
|
||||
this.c = s.codePointAt(i);
|
||||
else
|
||||
this.c = EOS;
|
||||
}
|
||||
|
||||
static Access parseAccess(String identity, String s) {
|
||||
return new Parser(identity, s).parseAccess();
|
||||
}
|
||||
|
||||
private Access parseAccess() {
|
||||
skipSpace();
|
||||
String type = parseWord();
|
||||
Access access;
|
||||
if (type.equals(READONLY))
|
||||
access = new Access(false, false, null);
|
||||
else if (type.equals(READWRITE))
|
||||
access = parseReadWrite();
|
||||
else {
|
||||
throw syntax("Expected " + READONLY + " or " + READWRITE +
|
||||
": " + type);
|
||||
}
|
||||
if (c != EOS)
|
||||
throw syntax("Extra text at end of line");
|
||||
return access;
|
||||
}
|
||||
|
||||
private Access parseReadWrite() {
|
||||
List<String> createClasses = new ArrayList<String>();
|
||||
boolean unregister = false;
|
||||
while (true) {
|
||||
skipSpace();
|
||||
if (c == EOS)
|
||||
break;
|
||||
String type = parseWord();
|
||||
if (type.equals(UNREGISTER))
|
||||
unregister = true;
|
||||
else if (type.equals(CREATE))
|
||||
parseCreate(createClasses);
|
||||
else
|
||||
throw syntax("Unrecognized keyword " + type);
|
||||
}
|
||||
return new Access(true, unregister, createClasses);
|
||||
}
|
||||
|
||||
private void parseCreate(List<String> createClasses) {
|
||||
while (true) {
|
||||
skipSpace();
|
||||
createClasses.add(parseClassName());
|
||||
skipSpace();
|
||||
if (c == ',')
|
||||
next();
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private String parseClassName() {
|
||||
// We don't check that classname components begin with suitable
|
||||
// characters (so we accept 1.2.3 for example). This means that
|
||||
// there are only two states, which we can call dotOK and !dotOK
|
||||
// according as a dot (.) is legal or not. Initially we're in
|
||||
// !dotOK since a classname can't start with a dot; after a dot
|
||||
// we're in !dotOK again; and after any other characters we're in
|
||||
// dotOK. The classname is only accepted if we end in dotOK,
|
||||
// so we reject an empty name or a name that ends with a dot.
|
||||
final int start = i;
|
||||
boolean dotOK = false;
|
||||
while (true) {
|
||||
if (c == '.') {
|
||||
if (!dotOK)
|
||||
throw syntax("Bad . in class name");
|
||||
dotOK = false;
|
||||
} else if (c == '*' || Character.isJavaIdentifierPart(c))
|
||||
dotOK = true;
|
||||
else
|
||||
break;
|
||||
next();
|
||||
}
|
||||
String className = s.substring(start, i);
|
||||
if (!dotOK)
|
||||
throw syntax("Bad class name " + className);
|
||||
return className;
|
||||
}
|
||||
|
||||
// Advance c and i to the next character, unless already at EOS.
|
||||
private void next() {
|
||||
if (c != EOS) {
|
||||
i += Character.charCount(c);
|
||||
if (i < len)
|
||||
c = s.codePointAt(i);
|
||||
else
|
||||
c = EOS;
|
||||
}
|
||||
}
|
||||
|
||||
private void skipSpace() {
|
||||
while (Character.isWhitespace(c))
|
||||
next();
|
||||
}
|
||||
|
||||
private String parseWord() {
|
||||
skipSpace();
|
||||
if (c == EOS)
|
||||
throw syntax("Expected word at end of line");
|
||||
final int start = i;
|
||||
while (c != EOS && !Character.isWhitespace(c))
|
||||
next();
|
||||
String word = s.substring(start, i);
|
||||
skipSpace();
|
||||
return word;
|
||||
}
|
||||
|
||||
private IllegalArgumentException syntax(String msg) {
|
||||
return new IllegalArgumentException(
|
||||
msg + " [" + identity + " " + s + "]");
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, Access> accessMap;
|
||||
private Properties originalProps;
|
||||
private String accessFileName;
|
||||
}
|
||||
|
|
|
@ -302,7 +302,16 @@ final public class LdapCtx extends ComponentDirContext
|
|||
|
||||
schemaTrees = new Hashtable(11, 0.75f);
|
||||
initEnv();
|
||||
try {
|
||||
connect(false);
|
||||
} catch (NamingException e) {
|
||||
try {
|
||||
close();
|
||||
} catch (Exception e2) {
|
||||
// Nothing
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
LdapCtx(LdapCtx existing, String newDN) throws NamingException {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 1999 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1999-2009 Sun Microsystems, Inc. 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
|
||||
|
@ -33,12 +33,33 @@ import java.security.PrivilegedAction;
|
|||
|
||||
final class VersionHelper12 extends VersionHelper {
|
||||
|
||||
// System property to control whether classes may be loaded from an
|
||||
// arbitrary URL code base.
|
||||
private static final String TRUST_URL_CODEBASE_PROPERTY =
|
||||
"com.sun.jndi.ldap.object.trustURLCodebase";
|
||||
|
||||
// Determine whether classes may be loaded from an arbitrary URL code base.
|
||||
private static final String trustURLCodebase =
|
||||
AccessController.doPrivileged(
|
||||
new PrivilegedAction<String>() {
|
||||
public String run() {
|
||||
return System.getProperty(TRUST_URL_CODEBASE_PROPERTY,
|
||||
"false");
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
VersionHelper12() {} // Disallow external from creating one of these.
|
||||
|
||||
ClassLoader getURLClassLoader(String[] url)
|
||||
throws MalformedURLException {
|
||||
ClassLoader parent = getContextClassLoader();
|
||||
if (url != null) {
|
||||
/*
|
||||
* Classes may only be loaded from an arbitrary URL code base when
|
||||
* the system property com.sun.jndi.ldap.object.trustURLCodebase
|
||||
* has been set to "true".
|
||||
*/
|
||||
if (url != null && "true".equalsIgnoreCase(trustURLCodebase)) {
|
||||
return URLClassLoader.newInstance(getUrlArray(url), parent);
|
||||
} else {
|
||||
return parent;
|
||||
|
|
|
@ -37,6 +37,8 @@ import java.awt.geom.Rectangle2D;
|
|||
import java.awt.peer.FontPeer;
|
||||
import java.io.*;
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.text.AttributedCharacterIterator.Attribute;
|
||||
import java.text.CharacterIterator;
|
||||
import java.text.StringCharacterIterator;
|
||||
|
@ -51,6 +53,7 @@ import sun.font.AttributeMap;
|
|||
import sun.font.AttributeValues;
|
||||
import sun.font.EAttribute;
|
||||
import sun.font.CompositeFont;
|
||||
import sun.font.CreatedFontTracker;
|
||||
import sun.font.Font2D;
|
||||
import sun.font.Font2DHandle;
|
||||
import sun.font.FontManager;
|
||||
|
@ -575,14 +578,16 @@ public class Font implements java.io.Serializable
|
|||
}
|
||||
|
||||
/* used to implement Font.createFont */
|
||||
private Font(File fontFile, int fontFormat, boolean isCopy)
|
||||
private Font(File fontFile, int fontFormat,
|
||||
boolean isCopy, CreatedFontTracker tracker)
|
||||
throws FontFormatException {
|
||||
this.createdFont = true;
|
||||
/* Font2D instances created by this method track their font file
|
||||
* so that when the Font2D is GC'd it can also remove the file.
|
||||
*/
|
||||
this.font2DHandle =
|
||||
FontManager.createFont2D(fontFile, fontFormat, isCopy).handle;
|
||||
FontManager.createFont2D(fontFile, fontFormat,
|
||||
isCopy, tracker).handle;
|
||||
this.name = this.font2DHandle.font2D.getFontName(Locale.getDefault());
|
||||
this.style = Font.PLAIN;
|
||||
this.size = 1;
|
||||
|
@ -787,6 +792,29 @@ public class Font implements java.io.Serializable
|
|||
return new Font(attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used with the byte count tracker for fonts created from streams.
|
||||
* If a thread can create temp files anyway, no point in counting
|
||||
* font bytes.
|
||||
*/
|
||||
private static boolean hasTempPermission() {
|
||||
|
||||
if (System.getSecurityManager() == null) {
|
||||
return true;
|
||||
}
|
||||
File f = null;
|
||||
boolean hasPerm = false;
|
||||
try {
|
||||
f = File.createTempFile("+~JT", ".tmp", null);
|
||||
f.delete();
|
||||
f = null;
|
||||
hasPerm = true;
|
||||
} catch (Throwable t) {
|
||||
/* inc. any kind of SecurityException */
|
||||
}
|
||||
return hasPerm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new <code>Font</code> using the specified font type
|
||||
* and input data. The new <code>Font</code> is
|
||||
|
@ -822,58 +850,96 @@ public class Font implements java.io.Serializable
|
|||
fontFormat != Font.TYPE1_FONT) {
|
||||
throw new IllegalArgumentException ("font format not recognized");
|
||||
}
|
||||
final InputStream fStream = fontStream;
|
||||
Object ret = java.security.AccessController.doPrivileged(
|
||||
new java.security.PrivilegedAction() {
|
||||
public Object run() {
|
||||
File tFile = null;
|
||||
FileOutputStream outStream = null;
|
||||
boolean copiedFontData = false;
|
||||
|
||||
try {
|
||||
tFile = File.createTempFile("+~JF", ".tmp", null);
|
||||
/* Temp file deleted by font shutdown hook */
|
||||
BufferedInputStream inStream =
|
||||
new BufferedInputStream(fStream);
|
||||
outStream = new FileOutputStream(tFile);
|
||||
int bytesRead = 0;
|
||||
int bufSize = 8192;
|
||||
byte [] buf = new byte[bufSize];
|
||||
while (bytesRead != -1) {
|
||||
try {
|
||||
bytesRead = inStream.read(buf, 0, bufSize);
|
||||
} catch (Throwable t) {
|
||||
throw new IOException();
|
||||
final File tFile = AccessController.doPrivileged(
|
||||
new PrivilegedExceptionAction<File>() {
|
||||
public File run() throws IOException {
|
||||
return File.createTempFile("+~JF", ".tmp", null);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
int totalSize = 0;
|
||||
CreatedFontTracker tracker = null;
|
||||
try {
|
||||
final OutputStream outStream =
|
||||
AccessController.doPrivileged(
|
||||
new PrivilegedExceptionAction<OutputStream>() {
|
||||
public OutputStream run() throws IOException {
|
||||
return new FileOutputStream(tFile);
|
||||
}
|
||||
}
|
||||
);
|
||||
if (!hasTempPermission()) {
|
||||
tracker = CreatedFontTracker.getTracker();
|
||||
}
|
||||
try {
|
||||
byte[] buf = new byte[8192];
|
||||
for (;;) {
|
||||
int bytesRead = fontStream.read(buf);
|
||||
if (bytesRead < 0) {
|
||||
break;
|
||||
}
|
||||
if (tracker != null) {
|
||||
if (totalSize+bytesRead > tracker.MAX_FILE_SIZE) {
|
||||
throw new IOException("File too big.");
|
||||
}
|
||||
if (totalSize+tracker.getNumBytes() >
|
||||
tracker.MAX_TOTAL_BYTES)
|
||||
{
|
||||
throw new IOException("Total files too big.");
|
||||
}
|
||||
totalSize += bytesRead;
|
||||
tracker.addBytes(bytesRead);
|
||||
}
|
||||
if (bytesRead != -1) {
|
||||
outStream.write(buf, 0, bytesRead);
|
||||
}
|
||||
}
|
||||
/* don't close the input stream */
|
||||
} finally {
|
||||
outStream.close();
|
||||
} catch (IOException e) {
|
||||
if (outStream != null) {
|
||||
try {
|
||||
outStream.close();
|
||||
} catch (Exception e1) {
|
||||
}
|
||||
/* After all references to a Font2D are dropped, the file
|
||||
* will be removed. To support long-lived AppContexts,
|
||||
* we need to then decrement the byte count by the size
|
||||
* of the file.
|
||||
* If the data isn't a valid font, the implementation will
|
||||
* delete the tmp file and decrement the byte count
|
||||
* in the tracker object before returning from the
|
||||
* constructor, so we can set 'copiedFontData' to true here
|
||||
* without waiting for the results of that constructor.
|
||||
*/
|
||||
copiedFontData = true;
|
||||
Font font = new Font(tFile, fontFormat, true, tracker);
|
||||
return font;
|
||||
} finally {
|
||||
if (!copiedFontData) {
|
||||
if (tracker != null) {
|
||||
tracker.subBytes(totalSize);
|
||||
}
|
||||
if (tFile != null) {
|
||||
try {
|
||||
AccessController.doPrivileged(
|
||||
new PrivilegedExceptionAction<Void>() {
|
||||
public Void run() {
|
||||
tFile.delete();
|
||||
} catch (Exception e2) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return e;
|
||||
);
|
||||
}
|
||||
return tFile;
|
||||
}
|
||||
});
|
||||
|
||||
if (ret instanceof File) {
|
||||
return new Font((File)ret, fontFormat, true);
|
||||
} else if (ret instanceof IOException) {
|
||||
throw (IOException)ret;
|
||||
} else {
|
||||
throw new FontFormatException("Couldn't access font stream");
|
||||
} catch (Throwable t) {
|
||||
if (t instanceof FontFormatException) {
|
||||
throw (FontFormatException)t;
|
||||
}
|
||||
if (t instanceof IOException) {
|
||||
throw (IOException)t;
|
||||
}
|
||||
Throwable cause = t.getCause();
|
||||
if (cause instanceof FontFormatException) {
|
||||
throw (FontFormatException)cause;
|
||||
}
|
||||
throw new IOException("Problem reading font data.");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -913,6 +979,9 @@ public class Font implements java.io.Serializable
|
|||
*/
|
||||
public static Font createFont(int fontFormat, File fontFile)
|
||||
throws java.awt.FontFormatException, java.io.IOException {
|
||||
|
||||
fontFile = new File(fontFile.getPath());
|
||||
|
||||
if (fontFormat != Font.TRUETYPE_FONT &&
|
||||
fontFormat != Font.TYPE1_FONT) {
|
||||
throw new IllegalArgumentException ("font format not recognized");
|
||||
|
@ -926,7 +995,7 @@ public class Font implements java.io.Serializable
|
|||
if (!fontFile.canRead()) {
|
||||
throw new IOException("Can't read " + fontFile);
|
||||
}
|
||||
return new Font(fontFile, fontFormat, false);
|
||||
return new Font(fontFile, fontFormat, false, null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -41,9 +41,14 @@ package java.util;
|
|||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.OptionalDataException;
|
||||
import java.io.Serializable;
|
||||
import java.security.AccessControlContext;
|
||||
import java.security.AccessController;
|
||||
import java.security.PermissionCollection;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.security.ProtectionDomain;
|
||||
import java.text.DateFormat;
|
||||
import java.text.DateFormatSymbols;
|
||||
import sun.util.BuddhistCalendar;
|
||||
|
@ -2628,6 +2633,18 @@ public abstract class Calendar implements Serializable, Cloneable, Comparable<Ca
|
|||
}
|
||||
}
|
||||
|
||||
private static class CalendarAccessControlContext {
|
||||
private static final AccessControlContext INSTANCE;
|
||||
static {
|
||||
RuntimePermission perm = new RuntimePermission("accessClassInPackage.sun.util.calendar");
|
||||
PermissionCollection perms = perm.newPermissionCollection();
|
||||
perms.add(perm);
|
||||
INSTANCE = new AccessControlContext(new ProtectionDomain[] {
|
||||
new ProtectionDomain(null, perms)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reconstitutes this object from a stream (i.e., deserialize it).
|
||||
*/
|
||||
|
@ -2657,18 +2674,31 @@ public abstract class Calendar implements Serializable, Cloneable, Comparable<Ca
|
|||
serialVersionOnStream = currentSerialVersion;
|
||||
|
||||
// If there's a ZoneInfo object, use it for zone.
|
||||
ZoneInfo zi = null;
|
||||
try {
|
||||
ZoneInfo zi = (ZoneInfo) AccessController.doPrivileged(
|
||||
new PrivilegedExceptionAction() {
|
||||
public Object run() throws Exception {
|
||||
return input.readObject();
|
||||
zi = AccessController.doPrivileged(
|
||||
new PrivilegedExceptionAction<ZoneInfo>() {
|
||||
public ZoneInfo run() throws Exception {
|
||||
return (ZoneInfo) input.readObject();
|
||||
}
|
||||
},
|
||||
CalendarAccessControlContext.INSTANCE);
|
||||
} catch (PrivilegedActionException pae) {
|
||||
Exception e = pae.getException();
|
||||
if (!(e instanceof OptionalDataException)) {
|
||||
if (e instanceof RuntimeException) {
|
||||
throw (RuntimeException) e;
|
||||
} else if (e instanceof IOException) {
|
||||
throw (IOException) e;
|
||||
} else if (e instanceof ClassNotFoundException) {
|
||||
throw (ClassNotFoundException) e;
|
||||
}
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
if (zi != null) {
|
||||
zone = zi;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
|
||||
// If the deserialized object has a SimpleTimeZone, try to
|
||||
// replace it with a ZoneInfo equivalent (as of 1.4) in order
|
||||
|
@ -2676,9 +2706,9 @@ public abstract class Calendar implements Serializable, Cloneable, Comparable<Ca
|
|||
// implementation as much as possible.
|
||||
if (zone instanceof SimpleTimeZone) {
|
||||
String id = zone.getID();
|
||||
TimeZone zi = TimeZone.getTimeZone(id);
|
||||
if (zi != null && zi.hasSameRules(zone) && zi.getID().equals(id)) {
|
||||
zone = zi;
|
||||
TimeZone tz = TimeZone.getTimeZone(id);
|
||||
if (tz != null && tz.hasSameRules(zone) && tz.getID().equals(id)) {
|
||||
zone = tz;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -599,7 +599,7 @@ public class CounterMonitor extends Monitor implements CounterMonitorMBean {
|
|||
*/
|
||||
@Override
|
||||
public MBeanNotificationInfo[] getNotificationInfo() {
|
||||
return notifsInfo;
|
||||
return notifsInfo.clone();
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -481,7 +481,7 @@ public class GaugeMonitor extends Monitor implements GaugeMonitorMBean {
|
|||
*/
|
||||
@Override
|
||||
public MBeanNotificationInfo[] getNotificationInfo() {
|
||||
return notifsInfo;
|
||||
return notifsInfo.clone();
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -32,7 +32,10 @@ import java.io.IOException;
|
|||
import java.security.AccessControlContext;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.ProtectionDomain;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
|
@ -163,7 +166,10 @@ public abstract class Monitor
|
|||
/**
|
||||
* AccessControlContext of the Monitor.start() caller.
|
||||
*/
|
||||
private AccessControlContext acc;
|
||||
private static final AccessControlContext noPermissionsACC =
|
||||
new AccessControlContext(
|
||||
new ProtectionDomain[] {new ProtectionDomain(null, null)});
|
||||
private volatile AccessControlContext acc = noPermissionsACC;
|
||||
|
||||
/**
|
||||
* Scheduler Service.
|
||||
|
@ -172,15 +178,21 @@ public abstract class Monitor
|
|||
Executors.newSingleThreadScheduledExecutor(
|
||||
new DaemonThreadFactory("Scheduler"));
|
||||
|
||||
/**
|
||||
* Map containing the thread pool executor per thread group.
|
||||
*/
|
||||
private static final Map<ThreadPoolExecutor, Void> executors =
|
||||
new WeakHashMap<ThreadPoolExecutor, Void>();
|
||||
|
||||
/**
|
||||
* Lock for executors map.
|
||||
*/
|
||||
private static final Object executorsLock = new Object();
|
||||
|
||||
/**
|
||||
* Maximum Pool Size
|
||||
*/
|
||||
private static final int maximumPoolSize;
|
||||
|
||||
/**
|
||||
* Executor Service.
|
||||
*/
|
||||
private static final ThreadPoolExecutor executor;
|
||||
static {
|
||||
final String maximumPoolSizeSysProp = "jmx.x.monitor.maximum.pool.size";
|
||||
final String maximumPoolSizeStr = AccessController.doPrivileged(
|
||||
|
@ -210,21 +222,8 @@ public abstract class Monitor
|
|||
maximumPoolSize = maximumPoolSizeTmp;
|
||||
}
|
||||
}
|
||||
executor = new ThreadPoolExecutor(
|
||||
maximumPoolSize,
|
||||
maximumPoolSize,
|
||||
60L,
|
||||
TimeUnit.SECONDS,
|
||||
new LinkedBlockingQueue<Runnable>(),
|
||||
new DaemonThreadFactory("Executor"));
|
||||
executor.allowCoreThreadTimeOut(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Monitor task to be executed by the Executor Service.
|
||||
*/
|
||||
private final MonitorTask monitorTask = new MonitorTask();
|
||||
|
||||
/**
|
||||
* Future associated to the current monitor task.
|
||||
*/
|
||||
|
@ -233,7 +232,7 @@ public abstract class Monitor
|
|||
/**
|
||||
* Scheduler task to be executed by the Scheduler Service.
|
||||
*/
|
||||
private final SchedulerTask schedulerTask = new SchedulerTask(monitorTask);
|
||||
private final SchedulerTask schedulerTask = new SchedulerTask();
|
||||
|
||||
/**
|
||||
* ScheduledFuture associated to the current scheduler task.
|
||||
|
@ -719,6 +718,7 @@ public abstract class Monitor
|
|||
// Start the scheduler.
|
||||
//
|
||||
cleanupFutures();
|
||||
schedulerTask.setMonitorTask(new MonitorTask());
|
||||
schedulerFuture = scheduler.schedule(schedulerTask,
|
||||
getGranularityPeriod(),
|
||||
TimeUnit.MILLISECONDS);
|
||||
|
@ -748,7 +748,7 @@ public abstract class Monitor
|
|||
|
||||
// Reset the AccessControlContext.
|
||||
//
|
||||
acc = null;
|
||||
acc = noPermissionsACC;
|
||||
|
||||
// Reset the complex type attribute information
|
||||
// such that it is recalculated again.
|
||||
|
@ -1467,7 +1467,7 @@ public abstract class Monitor
|
|||
*/
|
||||
private class SchedulerTask implements Runnable {
|
||||
|
||||
private Runnable task = null;
|
||||
private MonitorTask task;
|
||||
|
||||
/*
|
||||
* ------------------------------------------
|
||||
|
@ -1475,7 +1475,16 @@ public abstract class Monitor
|
|||
* ------------------------------------------
|
||||
*/
|
||||
|
||||
public SchedulerTask(Runnable task) {
|
||||
public SchedulerTask() {
|
||||
}
|
||||
|
||||
/*
|
||||
* ------------------------------------------
|
||||
* GETTERS/SETTERS
|
||||
* ------------------------------------------
|
||||
*/
|
||||
|
||||
public void setMonitorTask(MonitorTask task) {
|
||||
this.task = task;
|
||||
}
|
||||
|
||||
|
@ -1487,7 +1496,7 @@ public abstract class Monitor
|
|||
|
||||
public void run() {
|
||||
synchronized (Monitor.this) {
|
||||
Monitor.this.monitorFuture = executor.submit(task);
|
||||
Monitor.this.monitorFuture = task.submit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1500,6 +1509,8 @@ public abstract class Monitor
|
|||
*/
|
||||
private class MonitorTask implements Runnable {
|
||||
|
||||
private ThreadPoolExecutor executor;
|
||||
|
||||
/*
|
||||
* ------------------------------------------
|
||||
* CONSTRUCTORS
|
||||
|
@ -1507,6 +1518,38 @@ public abstract class Monitor
|
|||
*/
|
||||
|
||||
public MonitorTask() {
|
||||
// Find out if there's already an existing executor for the calling
|
||||
// thread and reuse it. Otherwise, create a new one and store it in
|
||||
// the executors map. If there is a SecurityManager, the group of
|
||||
// System.getSecurityManager() is used, else the group of the thread
|
||||
// instantiating this MonitorTask, i.e. the group of the thread that
|
||||
// calls "Monitor.start()".
|
||||
SecurityManager s = System.getSecurityManager();
|
||||
ThreadGroup group = (s != null) ? s.getThreadGroup() :
|
||||
Thread.currentThread().getThreadGroup();
|
||||
synchronized (executorsLock) {
|
||||
for (ThreadPoolExecutor e : executors.keySet()) {
|
||||
DaemonThreadFactory tf =
|
||||
(DaemonThreadFactory) e.getThreadFactory();
|
||||
ThreadGroup tg = tf.getThreadGroup();
|
||||
if (tg == group) {
|
||||
executor = e;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (executor == null) {
|
||||
executor = new ThreadPoolExecutor(
|
||||
maximumPoolSize,
|
||||
maximumPoolSize,
|
||||
60L,
|
||||
TimeUnit.SECONDS,
|
||||
new LinkedBlockingQueue<Runnable>(),
|
||||
new DaemonThreadFactory("ThreadGroup<" +
|
||||
group.getName() + "> Executor", group));
|
||||
executor.allowCoreThreadTimeOut(true);
|
||||
executors.put(executor, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1515,12 +1558,18 @@ public abstract class Monitor
|
|||
* ------------------------------------------
|
||||
*/
|
||||
|
||||
public Future<?> submit() {
|
||||
return executor.submit(this);
|
||||
}
|
||||
|
||||
public void run() {
|
||||
final ScheduledFuture<?> sf;
|
||||
final AccessControlContext ac;
|
||||
synchronized (Monitor.this) {
|
||||
sf = Monitor.this.schedulerFuture;
|
||||
ac = Monitor.this.acc;
|
||||
}
|
||||
AccessController.doPrivileged(new PrivilegedAction<Void>() {
|
||||
PrivilegedAction<Void> action = new PrivilegedAction<Void>() {
|
||||
public Void run() {
|
||||
if (Monitor.this.isActive()) {
|
||||
final int an[] = alreadyNotifieds;
|
||||
|
@ -1533,7 +1582,11 @@ public abstract class Monitor
|
|||
}
|
||||
return null;
|
||||
}
|
||||
}, Monitor.this.acc);
|
||||
};
|
||||
if (ac == null) {
|
||||
throw new SecurityException("AccessControlContext cannot be null");
|
||||
}
|
||||
AccessController.doPrivileged(action, ac);
|
||||
synchronized (Monitor.this) {
|
||||
if (Monitor.this.isActive() &&
|
||||
Monitor.this.schedulerFuture == sf) {
|
||||
|
@ -1573,6 +1626,15 @@ public abstract class Monitor
|
|||
namePrefix = "JMX Monitor " + poolName + " Pool [Thread-";
|
||||
}
|
||||
|
||||
public DaemonThreadFactory(String poolName, ThreadGroup threadGroup) {
|
||||
group = threadGroup;
|
||||
namePrefix = "JMX Monitor " + poolName + " Pool [Thread-";
|
||||
}
|
||||
|
||||
public ThreadGroup getThreadGroup() {
|
||||
return group;
|
||||
}
|
||||
|
||||
public Thread newThread(Runnable r) {
|
||||
Thread t = new Thread(group,
|
||||
r,
|
||||
|
|
|
@ -184,6 +184,7 @@ public class StringMonitor extends Monitor implements StringMonitorMBean {
|
|||
* @return The derived gauge of the specified object.
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public synchronized String getDerivedGauge(ObjectName object) {
|
||||
return (String) super.getDerivedGauge(object);
|
||||
}
|
||||
|
@ -199,6 +200,7 @@ public class StringMonitor extends Monitor implements StringMonitorMBean {
|
|||
* @return The derived gauge timestamp of the specified object.
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public synchronized long getDerivedGaugeTimeStamp(ObjectName object) {
|
||||
return super.getDerivedGaugeTimeStamp(object);
|
||||
}
|
||||
|
@ -341,8 +343,9 @@ public class StringMonitor extends Monitor implements StringMonitorMBean {
|
|||
* the Java class of the notification and the notification types sent by
|
||||
* the string monitor.
|
||||
*/
|
||||
@Override
|
||||
public MBeanNotificationInfo[] getNotificationInfo() {
|
||||
return notifsInfo;
|
||||
return notifsInfo.clone();
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -123,8 +123,10 @@ public class MediaSize extends Size2DSyntax implements Attribute {
|
|||
if (x > y) {
|
||||
throw new IllegalArgumentException("X dimension > Y dimension");
|
||||
}
|
||||
if (media != null && mediaMap.get(media) == null) {
|
||||
mediaName = media;
|
||||
mediaMap.put(mediaName, this);
|
||||
}
|
||||
sizeVector.add(this);
|
||||
}
|
||||
|
||||
|
@ -147,8 +149,10 @@ public class MediaSize extends Size2DSyntax implements Attribute {
|
|||
if (x > y) {
|
||||
throw new IllegalArgumentException("X dimension > Y dimension");
|
||||
}
|
||||
if (media != null && mediaMap.get(media) == null) {
|
||||
mediaName = media;
|
||||
mediaMap.put(mediaName, this);
|
||||
}
|
||||
sizeVector.add(this);
|
||||
}
|
||||
|
||||
|
|
|
@ -585,9 +585,16 @@ public class GifImageDecoder extends ImageDecoder {
|
|||
System.out.print("Reading a " + width + " by " + height + " " +
|
||||
(interlace ? "" : "non-") + "interlaced image...");
|
||||
}
|
||||
|
||||
int initCodeSize = ExtractByte(block, 9);
|
||||
if (initCodeSize >= 12) {
|
||||
if (verbose) {
|
||||
System.out.println("Invalid initial code size: " +
|
||||
initCodeSize);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
boolean ret = parseImage(x, y, width, height,
|
||||
interlace, ExtractByte(block, 9),
|
||||
interlace, initCodeSize,
|
||||
block, rasline, model);
|
||||
|
||||
if (!ret) {
|
||||
|
|
54
jdk/src/share/classes/sun/font/CreatedFontTracker.java
Normal file
54
jdk/src/share/classes/sun/font/CreatedFontTracker.java
Normal file
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. 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. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
package sun.font;
|
||||
|
||||
public class CreatedFontTracker {
|
||||
|
||||
public static final int MAX_FILE_SIZE = 32 * 1024 * 1024;
|
||||
public static final int MAX_TOTAL_BYTES = 10 * MAX_FILE_SIZE;
|
||||
|
||||
static int numBytes;
|
||||
static CreatedFontTracker tracker;
|
||||
|
||||
public static synchronized CreatedFontTracker getTracker() {
|
||||
if (tracker == null) {
|
||||
tracker = new CreatedFontTracker();
|
||||
}
|
||||
return tracker;
|
||||
}
|
||||
|
||||
public synchronized int getNumBytes() {
|
||||
return numBytes;
|
||||
}
|
||||
|
||||
public synchronized void addBytes(int sz) {
|
||||
numBytes += sz;
|
||||
}
|
||||
|
||||
public synchronized void subBytes(int sz) {
|
||||
numBytes -= sz;
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -125,9 +125,9 @@ public abstract class FileFont extends PhysicalFont {
|
|||
return true;
|
||||
}
|
||||
|
||||
void setFileToRemove(File file) {
|
||||
void setFileToRemove(File file, CreatedFontTracker tracker) {
|
||||
Disposer.addObjectRecord(this,
|
||||
new CreatedFontFileDisposerRecord(file));
|
||||
new CreatedFontFileDisposerRecord(file, tracker));
|
||||
}
|
||||
|
||||
/* This is called when a font scaler is determined to
|
||||
|
@ -246,12 +246,16 @@ public abstract class FileFont extends PhysicalFont {
|
|||
return getScaler().getUnitsPerEm();
|
||||
}
|
||||
|
||||
private static class CreatedFontFileDisposerRecord implements DisposerRecord {
|
||||
private static class CreatedFontFileDisposerRecord
|
||||
implements DisposerRecord {
|
||||
|
||||
File fontFile = null;
|
||||
CreatedFontTracker tracker;
|
||||
|
||||
private CreatedFontFileDisposerRecord(File file) {
|
||||
private CreatedFontFileDisposerRecord(File file,
|
||||
CreatedFontTracker tracker) {
|
||||
fontFile = file;
|
||||
this.tracker = tracker;
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
|
@ -260,6 +264,9 @@ public abstract class FileFont extends PhysicalFont {
|
|||
public Object run() {
|
||||
if (fontFile != null) {
|
||||
try {
|
||||
if (tracker != null) {
|
||||
tracker.subBytes((int)fontFile.length());
|
||||
}
|
||||
/* REMIND: is it possible that the file is
|
||||
* still open? It will be closed when the
|
||||
* font2D is disposed but could this code
|
||||
|
|
|
@ -2348,19 +2348,21 @@ public final class FontManager {
|
|||
static Vector<File> tmpFontFiles = null;
|
||||
|
||||
public static Font2D createFont2D(File fontFile, int fontFormat,
|
||||
boolean isCopy)
|
||||
boolean isCopy,
|
||||
CreatedFontTracker tracker)
|
||||
throws FontFormatException {
|
||||
|
||||
String fontFilePath = fontFile.getPath();
|
||||
FileFont font2D = null;
|
||||
final File fFile = fontFile;
|
||||
final CreatedFontTracker _tracker = tracker;
|
||||
try {
|
||||
switch (fontFormat) {
|
||||
case Font.TRUETYPE_FONT:
|
||||
font2D = new TrueTypeFont(fontFilePath, null, 0, true);
|
||||
break;
|
||||
case Font.TYPE1_FONT:
|
||||
font2D = new Type1Font(fontFilePath, null);
|
||||
font2D = new Type1Font(fontFilePath, null, isCopy);
|
||||
break;
|
||||
default:
|
||||
throw new FontFormatException("Unrecognised Font Format");
|
||||
|
@ -2370,6 +2372,9 @@ public final class FontManager {
|
|||
java.security.AccessController.doPrivileged(
|
||||
new java.security.PrivilegedAction() {
|
||||
public Object run() {
|
||||
if (_tracker != null) {
|
||||
_tracker.subBytes((int)fFile.length());
|
||||
}
|
||||
fFile.delete();
|
||||
return null;
|
||||
}
|
||||
|
@ -2378,7 +2383,7 @@ public final class FontManager {
|
|||
throw(e);
|
||||
}
|
||||
if (isCopy) {
|
||||
font2D.setFileToRemove(fontFile);
|
||||
font2D.setFileToRemove(fontFile, tracker);
|
||||
synchronized (FontManager.class) {
|
||||
|
||||
if (tmpFontFiles == null) {
|
||||
|
|
|
@ -175,8 +175,17 @@ public class TrueTypeFont extends FileFont {
|
|||
super(platname, nativeNames);
|
||||
useJavaRasterizer = javaRasterizer;
|
||||
fontRank = Font2D.TTF_RANK;
|
||||
try {
|
||||
verify();
|
||||
init(fIndex);
|
||||
} catch (Throwable t) {
|
||||
close();
|
||||
if (t instanceof FontFormatException) {
|
||||
throw (FontFormatException)t;
|
||||
} else {
|
||||
throw new FontFormatException("Unexpected runtime exception.");
|
||||
}
|
||||
}
|
||||
Disposer.addObjectRecord(this, disposerRecord);
|
||||
}
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@ import java.nio.BufferUnderflowException;
|
|||
import java.nio.channels.ClosedChannelException;
|
||||
import java.nio.channels.FileChannel;
|
||||
import sun.java2d.Disposer;
|
||||
import sun.java2d.DisposerRecord;
|
||||
import java.util.HashSet;
|
||||
import java.util.HashMap;
|
||||
import java.awt.Font;
|
||||
|
@ -76,6 +77,27 @@ import java.awt.Font;
|
|||
*/
|
||||
public class Type1Font extends FileFont {
|
||||
|
||||
private static class T1DisposerRecord implements DisposerRecord {
|
||||
String fileName = null;
|
||||
|
||||
T1DisposerRecord(String name) {
|
||||
fileName = name;
|
||||
}
|
||||
|
||||
public synchronized void dispose() {
|
||||
java.security.AccessController.doPrivileged(
|
||||
new java.security.PrivilegedAction() {
|
||||
public Object run() {
|
||||
|
||||
if (fileName != null) {
|
||||
(new java.io.File(fileName)).delete();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
WeakReference bufferRef = new WeakReference(null);
|
||||
|
||||
private String psName = null;
|
||||
|
@ -124,6 +146,17 @@ public class Type1Font extends FileFont {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a Type1 Font.
|
||||
* @param platname - Platform identifier of the font. Typically file name.
|
||||
* @param nativeNames - Native names - typically XLFDs on Unix.
|
||||
*/
|
||||
public Type1Font(String platname, Object nativeNames)
|
||||
throws FontFormatException {
|
||||
|
||||
this(platname, nativeNames, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* - does basic verification of the file
|
||||
* - reads the names (full, family).
|
||||
|
@ -131,12 +164,25 @@ public class Type1Font extends FileFont {
|
|||
* @throws FontFormatException - if the font can't be opened
|
||||
* or fails verification, or there's no usable cmap
|
||||
*/
|
||||
public Type1Font(String platname, Object nativeNames)
|
||||
public Type1Font(String platname, Object nativeNames, boolean createdCopy)
|
||||
throws FontFormatException {
|
||||
super(platname, nativeNames);
|
||||
fontRank = Font2D.TYPE1_RANK;
|
||||
checkedNatives = true;
|
||||
try {
|
||||
verify();
|
||||
} catch (Throwable t) {
|
||||
if (createdCopy) {
|
||||
T1DisposerRecord ref = new T1DisposerRecord(platname);
|
||||
Disposer.addObjectRecord(bufferRef, ref);
|
||||
bufferRef = null;
|
||||
}
|
||||
if (t instanceof FontFormatException) {
|
||||
throw (FontFormatException)t;
|
||||
} else {
|
||||
throw new FontFormatException("Unexpected runtime exception.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized ByteBuffer getBuffer() throws FontFormatException {
|
||||
|
|
|
@ -52,6 +52,9 @@ class Request {
|
|||
os = rawout;
|
||||
do {
|
||||
startLine = readLine();
|
||||
if (startLine == null) {
|
||||
return;
|
||||
}
|
||||
/* skip blank lines */
|
||||
} while (startLine == null ? false : startLine.equals (""));
|
||||
}
|
||||
|
|
|
@ -433,6 +433,7 @@ class ServerImpl implements TimeSource {
|
|||
rawin = sslStreams.getInputStream();
|
||||
rawout = sslStreams.getOutputStream();
|
||||
engine = sslStreams.getSSLEngine();
|
||||
connection.sslStreams = sslStreams;
|
||||
} else {
|
||||
rawin = new BufferedInputStream(
|
||||
new Request.ReadStream (
|
||||
|
@ -442,6 +443,8 @@ class ServerImpl implements TimeSource {
|
|||
ServerImpl.this, chan
|
||||
);
|
||||
}
|
||||
connection.raw = rawin;
|
||||
connection.rawout = rawout;
|
||||
}
|
||||
Request req = new Request (rawin, rawout);
|
||||
requestLine = req.requestLine();
|
||||
|
|
|
@ -274,6 +274,7 @@ public abstract class KrbKdcReq {
|
|||
+ ",Attempt =" + i
|
||||
+ ", #bytes=" + obuf.length);
|
||||
}
|
||||
try {
|
||||
/*
|
||||
* Send the data to the kdc.
|
||||
*/
|
||||
|
@ -296,6 +297,9 @@ public abstract class KrbKdcReq {
|
|||
throw se;
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
kdcClient.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
return ibuf;
|
||||
|
|
|
@ -93,4 +93,7 @@ public class UDPClient {
|
|||
return data;
|
||||
}
|
||||
|
||||
public void close() {
|
||||
dgSocket.close();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2003-2008 Sun Microsystems, Inc. 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
|
||||
|
@ -38,6 +38,8 @@ import static sun.security.pkcs11.TemplateManager.*;
|
|||
import sun.security.pkcs11.wrapper.*;
|
||||
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
|
||||
|
||||
import sun.security.rsa.RSAKeyFactory;
|
||||
|
||||
/**
|
||||
* KeyPairGenerator implementation class. This class currently supports
|
||||
* RSA, DSA, DH, and EC.
|
||||
|
@ -66,7 +68,7 @@ final class P11KeyPairGenerator extends KeyPairGeneratorSpi {
|
|||
private AlgorithmParameterSpec params;
|
||||
|
||||
// for RSA, selected or default value of public exponent, always valid
|
||||
private BigInteger rsaPublicExponent;
|
||||
private BigInteger rsaPublicExponent = RSAKeyGenParameterSpec.F4;
|
||||
|
||||
// SecureRandom instance, if specified in init
|
||||
private SecureRandom random;
|
||||
|
@ -88,19 +90,19 @@ final class P11KeyPairGenerator extends KeyPairGeneratorSpi {
|
|||
public void initialize(int keySize, SecureRandom random) {
|
||||
token.ensureValid();
|
||||
try {
|
||||
checkKeySize(keySize);
|
||||
checkKeySize(keySize, null);
|
||||
} catch (InvalidAlgorithmParameterException e) {
|
||||
throw new InvalidParameterException(e.getMessage());
|
||||
}
|
||||
this.keySize = keySize;
|
||||
this.params = null;
|
||||
this.random = random;
|
||||
this.rsaPublicExponent = RSAKeyGenParameterSpec.F4;
|
||||
if (algorithm.equals("EC")) {
|
||||
params = P11ECKeyFactory.getECParameterSpec(keySize);
|
||||
if (params == null) {
|
||||
throw new InvalidParameterException
|
||||
("No EC parameters available for key size " + keySize + " bits");
|
||||
throw new InvalidParameterException(
|
||||
"No EC parameters available for key size "
|
||||
+ keySize + " bits");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -115,8 +117,10 @@ final class P11KeyPairGenerator extends KeyPairGeneratorSpi {
|
|||
("DHParameterSpec required for Diffie-Hellman");
|
||||
}
|
||||
DHParameterSpec dhParams = (DHParameterSpec)params;
|
||||
this.keySize = dhParams.getP().bitLength();
|
||||
this.params = params;
|
||||
int tmpKeySize = dhParams.getP().bitLength();
|
||||
checkKeySize(tmpKeySize, dhParams);
|
||||
this.keySize = tmpKeySize;
|
||||
this.params = dhParams;
|
||||
// XXX sanity check params
|
||||
} else if (algorithm.equals("RSA")) {
|
||||
if (params instanceof RSAKeyGenParameterSpec == false) {
|
||||
|
@ -124,7 +128,9 @@ final class P11KeyPairGenerator extends KeyPairGeneratorSpi {
|
|||
("RSAKeyGenParameterSpec required for RSA");
|
||||
}
|
||||
RSAKeyGenParameterSpec rsaParams = (RSAKeyGenParameterSpec)params;
|
||||
this.keySize = rsaParams.getKeysize();
|
||||
int tmpKeySize = rsaParams.getKeysize();
|
||||
checkKeySize(tmpKeySize, rsaParams);
|
||||
this.keySize = tmpKeySize;
|
||||
this.params = null;
|
||||
this.rsaPublicExponent = rsaParams.getPublicExponent();
|
||||
// XXX sanity check params
|
||||
|
@ -134,13 +140,16 @@ final class P11KeyPairGenerator extends KeyPairGeneratorSpi {
|
|||
("DSAParameterSpec required for DSA");
|
||||
}
|
||||
DSAParameterSpec dsaParams = (DSAParameterSpec)params;
|
||||
this.keySize = dsaParams.getP().bitLength();
|
||||
this.params = params;
|
||||
int tmpKeySize = dsaParams.getP().bitLength();
|
||||
checkKeySize(tmpKeySize, dsaParams);
|
||||
this.keySize = tmpKeySize;
|
||||
this.params = dsaParams;
|
||||
// XXX sanity check params
|
||||
} else if (algorithm.equals("EC")) {
|
||||
ECParameterSpec ecParams;
|
||||
if (params instanceof ECParameterSpec) {
|
||||
ecParams = P11ECKeyFactory.getECParameterSpec((ECParameterSpec)params);
|
||||
ecParams = P11ECKeyFactory.getECParameterSpec(
|
||||
(ECParameterSpec)params);
|
||||
if (ecParams == null) {
|
||||
throw new InvalidAlgorithmParameterException
|
||||
("Unsupported curve: " + params);
|
||||
|
@ -156,16 +165,17 @@ final class P11KeyPairGenerator extends KeyPairGeneratorSpi {
|
|||
throw new InvalidAlgorithmParameterException
|
||||
("ECParameterSpec or ECGenParameterSpec required for EC");
|
||||
}
|
||||
this.keySize = ecParams.getCurve().getField().getFieldSize();
|
||||
int tmpKeySize = ecParams.getCurve().getField().getFieldSize();
|
||||
checkKeySize(tmpKeySize, ecParams);
|
||||
this.keySize = tmpKeySize;
|
||||
this.params = ecParams;
|
||||
} else {
|
||||
throw new ProviderException("Unknown algorithm: " + algorithm);
|
||||
}
|
||||
this.random = random;
|
||||
checkKeySize(keySize);
|
||||
}
|
||||
|
||||
private void checkKeySize(int keySize)
|
||||
private void checkKeySize(int keySize, AlgorithmParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException {
|
||||
if (algorithm.equals("EC")) {
|
||||
if (keySize < 112) {
|
||||
|
@ -178,13 +188,28 @@ final class P11KeyPairGenerator extends KeyPairGeneratorSpi {
|
|||
("Key size must be at most 2048 bit");
|
||||
}
|
||||
return;
|
||||
} else if (algorithm.equals("RSA")) {
|
||||
BigInteger tmpExponent = rsaPublicExponent;
|
||||
if (params != null) {
|
||||
// Already tested for instanceof RSAKeyGenParameterSpec above
|
||||
tmpExponent =
|
||||
((RSAKeyGenParameterSpec)params).getPublicExponent();
|
||||
}
|
||||
try {
|
||||
// This provider supports 64K or less.
|
||||
RSAKeyFactory.checkKeyLengths(keySize, tmpExponent,
|
||||
512, 64 * 1024);
|
||||
} catch (InvalidKeyException e) {
|
||||
throw new InvalidAlgorithmParameterException(e.getMessage());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (keySize < 512) {
|
||||
throw new InvalidAlgorithmParameterException
|
||||
("Key size must be at least 512 bit");
|
||||
}
|
||||
if (algorithm.equals("RSA") ||
|
||||
(algorithm.equals("DH") && (params != null))) {
|
||||
if (algorithm.equals("DH") && (params != null)) {
|
||||
// sanity check, nobody really wants keys this large
|
||||
if (keySize > 64 * 1024) {
|
||||
throw new InvalidAlgorithmParameterException
|
||||
|
|
|
@ -80,6 +80,8 @@ import static sun.security.pkcs11.P11Util.*;
|
|||
import sun.security.pkcs11.wrapper.*;
|
||||
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
|
||||
|
||||
import sun.security.rsa.RSAKeyFactory;
|
||||
|
||||
final class P11KeyStore extends KeyStoreSpi {
|
||||
|
||||
private static final CK_ATTRIBUTE ATTR_CLASS_CERT =
|
||||
|
@ -1328,6 +1330,15 @@ final class P11KeyStore extends KeyStoreSpi {
|
|||
BigInteger modulus = attrs[0].getBigInteger();
|
||||
keyLength = modulus.bitLength();
|
||||
|
||||
// This check will combine our "don't care" values here
|
||||
// with the system-wide min/max values.
|
||||
try {
|
||||
RSAKeyFactory.checkKeyLengths(keyLength, null,
|
||||
-1, Integer.MAX_VALUE);
|
||||
} catch (InvalidKeyException e) {
|
||||
throw new KeyStoreException(e.getMessage());
|
||||
}
|
||||
|
||||
return P11Key.privateKey(session,
|
||||
oHandle,
|
||||
keyType,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2003 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -35,6 +35,8 @@ import static sun.security.pkcs11.TemplateManager.*;
|
|||
import sun.security.pkcs11.wrapper.*;
|
||||
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
|
||||
|
||||
import sun.security.rsa.RSAKeyFactory;
|
||||
|
||||
/**
|
||||
* RSA KeyFactory implemenation.
|
||||
*
|
||||
|
@ -131,6 +133,9 @@ final class P11RSAKeyFactory extends P11KeyFactory {
|
|||
} catch (PKCS11Exception e) {
|
||||
throw new InvalidKeySpecException
|
||||
("Could not create RSA public key", e);
|
||||
} catch (InvalidKeyException e) {
|
||||
throw new InvalidKeySpecException
|
||||
("Could not create RSA public key", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -175,11 +180,15 @@ final class P11RSAKeyFactory extends P11KeyFactory {
|
|||
} catch (PKCS11Exception e) {
|
||||
throw new InvalidKeySpecException
|
||||
("Could not create RSA private key", e);
|
||||
} catch (InvalidKeyException e) {
|
||||
throw new InvalidKeySpecException
|
||||
("Could not create RSA private key", e);
|
||||
}
|
||||
}
|
||||
|
||||
private PublicKey generatePublic(BigInteger n, BigInteger e)
|
||||
throws PKCS11Exception {
|
||||
throws PKCS11Exception, InvalidKeyException {
|
||||
RSAKeyFactory.checkKeyLengths(n.bitLength(), e, -1, 64 * 1024);
|
||||
CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
|
||||
new CK_ATTRIBUTE(CKA_CLASS, CKO_PUBLIC_KEY),
|
||||
new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_RSA),
|
||||
|
@ -200,7 +209,8 @@ final class P11RSAKeyFactory extends P11KeyFactory {
|
|||
}
|
||||
|
||||
private PrivateKey generatePrivate(BigInteger n, BigInteger d)
|
||||
throws PKCS11Exception {
|
||||
throws PKCS11Exception, InvalidKeyException {
|
||||
RSAKeyFactory.checkKeyLengths(n.bitLength(), null, -1, 64 * 1024);
|
||||
CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
|
||||
new CK_ATTRIBUTE(CKA_CLASS, CKO_PRIVATE_KEY),
|
||||
new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_RSA),
|
||||
|
@ -222,7 +232,9 @@ final class P11RSAKeyFactory extends P11KeyFactory {
|
|||
|
||||
private PrivateKey generatePrivate(BigInteger n, BigInteger e,
|
||||
BigInteger d, BigInteger p, BigInteger q, BigInteger pe,
|
||||
BigInteger qe, BigInteger coeff) throws PKCS11Exception {
|
||||
BigInteger qe, BigInteger coeff) throws PKCS11Exception,
|
||||
InvalidKeyException {
|
||||
RSAKeyFactory.checkKeyLengths(n.bitLength(), e, -1, 64 * 1024);
|
||||
CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
|
||||
new CK_ATTRIBUTE(CKA_CLASS, CKO_PRIVATE_KEY),
|
||||
new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_RSA),
|
||||
|
|
|
@ -120,11 +120,13 @@ public final class SunPKCS11 extends AuthProvider {
|
|||
}
|
||||
|
||||
/**
|
||||
* @deprecated use new SunPKCS11(String) or new SunPKCS11(InputStream) instead
|
||||
* @deprecated use new SunPKCS11(String) or new SunPKCS11(InputStream)
|
||||
* instead
|
||||
*/
|
||||
@Deprecated
|
||||
public SunPKCS11(String configName, InputStream configStream) {
|
||||
super("SunPKCS11-" + Config.getConfig(configName, configStream).getName(),
|
||||
super("SunPKCS11-" +
|
||||
Config.getConfig(configName, configStream).getName(),
|
||||
1.7d, Config.getConfig(configName, configStream).getDescription());
|
||||
this.configName = configName;
|
||||
this.config = Config.removeConfig(configName);
|
||||
|
@ -153,7 +155,8 @@ public final class SunPKCS11 extends AuthProvider {
|
|||
//
|
||||
// If we are in Secmod mode and configured to use either the
|
||||
// nssKeyStore or the nssTrustAnchors module, we automatically
|
||||
// switch to using the NSS trust attributes for trusted certs (KeyStore).
|
||||
// switch to using the NSS trust attributes for trusted certs
|
||||
// (KeyStore).
|
||||
//
|
||||
|
||||
if (useSecmod) {
|
||||
|
@ -168,33 +171,40 @@ public final class SunPKCS11 extends AuthProvider {
|
|||
if (secmod.isInitialized()) {
|
||||
if (nssSecmodDirectory != null) {
|
||||
String s = secmod.getConfigDir();
|
||||
if ((s != null) && (s.equals(nssSecmodDirectory) == false)) {
|
||||
if ((s != null) &&
|
||||
(s.equals(nssSecmodDirectory) == false)) {
|
||||
throw new ProviderException("Secmod directory "
|
||||
+ nssSecmodDirectory
|
||||
+ " invalid, NSS already initialized with " + s);
|
||||
+ " invalid, NSS already initialized with "
|
||||
+ s);
|
||||
}
|
||||
}
|
||||
if (nssLibraryDirectory != null) {
|
||||
String s = secmod.getLibDir();
|
||||
if ((s != null) && (s.equals(nssLibraryDirectory) == false)) {
|
||||
if ((s != null) &&
|
||||
(s.equals(nssLibraryDirectory) == false)) {
|
||||
throw new ProviderException("NSS library directory "
|
||||
+ nssLibraryDirectory
|
||||
+ " invalid, NSS already initialized with " + s);
|
||||
+ " invalid, NSS already initialized with "
|
||||
+ s);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (nssDbMode != DbMode.NO_DB) {
|
||||
if (nssSecmodDirectory == null) {
|
||||
throw new ProviderException("Secmod not initialized and "
|
||||
throw new ProviderException(
|
||||
"Secmod not initialized and "
|
||||
+ "nssSecmodDirectory not specified");
|
||||
}
|
||||
} else {
|
||||
if (nssSecmodDirectory != null) {
|
||||
throw new ProviderException
|
||||
("nssSecmodDirectory must not be specified in noDb mode");
|
||||
throw new ProviderException(
|
||||
"nssSecmodDirectory must not be "
|
||||
+ "specified in noDb mode");
|
||||
}
|
||||
}
|
||||
secmod.initialize(nssDbMode, nssSecmodDirectory, nssLibraryDirectory);
|
||||
secmod.initialize(nssDbMode, nssSecmodDirectory,
|
||||
nssLibraryDirectory);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// XXX which exception to throw
|
||||
|
@ -211,7 +221,8 @@ public final class SunPKCS11 extends AuthProvider {
|
|||
if (nssModule != null) {
|
||||
moduleName = "fips";
|
||||
} else {
|
||||
moduleName = (nssDbMode == DbMode.NO_DB) ? "crypto" : "keystore";
|
||||
moduleName = (nssDbMode == DbMode.NO_DB) ?
|
||||
"crypto" : "keystore";
|
||||
}
|
||||
}
|
||||
if (moduleName.equals("fips")) {
|
||||
|
@ -253,10 +264,12 @@ public final class SunPKCS11 extends AuthProvider {
|
|||
+ ": only " + k + " external NSS modules available");
|
||||
}
|
||||
} else {
|
||||
throw new ProviderException("Unknown NSS module: " + moduleName);
|
||||
throw new ProviderException(
|
||||
"Unknown NSS module: " + moduleName);
|
||||
}
|
||||
if (nssModule == null) {
|
||||
throw new ProviderException("NSS module not available: " + moduleName);
|
||||
throw new ProviderException(
|
||||
"NSS module not available: " + moduleName);
|
||||
}
|
||||
if (nssModule.hasInitializedProvider()) {
|
||||
throw new ProviderException("Secmod module already configured");
|
||||
|
@ -296,8 +309,9 @@ public final class SunPKCS11 extends AuthProvider {
|
|||
initArgs.flags = CKF_OS_LOCKING_OK;
|
||||
PKCS11 tmpPKCS11;
|
||||
try {
|
||||
tmpPKCS11 = PKCS11.getInstance
|
||||
(library, functionList, initArgs, config.getOmitInitialize());
|
||||
tmpPKCS11 = PKCS11.getInstance(
|
||||
library, functionList, initArgs,
|
||||
config.getOmitInitialize());
|
||||
} catch (PKCS11Exception e) {
|
||||
if (debug != null) {
|
||||
debug.println("Multi-threaded initialization failed: " + e);
|
||||
|
@ -312,8 +326,8 @@ public final class SunPKCS11 extends AuthProvider {
|
|||
} else {
|
||||
initArgs.flags = 0;
|
||||
}
|
||||
tmpPKCS11 = PKCS11.getInstance
|
||||
(library, functionList, initArgs, config.getOmitInitialize());
|
||||
tmpPKCS11 = PKCS11.getInstance(library,
|
||||
functionList, initArgs, config.getOmitInitialize());
|
||||
}
|
||||
p11 = tmpPKCS11;
|
||||
|
||||
|
@ -336,8 +350,10 @@ public final class SunPKCS11 extends AuthProvider {
|
|||
System.out.println("Slots with tokens: " + toString(slots));
|
||||
}
|
||||
if (slotID < 0) {
|
||||
if ((slotListIndex < 0) || (slotListIndex >= slots.length)) {
|
||||
throw new ProviderException("slotListIndex is " + slotListIndex
|
||||
if ((slotListIndex < 0)
|
||||
|| (slotListIndex >= slots.length)) {
|
||||
throw new ProviderException("slotListIndex is "
|
||||
+ slotListIndex
|
||||
+ " but token only has " + slots.length + " slots");
|
||||
}
|
||||
slotID = slots[slotListIndex];
|
||||
|
@ -575,12 +591,15 @@ public final class SunPKCS11 extends AuthProvider {
|
|||
d(KF, "DH", P11DHKeyFactory, s("DiffieHellman"),
|
||||
m(CKM_DH_PKCS_KEY_PAIR_GEN, CKM_DH_PKCS_DERIVE));
|
||||
d(KF, "EC", P11DHKeyFactory,
|
||||
m(CKM_EC_KEY_PAIR_GEN, CKM_ECDH1_DERIVE, CKM_ECDSA, CKM_ECDSA_SHA1));
|
||||
m(CKM_EC_KEY_PAIR_GEN, CKM_ECDH1_DERIVE,
|
||||
CKM_ECDSA, CKM_ECDSA_SHA1));
|
||||
|
||||
// AlgorithmParameters for EC.
|
||||
// Only needed until we have an EC implementation in the SUN provider.
|
||||
d(AGP, "EC", "sun.security.ec.ECParameters", s("1.2.840.10045.2.1"),
|
||||
m(CKM_EC_KEY_PAIR_GEN, CKM_ECDH1_DERIVE, CKM_ECDSA, CKM_ECDSA_SHA1));
|
||||
d(AGP, "EC", "sun.security.ec.ECParameters",
|
||||
s("1.2.840.10045.2.1"),
|
||||
m(CKM_EC_KEY_PAIR_GEN, CKM_ECDH1_DERIVE,
|
||||
CKM_ECDSA, CKM_ECDSA_SHA1));
|
||||
|
||||
d(KA, "DH", P11KeyAgreement, s("DiffieHellman"),
|
||||
m(CKM_DH_PKCS_DERIVE));
|
||||
|
@ -654,12 +673,16 @@ public final class SunPKCS11 extends AuthProvider {
|
|||
d(SIG, "SHA512withRSA", P11Signature,
|
||||
m(CKM_SHA512_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
|
||||
|
||||
d(KG, "SunTlsRsaPremasterSecret", "sun.security.pkcs11.P11TlsRsaPremasterSecretGenerator",
|
||||
d(KG, "SunTlsRsaPremasterSecret",
|
||||
"sun.security.pkcs11.P11TlsRsaPremasterSecretGenerator",
|
||||
m(CKM_SSL3_PRE_MASTER_KEY_GEN, CKM_TLS_PRE_MASTER_KEY_GEN));
|
||||
d(KG, "SunTlsMasterSecret", "sun.security.pkcs11.P11TlsMasterSecretGenerator",
|
||||
d(KG, "SunTlsMasterSecret",
|
||||
"sun.security.pkcs11.P11TlsMasterSecretGenerator",
|
||||
m(CKM_SSL3_MASTER_KEY_DERIVE, CKM_TLS_MASTER_KEY_DERIVE,
|
||||
CKM_SSL3_MASTER_KEY_DERIVE_DH, CKM_TLS_MASTER_KEY_DERIVE_DH));
|
||||
d(KG, "SunTlsKeyMaterial", "sun.security.pkcs11.P11TlsKeyMaterialGenerator",
|
||||
CKM_SSL3_MASTER_KEY_DERIVE_DH,
|
||||
CKM_TLS_MASTER_KEY_DERIVE_DH));
|
||||
d(KG, "SunTlsKeyMaterial",
|
||||
"sun.security.pkcs11.P11TlsKeyMaterialGenerator",
|
||||
m(CKM_SSL3_KEY_AND_MAC_DERIVE, CKM_TLS_KEY_AND_MAC_DERIVE));
|
||||
d(KG, "SunTlsPrf", "sun.security.pkcs11.P11TlsPrfGenerator",
|
||||
m(CKM_TLS_PRF, CKM_NSS_TLS_PRF_GENERAL));
|
||||
|
@ -773,6 +796,13 @@ public final class SunPKCS11 extends AuthProvider {
|
|||
System.out.println(token.tokenInfo);
|
||||
}
|
||||
long[] supportedMechanisms = p11.C_GetMechanismList(slotID);
|
||||
|
||||
// Create a map from the various Descriptors to the "most
|
||||
// preferred" mechanism that was defined during the
|
||||
// static initialization. For example, DES/CBC/PKCS5Padding
|
||||
// could be mapped to CKM_DES_CBC_PAD or CKM_DES_CBC. Prefer
|
||||
// the earliest entry. When asked for "DES/CBC/PKCS5Padding", we
|
||||
// return a CKM_DES_CBC_PAD.
|
||||
final Map<Descriptor,Integer> supportedAlgs =
|
||||
new HashMap<Descriptor,Integer>();
|
||||
for (int i = 0; i < supportedMechanisms.length; i++) {
|
||||
|
@ -807,6 +837,9 @@ public final class SunPKCS11 extends AuthProvider {
|
|||
supportedAlgs.put(d, integerMech);
|
||||
continue;
|
||||
}
|
||||
// See if there is something "more preferred"
|
||||
// than what we currently have in the supportedAlgs
|
||||
// map.
|
||||
int intOldMech = oldMech.intValue();
|
||||
for (int j = 0; j < d.mechanisms.length; j++) {
|
||||
int nextMech = d.mechanisms[j];
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2003-2008 Sun Microsystems, Inc. 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
|
||||
|
@ -31,6 +31,8 @@ import java.security.*;
|
|||
import java.security.interfaces.*;
|
||||
import java.security.spec.*;
|
||||
|
||||
import sun.security.action.GetPropertyAction;
|
||||
|
||||
/**
|
||||
* KeyFactory for RSA keys. Keys must be instances of PublicKey or PrivateKey
|
||||
* and getAlgorithm() must return "RSA". For such keys, it supports conversion
|
||||
|
@ -68,6 +70,24 @@ public final class RSAKeyFactory extends KeyFactorySpi {
|
|||
private final static Class<?> x509KeySpecClass = X509EncodedKeySpec.class;
|
||||
private final static Class<?> pkcs8KeySpecClass = PKCS8EncodedKeySpec.class;
|
||||
|
||||
public final static int MIN_MODLEN = 512;
|
||||
public final static int MAX_MODLEN = 16384;
|
||||
|
||||
/*
|
||||
* If the modulus length is above this value, restrict the size of
|
||||
* the exponent to something that can be reasonably computed. We
|
||||
* could simply hardcode the exp len to something like 64 bits, but
|
||||
* this approach allows flexibility in case impls would like to use
|
||||
* larger module and exponent values.
|
||||
*/
|
||||
public final static int MAX_MODLEN_RESTRICT_EXP = 3072;
|
||||
public final static int MAX_RESTRICTED_EXPLEN = 64;
|
||||
|
||||
private static final boolean restrictExpLen =
|
||||
"true".equalsIgnoreCase(AccessController.doPrivileged(
|
||||
new GetPropertyAction(
|
||||
"sun.security.rsa.restrictRSAExponent", "true")));
|
||||
|
||||
// instance used for static translateKey();
|
||||
private final static RSAKeyFactory INSTANCE = new RSAKeyFactory();
|
||||
|
||||
|
@ -76,74 +96,79 @@ public final class RSAKeyFactory extends KeyFactorySpi {
|
|||
}
|
||||
|
||||
/**
|
||||
* Static method to convert Key into a useable instance of
|
||||
* RSAPublicKey or RSAPrivate(Crt)Key. Check the key and convert it
|
||||
* to a SunRsaSign key if necessary. If the key is not an RSA key
|
||||
* or cannot be used, throw an InvalidKeyException.
|
||||
*
|
||||
* The difference between this method and engineTranslateKey() is that
|
||||
* we do not convert keys of other providers that are already an
|
||||
* instance of RSAPublicKey or RSAPrivate(Crt)Key.
|
||||
* Static method to convert Key into an instance of RSAPublicKeyImpl
|
||||
* or RSAPrivate(Crt)KeyImpl. If the key is not an RSA key or cannot be
|
||||
* used, throw an InvalidKeyException.
|
||||
*
|
||||
* Used by RSASignature and RSACipher.
|
||||
*/
|
||||
public static RSAKey toRSAKey(Key key) throws InvalidKeyException {
|
||||
if (key instanceof RSAKey) {
|
||||
RSAKey rsaKey = (RSAKey)key;
|
||||
checkKey(rsaKey);
|
||||
return rsaKey;
|
||||
if ((key instanceof RSAPrivateKeyImpl) ||
|
||||
(key instanceof RSAPrivateCrtKeyImpl) ||
|
||||
(key instanceof RSAPublicKeyImpl)) {
|
||||
return (RSAKey)key;
|
||||
} else {
|
||||
return (RSAKey)INSTANCE.engineTranslateKey(key);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that the given RSA key is valid.
|
||||
/*
|
||||
* Single test entry point for all of the mechanisms in the SunRsaSign
|
||||
* provider (RSA*KeyImpls). All of the tests are the same.
|
||||
*
|
||||
* For compatibility, we round up to the nearest byte here:
|
||||
* some Key impls might pass in a value within a byte of the
|
||||
* real value.
|
||||
*/
|
||||
private static void checkKey(RSAKey key) throws InvalidKeyException {
|
||||
// check for subinterfaces, omit additional checks for our keys
|
||||
if (key instanceof RSAPublicKey) {
|
||||
if (key instanceof RSAPublicKeyImpl) {
|
||||
return;
|
||||
}
|
||||
} else if (key instanceof RSAPrivateKey) {
|
||||
if ((key instanceof RSAPrivateCrtKeyImpl)
|
||||
|| (key instanceof RSAPrivateKeyImpl)) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
throw new InvalidKeyException("Neither a public nor a private key");
|
||||
}
|
||||
// RSAKey does not extend Key, so we need to do a cast
|
||||
String keyAlg = ((Key)key).getAlgorithm();
|
||||
if (keyAlg.equals("RSA") == false) {
|
||||
throw new InvalidKeyException("Not an RSA key: " + keyAlg);
|
||||
}
|
||||
BigInteger modulus;
|
||||
// some providers implement RSAKey for keys where the values are
|
||||
// not accessible (although they should). Detect those here
|
||||
// for a more graceful failure.
|
||||
try {
|
||||
modulus = key.getModulus();
|
||||
if (modulus == null) {
|
||||
throw new InvalidKeyException("Modulus is missing");
|
||||
}
|
||||
} catch (RuntimeException e) {
|
||||
throw new InvalidKeyException(e);
|
||||
}
|
||||
checkKeyLength(modulus);
|
||||
static void checkRSAProviderKeyLengths(int modulusLen, BigInteger exponent)
|
||||
throws InvalidKeyException {
|
||||
checkKeyLengths(((modulusLen + 7) & ~7), exponent,
|
||||
RSAKeyFactory.MIN_MODLEN, Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the length of the modulus of an RSA key. We only support keys
|
||||
* at least 505 bits long.
|
||||
* Check the length of an RSA key modulus/exponent to make sure it
|
||||
* is not too short or long. Some impls have their own min and
|
||||
* max key sizes that may or may not match with a system defined value.
|
||||
*
|
||||
* @param modulusLen the bit length of the RSA modulus.
|
||||
* @param exponent the RSA exponent
|
||||
* @param minModulusLen if > 0, check to see if modulusLen is at
|
||||
* least this long, otherwise unused.
|
||||
* @param maxModulusLen caller will allow this max number of bits.
|
||||
* Allow the smaller of the system-defined maximum and this param.
|
||||
*
|
||||
* @throws InvalidKeyException if any of the values are unacceptable.
|
||||
*/
|
||||
static void checkKeyLength(BigInteger modulus) throws InvalidKeyException {
|
||||
if (modulus.bitLength() < 505) {
|
||||
// some providers may generate slightly shorter keys
|
||||
// accept them if the encoding is at least 64 bytes long
|
||||
throw new InvalidKeyException
|
||||
("RSA keys must be at least 512 bits long");
|
||||
public static void checkKeyLengths(int modulusLen, BigInteger exponent,
|
||||
int minModulusLen, int maxModulusLen) throws InvalidKeyException {
|
||||
|
||||
if ((minModulusLen > 0) && (modulusLen < (minModulusLen))) {
|
||||
throw new InvalidKeyException( "RSA keys must be at least " +
|
||||
minModulusLen + " bits long");
|
||||
}
|
||||
|
||||
// Even though our policy file may allow this, we don't want
|
||||
// either value (mod/exp) to be too big.
|
||||
|
||||
int maxLen = Math.min(maxModulusLen, MAX_MODLEN);
|
||||
|
||||
// If a RSAPrivateKey/RSAPublicKey, make sure the
|
||||
// modulus len isn't too big.
|
||||
if (modulusLen > maxLen) {
|
||||
throw new InvalidKeyException(
|
||||
"RSA keys must be no longer than " + maxLen + " bits");
|
||||
}
|
||||
|
||||
// If a RSAPublicKey, make sure the exponent isn't too big.
|
||||
if (restrictExpLen && (exponent != null) &&
|
||||
(modulusLen > MAX_MODLEN_RESTRICT_EXP) &&
|
||||
(exponent.bitLength() > MAX_RESTRICTED_EXPLEN)) {
|
||||
throw new InvalidKeyException(
|
||||
"RSA exponents can be no longer than " +
|
||||
MAX_RESTRICTED_EXPLEN + " bits " +
|
||||
" if modulus is greater than " +
|
||||
MAX_MODLEN_RESTRICT_EXP + " bits");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2003-2008 Sun Microsystems, Inc. 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
|
||||
|
@ -47,7 +47,7 @@ public final class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
|
|||
// public exponent to use
|
||||
private BigInteger publicExponent;
|
||||
|
||||
// size of the key to generate, >= 512
|
||||
// size of the key to generate, >= RSAKeyFactory.MIN_MODLEN
|
||||
private int keySize;
|
||||
|
||||
// PRNG to use
|
||||
|
@ -60,15 +60,16 @@ public final class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
|
|||
|
||||
// initialize the generator. See JCA doc
|
||||
public void initialize(int keySize, SecureRandom random) {
|
||||
if (keySize < 512) {
|
||||
throw new InvalidParameterException
|
||||
("Key size must be at least 512 bits");
|
||||
}
|
||||
if (keySize > 64 * 1024) {
|
||||
// do not allow unreasonably large key sizes, probably user error
|
||||
throw new InvalidParameterException
|
||||
("Key size must be 65536 bits or less");
|
||||
|
||||
// do not allow unreasonably small or large key sizes,
|
||||
// probably user error
|
||||
try {
|
||||
RSAKeyFactory.checkKeyLengths(keySize, RSAKeyGenParameterSpec.F4,
|
||||
512, 64 * 1024);
|
||||
} catch (InvalidKeyException e) {
|
||||
throw new InvalidParameterException(e.getMessage());
|
||||
}
|
||||
|
||||
this.keySize = keySize;
|
||||
this.random = random;
|
||||
this.publicExponent = RSAKeyGenParameterSpec.F4;
|
||||
|
@ -77,35 +78,41 @@ public final class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
|
|||
// second initialize method. See JCA doc.
|
||||
public void initialize(AlgorithmParameterSpec params, SecureRandom random)
|
||||
throws InvalidAlgorithmParameterException {
|
||||
|
||||
if (params instanceof RSAKeyGenParameterSpec == false) {
|
||||
throw new InvalidAlgorithmParameterException
|
||||
("Params must be instance of RSAKeyGenParameterSpec");
|
||||
}
|
||||
|
||||
RSAKeyGenParameterSpec rsaSpec = (RSAKeyGenParameterSpec)params;
|
||||
keySize = rsaSpec.getKeysize();
|
||||
publicExponent = rsaSpec.getPublicExponent();
|
||||
this.random = random;
|
||||
if (keySize < 512) {
|
||||
throw new InvalidAlgorithmParameterException
|
||||
("Key size must be at least 512 bits");
|
||||
}
|
||||
if (keySize > 64 * 1024) {
|
||||
// do not allow unreasonably large key sizes, probably user error
|
||||
throw new InvalidAlgorithmParameterException
|
||||
("Key size must be 65536 bits or less");
|
||||
}
|
||||
if (publicExponent == null) {
|
||||
publicExponent = RSAKeyGenParameterSpec.F4;
|
||||
int tmpKeySize = rsaSpec.getKeysize();
|
||||
BigInteger tmpPublicExponent = rsaSpec.getPublicExponent();
|
||||
|
||||
if (tmpPublicExponent == null) {
|
||||
tmpPublicExponent = RSAKeyGenParameterSpec.F4;
|
||||
} else {
|
||||
if (publicExponent.compareTo(RSAKeyGenParameterSpec.F0) < 0) {
|
||||
if (tmpPublicExponent.compareTo(RSAKeyGenParameterSpec.F0) < 0) {
|
||||
throw new InvalidAlgorithmParameterException
|
||||
("Public exponent must be 3 or larger");
|
||||
}
|
||||
if (publicExponent.bitLength() > keySize) {
|
||||
if (tmpPublicExponent.bitLength() > tmpKeySize) {
|
||||
throw new InvalidAlgorithmParameterException
|
||||
("Public exponent must be smaller than key size");
|
||||
}
|
||||
}
|
||||
|
||||
// do not allow unreasonably large key sizes, probably user error
|
||||
try {
|
||||
RSAKeyFactory.checkKeyLengths(tmpKeySize, tmpPublicExponent,
|
||||
512, 64 * 1024);
|
||||
} catch (InvalidKeyException e) {
|
||||
throw new InvalidAlgorithmParameterException(
|
||||
"Invalid key sizes", e);
|
||||
}
|
||||
|
||||
this.keySize = tmpKeySize;
|
||||
this.publicExponent = tmpPublicExponent;
|
||||
this.random = random;
|
||||
}
|
||||
|
||||
// generate the keypair. See JCA doc
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2003-2008 Sun Microsystems, Inc. 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
|
||||
|
@ -89,7 +89,7 @@ public final class RSAPrivateCrtKeyImpl
|
|||
*/
|
||||
RSAPrivateCrtKeyImpl(byte[] encoded) throws InvalidKeyException {
|
||||
decode(encoded);
|
||||
RSAKeyFactory.checkKeyLength(n);
|
||||
RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), e);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -107,7 +107,8 @@ public final class RSAPrivateCrtKeyImpl
|
|||
this.pe = pe;
|
||||
this.qe = qe;
|
||||
this.coeff = coeff;
|
||||
RSAKeyFactory.checkKeyLength(n);
|
||||
RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), e);
|
||||
|
||||
// generate the encoding
|
||||
algid = rsaId;
|
||||
try {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2003 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2003-2008 Sun Microsystems, Inc. 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
|
||||
|
@ -61,7 +61,7 @@ public final class RSAPrivateKeyImpl extends PKCS8Key implements RSAPrivateKey {
|
|||
RSAPrivateKeyImpl(BigInteger n, BigInteger d) throws InvalidKeyException {
|
||||
this.n = n;
|
||||
this.d = d;
|
||||
RSAKeyFactory.checkKeyLength(n);
|
||||
RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), null);
|
||||
// generate the encoding
|
||||
algid = RSAPrivateCrtKeyImpl.rsaId;
|
||||
try {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2003-2008 Sun Microsystems, Inc. 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
|
||||
|
@ -56,10 +56,11 @@ public final class RSAPublicKeyImpl extends X509Key implements RSAPublicKey {
|
|||
* Construct a key from its components. Used by the
|
||||
* RSAKeyFactory and the RSAKeyPairGenerator.
|
||||
*/
|
||||
public RSAPublicKeyImpl(BigInteger n, BigInteger e) throws InvalidKeyException {
|
||||
public RSAPublicKeyImpl(BigInteger n, BigInteger e)
|
||||
throws InvalidKeyException {
|
||||
this.n = n;
|
||||
this.e = e;
|
||||
RSAKeyFactory.checkKeyLength(n);
|
||||
RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), e);
|
||||
// generate the encoding
|
||||
algid = RSAPrivateCrtKeyImpl.rsaId;
|
||||
try {
|
||||
|
@ -80,7 +81,7 @@ public final class RSAPublicKeyImpl extends X509Key implements RSAPublicKey {
|
|||
*/
|
||||
public RSAPublicKeyImpl(byte[] encoded) throws InvalidKeyException {
|
||||
decode(encoded);
|
||||
RSAKeyFactory.checkKeyLength(n);
|
||||
RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), e);
|
||||
}
|
||||
|
||||
// see JCA doc
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
# passwords. To be functional, a role must have an entry in
|
||||
# both the password and the access files.
|
||||
#
|
||||
# Default location of this file is $JRE/lib/management/jmxremote.access
|
||||
# The default location of this file is $JRE/lib/management/jmxremote.access
|
||||
# You can specify an alternate location by specifying a property in
|
||||
# the management config file $JRE/lib/management/management.properties
|
||||
# (See that file for details)
|
||||
|
@ -16,7 +16,7 @@
|
|||
# The file format for password and access files is syntactically the same
|
||||
# as the Properties file format. The syntax is described in the Javadoc
|
||||
# for java.util.Properties.load.
|
||||
# Typical access file has multiple lines, where each line is blank,
|
||||
# A typical access file has multiple lines, where each line is blank,
|
||||
# a comment (like this one), or an access control entry.
|
||||
#
|
||||
# An access control entry consists of a role name, and an
|
||||
|
@ -29,10 +29,38 @@
|
|||
# role can read measurements but cannot perform any action
|
||||
# that changes the environment of the running program.
|
||||
# "readwrite" grants access to read and write attributes of MBeans,
|
||||
# to invoke operations on them, and to create or remove them.
|
||||
# This access should be granted to only trusted clients,
|
||||
# since they can potentially interfere with the smooth
|
||||
# operation of a running program
|
||||
# to invoke operations on them, and optionally
|
||||
# to create or remove them. This access should be granted
|
||||
# only to trusted clients, since they can potentially
|
||||
# interfere with the smooth operation of a running program.
|
||||
#
|
||||
# The "readwrite" access level can optionally be followed by the "create" and/or
|
||||
# "unregister" keywords. The "unregister" keyword grants access to unregister
|
||||
# (delete) MBeans. The "create" keyword grants access to create MBeans of a
|
||||
# particular class or of any class matching a particular pattern. Access
|
||||
# should only be granted to create MBeans of known and trusted classes.
|
||||
#
|
||||
# For example, the following entry would grant readwrite access
|
||||
# to "controlRole", as well as access to create MBeans of the class
|
||||
# javax.management.monitor.CounterMonitor and to unregister any MBean:
|
||||
# controlRole readwrite \
|
||||
# create javax.management.monitor.CounterMonitorMBean \
|
||||
# unregister
|
||||
# or equivalently:
|
||||
# controlRole readwrite unregister create javax.management.monitor.CounterMBean
|
||||
#
|
||||
# The following entry would grant readwrite access as well as access to create
|
||||
# MBeans of any class in the packages javax.management.monitor and
|
||||
# javax.management.timer:
|
||||
# controlRole readwrite \
|
||||
# create javax.management.monitor.*,javax.management.timer.* \
|
||||
# unregister
|
||||
#
|
||||
# The \ character is defined in the Properties file syntax to allow continuation
|
||||
# lines as shown here. A * in a class pattern matches a sequence of characters
|
||||
# other than dot (.), so javax.management.monitor.* matches
|
||||
# javax.management.monitor.CounterMonitor but not
|
||||
# javax.management.monitor.foo.Bar.
|
||||
#
|
||||
# A given role should have at most one entry in this file. If a role
|
||||
# has no entry, it has no access.
|
||||
|
@ -42,7 +70,10 @@
|
|||
#
|
||||
# Default access control entries:
|
||||
# o The "monitorRole" role has readonly access.
|
||||
# o The "controlRole" role has readwrite access.
|
||||
# o The "controlRole" role has readwrite access and can create the standard
|
||||
# Timer and Monitor MBeans defined by the JMX API.
|
||||
|
||||
monitorRole readonly
|
||||
controlRole readwrite
|
||||
controlRole readwrite \
|
||||
create javax.management.monitor.*,javax.management.timer.* \
|
||||
unregister
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2002-2009 Sun Microsystems, Inc. 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
|
||||
|
@ -94,6 +94,7 @@ void band::readData(int expectedLength) {
|
|||
assert(!valc->isMalloc);
|
||||
}
|
||||
xvs.init(u->rp, u->rplimit, valc);
|
||||
CHECK;
|
||||
int X = xvs.getInt();
|
||||
if (valc->S() != 0) {
|
||||
assert(valc->min <= -256);
|
||||
|
@ -117,6 +118,7 @@ void band::readData(int expectedLength) {
|
|||
byte XB_byte = (byte) XB;
|
||||
byte* XB_ptr = &XB_byte;
|
||||
cm.init(u->rp, u->rplimit, XB_ptr, 0, defc, length, null);
|
||||
CHECK;
|
||||
} else {
|
||||
NOT_PRODUCT(byte* meta_rp0 = u->meta_rp);
|
||||
assert(u->meta_rp != null);
|
||||
|
@ -215,8 +217,19 @@ int band::getIntTotal() {
|
|||
if (length == 0) return 0;
|
||||
if (total_memo > 0) return total_memo-1;
|
||||
int total = getInt();
|
||||
// overflow checks require that none of the addends are <0,
|
||||
// and that the partial sums never overflow (wrap negative)
|
||||
if (total < 0) {
|
||||
abort("overflow detected");
|
||||
return 0;
|
||||
}
|
||||
for (int k = length-1; k > 0; k--) {
|
||||
int prev_total = total;
|
||||
total += vs[0].getInt();
|
||||
if (total < prev_total) {
|
||||
abort("overflow detected");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
rewind();
|
||||
total_memo = total+1;
|
||||
|
|
|
@ -56,7 +56,7 @@ void bytes::realloc(size_t len_) {
|
|||
return;
|
||||
}
|
||||
byte* oldptr = ptr;
|
||||
ptr = (byte*)::realloc(ptr, len_+1);
|
||||
ptr = (len_ >= PSIZE_MAX) ? null : (byte*)::realloc(ptr, len_+1);
|
||||
if (ptr != null) {
|
||||
mtrace('r', oldptr, 0);
|
||||
mtrace('m', ptr, len_+1);
|
||||
|
@ -128,7 +128,7 @@ const char* bytes::string() {
|
|||
// Make sure there are 'o' bytes beyond the fill pointer,
|
||||
// advance the fill pointer, and return the old fill pointer.
|
||||
byte* fillbytes::grow(size_t s) {
|
||||
size_t nlen = b.len+s;
|
||||
size_t nlen = add_size(b.len, s);
|
||||
if (nlen <= allocated) {
|
||||
b.len = nlen;
|
||||
return limit()-s;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2002-2009 Sun Microsystems, Inc. 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
|
||||
|
@ -814,6 +814,7 @@ void coding_method::init(byte* &band_rp, byte* band_limit,
|
|||
}
|
||||
band_rp = vs.rp;
|
||||
}
|
||||
CHECK;
|
||||
|
||||
// Get an accurate upper limit now.
|
||||
vs0.rplimit = band_rp;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2001-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2001-2009 Sun Microsystems, Inc. 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
|
||||
|
@ -47,11 +47,13 @@
|
|||
#define NOT_PRODUCT(xxx)
|
||||
#define assert(p)
|
||||
#define PRINTCR(args)
|
||||
#define VERSION_STRING "%s version %s\n"
|
||||
#else
|
||||
#define IF_PRODUCT(xxx)
|
||||
#define NOT_PRODUCT(xxx) xxx
|
||||
#define assert(p) ((p) || assert_failed(#p))
|
||||
#define PRINTCR(args) u->verbose && u->printcr_if_verbose args
|
||||
#define VERSION_STRING "%s version non-product %s\n"
|
||||
extern "C" void breakpoint();
|
||||
extern int assert_failed(const char*);
|
||||
#define BREAK (breakpoint())
|
||||
|
@ -79,9 +81,9 @@ extern int assert_failed(const char*);
|
|||
|
||||
#define lengthof(array) (sizeof(array)/sizeof(array[0]))
|
||||
|
||||
#define NEW(T, n) (T*) must_malloc((int)(sizeof(T)*(n)))
|
||||
#define U_NEW(T, n) (T*) u->alloc(sizeof(T)*(n))
|
||||
#define T_NEW(T, n) (T*) u->temp_alloc(sizeof(T)*(n))
|
||||
#define NEW(T, n) (T*) must_malloc((int)(scale_size(n, sizeof(T))))
|
||||
#define U_NEW(T, n) (T*) u->alloc(scale_size(n, sizeof(T)))
|
||||
#define T_NEW(T, n) (T*) u->temp_alloc(scale_size(n, sizeof(T)))
|
||||
|
||||
|
||||
// bytes and byte arrays
|
||||
|
@ -153,6 +155,8 @@ enum { false, true };
|
|||
#define CHECK_NULL_(y,p) _CHECK_DO((p)==null, return y)
|
||||
#define CHECK_NULL_0(p) _CHECK_DO((p)==null, return 0)
|
||||
|
||||
#define CHECK_COUNT(t) if (t < 0){abort("bad value count");} CHECK
|
||||
|
||||
#define STR_TRUE "true"
|
||||
#define STR_FALSE "false"
|
||||
|
||||
|
|
|
@ -299,7 +299,7 @@ int unpacker::run(int argc, char **argv) {
|
|||
case 'J': argp += 1; break; // skip ignored -Jxxx parameter
|
||||
|
||||
case 'V':
|
||||
fprintf(u.errstrm, "%s version %s\n", nbasename(argv[0]), sccsver);
|
||||
fprintf(u.errstrm, VERSION_STRING, nbasename(argv[0]), sccsver);
|
||||
exit(0);
|
||||
|
||||
case 'h':
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2001-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2001-2009 Sun Microsystems, Inc. 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
|
||||
|
@ -523,15 +523,39 @@ void unpacker::read_file_header() {
|
|||
enum {
|
||||
MAGIC_BYTES = 4,
|
||||
AH_LENGTH_0 = 3, //minver, majver, options are outside of archive_size
|
||||
AH_LENGTH_0_MAX = AH_LENGTH_0 + 1, // options might have 2 bytes
|
||||
AH_LENGTH = 26, //maximum archive header length (w/ all fields)
|
||||
// Length contributions from optional header fields:
|
||||
AH_FILE_HEADER_LEN = 5, // sizehi/lo/next/modtime/files
|
||||
AH_ARCHIVE_SIZE_LEN = 2, // sizehi/lo only; part of AH_FILE_HEADER_LEN
|
||||
AH_CP_NUMBER_LEN = 4, // int/float/long/double
|
||||
AH_SPECIAL_FORMAT_LEN = 2, // layouts/band-headers
|
||||
AH_LENGTH_MIN = AH_LENGTH
|
||||
-(AH_FILE_HEADER_LEN+AH_SPECIAL_FORMAT_LEN+AH_CP_NUMBER_LEN),
|
||||
ARCHIVE_SIZE_MIN = AH_LENGTH_MIN - (AH_LENGTH_0 + AH_ARCHIVE_SIZE_LEN),
|
||||
FIRST_READ = MAGIC_BYTES + AH_LENGTH_MIN
|
||||
};
|
||||
|
||||
assert(AH_LENGTH_MIN == 15); // # of UNSIGNED5 fields required after archive_magic
|
||||
assert(ARCHIVE_SIZE_MIN == 10); // # of UNSIGNED5 fields required after archive_size
|
||||
// An absolute minimum null archive is magic[4], {minver,majver,options}[3],
|
||||
// archive_size[0], cp_counts[8], class_counts[4], for a total of 19 bytes.
|
||||
// (Note that archive_size is optional; it may be 0..10 bytes in length.)
|
||||
// The first read must capture everything up through the options field.
|
||||
// This happens to work even if {minver,majver,options} is a pathological
|
||||
// 15 bytes long. Legal pack files limit those three fields to 1+1+2 bytes.
|
||||
assert(FIRST_READ >= MAGIC_BYTES + AH_LENGTH_0 * B_MAX);
|
||||
|
||||
// Up through archive_size, the largest possible archive header is
|
||||
// magic[4], {minver,majver,options}[4], archive_size[10].
|
||||
// (Note only the low 12 bits of options are allowed to be non-zero.)
|
||||
// In order to parse archive_size, we need at least this many bytes
|
||||
// in the first read. Of course, if archive_size_hi is more than
|
||||
// a byte, we probably will fail to allocate the buffer, since it
|
||||
// will be many gigabytes long. This is a practical, not an
|
||||
// architectural limit to Pack200 archive sizes.
|
||||
assert(FIRST_READ >= MAGIC_BYTES + AH_LENGTH_0_MAX + 2*B_MAX);
|
||||
|
||||
bool foreign_buf = (read_input_fn == null);
|
||||
byte initbuf[(int)FIRST_READ + (int)C_SLOP + 200]; // 200 is for JAR I/O
|
||||
if (foreign_buf) {
|
||||
|
@ -547,7 +571,7 @@ void unpacker::read_file_header() {
|
|||
// There is no way to tell the caller that we used only part of them.
|
||||
// Therefore, the caller must use only a bare minimum of read-ahead.
|
||||
if (inbytes.len > FIRST_READ) {
|
||||
abort("too much pushback");
|
||||
abort("too much read-ahead");
|
||||
return;
|
||||
}
|
||||
input.set(initbuf, sizeof(initbuf));
|
||||
|
@ -557,7 +581,7 @@ void unpacker::read_file_header() {
|
|||
rplimit += inbytes.len;
|
||||
bytes_read += inbytes.len;
|
||||
}
|
||||
// Read only 19 bytes, which is certain to contain #archive_size fields,
|
||||
// Read only 19 bytes, which is certain to contain #archive_options fields,
|
||||
// but is certain not to overflow past the archive_header.
|
||||
input.b.len = FIRST_READ;
|
||||
if (!ensure_input(FIRST_READ))
|
||||
|
@ -630,25 +654,24 @@ void unpacker::read_file_header() {
|
|||
if ((archive_options & ~OPTION_LIMIT) != 0) {
|
||||
fprintf(errstrm, "Warning: Illegal archive options 0x%x\n",
|
||||
archive_options);
|
||||
// Do not abort. If the format really changes, version numbers will bump.
|
||||
//abort("illegal archive options");
|
||||
abort("illegal archive options");
|
||||
return;
|
||||
}
|
||||
|
||||
if ((archive_options & AO_HAVE_FILE_HEADERS) != 0) {
|
||||
uint hi = hdr.getInt();
|
||||
uint lo = hdr.getInt();
|
||||
archive_size = band::makeLong(hi, lo);
|
||||
julong x = band::makeLong(hi, lo);
|
||||
archive_size = (size_t) x;
|
||||
if (archive_size != x) {
|
||||
// Silly size specified; force overflow.
|
||||
archive_size = PSIZE_MAX+1;
|
||||
}
|
||||
hdrVals += 2;
|
||||
} else {
|
||||
hdrValsSkipped += 2;
|
||||
}
|
||||
|
||||
if (archive_size != (size_t)archive_size) {
|
||||
// Silly size specified.
|
||||
abort("archive too large");
|
||||
return;
|
||||
}
|
||||
|
||||
// Now we can size the whole archive.
|
||||
// Read everything else into a mega-buffer.
|
||||
rp = hdr.rp;
|
||||
|
@ -662,9 +685,18 @@ void unpacker::read_file_header() {
|
|||
abort("EOF reading fixed input buffer");
|
||||
return;
|
||||
}
|
||||
} else if (archive_size > 0) {
|
||||
input.set(U_NEW(byte, (size_t)(header_size_0 + archive_size + C_SLOP)),
|
||||
(size_t) header_size_0 + (size_t)archive_size);
|
||||
} else if (archive_size != 0) {
|
||||
if (archive_size < ARCHIVE_SIZE_MIN) {
|
||||
abort("impossible archive size"); // bad input data
|
||||
return;
|
||||
}
|
||||
if (archive_size < header_size_1) {
|
||||
abort("too much read-ahead"); // somehow we pre-fetched too much?
|
||||
return;
|
||||
}
|
||||
input.set(U_NEW(byte, add_size(header_size_0, archive_size, C_SLOP)),
|
||||
(size_t) header_size_0 + archive_size);
|
||||
CHECK;
|
||||
assert(input.limit()[0] == 0);
|
||||
// Move all the bytes we read initially into the real buffer.
|
||||
input.b.copyFrom(initbuf, header_size);
|
||||
|
@ -673,17 +705,17 @@ void unpacker::read_file_header() {
|
|||
} else {
|
||||
// It's more complicated and painful.
|
||||
// A zero archive_size means that we must read until EOF.
|
||||
assert(archive_size == 0);
|
||||
input.init(CHUNK*2);
|
||||
CHECK;
|
||||
input.b.len = input.allocated;
|
||||
rp = rplimit = input.base();
|
||||
// Set up input buffer as if we already read the header:
|
||||
input.b.copyFrom(initbuf, header_size);
|
||||
CHECK;
|
||||
rplimit += header_size;
|
||||
while (ensure_input(input.limit() - rp)) {
|
||||
size_t dataSoFar = input_remaining();
|
||||
size_t nextSize = dataSoFar + CHUNK;
|
||||
size_t nextSize = add_size(dataSoFar, CHUNK);
|
||||
input.ensureSize(nextSize);
|
||||
CHECK;
|
||||
input.b.len = input.allocated;
|
||||
|
@ -715,8 +747,10 @@ void unpacker::read_file_header() {
|
|||
|
||||
if ((archive_options & AO_HAVE_FILE_HEADERS) != 0) {
|
||||
archive_next_count = hdr.getInt();
|
||||
CHECK_COUNT(archive_next_count);
|
||||
archive_modtime = hdr.getInt();
|
||||
file_count = hdr.getInt();
|
||||
CHECK_COUNT(file_count);
|
||||
hdrVals += 3;
|
||||
} else {
|
||||
hdrValsSkipped += 3;
|
||||
|
@ -724,7 +758,9 @@ void unpacker::read_file_header() {
|
|||
|
||||
if ((archive_options & AO_HAVE_SPECIAL_FORMATS) != 0) {
|
||||
band_headers_size = hdr.getInt();
|
||||
CHECK_COUNT(band_headers_size);
|
||||
attr_definition_count = hdr.getInt();
|
||||
CHECK_COUNT(attr_definition_count);
|
||||
hdrVals += 2;
|
||||
} else {
|
||||
hdrValsSkipped += 2;
|
||||
|
@ -744,13 +780,16 @@ void unpacker::read_file_header() {
|
|||
}
|
||||
}
|
||||
cp_counts[k] = hdr.getInt();
|
||||
CHECK_COUNT(cp_counts[k]);
|
||||
hdrVals += 1;
|
||||
}
|
||||
|
||||
ic_count = hdr.getInt();
|
||||
CHECK_COUNT(ic_count);
|
||||
default_class_minver = hdr.getInt();
|
||||
default_class_majver = hdr.getInt();
|
||||
class_count = hdr.getInt();
|
||||
CHECK_COUNT(class_count);
|
||||
hdrVals += 4;
|
||||
|
||||
// done with archive_header
|
||||
|
@ -807,7 +846,6 @@ void unpacker::read_file_header() {
|
|||
bytes::of(band_headers.limit(), C_SLOP).clear(_meta_error);
|
||||
}
|
||||
|
||||
|
||||
void unpacker::finish() {
|
||||
if (verbose >= 1) {
|
||||
fprintf(errstrm,
|
||||
|
@ -2117,6 +2155,7 @@ void unpacker::read_classes() {
|
|||
|
||||
field_descr.readData(field_count);
|
||||
read_attrs(ATTR_CONTEXT_FIELD, field_count);
|
||||
CHECK;
|
||||
|
||||
method_descr.readData(method_count);
|
||||
read_attrs(ATTR_CONTEXT_METHOD, method_count);
|
||||
|
@ -2124,6 +2163,7 @@ void unpacker::read_classes() {
|
|||
CHECK;
|
||||
|
||||
read_attrs(ATTR_CONTEXT_CLASS, class_count);
|
||||
CHECK;
|
||||
|
||||
read_code_headers();
|
||||
|
||||
|
@ -2150,10 +2190,12 @@ void unpacker::read_attrs(int attrc, int obj_count) {
|
|||
assert(endsWith(xxx_flags_hi.name, "_flags_hi"));
|
||||
if (haveLongFlags)
|
||||
xxx_flags_hi.readData(obj_count);
|
||||
CHECK;
|
||||
|
||||
band& xxx_flags_lo = ad.xxx_flags_lo();
|
||||
assert(endsWith(xxx_flags_lo.name, "_flags_lo"));
|
||||
xxx_flags_lo.readData(obj_count);
|
||||
CHECK;
|
||||
|
||||
// pre-scan flags, counting occurrences of each index bit
|
||||
julong indexMask = ad.flagIndexMask(); // which flag bits are index bits?
|
||||
|
@ -2176,11 +2218,13 @@ void unpacker::read_attrs(int attrc, int obj_count) {
|
|||
assert(endsWith(xxx_attr_count.name, "_attr_count"));
|
||||
// There is one count element for each 1<<16 bit set in flags:
|
||||
xxx_attr_count.readData(ad.predefCount(X_ATTR_OVERFLOW));
|
||||
CHECK;
|
||||
|
||||
band& xxx_attr_indexes = ad.xxx_attr_indexes();
|
||||
assert(endsWith(xxx_attr_indexes.name, "_attr_indexes"));
|
||||
int overflowIndexCount = xxx_attr_count.getIntTotal();
|
||||
xxx_attr_indexes.readData(overflowIndexCount);
|
||||
CHECK;
|
||||
// pre-scan attr indexes, counting occurrences of each value
|
||||
for (i = 0; i < overflowIndexCount; i++) {
|
||||
idx = xxx_attr_indexes.getInt();
|
||||
|
@ -2211,6 +2255,7 @@ void unpacker::read_attrs(int attrc, int obj_count) {
|
|||
}
|
||||
}
|
||||
ad.xxx_attr_calls().readData(backwardCounts);
|
||||
CHECK;
|
||||
|
||||
// Read built-in bands.
|
||||
// Mostly, these are hand-coded equivalents to readBandData().
|
||||
|
@ -2219,42 +2264,53 @@ void unpacker::read_attrs(int attrc, int obj_count) {
|
|||
|
||||
count = ad.predefCount(CLASS_ATTR_SourceFile);
|
||||
class_SourceFile_RUN.readData(count);
|
||||
CHECK;
|
||||
|
||||
count = ad.predefCount(CLASS_ATTR_EnclosingMethod);
|
||||
class_EnclosingMethod_RC.readData(count);
|
||||
class_EnclosingMethod_RDN.readData(count);
|
||||
CHECK;
|
||||
|
||||
count = ad.predefCount(X_ATTR_Signature);
|
||||
class_Signature_RS.readData(count);
|
||||
CHECK;
|
||||
|
||||
ad.readBandData(X_ATTR_RuntimeVisibleAnnotations);
|
||||
ad.readBandData(X_ATTR_RuntimeInvisibleAnnotations);
|
||||
|
||||
count = ad.predefCount(CLASS_ATTR_InnerClasses);
|
||||
class_InnerClasses_N.readData(count);
|
||||
CHECK;
|
||||
|
||||
count = class_InnerClasses_N.getIntTotal();
|
||||
class_InnerClasses_RC.readData(count);
|
||||
class_InnerClasses_F.readData(count);
|
||||
CHECK;
|
||||
// Drop remaining columns wherever flags are zero:
|
||||
count -= class_InnerClasses_F.getIntCount(0);
|
||||
class_InnerClasses_outer_RCN.readData(count);
|
||||
class_InnerClasses_name_RUN.readData(count);
|
||||
CHECK;
|
||||
|
||||
count = ad.predefCount(CLASS_ATTR_ClassFile_version);
|
||||
class_ClassFile_version_minor_H.readData(count);
|
||||
class_ClassFile_version_major_H.readData(count);
|
||||
CHECK;
|
||||
break;
|
||||
|
||||
case ATTR_CONTEXT_FIELD:
|
||||
|
||||
count = ad.predefCount(FIELD_ATTR_ConstantValue);
|
||||
field_ConstantValue_KQ.readData(count);
|
||||
CHECK;
|
||||
|
||||
count = ad.predefCount(X_ATTR_Signature);
|
||||
field_Signature_RS.readData(count);
|
||||
CHECK;
|
||||
|
||||
ad.readBandData(X_ATTR_RuntimeVisibleAnnotations);
|
||||
ad.readBandData(X_ATTR_RuntimeInvisibleAnnotations);
|
||||
CHECK;
|
||||
break;
|
||||
|
||||
case ATTR_CONTEXT_METHOD:
|
||||
|
@ -2266,15 +2322,18 @@ void unpacker::read_attrs(int attrc, int obj_count) {
|
|||
method_Exceptions_N.readData(count);
|
||||
count = method_Exceptions_N.getIntTotal();
|
||||
method_Exceptions_RC.readData(count);
|
||||
CHECK;
|
||||
|
||||
count = ad.predefCount(X_ATTR_Signature);
|
||||
method_Signature_RS.readData(count);
|
||||
CHECK;
|
||||
|
||||
ad.readBandData(X_ATTR_RuntimeVisibleAnnotations);
|
||||
ad.readBandData(X_ATTR_RuntimeInvisibleAnnotations);
|
||||
ad.readBandData(METHOD_ATTR_RuntimeVisibleParameterAnnotations);
|
||||
ad.readBandData(METHOD_ATTR_RuntimeInvisibleParameterAnnotations);
|
||||
ad.readBandData(METHOD_ATTR_AnnotationDefault);
|
||||
CHECK;
|
||||
break;
|
||||
|
||||
case ATTR_CONTEXT_CODE:
|
||||
|
@ -2286,8 +2345,10 @@ void unpacker::read_attrs(int attrc, int obj_count) {
|
|||
return;
|
||||
}
|
||||
code_StackMapTable_N.readData(count);
|
||||
CHECK;
|
||||
count = code_StackMapTable_N.getIntTotal();
|
||||
code_StackMapTable_frame_T.readData(count);
|
||||
CHECK;
|
||||
// the rest of it depends in a complicated way on frame tags
|
||||
{
|
||||
int fat_frame_count = 0;
|
||||
|
@ -2321,18 +2382,23 @@ void unpacker::read_attrs(int attrc, int obj_count) {
|
|||
// deal completely with fat frames:
|
||||
offset_count += fat_frame_count;
|
||||
code_StackMapTable_local_N.readData(fat_frame_count);
|
||||
CHECK;
|
||||
type_count += code_StackMapTable_local_N.getIntTotal();
|
||||
code_StackMapTable_stack_N.readData(fat_frame_count);
|
||||
type_count += code_StackMapTable_stack_N.getIntTotal();
|
||||
CHECK;
|
||||
// read the rest:
|
||||
code_StackMapTable_offset.readData(offset_count);
|
||||
code_StackMapTable_T.readData(type_count);
|
||||
CHECK;
|
||||
// (7) [RCH]
|
||||
count = code_StackMapTable_T.getIntCount(7);
|
||||
code_StackMapTable_RC.readData(count);
|
||||
CHECK;
|
||||
// (8) [PH]
|
||||
count = code_StackMapTable_T.getIntCount(8);
|
||||
code_StackMapTable_P.readData(count);
|
||||
CHECK;
|
||||
}
|
||||
|
||||
count = ad.predefCount(CODE_ATTR_LineNumberTable);
|
||||
|
@ -2654,6 +2720,7 @@ void unpacker::read_code_headers() {
|
|||
code_max_na_locals.readData();
|
||||
code_handler_count.readData();
|
||||
totalHandlerCount += code_handler_count.getIntTotal();
|
||||
CHECK;
|
||||
|
||||
// Read handler specifications.
|
||||
// Cf. PackageReader.readCodeHandlers.
|
||||
|
@ -2661,8 +2728,10 @@ void unpacker::read_code_headers() {
|
|||
code_handler_end_PO.readData(totalHandlerCount);
|
||||
code_handler_catch_PO.readData(totalHandlerCount);
|
||||
code_handler_class_RCN.readData(totalHandlerCount);
|
||||
CHECK;
|
||||
|
||||
read_attrs(ATTR_CONTEXT_CODE, totalFlagsCount);
|
||||
CHECK;
|
||||
}
|
||||
|
||||
static inline bool is_in_range(uint n, uint min, uint max) {
|
||||
|
|
|
@ -204,7 +204,7 @@ struct unpacker {
|
|||
|
||||
// archive header fields
|
||||
int magic, minver, majver;
|
||||
julong archive_size;
|
||||
size_t archive_size;
|
||||
int archive_next_count, archive_options, archive_modtime;
|
||||
int band_headers_size;
|
||||
int file_count, attr_definition_count, ic_count, class_count;
|
||||
|
|
|
@ -46,14 +46,13 @@
|
|||
|
||||
#include "unpack.h"
|
||||
|
||||
void* must_malloc(int size) {
|
||||
int msize = size;
|
||||
assert(size >= 0);
|
||||
void* must_malloc(size_t size) {
|
||||
size_t msize = size;
|
||||
#ifdef USE_MTRACE
|
||||
if (msize < sizeof(int))
|
||||
if (msize >= 0 && msize < sizeof(int))
|
||||
msize = sizeof(int); // see 0xbaadf00d below
|
||||
#endif
|
||||
void* ptr = malloc(msize);
|
||||
void* ptr = (msize > PSIZE_MAX) ? null : malloc(msize);
|
||||
if (ptr != null) {
|
||||
memset(ptr, 0, size);
|
||||
} else {
|
||||
|
|
|
@ -25,13 +25,31 @@
|
|||
|
||||
//Definitions of our util functions
|
||||
|
||||
void* must_malloc(int size);
|
||||
void* must_malloc(size_t size);
|
||||
#ifndef USE_MTRACE
|
||||
#define mtrace(c, ptr, size)
|
||||
#else
|
||||
void mtrace(char c, void* ptr, size_t size);
|
||||
#endif
|
||||
|
||||
// overflow management
|
||||
#define OVERFLOW ((size_t)-1)
|
||||
#define PSIZE_MAX (OVERFLOW/2) /* normal size limit */
|
||||
|
||||
inline size_t scale_size(size_t size, size_t scale) {
|
||||
return (size > PSIZE_MAX / scale) ? OVERFLOW : size * scale;
|
||||
}
|
||||
|
||||
inline size_t add_size(size_t size1, size_t size2) {
|
||||
return ((size1 | size2 | (size1 + size2)) > PSIZE_MAX)
|
||||
? OVERFLOW
|
||||
: size1 + size2;
|
||||
}
|
||||
|
||||
inline size_t add_size(size_t size1, size_t size2, int size3) {
|
||||
return add_size(add_size(size1, size2), size3);
|
||||
}
|
||||
|
||||
// These may be expensive, because they have to go via Java TSD,
|
||||
// if the optional u argument is missing.
|
||||
struct unpacker;
|
||||
|
|
|
@ -722,6 +722,10 @@ DGifSetupDecompress(GifFileType * GifFile) {
|
|||
GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
|
||||
|
||||
READ(GifFile, &CodeSize, 1); /* Read Code size from file. */
|
||||
if (CodeSize >= 12) {
|
||||
/* Invalid initial code size: report failure */
|
||||
return GIF_ERROR;
|
||||
}
|
||||
BitsPerPixel = CodeSize;
|
||||
|
||||
Private->Buf[0] = 0; /* Input Buffer empty. */
|
||||
|
@ -964,10 +968,13 @@ DGifDecompressInput(GifFileType * GifFile,
|
|||
|
||||
/* If code cannot fit into RunningBits bits, must raise its size. Note
|
||||
* however that codes above 4095 are used for special signaling. */
|
||||
if (++Private->RunningCode > Private->MaxCode1 &&
|
||||
Private->RunningBits < LZ_BITS) {
|
||||
if (++Private->RunningCode > Private->MaxCode1) {
|
||||
if (Private->RunningBits < LZ_BITS) {
|
||||
Private->MaxCode1 <<= 1;
|
||||
Private->RunningBits++;
|
||||
} else {
|
||||
Private->RunningCode = Private->MaxCode1;
|
||||
}
|
||||
}
|
||||
return GIF_OK;
|
||||
}
|
||||
|
|
|
@ -191,6 +191,11 @@ Java_sun_awt_image_GifImageDecoder_parseImage(JNIEnv *env,
|
|||
int passht = passinc;
|
||||
int len;
|
||||
|
||||
/* We have verified the initial code size on the java layer.
|
||||
* Here we just check bounds for particular indexes. */
|
||||
if (freeCode >= 4096 || maxCode >= 4096) {
|
||||
return 0;
|
||||
}
|
||||
if (blockh == 0 || raslineh == 0
|
||||
|| prefixh == 0 || suffixh == 0
|
||||
|| outCodeh == 0)
|
||||
|
|
|
@ -216,6 +216,16 @@ printMedialibError(int status) {
|
|||
|
||||
#endif /* ! DEBUG */
|
||||
|
||||
static int
|
||||
getMlibEdgeHint(jint edgeHint) {
|
||||
switch (edgeHint) {
|
||||
case java_awt_image_ConvolveOp_EDGE_NO_OP:
|
||||
return MLIB_EDGE_DST_COPY_SRC;
|
||||
case java_awt_image_ConvolveOp_EDGE_ZERO_FILL:
|
||||
default:
|
||||
return MLIB_EDGE_DST_FILL_ZERO;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* External Functions *
|
||||
|
@ -400,22 +410,10 @@ Java_sun_awt_image_ImagingLib_convolveBI(JNIEnv *env, jobject this,
|
|||
}
|
||||
}
|
||||
|
||||
if (edgeHint == java_awt_image_ConvolveOp_EDGE_NO_OP) {
|
||||
int kw2 = kwidth>>1;
|
||||
int kh2 = kheight>>1;
|
||||
int bsize = mlib_ImageGetChannels(src)*
|
||||
(mlib_ImageGetType(src) == MLIB_BYTE ? 1 : 2);
|
||||
|
||||
void *dstDataP = mlib_ImageGetData(dst);
|
||||
void *srcDataP = mlib_ImageGetData(src);
|
||||
/* REMIND: Copy a smaller area */
|
||||
memcpy(dstDataP, srcDataP, dst->width*dst->height*bsize);
|
||||
}
|
||||
|
||||
cmask = (1<<src->channels)-1;
|
||||
status = (*sMlibFns[MLIB_CONVMxN].fptr)(dst, src, kdata, w, h,
|
||||
(w-1)/2, (h-1)/2, scale, cmask,
|
||||
MLIB_EDGE_DST_NO_WRITE);
|
||||
getMlibEdgeHint(edgeHint));
|
||||
|
||||
if (status != MLIB_SUCCESS) {
|
||||
printMedialibError(status);
|
||||
|
@ -660,22 +658,10 @@ Java_sun_awt_image_ImagingLib_convolveRaster(JNIEnv *env, jobject this,
|
|||
}
|
||||
}
|
||||
|
||||
if (edgeHint == java_awt_image_ConvolveOp_EDGE_NO_OP) {
|
||||
int kw2 = kwidth>>1;
|
||||
int kh2 = kheight>>1;
|
||||
int bsize = mlib_ImageGetChannels(src)*
|
||||
(mlib_ImageGetType(src) == MLIB_BYTE ? 1 : 2);
|
||||
|
||||
void *dstDataP = mlib_ImageGetData(dst);
|
||||
void *srcDataP = mlib_ImageGetData(src);
|
||||
/* REMIND: Copy a smaller area */
|
||||
memcpy(dstDataP, srcDataP, dst->width*dst->height*bsize);
|
||||
}
|
||||
|
||||
cmask = (1<<src->channels)-1;
|
||||
status = (*sMlibFns[MLIB_CONVMxN].fptr)(dst, src, kdata, w, h,
|
||||
(w-1)/2, (h-1)/2, scale, cmask,
|
||||
MLIB_EDGE_DST_NO_WRITE);
|
||||
getMlibEdgeHint(edgeHint));
|
||||
|
||||
if (status != MLIB_SUCCESS) {
|
||||
printMedialibError(status);
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
/* here come some very simple macros */
|
||||
|
||||
/* advance a pointer p by sizeof(type)*n bytes */
|
||||
#define INCPN(type,p,n) ((p) = (type*)(p)+n)
|
||||
#define INCPN(type,p,n) ((p) = (type*)(p)+(n))
|
||||
|
||||
/* advance a pointer by sizeof(type) */
|
||||
#define INCP(type,p) INCPN(type,(p),1)
|
||||
|
|
|
@ -62,6 +62,15 @@ SplashStreamGifInputFunc(GifFileType * gif, GifByteType * buf, int n)
|
|||
return rc;
|
||||
}
|
||||
|
||||
/* These macro help to ensure that we only take part of frame that fits into
|
||||
logical screen. */
|
||||
|
||||
/* Ensure that p belongs to [pmin, pmax) interval. Returns fixed point (if fix is needed) */
|
||||
#define FIX_POINT(p, pmin, pmax) ( ((p) < (pmin)) ? (pmin) : (((p) > (pmax)) ? (pmax) : (p)))
|
||||
/* Ensures that line starting at point p does not exceed boundary pmax.
|
||||
Returns fixed length (if fix is needed) */
|
||||
#define FIX_LENGTH(p, len, pmax) ( ((p) + (len)) > (pmax) ? ((pmax) - (p)) : (len))
|
||||
|
||||
int
|
||||
SplashDecodeGif(Splash * splash, GifFileType * gif)
|
||||
{
|
||||
|
@ -70,6 +79,7 @@ SplashDecodeGif(Splash * splash, GifFileType * gif)
|
|||
byte_t *pBitmapBits, *pOldBitmapBits;
|
||||
int i, j;
|
||||
int imageIndex;
|
||||
int cx, cy, cw, ch; /* clamped coordinates */
|
||||
const int interlacedOffset[] = { 0, 4, 2, 1, 0 }; /* The way Interlaced image should. */
|
||||
const int interlacedJumps[] = { 8, 8, 4, 2, 1 }; /* be read - offsets and jumps... */
|
||||
|
||||
|
@ -79,14 +89,31 @@ SplashDecodeGif(Splash * splash, GifFileType * gif)
|
|||
|
||||
SplashCleanup(splash);
|
||||
|
||||
if (!SAFE_TO_ALLOC(gif->SWidth, splash->imageFormat.depthBytes)) {
|
||||
return 0;
|
||||
}
|
||||
stride = gif->SWidth * splash->imageFormat.depthBytes;
|
||||
if (splash->byteAlignment > 1)
|
||||
stride =
|
||||
(stride + splash->byteAlignment - 1) & ~(splash->byteAlignment - 1);
|
||||
|
||||
if (!SAFE_TO_ALLOC(gif->SHeight, stride)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!SAFE_TO_ALLOC(gif->ImageCount, sizeof(SplashImage*))) {
|
||||
return 0;
|
||||
}
|
||||
bufferSize = stride * gif->SHeight;
|
||||
pBitmapBits = (byte_t *) malloc(bufferSize);
|
||||
if (!pBitmapBits) {
|
||||
return 0;
|
||||
}
|
||||
pOldBitmapBits = (byte_t *) malloc(bufferSize);
|
||||
if (!pOldBitmapBits) {
|
||||
free(pBitmapBits);
|
||||
return 0;
|
||||
}
|
||||
memset(pBitmapBits, 0, bufferSize);
|
||||
|
||||
splash->width = gif->SWidth;
|
||||
|
@ -94,6 +121,11 @@ SplashDecodeGif(Splash * splash, GifFileType * gif)
|
|||
splash->frameCount = gif->ImageCount;
|
||||
splash->frames = (SplashImage *)
|
||||
malloc(sizeof(SplashImage) * gif->ImageCount);
|
||||
if (!splash->frames) {
|
||||
free(pBitmapBits);
|
||||
free(pOldBitmapBits);
|
||||
return 0;
|
||||
}
|
||||
memset(splash->frames, 0, sizeof(SplashImage) * gif->ImageCount);
|
||||
splash->loopCount = 1;
|
||||
|
||||
|
@ -109,6 +141,11 @@ SplashDecodeGif(Splash * splash, GifFileType * gif)
|
|||
int colorCount = 0;
|
||||
rgbquad_t colorMapBuf[SPLASH_COLOR_MAP_SIZE];
|
||||
|
||||
cx = FIX_POINT(desc->Left, 0, gif->SWidth);
|
||||
cy = FIX_POINT(desc->Top, 0, gif->SHeight);
|
||||
cw = FIX_LENGTH(desc->Left, desc->Width, gif->SWidth);
|
||||
ch = FIX_LENGTH(desc->Top, desc->Height, gif->SHeight);
|
||||
|
||||
if (colorMap) {
|
||||
if (colorMap->ColorCount <= SPLASH_COLOR_MAP_SIZE) {
|
||||
colorCount = colorMap->ColorCount;
|
||||
|
@ -195,20 +232,35 @@ SplashDecodeGif(Splash * splash, GifFileType * gif)
|
|||
for (; pass < npass; ++pass) {
|
||||
int jump = interlacedJumps[pass];
|
||||
int ofs = interlacedOffset[pass];
|
||||
int numLines = (desc->Height + jump - 1 - ofs) / jump;
|
||||
/* Number of source lines for current pass */
|
||||
int numPassLines = (desc->Height + jump - ofs - 1) / jump;
|
||||
/* Number of lines that fits to dest buffer */
|
||||
int numLines = (ch + jump - ofs - 1) / jump;
|
||||
|
||||
initRect(&srcRect, 0, 0, desc->Width, numLines, 1,
|
||||
desc->Width, pSrc, &srcFormat);
|
||||
initRect(&dstRect, desc->Left, desc->Top + ofs, desc->Width,
|
||||
numLines, jump, stride, pBitmapBits, &splash->imageFormat);
|
||||
|
||||
if (numLines > 0) {
|
||||
initRect(&dstRect, cx, cy + ofs, cw,
|
||||
numLines , jump, stride, pBitmapBits, &splash->imageFormat);
|
||||
|
||||
pSrc += convertRect(&srcRect, &dstRect, CVT_ALPHATEST);
|
||||
}
|
||||
// skip extra source data
|
||||
pSrc += (numPassLines - numLines) * srcRect.stride;
|
||||
}
|
||||
}
|
||||
|
||||
// now dispose of the previous frame correctly
|
||||
|
||||
splash->frames[imageIndex].bitmapBits =
|
||||
(rgbquad_t *) malloc(bufferSize);
|
||||
if (!splash->frames[imageIndex].bitmapBits) {
|
||||
free(pBitmapBits);
|
||||
free(pOldBitmapBits);
|
||||
/* Assuming that callee will take care of splash frames we have already allocated */
|
||||
return 0;
|
||||
}
|
||||
memcpy(splash->frames[imageIndex].bitmapBits, pBitmapBits, bufferSize);
|
||||
|
||||
SplashInitFrameShape(splash, imageIndex);
|
||||
|
@ -224,27 +276,29 @@ SplashDecodeGif(Splash * splash, GifFileType * gif)
|
|||
{
|
||||
ImageRect dstRect;
|
||||
rgbquad_t fillColor = 0; // 0 is transparent
|
||||
if (transparentColor < 0) {
|
||||
|
||||
if (transparentColor > 0) {
|
||||
fillColor= MAKE_QUAD_GIF(
|
||||
colorMap->Colors[gif->SBackGroundColor], 0xff);
|
||||
}
|
||||
initRect(&dstRect, desc->Left, desc->Top,
|
||||
desc->Width, desc->Height, 1, stride,
|
||||
initRect(&dstRect,
|
||||
cx, cy, cw, ch,
|
||||
1, stride,
|
||||
pBitmapBits, &splash->imageFormat);
|
||||
fillRect(fillColor, &dstRect);
|
||||
}
|
||||
break;
|
||||
case GIF_DISPOSE_RESTORE:
|
||||
{
|
||||
|
||||
int lineSize = desc->Width * splash->imageFormat.depthBytes;
|
||||
|
||||
for (j = 0; j < desc->Height; j++) {
|
||||
int lineIndex = stride * (j + desc->Top) +
|
||||
desc->Left * splash->imageFormat.depthBytes;
|
||||
|
||||
int lineSize = cw * splash->imageFormat.depthBytes;
|
||||
if (lineSize > 0) {
|
||||
int lineOffset = cx * splash->imageFormat.depthBytes;
|
||||
int lineIndex = cy * stride + lineOffset;
|
||||
for (j=0; j<ch; j++) {
|
||||
memcpy(pBitmapBits + lineIndex, pOldBitmapBits + lineIndex,
|
||||
lineSize);
|
||||
lineIndex += stride;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -155,6 +155,10 @@ int BitmapToYXBandedRectangles(ImageRect * pSrcRect, RECT_T * out);
|
|||
|
||||
void SplashInitFrameShape(Splash * splash, int imageIndex);
|
||||
|
||||
#define SAFE_TO_ALLOC(c, sz) \
|
||||
(((c) > 0) && ((sz) > 0) && \
|
||||
((0xffffffffu / ((unsigned int)(c))) > (unsigned int)(sz)))
|
||||
|
||||
#define dbgprintf printf
|
||||
|
||||
#endif
|
||||
|
|
|
@ -103,9 +103,17 @@ SplashDecodePng(Splash * splash, png_rw_ptr read_func, void *io_ptr)
|
|||
|
||||
rowbytes = png_get_rowbytes(png_ptr, info_ptr);
|
||||
|
||||
if (!SAFE_TO_ALLOC(rowbytes, height)) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ((image_data = (unsigned char *) malloc(rowbytes * height)) == NULL) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!SAFE_TO_ALLOC(height, sizeof(png_bytep))) {
|
||||
goto done;
|
||||
}
|
||||
if ((row_pointers = (png_bytepp) malloc(height * sizeof(png_bytep)))
|
||||
== NULL) {
|
||||
goto done;
|
||||
|
@ -121,13 +129,28 @@ SplashDecodePng(Splash * splash, png_rw_ptr read_func, void *io_ptr)
|
|||
splash->width = width;
|
||||
splash->height = height;
|
||||
|
||||
if (!SAFE_TO_ALLOC(splash->width, splash->imageFormat.depthBytes)) {
|
||||
goto done;
|
||||
}
|
||||
stride = splash->width * splash->imageFormat.depthBytes;
|
||||
|
||||
if (!SAFE_TO_ALLOC(splash->height, stride)) {
|
||||
goto done;
|
||||
}
|
||||
splash->frameCount = 1;
|
||||
splash->frames = (SplashImage *)
|
||||
malloc(sizeof(SplashImage) * splash->frameCount);
|
||||
|
||||
if (splash->frames == NULL) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
splash->loopCount = 1;
|
||||
splash->frames[0].bitmapBits = malloc(stride * splash->height);
|
||||
if (splash->frames[0].bitmapBits == NULL) {
|
||||
free(splash->frames);
|
||||
goto done;
|
||||
}
|
||||
splash->frames[0].delay = 0;
|
||||
|
||||
/* FIXME: sort out the real format */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2005 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2005-2008 Sun Microsystems, Inc. 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
|
||||
|
@ -31,6 +31,7 @@ import java.security.spec.AlgorithmParameterSpec;
|
|||
import java.security.spec.RSAKeyGenParameterSpec;
|
||||
|
||||
import sun.security.jca.JCAUtil;
|
||||
import sun.security.rsa.RSAKeyFactory;
|
||||
|
||||
/**
|
||||
* RSA keypair generator.
|
||||
|
@ -43,8 +44,8 @@ import sun.security.jca.JCAUtil;
|
|||
public final class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
|
||||
|
||||
// Supported by Microsoft Base, Strong and Enhanced Cryptographic Providers
|
||||
private static final int KEY_SIZE_MIN = 512; // disallow MSCAPI min. of 384
|
||||
private static final int KEY_SIZE_MAX = 16384;
|
||||
static final int KEY_SIZE_MIN = 512; // disallow MSCAPI min. of 384
|
||||
static final int KEY_SIZE_MAX = 16384;
|
||||
private static final int KEY_SIZE_DEFAULT = 1024;
|
||||
|
||||
// size of the key to generate, KEY_SIZE_MIN <= keySize <= KEY_SIZE_MAX
|
||||
|
@ -59,7 +60,14 @@ public final class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
|
|||
// random is always ignored
|
||||
public void initialize(int keySize, SecureRandom random) {
|
||||
|
||||
checkKeySize(keySize);
|
||||
try {
|
||||
RSAKeyFactory.checkKeyLengths(keySize, null,
|
||||
KEY_SIZE_MIN, KEY_SIZE_MAX);
|
||||
} catch (InvalidKeyException e) {
|
||||
throw new InvalidParameterException(e.getMessage());
|
||||
}
|
||||
|
||||
this.keySize = keySize;
|
||||
}
|
||||
|
||||
// second initialize method. See JCA doc
|
||||
|
@ -67,21 +75,31 @@ public final class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
|
|||
public void initialize(AlgorithmParameterSpec params, SecureRandom random)
|
||||
throws InvalidAlgorithmParameterException {
|
||||
|
||||
int tmpSize;
|
||||
if (params == null) {
|
||||
checkKeySize(KEY_SIZE_DEFAULT);
|
||||
|
||||
tmpSize = KEY_SIZE_DEFAULT;
|
||||
} else if (params instanceof RSAKeyGenParameterSpec) {
|
||||
|
||||
if (((RSAKeyGenParameterSpec) params).getPublicExponent() != null) {
|
||||
throw new InvalidAlgorithmParameterException
|
||||
("Exponent parameter is not supported");
|
||||
}
|
||||
checkKeySize(((RSAKeyGenParameterSpec) params).getKeysize());
|
||||
tmpSize = ((RSAKeyGenParameterSpec) params).getKeysize();
|
||||
|
||||
} else {
|
||||
throw new InvalidAlgorithmParameterException
|
||||
("Params must be an instance of RSAKeyGenParameterSpec");
|
||||
}
|
||||
|
||||
try {
|
||||
RSAKeyFactory.checkKeyLengths(tmpSize, null,
|
||||
KEY_SIZE_MIN, KEY_SIZE_MAX);
|
||||
} catch (InvalidKeyException e) {
|
||||
throw new InvalidAlgorithmParameterException(
|
||||
"Invalid Key sizes", e);
|
||||
}
|
||||
|
||||
this.keySize = tmpSize;
|
||||
}
|
||||
|
||||
// generate the keypair. See JCA doc
|
||||
|
@ -95,18 +113,6 @@ public final class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
|
|||
return new KeyPair(keys.getPublic(), keys.getPrivate());
|
||||
}
|
||||
|
||||
private void checkKeySize(int keySize) throws InvalidParameterException {
|
||||
if (keySize < KEY_SIZE_MIN) {
|
||||
throw new InvalidParameterException
|
||||
("Key size must be at least " + KEY_SIZE_MIN + " bits");
|
||||
}
|
||||
if (keySize > KEY_SIZE_MAX) {
|
||||
throw new InvalidParameterException
|
||||
("Key size must be " + KEY_SIZE_MAX + " bits or less");
|
||||
}
|
||||
this.keySize = keySize;
|
||||
}
|
||||
|
||||
private static native RSAKeyPair generateRSAKeyPair(int keySize,
|
||||
String keyContainerName);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2005 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2005-2008 Sun Microsystems, Inc. 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
|
||||
|
@ -38,6 +38,9 @@ import java.security.SecureRandom;
|
|||
import java.security.Signature;
|
||||
import java.security.SignatureSpi;
|
||||
import java.security.SignatureException;
|
||||
import java.math.BigInteger;
|
||||
|
||||
import sun.security.rsa.RSAKeyFactory;
|
||||
|
||||
/**
|
||||
* RSA signature implementation. Supports RSA signing using PKCS#1 v1.5 padding.
|
||||
|
@ -124,7 +127,16 @@ abstract class RSASignature extends java.security.SignatureSpi
|
|||
|
||||
// convert key to MSCAPI format
|
||||
|
||||
byte[] modulusBytes = rsaKey.getModulus().toByteArray();
|
||||
BigInteger modulus = rsaKey.getModulus();
|
||||
BigInteger exponent = rsaKey.getPublicExponent();
|
||||
|
||||
// Check against the local and global values to make sure
|
||||
// the sizes are ok. Round up to the nearest byte.
|
||||
RSAKeyFactory.checkKeyLengths(((modulus.bitLength() + 7) & ~7),
|
||||
exponent, -1, RSAKeyPairGenerator.KEY_SIZE_MAX);
|
||||
|
||||
byte[] modulusBytes = modulus.toByteArray();
|
||||
byte[] exponentBytes = exponent.toByteArray();
|
||||
|
||||
// Adjust key length due to sign bit
|
||||
int keyBitLength = (modulusBytes[0] == 0)
|
||||
|
@ -132,8 +144,7 @@ abstract class RSASignature extends java.security.SignatureSpi
|
|||
: modulusBytes.length * 8;
|
||||
|
||||
byte[] keyBlob = generatePublicKeyBlob(
|
||||
keyBitLength, modulusBytes,
|
||||
rsaKey.getPublicExponent().toByteArray());
|
||||
keyBitLength, modulusBytes, exponentBytes);
|
||||
|
||||
publicKey = importPublicKey(keyBlob, keyBitLength);
|
||||
|
||||
|
@ -166,12 +177,11 @@ abstract class RSASignature extends java.security.SignatureSpi
|
|||
}
|
||||
privateKey = (sun.security.mscapi.RSAPrivateKey) key;
|
||||
|
||||
// Determine byte length from bit length
|
||||
int keySize = (privateKey.bitLength() + 7) >> 3;
|
||||
|
||||
if (keySize < 64)
|
||||
throw new InvalidKeyException(
|
||||
"RSA keys must be at least 512 bits long");
|
||||
// Check against the local and global values to make sure
|
||||
// the sizes are ok. Round up to nearest byte.
|
||||
RSAKeyFactory.checkKeyLengths(((privateKey.bitLength() + 7) & ~7),
|
||||
null, RSAKeyPairGenerator.KEY_SIZE_MIN,
|
||||
RSAKeyPairGenerator.KEY_SIZE_MAX);
|
||||
|
||||
if (needsReset) {
|
||||
messageDigest.reset();
|
||||
|
|
BIN
jdk/test/java/awt/FontClass/CreateFont/A.ttf
Normal file
BIN
jdk/test/java/awt/FontClass/CreateFont/A.ttf
Normal file
Binary file not shown.
139
jdk/test/java/awt/FontClass/CreateFont/BigFont.java
Normal file
139
jdk/test/java/awt/FontClass/CreateFont/BigFont.java
Normal file
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
import java.applet.*;
|
||||
import java.awt.*;
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
|
||||
public class BigFont extends Applet {
|
||||
|
||||
static private class SizedInputStream extends InputStream {
|
||||
|
||||
int size;
|
||||
int cnt = 0;
|
||||
|
||||
SizedInputStream(int size) {
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
public int read() {
|
||||
if (cnt < size) {
|
||||
cnt++;
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public int getCurrentSize() {
|
||||
return cnt;
|
||||
}
|
||||
}
|
||||
|
||||
String id;
|
||||
String fileName;
|
||||
|
||||
public void init() {
|
||||
id = getParameter("number");
|
||||
fileName = getParameter("font");
|
||||
|
||||
System.out.println("Applet " + id + " "+
|
||||
Thread.currentThread().getThreadGroup());
|
||||
// Larger than size for a single font.
|
||||
int fontSize = 64 * 1000 * 1000;
|
||||
SizedInputStream sis = new SizedInputStream(fontSize);
|
||||
try {
|
||||
Font font = Font.createFont(Font.TRUETYPE_FONT, sis);
|
||||
} catch (Throwable t) {
|
||||
if (t instanceof FontFormatException ||
|
||||
fontSize <= sis.getCurrentSize())
|
||||
{
|
||||
System.out.println(sis.getCurrentSize());
|
||||
System.out.println(t);
|
||||
throw new RuntimeException("Allowed file to be too large.");
|
||||
}
|
||||
}
|
||||
// The following part of the test was verified manually but
|
||||
// is impractical to enable because it requires a fairly large
|
||||
// valid font to be part of the test, and we can't easily include
|
||||
// that, nor dependably reference one from the applet environment.
|
||||
/*
|
||||
if (fileName == null) {
|
||||
return;
|
||||
}
|
||||
int size = getFileSize(fileName);
|
||||
if (size == 0) {
|
||||
return;
|
||||
}
|
||||
int fontCnt = 1000 * 1000 * 1000 / size;
|
||||
loadMany(size, fontCnt, fileName);
|
||||
System.gc(); System.gc();
|
||||
fontCnt = fontCnt / 2;
|
||||
System.out.println("Applet " + id + " load more.");
|
||||
loadMany(size, fontCnt, fileName);
|
||||
*/
|
||||
System.out.println("Applet " + id + " finished.");
|
||||
}
|
||||
|
||||
int getFileSize(String fileName) {
|
||||
try {
|
||||
URL url = new URL(getCodeBase(), fileName);
|
||||
InputStream inStream = url.openStream();
|
||||
BufferedInputStream fontStream = new BufferedInputStream(inStream);
|
||||
int size = 0;
|
||||
while (fontStream.read() != -1) {
|
||||
size++;
|
||||
}
|
||||
fontStream.close();
|
||||
return size;
|
||||
} catch (IOException e) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
void loadMany(int oneFont, int fontCnt, String fileName) {
|
||||
System.out.println("fontcnt= " + fontCnt);
|
||||
Font[] fonts = new Font[fontCnt];
|
||||
int totalSize = 0;
|
||||
boolean gotException = false;
|
||||
for (int i=0; i<fontCnt; i++) {
|
||||
try {
|
||||
URL url = new URL(getCodeBase(), fileName);
|
||||
InputStream inStream = url.openStream();
|
||||
BufferedInputStream fontStream =
|
||||
new BufferedInputStream(inStream);
|
||||
fonts[i] = Font.createFont(Font.TRUETYPE_FONT, fontStream);
|
||||
totalSize += oneFont;
|
||||
fontStream.close();
|
||||
} catch (Throwable t) {
|
||||
gotException = true;
|
||||
System.out.println("Applet " + id + " " + t);
|
||||
}
|
||||
}
|
||||
if (!gotException) {
|
||||
throw new RuntimeException("No expected exception");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
89
jdk/test/java/awt/FontClass/CreateFont/DeleteFont.java
Normal file
89
jdk/test/java/awt/FontClass/CreateFont/DeleteFont.java
Normal file
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* Copyright 2004-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.awt.*;
|
||||
|
||||
public class DeleteFont {
|
||||
|
||||
public static void main(String args[]) throws Exception {
|
||||
|
||||
String font = "A.ttf";
|
||||
String sep = System.getProperty("file.separator");
|
||||
String testSrc = System.getenv("TESTSRC");
|
||||
if (testSrc != null) {
|
||||
font = testSrc + sep + font;
|
||||
}
|
||||
System.out.println("Using font file: " + font);
|
||||
FileInputStream fis = new FileInputStream(font);
|
||||
Font f = Font.createFont(Font.TRUETYPE_FONT, fis);
|
||||
f.toString();
|
||||
f.deriveFont(Font.BOLD);
|
||||
f.canDisplay('X');
|
||||
|
||||
InputStream in = new InputStream() {
|
||||
public int read() {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
};
|
||||
boolean gotException = false;
|
||||
try {
|
||||
Font.createFont(java.awt.Font.TRUETYPE_FONT, in);
|
||||
} catch (IOException e) {
|
||||
gotException = true;
|
||||
}
|
||||
if (!gotException) {
|
||||
throw new RuntimeException("No expected IOException");
|
||||
}
|
||||
badRead(-2, Font.TRUETYPE_FONT);
|
||||
badRead(8193, Font.TRUETYPE_FONT);
|
||||
|
||||
badRead(-2, Font.TYPE1_FONT);
|
||||
badRead(8193, Font.TYPE1_FONT);
|
||||
|
||||
// Make sure GC has a chance to clean up before we exit.
|
||||
System.gc(); System.gc();
|
||||
}
|
||||
|
||||
static void badRead(final int retval, int fontType) {
|
||||
int num = 2;
|
||||
byte[] buff = new byte[16*8192]; // Multiple of 8192 is important.
|
||||
for (int ct=0; ct<num; ++ct) {
|
||||
try {
|
||||
Font.createFont(
|
||||
fontType,
|
||||
new ByteArrayInputStream(buff) {
|
||||
@Override
|
||||
public int read(byte[] buff, int off, int len) {
|
||||
int read = super.read(buff, off, len);
|
||||
return read<0 ? retval : read;
|
||||
}
|
||||
}
|
||||
);
|
||||
} catch (Throwable exc) {
|
||||
//exc.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
66
jdk/test/java/awt/FontClass/CreateFont/DeleteFont.sh
Normal file
66
jdk/test/java/awt/FontClass/CreateFont/DeleteFont.sh
Normal file
|
@ -0,0 +1,66 @@
|
|||
# Copyright 2004-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
# CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
# have any questions.
|
||||
|
||||
# @test
|
||||
# @bug 6189812 6380357 6632886
|
||||
# @summary Verify that temporary font files are deleted on exit.
|
||||
|
||||
if [ -z "${TESTSRC}" ]; then
|
||||
echo "TESTSRC undefined: defaulting to ."
|
||||
TESTSRC=.
|
||||
fi
|
||||
|
||||
if [ -z "${TESTCLASSES}" ]; then
|
||||
echo "TESTCLASSES undefined: defaulting to ."
|
||||
TESTCLASSES=.
|
||||
fi
|
||||
|
||||
if [ -z "${TESTJAVA}" ]; then
|
||||
echo "TESTJAVA undefined: can't continue."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "TESTJAVA=${TESTJAVA}"
|
||||
echo "TESTSRC=${TESTSRC}"
|
||||
echo "TESTCLASSES=${TESTCLASSES}"
|
||||
cd ${TESTSRC}
|
||||
${TESTJAVA}/bin/javac -d ${TESTCLASSES} DeleteFont.java
|
||||
|
||||
cd ${TESTCLASSES}
|
||||
|
||||
numfiles0=`ls ${TESTCLASSES} | wc -l`
|
||||
${TESTJAVA}/bin/java -Djava.io.tmpdir=${TESTCLASSES} DeleteFont
|
||||
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
echo "Test fails: exception thrown!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
numfiles1=`ls ${TESTCLASSES} | wc -l`
|
||||
|
||||
if [ $numfiles0 -ne $numfiles1 ]
|
||||
then
|
||||
echo "Test fails: tmp file exists!"
|
||||
ls ${TESTCLASSES}
|
||||
exit 1
|
||||
fi
|
||||
exit 0
|
48
jdk/test/java/awt/FontClass/CreateFont/bigfont.html
Normal file
48
jdk/test/java/awt/FontClass/CreateFont/bigfont.html
Normal file
|
@ -0,0 +1,48 @@
|
|||
<!--
|
||||
|
||||
Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
have any questions.
|
||||
|
||||
@test
|
||||
@bug 6522586
|
||||
@run applet bigfont.html
|
||||
@summary Enforce limits on font creation
|
||||
|
||||
-->
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>Test Font Creation Limits</title>
|
||||
</head>
|
||||
<body>
|
||||
<hr>
|
||||
<APPLET CODE = BigFont.class WIDTH = 100 HEIGHT = 100 >
|
||||
<param name="number" value="1">
|
||||
<param name="font" value="A.ttf">
|
||||
</APPLET>
|
||||
<APPLET CODE = BigFont.class WIDTH = 100 HEIGHT = 100>
|
||||
<param name="number" value="2">
|
||||
<param name="font" value="A.ttf">
|
||||
</APPLET>
|
||||
<hr>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6652929
|
||||
* @summary verify handling of File.getPath()
|
||||
*/
|
||||
|
||||
import java.awt.*;
|
||||
import java.io.*;
|
||||
|
||||
public class FontFile {
|
||||
public static void main(String[] args) throws Exception {
|
||||
String sep = System.getProperty("file.separator");
|
||||
String fname = ".." + sep + "A.ttf";
|
||||
String dir = System.getProperty("test.src");
|
||||
if (dir != null) {
|
||||
fname = dir + sep + fname;
|
||||
}
|
||||
final String name = fname;
|
||||
System.out.println("Will try to access " + name);
|
||||
if (!(new File(name)).canRead()) {
|
||||
System.out.println("File not available : can't run test");
|
||||
return;
|
||||
}
|
||||
System.out.println("File is available. Verify no access under SM");
|
||||
|
||||
System.setSecurityManager(new SecurityManager());
|
||||
|
||||
|
||||
// Check cannot read file.
|
||||
try {
|
||||
new FileInputStream(name);
|
||||
throw new Error("Something wrong with test environment");
|
||||
} catch (SecurityException exc) {
|
||||
// Good.
|
||||
}
|
||||
|
||||
try {
|
||||
Font font = Font.createFont(Font.TRUETYPE_FONT,
|
||||
new File("nosuchfile") {
|
||||
private boolean read;
|
||||
@Override public String getPath() {
|
||||
if (read) {
|
||||
return name;
|
||||
} else {
|
||||
read = true;
|
||||
return "somefile";
|
||||
}
|
||||
}
|
||||
@Override public boolean canRead() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
);
|
||||
System.err.println(font.getFontName());
|
||||
throw new RuntimeException("No expected exception");
|
||||
} catch (IOException e) {
|
||||
System.err.println("Test passed.");
|
||||
}
|
||||
}
|
||||
}
|
95
jdk/test/java/awt/image/ConvolveOp/EdgeNoOpCrash.java
Normal file
95
jdk/test/java/awt/image/ConvolveOp/EdgeNoOpCrash.java
Normal file
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6726779
|
||||
* @summary Test verifies that ConvolveOp with the EDGE_NO_OP edge condition
|
||||
* does not cause JVM crash if size of source raster elements is
|
||||
* greather than size of the destination raster element.
|
||||
*
|
||||
* @run main EdgeNoOpCrash
|
||||
*/
|
||||
import java.awt.Point;
|
||||
import java.awt.image.ConvolveOp;
|
||||
import java.awt.image.DataBuffer;
|
||||
import java.awt.image.ImagingOpException;
|
||||
import java.awt.image.Kernel;
|
||||
import java.awt.image.Raster;
|
||||
import java.awt.image.WritableRaster;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class EdgeNoOpCrash {
|
||||
private static final int w = 3000;
|
||||
private static final int h = 200;
|
||||
|
||||
public static void main(String[] args) {
|
||||
crashTest();
|
||||
}
|
||||
|
||||
private static void crashTest() {
|
||||
Raster src = createSrcRaster();
|
||||
WritableRaster dst = createDstRaster();
|
||||
ConvolveOp op = createConvolveOp(ConvolveOp.EDGE_NO_OP);
|
||||
try {
|
||||
op.filter(src, dst);
|
||||
} catch (ImagingOpException e) {
|
||||
/*
|
||||
* The test pair of source and destination rasters
|
||||
* may cause failure of the medialib convolution routine,
|
||||
* so this exception is expected.
|
||||
*
|
||||
* The JVM crash is the only manifestation of this
|
||||
* test failure.
|
||||
*/
|
||||
}
|
||||
System.out.println("Test PASSED.");
|
||||
}
|
||||
|
||||
private static Raster createSrcRaster() {
|
||||
WritableRaster r = Raster.createInterleavedRaster(DataBuffer.TYPE_USHORT,
|
||||
w, h, 4, new Point(0, 0));
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
private static WritableRaster createDstRaster() {
|
||||
WritableRaster r = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
|
||||
w, h, 4, new Point(0, 0));
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
private static ConvolveOp createConvolveOp(int edgeHint) {
|
||||
final int kw = 3;
|
||||
final int kh = 3;
|
||||
float[] kdata = new float[kw * kh];
|
||||
float v = 1f / kdata.length;
|
||||
Arrays.fill(kdata, v);
|
||||
|
||||
Kernel k = new Kernel(kw, kh, kdata);
|
||||
ConvolveOp op = new ConvolveOp(k, edgeHint, null);
|
||||
|
||||
return op;
|
||||
}
|
||||
}
|
48
jdk/test/javax/print/attribute/MediaMappingsTest.java
Normal file
48
jdk/test/javax/print/attribute/MediaMappingsTest.java
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6652463
|
||||
* @summary Verify media size-> media mappings can't be altered
|
||||
* @run main MediaMappingsTest
|
||||
*/
|
||||
|
||||
import javax.print.attribute.standard.MediaSize;
|
||||
import javax.print.attribute.standard.MediaSizeName;
|
||||
|
||||
public class MediaMappingsTest {
|
||||
|
||||
public static void main(String args[]) {
|
||||
MediaSize sizeA = MediaSize.getMediaSizeForName(MediaSizeName.A);
|
||||
new MediaSize(1.0f, 2.0f, MediaSize.MM, MediaSizeName.A);
|
||||
if (!sizeA.equals(MediaSize.getMediaSizeForName(MediaSizeName.A))) {
|
||||
throw new RuntimeException("mapping changed");
|
||||
}
|
||||
MediaSize sizeB = MediaSize.getMediaSizeForName(MediaSizeName.B);
|
||||
new MediaSize(1, 2, MediaSize.MM, MediaSizeName.B);
|
||||
if (!sizeB.equals(MediaSize.getMediaSizeForName(MediaSizeName.B))) {
|
||||
throw new RuntimeException("mapping changed");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,14 +1,14 @@
|
|||
# @test MultipleJRE.sh
|
||||
# @bug 4811102 4953711 4955505 4956301 4991229 4998210 5018605 6387069
|
||||
# @bug 4811102 4953711 4955505 4956301 4991229 4998210 5018605 6387069 6733959
|
||||
# @build PrintVersion
|
||||
# @build UglyPrintVersion
|
||||
# @build ZipMeUp
|
||||
# @run shell MultipleJRE.sh
|
||||
# @summary Verify Multiple JRE version support
|
||||
# @author Joseph E. Kowalski
|
||||
|
||||
|
||||
#
|
||||
# Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
# Copyright 2003-2008 Sun Microsystems, Inc. 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
|
||||
|
@ -49,10 +49,25 @@ then
|
|||
exit 1
|
||||
fi
|
||||
|
||||
JAVAEXE="$TESTJAVA/bin/java"
|
||||
JAVA="$TESTJAVA/bin/java -classpath $TESTCLASSES"
|
||||
JAR="$TESTJAVA/bin/jar"
|
||||
OS=`uname -s`;
|
||||
|
||||
#
|
||||
# Tests whether we are on windows (true) or not.
|
||||
#
|
||||
IsWindows() {
|
||||
case "$OS" in
|
||||
Windows* | CYGWIN* )
|
||||
printf "true"
|
||||
;;
|
||||
* )
|
||||
printf "false"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
#
|
||||
# Shell routine to test for the proper rejection of syntactically incorrect
|
||||
# version specifications.
|
||||
|
@ -139,7 +154,6 @@ CreateUglyJar() {
|
|||
$PACKAGE/UglyPrintVersion.class
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
# Constructs a jar file with a fair number of "zip directory" entries and
|
||||
# the MANIFEST.MF entry at or near the end of that directory to validate
|
||||
|
@ -262,6 +276,29 @@ LaunchVM() {
|
|||
fi
|
||||
}
|
||||
|
||||
# Tests very long Main-Class attribute in the jar
|
||||
TestLongMainClass() {
|
||||
JVER=$1
|
||||
if [ "$JVER" = "mklink" ]; then
|
||||
JVER=XX
|
||||
JDKXX=jdk/j2re$JVER
|
||||
rm -rf jdk
|
||||
mkdir jdk
|
||||
ln -s $TESTJAVA $JDKXX
|
||||
JAVA_VERSION_PATH="`pwd`/jdk"
|
||||
export JAVA_VERSION_PATH
|
||||
fi
|
||||
$JAVAEXE -cp $TESTCLASSES ZipMeUp UglyBetty.jar 4097
|
||||
message="`$JAVAEXE -version:$JVER -jar UglyBetty.jar 2>&1`"
|
||||
echo $message | grep "Error: main-class: attribute exceeds system limits" > /dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
printf "Long manifest test did not get expected error"
|
||||
exit 1
|
||||
fi
|
||||
unset JAVA_VERSION_PATH
|
||||
rm -rf jdk
|
||||
}
|
||||
|
||||
#
|
||||
# Main test sequence starts here
|
||||
#
|
||||
|
@ -280,14 +317,11 @@ CreateJar "" ""
|
|||
LaunchVM "" "${RELEASE}"
|
||||
CreateJar "" "0"
|
||||
LaunchVM "" "${RELEASE}"
|
||||
case "$OS" in
|
||||
Windows* | CYGWIN* )
|
||||
if [ `IsWindows` = "true" ]; then
|
||||
MAXIMUM_PATH=255;
|
||||
;;
|
||||
*)
|
||||
else
|
||||
MAXIMUM_PATH=1024;
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
PATH_LENGTH=`printf "%s" "$UGLYCLASS" | wc -c`
|
||||
if [ ${PATH_LENGTH} -lt ${MAXIMUM_PATH} ]; then
|
||||
|
@ -346,7 +380,6 @@ if [ -x /usr/bin/zipnote ]; then
|
|||
LaunchVM "" "${RELEASE}"
|
||||
fi
|
||||
|
||||
|
||||
#
|
||||
# Throw some syntactically challenged (illegal) version specifiers at
|
||||
# the interface. Failure (of the launcher) is success for the test.
|
||||
|
@ -357,15 +390,28 @@ TestSyntax "1.2.3-" # Ends with a separator
|
|||
TestSyntax "1.2+.3" # Embedded modifier
|
||||
TestSyntax "1.2.4+&1.2*&1++" # Long and invalid
|
||||
|
||||
# On windows we see if there is another jre installed, usually
|
||||
# there is, then we test using that, otherwise links are created
|
||||
# to get through to SelectVersion.
|
||||
if [ `IsWindows` = "false" ]; then
|
||||
TestLongMainClass "mklink"
|
||||
else
|
||||
$JAVAEXE -version:1.0+
|
||||
if [ $? -eq 0 ]; then
|
||||
TestLongMainClass "1.0+"
|
||||
else
|
||||
printf "Warning: TestLongMainClass skipped as there is no"
|
||||
printf "viable MJRE installed.\n"
|
||||
fi
|
||||
fi
|
||||
|
||||
#
|
||||
# Because scribbling in the registry can be rather destructive, only a
|
||||
# subset of the tests are run on Windows.
|
||||
#
|
||||
case "$OS" in
|
||||
Windows* | CYGWIN* )
|
||||
if [ `IsWindows` = "true" ]; then
|
||||
exit 0;
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
#
|
||||
# Additional version specifiers containing spaces. (Sigh, unable to
|
||||
|
|
91
jdk/test/tools/launcher/ZipMeUp.java
Normal file
91
jdk/test/tools/launcher/ZipMeUp.java
Normal file
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* A simple class to create our erring Jar with a very long Main-Class
|
||||
* attribute in the manifest.
|
||||
*/
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
import java.util.zip.CRC32;
|
||||
import java.util.zip.CheckedOutputStream;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
public class ZipMeUp {
|
||||
|
||||
static final CRC32 crc = new CRC32();
|
||||
|
||||
private static String SOME_KLASS = ".Some";
|
||||
|
||||
static byte[] getManifestAsBytes(int nchars) throws IOException {
|
||||
crc.reset();
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
CheckedOutputStream cos = new CheckedOutputStream(baos, crc);
|
||||
PrintStream ps = new PrintStream(cos);
|
||||
ps.println("Manifest-Version: 1.0");
|
||||
ps.print("Main-Class: ");
|
||||
for (int i = 0 ; i < nchars - SOME_KLASS.length() ; i++) {
|
||||
ps.print(i%10);
|
||||
}
|
||||
ps.println(SOME_KLASS);
|
||||
cos.flush();
|
||||
cos.close();
|
||||
ps.close();
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* The arguments are: filename_to_create length
|
||||
* @param args
|
||||
* @throws java.lang.Exception
|
||||
*/
|
||||
public static void main(String...args) throws Exception {
|
||||
FileOutputStream fos = new FileOutputStream(args[0]);
|
||||
ZipOutputStream zos = new ZipOutputStream(fos);
|
||||
byte[] manifest = getManifestAsBytes(Integer.parseInt(args[1]));
|
||||
ZipEntry ze = new ZipEntry("META-INF/MANIFEST.MF");
|
||||
ze.setMethod(ZipEntry.STORED);
|
||||
ze.setSize(manifest.length);
|
||||
ze.setCompressedSize(manifest.length);
|
||||
ze.setCrc(crc.getValue());
|
||||
ze.setTime(System.currentTimeMillis());
|
||||
zos.putNextEntry(ze);
|
||||
zos.write(manifest);
|
||||
zos.flush();
|
||||
|
||||
// add a zero length class
|
||||
ze = new ZipEntry(SOME_KLASS + ".class");
|
||||
ze.setMethod(ZipEntry.STORED);
|
||||
ze.setSize(0);
|
||||
ze.setCompressedSize(0);
|
||||
ze.setCrc(0);
|
||||
ze.setTime(System.currentTimeMillis());
|
||||
zos.putNextEntry(ze);
|
||||
zos.flush();
|
||||
zos.closeEntry();
|
||||
zos.close();
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue