mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-23 12:34:32 +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_ERROR2 "Error: Unable to access jarfile %s"
|
||||||
#define JAR_ERROR3 "Error: Invalid or corrupt 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_WARN1 "Warning: %s VM not supported; %s VM will be used"
|
||||||
#define CFG_WARN2 "Warning: No leading - on line %d of `%s'"
|
#define CFG_WARN2 "Warning: No leading - on line %d of `%s'"
|
||||||
#define CFG_WARN3 "Warning: Missing VM type 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
|
* to avoid locating, expanding and parsing the manifest extra
|
||||||
* times.
|
* 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);
|
(void)JLI_StrCat(env_entry, info.main_class);
|
||||||
|
} else {
|
||||||
|
JLI_ReportErrorMessage(CLS_ERROR5, MAXNAMELEN);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
(void)putenv(env_entry);
|
(void)putenv(env_entry);
|
||||||
ExecJRE(jre, new_argv);
|
ExecJRE(jre, new_argv);
|
||||||
JLI_FreeManifest();
|
JLI_FreeManifest();
|
||||||
|
|
|
@ -22,7 +22,6 @@
|
||||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||||
* have any questions.
|
* have any questions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.sun.jmx.remote.internal;
|
package com.sun.jmx.remote.internal;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -34,6 +33,7 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
|
import java.security.AccessControlContext;
|
||||||
import java.security.AccessController;
|
import java.security.AccessController;
|
||||||
import java.security.PrivilegedAction;
|
import java.security.PrivilegedAction;
|
||||||
import javax.security.auth.Subject;
|
import javax.security.auth.Subject;
|
||||||
|
@ -54,7 +54,10 @@ import com.sun.jmx.remote.util.EnvHelp;
|
||||||
|
|
||||||
|
|
||||||
public abstract class ClientNotifForwarder {
|
public abstract class ClientNotifForwarder {
|
||||||
public ClientNotifForwarder(Map<String, ?> env) {
|
|
||||||
|
private final AccessControlContext acc;
|
||||||
|
|
||||||
|
public ClientNotifForwarder(Map env) {
|
||||||
this(null, env);
|
this(null, env);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,6 +90,8 @@ public abstract class ClientNotifForwarder {
|
||||||
this.command = command;
|
this.command = command;
|
||||||
if (thread == null) {
|
if (thread == null) {
|
||||||
thread = new Thread() {
|
thread = new Thread() {
|
||||||
|
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
while (true) {
|
while (true) {
|
||||||
Runnable r;
|
Runnable r;
|
||||||
|
@ -130,6 +135,7 @@ public abstract class ClientNotifForwarder {
|
||||||
|
|
||||||
this.defaultClassLoader = defaultClassLoader;
|
this.defaultClassLoader = defaultClassLoader;
|
||||||
this.executor = ex;
|
this.executor = ex;
|
||||||
|
this.acc = AccessController.getContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -380,28 +386,85 @@ public abstract class ClientNotifForwarder {
|
||||||
setState(TERMINATED);
|
setState(TERMINATED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------
|
// -------------------------------------------------
|
||||||
// private classes
|
// private classes
|
||||||
// -------------------------------------------------
|
// -------------------------------------------------
|
||||||
//
|
//
|
||||||
|
|
||||||
private class NotifFetcher implements Runnable {
|
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() {
|
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) {
|
synchronized (ClientNotifForwarder.this) {
|
||||||
currentFetchThread = Thread.currentThread();
|
currentFetchThread = Thread.currentThread();
|
||||||
|
|
||||||
if (state == STARTING)
|
if (state == STARTING) {
|
||||||
setState(STARTED);
|
setState(STARTED);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (defaultClassLoader != null) {
|
|
||||||
AccessController.doPrivileged(new PrivilegedAction<Void>() {
|
|
||||||
public Void run() {
|
|
||||||
Thread.currentThread().
|
|
||||||
setContextClassLoader(defaultClassLoader);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
NotificationResult nr = null;
|
NotificationResult nr = null;
|
||||||
if (!shouldStop() && (nr = fetchNotifs()) != null) {
|
if (!shouldStop() && (nr = fetchNotifs()) != null) {
|
||||||
|
@ -434,8 +497,9 @@ public abstract class ClientNotifForwarder {
|
||||||
// check if an mbean unregistration notif
|
// check if an mbean unregistration notif
|
||||||
if (!listenerID.equals(mbeanRemovedNotifID)) {
|
if (!listenerID.equals(mbeanRemovedNotifID)) {
|
||||||
final ClientListenerInfo li = infoList.get(listenerID);
|
final ClientListenerInfo li = infoList.get(listenerID);
|
||||||
if (li != null)
|
if (li != null) {
|
||||||
listeners.put(listenerID, li);
|
listeners.put(listenerID, li);
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
final Notification notif = tn.getNotification();
|
final Notification notif = tn.getNotification();
|
||||||
|
@ -799,9 +863,7 @@ public abstract class ClientNotifForwarder {
|
||||||
private long clientSequenceNumber = -1;
|
private long clientSequenceNumber = -1;
|
||||||
private final int maxNotifications;
|
private final int maxNotifications;
|
||||||
private final long timeout;
|
private final long timeout;
|
||||||
|
|
||||||
private Integer mbeanRemovedNotifID = null;
|
private Integer mbeanRemovedNotifID = null;
|
||||||
|
|
||||||
private Thread currentFetchThread;
|
private Thread currentFetchThread;
|
||||||
|
|
||||||
// state
|
// state
|
||||||
|
|
|
@ -111,6 +111,22 @@ public abstract class MBeanServerAccessController
|
||||||
*/
|
*/
|
||||||
protected abstract void checkWrite();
|
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.
|
* wrapped object.
|
||||||
*/
|
*/
|
||||||
public ObjectInstance createMBean(String className, ObjectName name)
|
public ObjectInstance createMBean(String className, ObjectName name)
|
||||||
|
@ -158,7 +174,7 @@ public abstract class MBeanServerAccessController
|
||||||
MBeanRegistrationException,
|
MBeanRegistrationException,
|
||||||
MBeanException,
|
MBeanException,
|
||||||
NotCompliantMBeanException {
|
NotCompliantMBeanException {
|
||||||
checkWrite();
|
checkCreate(className);
|
||||||
SecurityManager sm = System.getSecurityManager();
|
SecurityManager sm = System.getSecurityManager();
|
||||||
if (sm == null) {
|
if (sm == null) {
|
||||||
Object object = getMBeanServer().instantiate(className);
|
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.
|
* wrapped object.
|
||||||
*/
|
*/
|
||||||
public ObjectInstance createMBean(String className, ObjectName name,
|
public ObjectInstance createMBean(String className, ObjectName name,
|
||||||
|
@ -181,7 +197,7 @@ public abstract class MBeanServerAccessController
|
||||||
MBeanRegistrationException,
|
MBeanRegistrationException,
|
||||||
MBeanException,
|
MBeanException,
|
||||||
NotCompliantMBeanException {
|
NotCompliantMBeanException {
|
||||||
checkWrite();
|
checkCreate(className);
|
||||||
SecurityManager sm = System.getSecurityManager();
|
SecurityManager sm = System.getSecurityManager();
|
||||||
if (sm == null) {
|
if (sm == null) {
|
||||||
Object object = getMBeanServer().instantiate(className,
|
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.
|
* wrapped object.
|
||||||
*/
|
*/
|
||||||
public ObjectInstance createMBean(String className,
|
public ObjectInstance createMBean(String className,
|
||||||
|
@ -209,7 +225,7 @@ public abstract class MBeanServerAccessController
|
||||||
MBeanException,
|
MBeanException,
|
||||||
NotCompliantMBeanException,
|
NotCompliantMBeanException,
|
||||||
InstanceNotFoundException {
|
InstanceNotFoundException {
|
||||||
checkWrite();
|
checkCreate(className);
|
||||||
SecurityManager sm = System.getSecurityManager();
|
SecurityManager sm = System.getSecurityManager();
|
||||||
if (sm == null) {
|
if (sm == null) {
|
||||||
Object object = getMBeanServer().instantiate(className,
|
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.
|
* wrapped object.
|
||||||
*/
|
*/
|
||||||
public ObjectInstance createMBean(String className,
|
public ObjectInstance createMBean(String className,
|
||||||
|
@ -237,7 +253,7 @@ public abstract class MBeanServerAccessController
|
||||||
MBeanException,
|
MBeanException,
|
||||||
NotCompliantMBeanException,
|
NotCompliantMBeanException,
|
||||||
InstanceNotFoundException {
|
InstanceNotFoundException {
|
||||||
checkWrite();
|
checkCreate(className);
|
||||||
SecurityManager sm = System.getSecurityManager();
|
SecurityManager sm = System.getSecurityManager();
|
||||||
if (sm == null) {
|
if (sm == null) {
|
||||||
Object object = getMBeanServer().instantiate(className,
|
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.
|
* wrapped object.
|
||||||
*/
|
*/
|
||||||
public Object instantiate(String className)
|
public Object instantiate(String className)
|
||||||
throws ReflectionException, MBeanException {
|
throws ReflectionException, MBeanException {
|
||||||
checkWrite();
|
checkCreate(className);
|
||||||
return getMBeanServer().instantiate(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.
|
* wrapped object.
|
||||||
*/
|
*/
|
||||||
public Object instantiate(String className,
|
public Object instantiate(String className,
|
||||||
Object params[],
|
Object params[],
|
||||||
String signature[])
|
String signature[])
|
||||||
throws ReflectionException, MBeanException {
|
throws ReflectionException, MBeanException {
|
||||||
checkWrite();
|
checkCreate(className);
|
||||||
return getMBeanServer().instantiate(className, params, signature);
|
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.
|
* wrapped object.
|
||||||
*/
|
*/
|
||||||
public Object instantiate(String className, ObjectName loaderName)
|
public Object instantiate(String className, ObjectName loaderName)
|
||||||
throws ReflectionException, MBeanException, InstanceNotFoundException {
|
throws ReflectionException, MBeanException, InstanceNotFoundException {
|
||||||
checkWrite();
|
checkCreate(className);
|
||||||
return getMBeanServer().instantiate(className, loaderName);
|
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.
|
* wrapped object.
|
||||||
*/
|
*/
|
||||||
public Object instantiate(String className, ObjectName loaderName,
|
public Object instantiate(String className, ObjectName loaderName,
|
||||||
Object params[], String signature[])
|
Object params[], String signature[])
|
||||||
throws ReflectionException, MBeanException, InstanceNotFoundException {
|
throws ReflectionException, MBeanException, InstanceNotFoundException {
|
||||||
checkWrite();
|
checkCreate(className);
|
||||||
return getMBeanServer().instantiate(className, loaderName,
|
return getMBeanServer().instantiate(className, loaderName,
|
||||||
params, signature);
|
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.
|
* wrapped object.
|
||||||
*/
|
*/
|
||||||
public void unregisterMBean(ObjectName name)
|
public void unregisterMBean(ObjectName name)
|
||||||
throws InstanceNotFoundException, MBeanRegistrationException {
|
throws InstanceNotFoundException, MBeanRegistrationException {
|
||||||
checkWrite();
|
checkUnregister(name);
|
||||||
getMBeanServer().unregisterMBean(name);
|
getMBeanServer().unregisterMBean(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,11 +31,17 @@ import java.security.AccessControlContext;
|
||||||
import java.security.AccessController;
|
import java.security.AccessController;
|
||||||
import java.security.Principal;
|
import java.security.Principal;
|
||||||
import java.security.PrivilegedAction;
|
import java.security.PrivilegedAction;
|
||||||
import java.util.Collection;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.StringTokenizer;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
import javax.management.MBeanServer;
|
import javax.management.MBeanServer;
|
||||||
|
import javax.management.ObjectName;
|
||||||
import javax.security.auth.Subject;
|
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
|
* not allowed; in this case the request is not forwarded to the
|
||||||
* wrapped object.</p>
|
* 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
|
* 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
|
* 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
|
* 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
|
* has exactly one access level. The same access level can be shared by several
|
||||||
* usernames.</p>
|
* usernames.</p>
|
||||||
*
|
*
|
||||||
* <p>The supported access level values are <i>readonly</i> and
|
* <p>The supported access level values are {@code readonly} and
|
||||||
* <i>readwrite</i>.</p>
|
* {@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
|
public class MBeanServerFileAccessController
|
||||||
extends MBeanServerAccessController {
|
extends MBeanServerAccessController {
|
||||||
|
|
||||||
public static final String READONLY = "readonly";
|
static final String READONLY = "readonly";
|
||||||
public static final String READWRITE = "readwrite";
|
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
|
* <p>Create a new MBeanServerAccessController that forwards all the
|
||||||
|
@ -87,8 +130,8 @@ public class MBeanServerFileAccessController
|
||||||
throws IOException {
|
throws IOException {
|
||||||
super();
|
super();
|
||||||
this.accessFileName = accessFileName;
|
this.accessFileName = accessFileName;
|
||||||
props = propertiesFromFile(accessFileName);
|
Properties props = propertiesFromFile(accessFileName);
|
||||||
checkValues(props);
|
parseProperties(props);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -123,14 +166,14 @@ public class MBeanServerFileAccessController
|
||||||
* #setMBeanServer} method after doing access checks based on read and
|
* #setMBeanServer} method after doing access checks based on read and
|
||||||
* write permissions.</p>
|
* write permissions.</p>
|
||||||
*
|
*
|
||||||
* <p>This instance is initialized from the specified properties instance.
|
* <p>This instance is initialized from the specified properties
|
||||||
* This constructor makes a copy of the properties instance using its
|
* instance. This constructor makes a copy of the properties
|
||||||
* <code>clone</code> method and it is the copy that is consulted to check
|
* instance and it is the copy that is consulted to check the
|
||||||
* the username and access level of an incoming connection. The original
|
* username and access level of an incoming connection. The
|
||||||
* properties object can be modified without affecting the copy. If the
|
* original properties object can be modified without affecting
|
||||||
* {@link #refresh} method is then called, the
|
* the copy. If the {@link #refresh} method is then called, the
|
||||||
* <code>MBeanServerFileAccessController</code> will make a new copy of the
|
* <code>MBeanServerFileAccessController</code> will make a new
|
||||||
* properties object at that time.</p>
|
* copy of the properties object at that time.</p>
|
||||||
*
|
*
|
||||||
* @param accessFileProps properties list containing the username/access
|
* @param accessFileProps properties list containing the username/access
|
||||||
* level entries.
|
* level entries.
|
||||||
|
@ -145,8 +188,7 @@ public class MBeanServerFileAccessController
|
||||||
if (accessFileProps == null)
|
if (accessFileProps == null)
|
||||||
throw new IllegalArgumentException("Null properties");
|
throw new IllegalArgumentException("Null properties");
|
||||||
originalProps = accessFileProps;
|
originalProps = accessFileProps;
|
||||||
props = (Properties) accessFileProps.clone();
|
parseProperties(accessFileProps);
|
||||||
checkValues(props);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -155,14 +197,14 @@ public class MBeanServerFileAccessController
|
||||||
* #setMBeanServer} method after doing access checks based on read and
|
* #setMBeanServer} method after doing access checks based on read and
|
||||||
* write permissions.</p>
|
* write permissions.</p>
|
||||||
*
|
*
|
||||||
* <p>This instance is initialized from the specified properties instance.
|
* <p>This instance is initialized from the specified properties
|
||||||
* This constructor makes a copy of the properties instance using its
|
* instance. This constructor makes a copy of the properties
|
||||||
* <code>clone</code> method and it is the copy that is consulted to check
|
* instance and it is the copy that is consulted to check the
|
||||||
* the username and access level of an incoming connection. The original
|
* username and access level of an incoming connection. The
|
||||||
* properties object can be modified without affecting the copy. If the
|
* original properties object can be modified without affecting
|
||||||
* {@link #refresh} method is then called, the
|
* the copy. If the {@link #refresh} method is then called, the
|
||||||
* <code>MBeanServerFileAccessController</code> will make a new copy of the
|
* <code>MBeanServerFileAccessController</code> will make a new
|
||||||
* properties object at that time.</p>
|
* copy of the properties object at that time.</p>
|
||||||
*
|
*
|
||||||
* @param accessFileProps properties list containing the username/access
|
* @param accessFileProps properties list containing the username/access
|
||||||
* level entries.
|
* level entries.
|
||||||
|
@ -184,16 +226,36 @@ public class MBeanServerFileAccessController
|
||||||
* Check if the caller can do read operations. This method does
|
* Check if the caller can do read operations. This method does
|
||||||
* nothing if so, otherwise throws SecurityException.
|
* nothing if so, otherwise throws SecurityException.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void checkRead() {
|
public void checkRead() {
|
||||||
checkAccessLevel(READONLY);
|
checkAccess(AccessType.READ, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the caller can do write operations. This method does
|
* Check if the caller can do write operations. This method does
|
||||||
* nothing if so, otherwise throws SecurityException.
|
* nothing if so, otherwise throws SecurityException.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void checkWrite() {
|
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
|
* @exception IllegalArgumentException if any of the supplied access
|
||||||
* level values differs from "readonly" or "readwrite".
|
* level values differs from "readonly" or "readwrite".
|
||||||
*/
|
*/
|
||||||
public void refresh() throws IOException {
|
public synchronized void refresh() throws IOException {
|
||||||
synchronized (props) {
|
Properties props;
|
||||||
if (accessFileName == null)
|
if (accessFileName == null)
|
||||||
props = (Properties) originalProps.clone();
|
props = (Properties) originalProps;
|
||||||
else
|
else
|
||||||
props = propertiesFromFile(accessFileName);
|
props = propertiesFromFile(accessFileName);
|
||||||
checkValues(props);
|
parseProperties(props);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Properties propertiesFromFile(String fname)
|
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 AccessControlContext acc = AccessController.getContext();
|
||||||
final Subject s =
|
final Subject s =
|
||||||
AccessController.doPrivileged(new PrivilegedAction<Subject>() {
|
AccessController.doPrivileged(new PrivilegedAction<Subject>() {
|
||||||
|
@ -249,39 +310,235 @@ public class MBeanServerFileAccessController
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (s == null) return; /* security has not been enabled */
|
if (s == null) return; /* security has not been enabled */
|
||||||
final Set<Principal> principals = s.getPrincipals();
|
final Set principals = s.getPrincipals();
|
||||||
for (Principal p : principals) {
|
String newPropertyValue = null;
|
||||||
String grantedAccessLevel;
|
for (Iterator i = principals.iterator(); i.hasNext(); ) {
|
||||||
synchronized (props) {
|
final Principal p = (Principal) i.next();
|
||||||
grantedAccessLevel = props.getProperty(p.getName());
|
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 (ok)
|
||||||
if (accessLevel.equals(READONLY) &&
|
|
||||||
(grantedAccessLevel.equals(READONLY) ||
|
|
||||||
grantedAccessLevel.equals(READWRITE)))
|
|
||||||
return;
|
|
||||||
if (accessLevel.equals(READWRITE) &&
|
|
||||||
grantedAccessLevel.equals(READWRITE))
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new SecurityException("Access denied! Invalid access level for " +
|
SecurityException se = new SecurityException("Access denied! Invalid " +
|
||||||
"requested MBeanServer operation.");
|
"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) {
|
private static boolean checkCreateAccess(Access access, String className) {
|
||||||
Collection<?> c = props.values();
|
for (String classNamePattern : access.createPatterns) {
|
||||||
for (Iterator<?> i = c.iterator(); i.hasNext(); ) {
|
if (classNameMatch(classNamePattern, className))
|
||||||
final String accessLevel = (String) i.next();
|
return true;
|
||||||
if (!accessLevel.equals(READONLY) &&
|
|
||||||
!accessLevel.equals(READWRITE)) {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"Syntax error in access level entry [" + accessLevel + "]");
|
|
||||||
}
|
}
|
||||||
|
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 Properties originalProps;
|
||||||
private String accessFileName;
|
private String accessFileName;
|
||||||
}
|
}
|
||||||
|
|
|
@ -302,7 +302,16 @@ final public class LdapCtx extends ComponentDirContext
|
||||||
|
|
||||||
schemaTrees = new Hashtable(11, 0.75f);
|
schemaTrees = new Hashtable(11, 0.75f);
|
||||||
initEnv();
|
initEnv();
|
||||||
|
try {
|
||||||
connect(false);
|
connect(false);
|
||||||
|
} catch (NamingException e) {
|
||||||
|
try {
|
||||||
|
close();
|
||||||
|
} catch (Exception e2) {
|
||||||
|
// Nothing
|
||||||
|
}
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LdapCtx(LdapCtx existing, String newDN) throws NamingException {
|
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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -33,12 +33,33 @@ import java.security.PrivilegedAction;
|
||||||
|
|
||||||
final class VersionHelper12 extends VersionHelper {
|
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.
|
VersionHelper12() {} // Disallow external from creating one of these.
|
||||||
|
|
||||||
ClassLoader getURLClassLoader(String[] url)
|
ClassLoader getURLClassLoader(String[] url)
|
||||||
throws MalformedURLException {
|
throws MalformedURLException {
|
||||||
ClassLoader parent = getContextClassLoader();
|
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);
|
return URLClassLoader.newInstance(getUrlArray(url), parent);
|
||||||
} else {
|
} else {
|
||||||
return parent;
|
return parent;
|
||||||
|
|
|
@ -37,6 +37,8 @@ import java.awt.geom.Rectangle2D;
|
||||||
import java.awt.peer.FontPeer;
|
import java.awt.peer.FontPeer;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.lang.ref.SoftReference;
|
import java.lang.ref.SoftReference;
|
||||||
|
import java.security.AccessController;
|
||||||
|
import java.security.PrivilegedExceptionAction;
|
||||||
import java.text.AttributedCharacterIterator.Attribute;
|
import java.text.AttributedCharacterIterator.Attribute;
|
||||||
import java.text.CharacterIterator;
|
import java.text.CharacterIterator;
|
||||||
import java.text.StringCharacterIterator;
|
import java.text.StringCharacterIterator;
|
||||||
|
@ -51,6 +53,7 @@ import sun.font.AttributeMap;
|
||||||
import sun.font.AttributeValues;
|
import sun.font.AttributeValues;
|
||||||
import sun.font.EAttribute;
|
import sun.font.EAttribute;
|
||||||
import sun.font.CompositeFont;
|
import sun.font.CompositeFont;
|
||||||
|
import sun.font.CreatedFontTracker;
|
||||||
import sun.font.Font2D;
|
import sun.font.Font2D;
|
||||||
import sun.font.Font2DHandle;
|
import sun.font.Font2DHandle;
|
||||||
import sun.font.FontManager;
|
import sun.font.FontManager;
|
||||||
|
@ -575,14 +578,16 @@ public class Font implements java.io.Serializable
|
||||||
}
|
}
|
||||||
|
|
||||||
/* used to implement Font.createFont */
|
/* 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 {
|
throws FontFormatException {
|
||||||
this.createdFont = true;
|
this.createdFont = true;
|
||||||
/* Font2D instances created by this method track their font file
|
/* Font2D instances created by this method track their font file
|
||||||
* so that when the Font2D is GC'd it can also remove the file.
|
* so that when the Font2D is GC'd it can also remove the file.
|
||||||
*/
|
*/
|
||||||
this.font2DHandle =
|
this.font2DHandle =
|
||||||
FontManager.createFont2D(fontFile, fontFormat, isCopy).handle;
|
FontManager.createFont2D(fontFile, fontFormat,
|
||||||
|
isCopy, tracker).handle;
|
||||||
this.name = this.font2DHandle.font2D.getFontName(Locale.getDefault());
|
this.name = this.font2DHandle.font2D.getFontName(Locale.getDefault());
|
||||||
this.style = Font.PLAIN;
|
this.style = Font.PLAIN;
|
||||||
this.size = 1;
|
this.size = 1;
|
||||||
|
@ -787,6 +792,29 @@ public class Font implements java.io.Serializable
|
||||||
return new Font(attributes);
|
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
|
* Returns a new <code>Font</code> using the specified font type
|
||||||
* and input data. The new <code>Font</code> is
|
* and input data. The new <code>Font</code> is
|
||||||
|
@ -822,58 +850,96 @@ public class Font implements java.io.Serializable
|
||||||
fontFormat != Font.TYPE1_FONT) {
|
fontFormat != Font.TYPE1_FONT) {
|
||||||
throw new IllegalArgumentException ("font format not recognized");
|
throw new IllegalArgumentException ("font format not recognized");
|
||||||
}
|
}
|
||||||
final InputStream fStream = fontStream;
|
boolean copiedFontData = false;
|
||||||
Object ret = java.security.AccessController.doPrivileged(
|
|
||||||
new java.security.PrivilegedAction() {
|
|
||||||
public Object run() {
|
|
||||||
File tFile = null;
|
|
||||||
FileOutputStream outStream = null;
|
|
||||||
try {
|
try {
|
||||||
tFile = File.createTempFile("+~JF", ".tmp", null);
|
final File tFile = AccessController.doPrivileged(
|
||||||
/* Temp file deleted by font shutdown hook */
|
new PrivilegedExceptionAction<File>() {
|
||||||
BufferedInputStream inStream =
|
public File run() throws IOException {
|
||||||
new BufferedInputStream(fStream);
|
return File.createTempFile("+~JF", ".tmp", null);
|
||||||
outStream = new FileOutputStream(tFile);
|
}
|
||||||
int bytesRead = 0;
|
}
|
||||||
int bufSize = 8192;
|
);
|
||||||
byte [] buf = new byte[bufSize];
|
|
||||||
while (bytesRead != -1) {
|
int totalSize = 0;
|
||||||
try {
|
CreatedFontTracker tracker = null;
|
||||||
bytesRead = inStream.read(buf, 0, bufSize);
|
try {
|
||||||
} catch (Throwable t) {
|
final OutputStream outStream =
|
||||||
throw new IOException();
|
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);
|
outStream.write(buf, 0, bytesRead);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
/* don't close the input stream */
|
/* don't close the input stream */
|
||||||
|
} finally {
|
||||||
outStream.close();
|
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) {
|
AccessController.doPrivileged(
|
||||||
try {
|
new PrivilegedExceptionAction<Void>() {
|
||||||
|
public Void run() {
|
||||||
tFile.delete();
|
tFile.delete();
|
||||||
} catch (Exception e2) {
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return e;
|
);
|
||||||
}
|
}
|
||||||
return tFile;
|
|
||||||
}
|
}
|
||||||
});
|
} catch (Throwable t) {
|
||||||
|
if (t instanceof FontFormatException) {
|
||||||
if (ret instanceof File) {
|
throw (FontFormatException)t;
|
||||||
return new Font((File)ret, fontFormat, true);
|
}
|
||||||
} else if (ret instanceof IOException) {
|
if (t instanceof IOException) {
|
||||||
throw (IOException)ret;
|
throw (IOException)t;
|
||||||
} else {
|
}
|
||||||
throw new FontFormatException("Couldn't access font stream");
|
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)
|
public static Font createFont(int fontFormat, File fontFile)
|
||||||
throws java.awt.FontFormatException, java.io.IOException {
|
throws java.awt.FontFormatException, java.io.IOException {
|
||||||
|
|
||||||
|
fontFile = new File(fontFile.getPath());
|
||||||
|
|
||||||
if (fontFormat != Font.TRUETYPE_FONT &&
|
if (fontFormat != Font.TRUETYPE_FONT &&
|
||||||
fontFormat != Font.TYPE1_FONT) {
|
fontFormat != Font.TYPE1_FONT) {
|
||||||
throw new IllegalArgumentException ("font format not recognized");
|
throw new IllegalArgumentException ("font format not recognized");
|
||||||
|
@ -926,7 +995,7 @@ public class Font implements java.io.Serializable
|
||||||
if (!fontFile.canRead()) {
|
if (!fontFile.canRead()) {
|
||||||
throw new IOException("Can't read " + fontFile);
|
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.IOException;
|
||||||
import java.io.ObjectInputStream;
|
import java.io.ObjectInputStream;
|
||||||
import java.io.ObjectOutputStream;
|
import java.io.ObjectOutputStream;
|
||||||
|
import java.io.OptionalDataException;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.security.AccessControlContext;
|
||||||
import java.security.AccessController;
|
import java.security.AccessController;
|
||||||
|
import java.security.PermissionCollection;
|
||||||
|
import java.security.PrivilegedActionException;
|
||||||
import java.security.PrivilegedExceptionAction;
|
import java.security.PrivilegedExceptionAction;
|
||||||
|
import java.security.ProtectionDomain;
|
||||||
import java.text.DateFormat;
|
import java.text.DateFormat;
|
||||||
import java.text.DateFormatSymbols;
|
import java.text.DateFormatSymbols;
|
||||||
import sun.util.BuddhistCalendar;
|
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).
|
* 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;
|
serialVersionOnStream = currentSerialVersion;
|
||||||
|
|
||||||
// If there's a ZoneInfo object, use it for zone.
|
// If there's a ZoneInfo object, use it for zone.
|
||||||
|
ZoneInfo zi = null;
|
||||||
try {
|
try {
|
||||||
ZoneInfo zi = (ZoneInfo) AccessController.doPrivileged(
|
zi = AccessController.doPrivileged(
|
||||||
new PrivilegedExceptionAction() {
|
new PrivilegedExceptionAction<ZoneInfo>() {
|
||||||
public Object run() throws Exception {
|
public ZoneInfo run() throws Exception {
|
||||||
return input.readObject();
|
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) {
|
if (zi != null) {
|
||||||
zone = zi;
|
zone = zi;
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the deserialized object has a SimpleTimeZone, try to
|
// If the deserialized object has a SimpleTimeZone, try to
|
||||||
// replace it with a ZoneInfo equivalent (as of 1.4) in order
|
// 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.
|
// implementation as much as possible.
|
||||||
if (zone instanceof SimpleTimeZone) {
|
if (zone instanceof SimpleTimeZone) {
|
||||||
String id = zone.getID();
|
String id = zone.getID();
|
||||||
TimeZone zi = TimeZone.getTimeZone(id);
|
TimeZone tz = TimeZone.getTimeZone(id);
|
||||||
if (zi != null && zi.hasSameRules(zone) && zi.getID().equals(id)) {
|
if (tz != null && tz.hasSameRules(zone) && tz.getID().equals(id)) {
|
||||||
zone = zi;
|
zone = tz;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -599,7 +599,7 @@ public class CounterMonitor extends Monitor implements CounterMonitorMBean {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public MBeanNotificationInfo[] getNotificationInfo() {
|
public MBeanNotificationInfo[] getNotificationInfo() {
|
||||||
return notifsInfo;
|
return notifsInfo.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -481,7 +481,7 @@ public class GaugeMonitor extends Monitor implements GaugeMonitorMBean {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public MBeanNotificationInfo[] getNotificationInfo() {
|
public MBeanNotificationInfo[] getNotificationInfo() {
|
||||||
return notifsInfo;
|
return notifsInfo.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -32,7 +32,10 @@ import java.io.IOException;
|
||||||
import java.security.AccessControlContext;
|
import java.security.AccessControlContext;
|
||||||
import java.security.AccessController;
|
import java.security.AccessController;
|
||||||
import java.security.PrivilegedAction;
|
import java.security.PrivilegedAction;
|
||||||
|
import java.security.ProtectionDomain;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.WeakHashMap;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
|
@ -163,7 +166,10 @@ public abstract class Monitor
|
||||||
/**
|
/**
|
||||||
* AccessControlContext of the Monitor.start() caller.
|
* 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.
|
* Scheduler Service.
|
||||||
|
@ -172,15 +178,21 @@ public abstract class Monitor
|
||||||
Executors.newSingleThreadScheduledExecutor(
|
Executors.newSingleThreadScheduledExecutor(
|
||||||
new DaemonThreadFactory("Scheduler"));
|
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
|
* Maximum Pool Size
|
||||||
*/
|
*/
|
||||||
private static final int maximumPoolSize;
|
private static final int maximumPoolSize;
|
||||||
|
|
||||||
/**
|
|
||||||
* Executor Service.
|
|
||||||
*/
|
|
||||||
private static final ThreadPoolExecutor executor;
|
|
||||||
static {
|
static {
|
||||||
final String maximumPoolSizeSysProp = "jmx.x.monitor.maximum.pool.size";
|
final String maximumPoolSizeSysProp = "jmx.x.monitor.maximum.pool.size";
|
||||||
final String maximumPoolSizeStr = AccessController.doPrivileged(
|
final String maximumPoolSizeStr = AccessController.doPrivileged(
|
||||||
|
@ -210,21 +222,8 @@ public abstract class Monitor
|
||||||
maximumPoolSize = maximumPoolSizeTmp;
|
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.
|
* Future associated to the current monitor task.
|
||||||
*/
|
*/
|
||||||
|
@ -233,7 +232,7 @@ public abstract class Monitor
|
||||||
/**
|
/**
|
||||||
* Scheduler task to be executed by the Scheduler Service.
|
* 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.
|
* ScheduledFuture associated to the current scheduler task.
|
||||||
|
@ -719,6 +718,7 @@ public abstract class Monitor
|
||||||
// Start the scheduler.
|
// Start the scheduler.
|
||||||
//
|
//
|
||||||
cleanupFutures();
|
cleanupFutures();
|
||||||
|
schedulerTask.setMonitorTask(new MonitorTask());
|
||||||
schedulerFuture = scheduler.schedule(schedulerTask,
|
schedulerFuture = scheduler.schedule(schedulerTask,
|
||||||
getGranularityPeriod(),
|
getGranularityPeriod(),
|
||||||
TimeUnit.MILLISECONDS);
|
TimeUnit.MILLISECONDS);
|
||||||
|
@ -748,7 +748,7 @@ public abstract class Monitor
|
||||||
|
|
||||||
// Reset the AccessControlContext.
|
// Reset the AccessControlContext.
|
||||||
//
|
//
|
||||||
acc = null;
|
acc = noPermissionsACC;
|
||||||
|
|
||||||
// Reset the complex type attribute information
|
// Reset the complex type attribute information
|
||||||
// such that it is recalculated again.
|
// such that it is recalculated again.
|
||||||
|
@ -1467,7 +1467,7 @@ public abstract class Monitor
|
||||||
*/
|
*/
|
||||||
private class SchedulerTask implements Runnable {
|
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;
|
this.task = task;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1487,7 +1496,7 @@ public abstract class Monitor
|
||||||
|
|
||||||
public void run() {
|
public void run() {
|
||||||
synchronized (Monitor.this) {
|
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 class MonitorTask implements Runnable {
|
||||||
|
|
||||||
|
private ThreadPoolExecutor executor;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ------------------------------------------
|
* ------------------------------------------
|
||||||
* CONSTRUCTORS
|
* CONSTRUCTORS
|
||||||
|
@ -1507,6 +1518,38 @@ public abstract class Monitor
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public MonitorTask() {
|
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() {
|
public void run() {
|
||||||
final ScheduledFuture<?> sf;
|
final ScheduledFuture<?> sf;
|
||||||
|
final AccessControlContext ac;
|
||||||
synchronized (Monitor.this) {
|
synchronized (Monitor.this) {
|
||||||
sf = Monitor.this.schedulerFuture;
|
sf = Monitor.this.schedulerFuture;
|
||||||
|
ac = Monitor.this.acc;
|
||||||
}
|
}
|
||||||
AccessController.doPrivileged(new PrivilegedAction<Void>() {
|
PrivilegedAction<Void> action = new PrivilegedAction<Void>() {
|
||||||
public Void run() {
|
public Void run() {
|
||||||
if (Monitor.this.isActive()) {
|
if (Monitor.this.isActive()) {
|
||||||
final int an[] = alreadyNotifieds;
|
final int an[] = alreadyNotifieds;
|
||||||
|
@ -1533,7 +1582,11 @@ public abstract class Monitor
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}, Monitor.this.acc);
|
};
|
||||||
|
if (ac == null) {
|
||||||
|
throw new SecurityException("AccessControlContext cannot be null");
|
||||||
|
}
|
||||||
|
AccessController.doPrivileged(action, ac);
|
||||||
synchronized (Monitor.this) {
|
synchronized (Monitor.this) {
|
||||||
if (Monitor.this.isActive() &&
|
if (Monitor.this.isActive() &&
|
||||||
Monitor.this.schedulerFuture == sf) {
|
Monitor.this.schedulerFuture == sf) {
|
||||||
|
@ -1573,6 +1626,15 @@ public abstract class Monitor
|
||||||
namePrefix = "JMX Monitor " + poolName + " Pool [Thread-";
|
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) {
|
public Thread newThread(Runnable r) {
|
||||||
Thread t = new Thread(group,
|
Thread t = new Thread(group,
|
||||||
r,
|
r,
|
||||||
|
|
|
@ -184,6 +184,7 @@ public class StringMonitor extends Monitor implements StringMonitorMBean {
|
||||||
* @return The derived gauge of the specified object.
|
* @return The derived gauge of the specified object.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public synchronized String getDerivedGauge(ObjectName object) {
|
public synchronized String getDerivedGauge(ObjectName object) {
|
||||||
return (String) super.getDerivedGauge(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.
|
* @return The derived gauge timestamp of the specified object.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public synchronized long getDerivedGaugeTimeStamp(ObjectName object) {
|
public synchronized long getDerivedGaugeTimeStamp(ObjectName object) {
|
||||||
return super.getDerivedGaugeTimeStamp(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 Java class of the notification and the notification types sent by
|
||||||
* the string monitor.
|
* the string monitor.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public MBeanNotificationInfo[] getNotificationInfo() {
|
public MBeanNotificationInfo[] getNotificationInfo() {
|
||||||
return notifsInfo;
|
return notifsInfo.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -123,8 +123,10 @@ public class MediaSize extends Size2DSyntax implements Attribute {
|
||||||
if (x > y) {
|
if (x > y) {
|
||||||
throw new IllegalArgumentException("X dimension > Y dimension");
|
throw new IllegalArgumentException("X dimension > Y dimension");
|
||||||
}
|
}
|
||||||
|
if (media != null && mediaMap.get(media) == null) {
|
||||||
mediaName = media;
|
mediaName = media;
|
||||||
mediaMap.put(mediaName, this);
|
mediaMap.put(mediaName, this);
|
||||||
|
}
|
||||||
sizeVector.add(this);
|
sizeVector.add(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,8 +149,10 @@ public class MediaSize extends Size2DSyntax implements Attribute {
|
||||||
if (x > y) {
|
if (x > y) {
|
||||||
throw new IllegalArgumentException("X dimension > Y dimension");
|
throw new IllegalArgumentException("X dimension > Y dimension");
|
||||||
}
|
}
|
||||||
|
if (media != null && mediaMap.get(media) == null) {
|
||||||
mediaName = media;
|
mediaName = media;
|
||||||
mediaMap.put(mediaName, this);
|
mediaMap.put(mediaName, this);
|
||||||
|
}
|
||||||
sizeVector.add(this);
|
sizeVector.add(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -585,9 +585,16 @@ public class GifImageDecoder extends ImageDecoder {
|
||||||
System.out.print("Reading a " + width + " by " + height + " " +
|
System.out.print("Reading a " + width + " by " + height + " " +
|
||||||
(interlace ? "" : "non-") + "interlaced image...");
|
(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,
|
boolean ret = parseImage(x, y, width, height,
|
||||||
interlace, ExtractByte(block, 9),
|
interlace, initCodeSize,
|
||||||
block, rasline, model);
|
block, rasline, model);
|
||||||
|
|
||||||
if (!ret) {
|
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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -125,9 +125,9 @@ public abstract class FileFont extends PhysicalFont {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setFileToRemove(File file) {
|
void setFileToRemove(File file, CreatedFontTracker tracker) {
|
||||||
Disposer.addObjectRecord(this,
|
Disposer.addObjectRecord(this,
|
||||||
new CreatedFontFileDisposerRecord(file));
|
new CreatedFontFileDisposerRecord(file, tracker));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is called when a font scaler is determined to
|
/* This is called when a font scaler is determined to
|
||||||
|
@ -246,12 +246,16 @@ public abstract class FileFont extends PhysicalFont {
|
||||||
return getScaler().getUnitsPerEm();
|
return getScaler().getUnitsPerEm();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class CreatedFontFileDisposerRecord implements DisposerRecord {
|
private static class CreatedFontFileDisposerRecord
|
||||||
|
implements DisposerRecord {
|
||||||
|
|
||||||
File fontFile = null;
|
File fontFile = null;
|
||||||
|
CreatedFontTracker tracker;
|
||||||
|
|
||||||
private CreatedFontFileDisposerRecord(File file) {
|
private CreatedFontFileDisposerRecord(File file,
|
||||||
|
CreatedFontTracker tracker) {
|
||||||
fontFile = file;
|
fontFile = file;
|
||||||
|
this.tracker = tracker;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
|
@ -260,6 +264,9 @@ public abstract class FileFont extends PhysicalFont {
|
||||||
public Object run() {
|
public Object run() {
|
||||||
if (fontFile != null) {
|
if (fontFile != null) {
|
||||||
try {
|
try {
|
||||||
|
if (tracker != null) {
|
||||||
|
tracker.subBytes((int)fontFile.length());
|
||||||
|
}
|
||||||
/* REMIND: is it possible that the file is
|
/* REMIND: is it possible that the file is
|
||||||
* still open? It will be closed when the
|
* still open? It will be closed when the
|
||||||
* font2D is disposed but could this code
|
* font2D is disposed but could this code
|
||||||
|
|
|
@ -2348,19 +2348,21 @@ public final class FontManager {
|
||||||
static Vector<File> tmpFontFiles = null;
|
static Vector<File> tmpFontFiles = null;
|
||||||
|
|
||||||
public static Font2D createFont2D(File fontFile, int fontFormat,
|
public static Font2D createFont2D(File fontFile, int fontFormat,
|
||||||
boolean isCopy)
|
boolean isCopy,
|
||||||
|
CreatedFontTracker tracker)
|
||||||
throws FontFormatException {
|
throws FontFormatException {
|
||||||
|
|
||||||
String fontFilePath = fontFile.getPath();
|
String fontFilePath = fontFile.getPath();
|
||||||
FileFont font2D = null;
|
FileFont font2D = null;
|
||||||
final File fFile = fontFile;
|
final File fFile = fontFile;
|
||||||
|
final CreatedFontTracker _tracker = tracker;
|
||||||
try {
|
try {
|
||||||
switch (fontFormat) {
|
switch (fontFormat) {
|
||||||
case Font.TRUETYPE_FONT:
|
case Font.TRUETYPE_FONT:
|
||||||
font2D = new TrueTypeFont(fontFilePath, null, 0, true);
|
font2D = new TrueTypeFont(fontFilePath, null, 0, true);
|
||||||
break;
|
break;
|
||||||
case Font.TYPE1_FONT:
|
case Font.TYPE1_FONT:
|
||||||
font2D = new Type1Font(fontFilePath, null);
|
font2D = new Type1Font(fontFilePath, null, isCopy);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new FontFormatException("Unrecognised Font Format");
|
throw new FontFormatException("Unrecognised Font Format");
|
||||||
|
@ -2370,6 +2372,9 @@ public final class FontManager {
|
||||||
java.security.AccessController.doPrivileged(
|
java.security.AccessController.doPrivileged(
|
||||||
new java.security.PrivilegedAction() {
|
new java.security.PrivilegedAction() {
|
||||||
public Object run() {
|
public Object run() {
|
||||||
|
if (_tracker != null) {
|
||||||
|
_tracker.subBytes((int)fFile.length());
|
||||||
|
}
|
||||||
fFile.delete();
|
fFile.delete();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -2378,7 +2383,7 @@ public final class FontManager {
|
||||||
throw(e);
|
throw(e);
|
||||||
}
|
}
|
||||||
if (isCopy) {
|
if (isCopy) {
|
||||||
font2D.setFileToRemove(fontFile);
|
font2D.setFileToRemove(fontFile, tracker);
|
||||||
synchronized (FontManager.class) {
|
synchronized (FontManager.class) {
|
||||||
|
|
||||||
if (tmpFontFiles == null) {
|
if (tmpFontFiles == null) {
|
||||||
|
|
|
@ -175,8 +175,17 @@ public class TrueTypeFont extends FileFont {
|
||||||
super(platname, nativeNames);
|
super(platname, nativeNames);
|
||||||
useJavaRasterizer = javaRasterizer;
|
useJavaRasterizer = javaRasterizer;
|
||||||
fontRank = Font2D.TTF_RANK;
|
fontRank = Font2D.TTF_RANK;
|
||||||
|
try {
|
||||||
verify();
|
verify();
|
||||||
init(fIndex);
|
init(fIndex);
|
||||||
|
} catch (Throwable t) {
|
||||||
|
close();
|
||||||
|
if (t instanceof FontFormatException) {
|
||||||
|
throw (FontFormatException)t;
|
||||||
|
} else {
|
||||||
|
throw new FontFormatException("Unexpected runtime exception.");
|
||||||
|
}
|
||||||
|
}
|
||||||
Disposer.addObjectRecord(this, disposerRecord);
|
Disposer.addObjectRecord(this, disposerRecord);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,7 @@ import java.nio.BufferUnderflowException;
|
||||||
import java.nio.channels.ClosedChannelException;
|
import java.nio.channels.ClosedChannelException;
|
||||||
import java.nio.channels.FileChannel;
|
import java.nio.channels.FileChannel;
|
||||||
import sun.java2d.Disposer;
|
import sun.java2d.Disposer;
|
||||||
|
import sun.java2d.DisposerRecord;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.awt.Font;
|
import java.awt.Font;
|
||||||
|
@ -76,6 +77,27 @@ import java.awt.Font;
|
||||||
*/
|
*/
|
||||||
public class Type1Font extends FileFont {
|
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);
|
WeakReference bufferRef = new WeakReference(null);
|
||||||
|
|
||||||
private String psName = 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
|
* - does basic verification of the file
|
||||||
* - reads the names (full, family).
|
* - reads the names (full, family).
|
||||||
|
@ -131,12 +164,25 @@ public class Type1Font extends FileFont {
|
||||||
* @throws FontFormatException - if the font can't be opened
|
* @throws FontFormatException - if the font can't be opened
|
||||||
* or fails verification, or there's no usable cmap
|
* 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 {
|
throws FontFormatException {
|
||||||
super(platname, nativeNames);
|
super(platname, nativeNames);
|
||||||
fontRank = Font2D.TYPE1_RANK;
|
fontRank = Font2D.TYPE1_RANK;
|
||||||
checkedNatives = true;
|
checkedNatives = true;
|
||||||
|
try {
|
||||||
verify();
|
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 {
|
private synchronized ByteBuffer getBuffer() throws FontFormatException {
|
||||||
|
|
|
@ -52,6 +52,9 @@ class Request {
|
||||||
os = rawout;
|
os = rawout;
|
||||||
do {
|
do {
|
||||||
startLine = readLine();
|
startLine = readLine();
|
||||||
|
if (startLine == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
/* skip blank lines */
|
/* skip blank lines */
|
||||||
} while (startLine == null ? false : startLine.equals (""));
|
} while (startLine == null ? false : startLine.equals (""));
|
||||||
}
|
}
|
||||||
|
|
|
@ -433,6 +433,7 @@ class ServerImpl implements TimeSource {
|
||||||
rawin = sslStreams.getInputStream();
|
rawin = sslStreams.getInputStream();
|
||||||
rawout = sslStreams.getOutputStream();
|
rawout = sslStreams.getOutputStream();
|
||||||
engine = sslStreams.getSSLEngine();
|
engine = sslStreams.getSSLEngine();
|
||||||
|
connection.sslStreams = sslStreams;
|
||||||
} else {
|
} else {
|
||||||
rawin = new BufferedInputStream(
|
rawin = new BufferedInputStream(
|
||||||
new Request.ReadStream (
|
new Request.ReadStream (
|
||||||
|
@ -442,6 +443,8 @@ class ServerImpl implements TimeSource {
|
||||||
ServerImpl.this, chan
|
ServerImpl.this, chan
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
connection.raw = rawin;
|
||||||
|
connection.rawout = rawout;
|
||||||
}
|
}
|
||||||
Request req = new Request (rawin, rawout);
|
Request req = new Request (rawin, rawout);
|
||||||
requestLine = req.requestLine();
|
requestLine = req.requestLine();
|
||||||
|
|
|
@ -274,6 +274,7 @@ public abstract class KrbKdcReq {
|
||||||
+ ",Attempt =" + i
|
+ ",Attempt =" + i
|
||||||
+ ", #bytes=" + obuf.length);
|
+ ", #bytes=" + obuf.length);
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
/*
|
/*
|
||||||
* Send the data to the kdc.
|
* Send the data to the kdc.
|
||||||
*/
|
*/
|
||||||
|
@ -296,6 +297,9 @@ public abstract class KrbKdcReq {
|
||||||
throw se;
|
throw se;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
|
kdcClient.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ibuf;
|
return ibuf;
|
||||||
|
|
|
@ -93,4 +93,7 @@ public class UDPClient {
|
||||||
return data;
|
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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -38,6 +38,8 @@ import static sun.security.pkcs11.TemplateManager.*;
|
||||||
import sun.security.pkcs11.wrapper.*;
|
import sun.security.pkcs11.wrapper.*;
|
||||||
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
|
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
|
||||||
|
|
||||||
|
import sun.security.rsa.RSAKeyFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* KeyPairGenerator implementation class. This class currently supports
|
* KeyPairGenerator implementation class. This class currently supports
|
||||||
* RSA, DSA, DH, and EC.
|
* RSA, DSA, DH, and EC.
|
||||||
|
@ -66,7 +68,7 @@ final class P11KeyPairGenerator extends KeyPairGeneratorSpi {
|
||||||
private AlgorithmParameterSpec params;
|
private AlgorithmParameterSpec params;
|
||||||
|
|
||||||
// for RSA, selected or default value of public exponent, always valid
|
// 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
|
// SecureRandom instance, if specified in init
|
||||||
private SecureRandom random;
|
private SecureRandom random;
|
||||||
|
@ -88,19 +90,19 @@ final class P11KeyPairGenerator extends KeyPairGeneratorSpi {
|
||||||
public void initialize(int keySize, SecureRandom random) {
|
public void initialize(int keySize, SecureRandom random) {
|
||||||
token.ensureValid();
|
token.ensureValid();
|
||||||
try {
|
try {
|
||||||
checkKeySize(keySize);
|
checkKeySize(keySize, null);
|
||||||
} catch (InvalidAlgorithmParameterException e) {
|
} catch (InvalidAlgorithmParameterException e) {
|
||||||
throw new InvalidParameterException(e.getMessage());
|
throw new InvalidParameterException(e.getMessage());
|
||||||
}
|
}
|
||||||
this.keySize = keySize;
|
this.keySize = keySize;
|
||||||
this.params = null;
|
this.params = null;
|
||||||
this.random = random;
|
this.random = random;
|
||||||
this.rsaPublicExponent = RSAKeyGenParameterSpec.F4;
|
|
||||||
if (algorithm.equals("EC")) {
|
if (algorithm.equals("EC")) {
|
||||||
params = P11ECKeyFactory.getECParameterSpec(keySize);
|
params = P11ECKeyFactory.getECParameterSpec(keySize);
|
||||||
if (params == null) {
|
if (params == null) {
|
||||||
throw new InvalidParameterException
|
throw new InvalidParameterException(
|
||||||
("No EC parameters available for key size " + keySize + " bits");
|
"No EC parameters available for key size "
|
||||||
|
+ keySize + " bits");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -115,8 +117,10 @@ final class P11KeyPairGenerator extends KeyPairGeneratorSpi {
|
||||||
("DHParameterSpec required for Diffie-Hellman");
|
("DHParameterSpec required for Diffie-Hellman");
|
||||||
}
|
}
|
||||||
DHParameterSpec dhParams = (DHParameterSpec)params;
|
DHParameterSpec dhParams = (DHParameterSpec)params;
|
||||||
this.keySize = dhParams.getP().bitLength();
|
int tmpKeySize = dhParams.getP().bitLength();
|
||||||
this.params = params;
|
checkKeySize(tmpKeySize, dhParams);
|
||||||
|
this.keySize = tmpKeySize;
|
||||||
|
this.params = dhParams;
|
||||||
// XXX sanity check params
|
// XXX sanity check params
|
||||||
} else if (algorithm.equals("RSA")) {
|
} else if (algorithm.equals("RSA")) {
|
||||||
if (params instanceof RSAKeyGenParameterSpec == false) {
|
if (params instanceof RSAKeyGenParameterSpec == false) {
|
||||||
|
@ -124,7 +128,9 @@ final class P11KeyPairGenerator extends KeyPairGeneratorSpi {
|
||||||
("RSAKeyGenParameterSpec required for RSA");
|
("RSAKeyGenParameterSpec required for RSA");
|
||||||
}
|
}
|
||||||
RSAKeyGenParameterSpec rsaParams = (RSAKeyGenParameterSpec)params;
|
RSAKeyGenParameterSpec rsaParams = (RSAKeyGenParameterSpec)params;
|
||||||
this.keySize = rsaParams.getKeysize();
|
int tmpKeySize = rsaParams.getKeysize();
|
||||||
|
checkKeySize(tmpKeySize, rsaParams);
|
||||||
|
this.keySize = tmpKeySize;
|
||||||
this.params = null;
|
this.params = null;
|
||||||
this.rsaPublicExponent = rsaParams.getPublicExponent();
|
this.rsaPublicExponent = rsaParams.getPublicExponent();
|
||||||
// XXX sanity check params
|
// XXX sanity check params
|
||||||
|
@ -134,13 +140,16 @@ final class P11KeyPairGenerator extends KeyPairGeneratorSpi {
|
||||||
("DSAParameterSpec required for DSA");
|
("DSAParameterSpec required for DSA");
|
||||||
}
|
}
|
||||||
DSAParameterSpec dsaParams = (DSAParameterSpec)params;
|
DSAParameterSpec dsaParams = (DSAParameterSpec)params;
|
||||||
this.keySize = dsaParams.getP().bitLength();
|
int tmpKeySize = dsaParams.getP().bitLength();
|
||||||
this.params = params;
|
checkKeySize(tmpKeySize, dsaParams);
|
||||||
|
this.keySize = tmpKeySize;
|
||||||
|
this.params = dsaParams;
|
||||||
// XXX sanity check params
|
// XXX sanity check params
|
||||||
} else if (algorithm.equals("EC")) {
|
} else if (algorithm.equals("EC")) {
|
||||||
ECParameterSpec ecParams;
|
ECParameterSpec ecParams;
|
||||||
if (params instanceof ECParameterSpec) {
|
if (params instanceof ECParameterSpec) {
|
||||||
ecParams = P11ECKeyFactory.getECParameterSpec((ECParameterSpec)params);
|
ecParams = P11ECKeyFactory.getECParameterSpec(
|
||||||
|
(ECParameterSpec)params);
|
||||||
if (ecParams == null) {
|
if (ecParams == null) {
|
||||||
throw new InvalidAlgorithmParameterException
|
throw new InvalidAlgorithmParameterException
|
||||||
("Unsupported curve: " + params);
|
("Unsupported curve: " + params);
|
||||||
|
@ -156,16 +165,17 @@ final class P11KeyPairGenerator extends KeyPairGeneratorSpi {
|
||||||
throw new InvalidAlgorithmParameterException
|
throw new InvalidAlgorithmParameterException
|
||||||
("ECParameterSpec or ECGenParameterSpec required for EC");
|
("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;
|
this.params = ecParams;
|
||||||
} else {
|
} else {
|
||||||
throw new ProviderException("Unknown algorithm: " + algorithm);
|
throw new ProviderException("Unknown algorithm: " + algorithm);
|
||||||
}
|
}
|
||||||
this.random = random;
|
this.random = random;
|
||||||
checkKeySize(keySize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkKeySize(int keySize)
|
private void checkKeySize(int keySize, AlgorithmParameterSpec params)
|
||||||
throws InvalidAlgorithmParameterException {
|
throws InvalidAlgorithmParameterException {
|
||||||
if (algorithm.equals("EC")) {
|
if (algorithm.equals("EC")) {
|
||||||
if (keySize < 112) {
|
if (keySize < 112) {
|
||||||
|
@ -178,13 +188,28 @@ final class P11KeyPairGenerator extends KeyPairGeneratorSpi {
|
||||||
("Key size must be at most 2048 bit");
|
("Key size must be at most 2048 bit");
|
||||||
}
|
}
|
||||||
return;
|
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) {
|
if (keySize < 512) {
|
||||||
throw new InvalidAlgorithmParameterException
|
throw new InvalidAlgorithmParameterException
|
||||||
("Key size must be at least 512 bit");
|
("Key size must be at least 512 bit");
|
||||||
}
|
}
|
||||||
if (algorithm.equals("RSA") ||
|
if (algorithm.equals("DH") && (params != null)) {
|
||||||
(algorithm.equals("DH") && (params != null))) {
|
|
||||||
// sanity check, nobody really wants keys this large
|
// sanity check, nobody really wants keys this large
|
||||||
if (keySize > 64 * 1024) {
|
if (keySize > 64 * 1024) {
|
||||||
throw new InvalidAlgorithmParameterException
|
throw new InvalidAlgorithmParameterException
|
||||||
|
|
|
@ -80,6 +80,8 @@ import static sun.security.pkcs11.P11Util.*;
|
||||||
import sun.security.pkcs11.wrapper.*;
|
import sun.security.pkcs11.wrapper.*;
|
||||||
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
|
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
|
||||||
|
|
||||||
|
import sun.security.rsa.RSAKeyFactory;
|
||||||
|
|
||||||
final class P11KeyStore extends KeyStoreSpi {
|
final class P11KeyStore extends KeyStoreSpi {
|
||||||
|
|
||||||
private static final CK_ATTRIBUTE ATTR_CLASS_CERT =
|
private static final CK_ATTRIBUTE ATTR_CLASS_CERT =
|
||||||
|
@ -1328,6 +1330,15 @@ final class P11KeyStore extends KeyStoreSpi {
|
||||||
BigInteger modulus = attrs[0].getBigInteger();
|
BigInteger modulus = attrs[0].getBigInteger();
|
||||||
keyLength = modulus.bitLength();
|
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,
|
return P11Key.privateKey(session,
|
||||||
oHandle,
|
oHandle,
|
||||||
keyType,
|
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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -35,6 +35,8 @@ import static sun.security.pkcs11.TemplateManager.*;
|
||||||
import sun.security.pkcs11.wrapper.*;
|
import sun.security.pkcs11.wrapper.*;
|
||||||
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
|
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
|
||||||
|
|
||||||
|
import sun.security.rsa.RSAKeyFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RSA KeyFactory implemenation.
|
* RSA KeyFactory implemenation.
|
||||||
*
|
*
|
||||||
|
@ -131,6 +133,9 @@ final class P11RSAKeyFactory extends P11KeyFactory {
|
||||||
} catch (PKCS11Exception e) {
|
} catch (PKCS11Exception e) {
|
||||||
throw new InvalidKeySpecException
|
throw new InvalidKeySpecException
|
||||||
("Could not create RSA public key", e);
|
("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) {
|
} catch (PKCS11Exception e) {
|
||||||
throw new InvalidKeySpecException
|
throw new InvalidKeySpecException
|
||||||
("Could not create RSA private key", e);
|
("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)
|
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[] {
|
CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
|
||||||
new CK_ATTRIBUTE(CKA_CLASS, CKO_PUBLIC_KEY),
|
new CK_ATTRIBUTE(CKA_CLASS, CKO_PUBLIC_KEY),
|
||||||
new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_RSA),
|
new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_RSA),
|
||||||
|
@ -200,7 +209,8 @@ final class P11RSAKeyFactory extends P11KeyFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
private PrivateKey generatePrivate(BigInteger n, BigInteger d)
|
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[] {
|
CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
|
||||||
new CK_ATTRIBUTE(CKA_CLASS, CKO_PRIVATE_KEY),
|
new CK_ATTRIBUTE(CKA_CLASS, CKO_PRIVATE_KEY),
|
||||||
new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_RSA),
|
new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_RSA),
|
||||||
|
@ -222,7 +232,9 @@ final class P11RSAKeyFactory extends P11KeyFactory {
|
||||||
|
|
||||||
private PrivateKey generatePrivate(BigInteger n, BigInteger e,
|
private PrivateKey generatePrivate(BigInteger n, BigInteger e,
|
||||||
BigInteger d, BigInteger p, BigInteger q, BigInteger pe,
|
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[] {
|
CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
|
||||||
new CK_ATTRIBUTE(CKA_CLASS, CKO_PRIVATE_KEY),
|
new CK_ATTRIBUTE(CKA_CLASS, CKO_PRIVATE_KEY),
|
||||||
new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_RSA),
|
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
|
@Deprecated
|
||||||
public SunPKCS11(String configName, InputStream configStream) {
|
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());
|
1.7d, Config.getConfig(configName, configStream).getDescription());
|
||||||
this.configName = configName;
|
this.configName = configName;
|
||||||
this.config = Config.removeConfig(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
|
// If we are in Secmod mode and configured to use either the
|
||||||
// nssKeyStore or the nssTrustAnchors module, we automatically
|
// 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) {
|
if (useSecmod) {
|
||||||
|
@ -168,33 +171,40 @@ public final class SunPKCS11 extends AuthProvider {
|
||||||
if (secmod.isInitialized()) {
|
if (secmod.isInitialized()) {
|
||||||
if (nssSecmodDirectory != null) {
|
if (nssSecmodDirectory != null) {
|
||||||
String s = secmod.getConfigDir();
|
String s = secmod.getConfigDir();
|
||||||
if ((s != null) && (s.equals(nssSecmodDirectory) == false)) {
|
if ((s != null) &&
|
||||||
|
(s.equals(nssSecmodDirectory) == false)) {
|
||||||
throw new ProviderException("Secmod directory "
|
throw new ProviderException("Secmod directory "
|
||||||
+ nssSecmodDirectory
|
+ nssSecmodDirectory
|
||||||
+ " invalid, NSS already initialized with " + s);
|
+ " invalid, NSS already initialized with "
|
||||||
|
+ s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (nssLibraryDirectory != null) {
|
if (nssLibraryDirectory != null) {
|
||||||
String s = secmod.getLibDir();
|
String s = secmod.getLibDir();
|
||||||
if ((s != null) && (s.equals(nssLibraryDirectory) == false)) {
|
if ((s != null) &&
|
||||||
|
(s.equals(nssLibraryDirectory) == false)) {
|
||||||
throw new ProviderException("NSS library directory "
|
throw new ProviderException("NSS library directory "
|
||||||
+ nssLibraryDirectory
|
+ nssLibraryDirectory
|
||||||
+ " invalid, NSS already initialized with " + s);
|
+ " invalid, NSS already initialized with "
|
||||||
|
+ s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (nssDbMode != DbMode.NO_DB) {
|
if (nssDbMode != DbMode.NO_DB) {
|
||||||
if (nssSecmodDirectory == null) {
|
if (nssSecmodDirectory == null) {
|
||||||
throw new ProviderException("Secmod not initialized and "
|
throw new ProviderException(
|
||||||
|
"Secmod not initialized and "
|
||||||
+ "nssSecmodDirectory not specified");
|
+ "nssSecmodDirectory not specified");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (nssSecmodDirectory != null) {
|
if (nssSecmodDirectory != null) {
|
||||||
throw new ProviderException
|
throw new ProviderException(
|
||||||
("nssSecmodDirectory must not be specified in noDb mode");
|
"nssSecmodDirectory must not be "
|
||||||
|
+ "specified in noDb mode");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
secmod.initialize(nssDbMode, nssSecmodDirectory, nssLibraryDirectory);
|
secmod.initialize(nssDbMode, nssSecmodDirectory,
|
||||||
|
nssLibraryDirectory);
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
// XXX which exception to throw
|
// XXX which exception to throw
|
||||||
|
@ -211,7 +221,8 @@ public final class SunPKCS11 extends AuthProvider {
|
||||||
if (nssModule != null) {
|
if (nssModule != null) {
|
||||||
moduleName = "fips";
|
moduleName = "fips";
|
||||||
} else {
|
} else {
|
||||||
moduleName = (nssDbMode == DbMode.NO_DB) ? "crypto" : "keystore";
|
moduleName = (nssDbMode == DbMode.NO_DB) ?
|
||||||
|
"crypto" : "keystore";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (moduleName.equals("fips")) {
|
if (moduleName.equals("fips")) {
|
||||||
|
@ -253,10 +264,12 @@ public final class SunPKCS11 extends AuthProvider {
|
||||||
+ ": only " + k + " external NSS modules available");
|
+ ": only " + k + " external NSS modules available");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new ProviderException("Unknown NSS module: " + moduleName);
|
throw new ProviderException(
|
||||||
|
"Unknown NSS module: " + moduleName);
|
||||||
}
|
}
|
||||||
if (nssModule == null) {
|
if (nssModule == null) {
|
||||||
throw new ProviderException("NSS module not available: " + moduleName);
|
throw new ProviderException(
|
||||||
|
"NSS module not available: " + moduleName);
|
||||||
}
|
}
|
||||||
if (nssModule.hasInitializedProvider()) {
|
if (nssModule.hasInitializedProvider()) {
|
||||||
throw new ProviderException("Secmod module already configured");
|
throw new ProviderException("Secmod module already configured");
|
||||||
|
@ -296,8 +309,9 @@ public final class SunPKCS11 extends AuthProvider {
|
||||||
initArgs.flags = CKF_OS_LOCKING_OK;
|
initArgs.flags = CKF_OS_LOCKING_OK;
|
||||||
PKCS11 tmpPKCS11;
|
PKCS11 tmpPKCS11;
|
||||||
try {
|
try {
|
||||||
tmpPKCS11 = PKCS11.getInstance
|
tmpPKCS11 = PKCS11.getInstance(
|
||||||
(library, functionList, initArgs, config.getOmitInitialize());
|
library, functionList, initArgs,
|
||||||
|
config.getOmitInitialize());
|
||||||
} catch (PKCS11Exception e) {
|
} catch (PKCS11Exception e) {
|
||||||
if (debug != null) {
|
if (debug != null) {
|
||||||
debug.println("Multi-threaded initialization failed: " + e);
|
debug.println("Multi-threaded initialization failed: " + e);
|
||||||
|
@ -312,8 +326,8 @@ public final class SunPKCS11 extends AuthProvider {
|
||||||
} else {
|
} else {
|
||||||
initArgs.flags = 0;
|
initArgs.flags = 0;
|
||||||
}
|
}
|
||||||
tmpPKCS11 = PKCS11.getInstance
|
tmpPKCS11 = PKCS11.getInstance(library,
|
||||||
(library, functionList, initArgs, config.getOmitInitialize());
|
functionList, initArgs, config.getOmitInitialize());
|
||||||
}
|
}
|
||||||
p11 = tmpPKCS11;
|
p11 = tmpPKCS11;
|
||||||
|
|
||||||
|
@ -336,8 +350,10 @@ public final class SunPKCS11 extends AuthProvider {
|
||||||
System.out.println("Slots with tokens: " + toString(slots));
|
System.out.println("Slots with tokens: " + toString(slots));
|
||||||
}
|
}
|
||||||
if (slotID < 0) {
|
if (slotID < 0) {
|
||||||
if ((slotListIndex < 0) || (slotListIndex >= slots.length)) {
|
if ((slotListIndex < 0)
|
||||||
throw new ProviderException("slotListIndex is " + slotListIndex
|
|| (slotListIndex >= slots.length)) {
|
||||||
|
throw new ProviderException("slotListIndex is "
|
||||||
|
+ slotListIndex
|
||||||
+ " but token only has " + slots.length + " slots");
|
+ " but token only has " + slots.length + " slots");
|
||||||
}
|
}
|
||||||
slotID = slots[slotListIndex];
|
slotID = slots[slotListIndex];
|
||||||
|
@ -575,12 +591,15 @@ public final class SunPKCS11 extends AuthProvider {
|
||||||
d(KF, "DH", P11DHKeyFactory, s("DiffieHellman"),
|
d(KF, "DH", P11DHKeyFactory, s("DiffieHellman"),
|
||||||
m(CKM_DH_PKCS_KEY_PAIR_GEN, CKM_DH_PKCS_DERIVE));
|
m(CKM_DH_PKCS_KEY_PAIR_GEN, CKM_DH_PKCS_DERIVE));
|
||||||
d(KF, "EC", P11DHKeyFactory,
|
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.
|
// AlgorithmParameters for EC.
|
||||||
// Only needed until we have an EC implementation in the SUN provider.
|
// 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"),
|
d(AGP, "EC", "sun.security.ec.ECParameters",
|
||||||
m(CKM_EC_KEY_PAIR_GEN, CKM_ECDH1_DERIVE, CKM_ECDSA, CKM_ECDSA_SHA1));
|
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"),
|
d(KA, "DH", P11KeyAgreement, s("DiffieHellman"),
|
||||||
m(CKM_DH_PKCS_DERIVE));
|
m(CKM_DH_PKCS_DERIVE));
|
||||||
|
@ -654,12 +673,16 @@ public final class SunPKCS11 extends AuthProvider {
|
||||||
d(SIG, "SHA512withRSA", P11Signature,
|
d(SIG, "SHA512withRSA", P11Signature,
|
||||||
m(CKM_SHA512_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
|
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));
|
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,
|
m(CKM_SSL3_MASTER_KEY_DERIVE, CKM_TLS_MASTER_KEY_DERIVE,
|
||||||
CKM_SSL3_MASTER_KEY_DERIVE_DH, CKM_TLS_MASTER_KEY_DERIVE_DH));
|
CKM_SSL3_MASTER_KEY_DERIVE_DH,
|
||||||
d(KG, "SunTlsKeyMaterial", "sun.security.pkcs11.P11TlsKeyMaterialGenerator",
|
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));
|
m(CKM_SSL3_KEY_AND_MAC_DERIVE, CKM_TLS_KEY_AND_MAC_DERIVE));
|
||||||
d(KG, "SunTlsPrf", "sun.security.pkcs11.P11TlsPrfGenerator",
|
d(KG, "SunTlsPrf", "sun.security.pkcs11.P11TlsPrfGenerator",
|
||||||
m(CKM_TLS_PRF, CKM_NSS_TLS_PRF_GENERAL));
|
m(CKM_TLS_PRF, CKM_NSS_TLS_PRF_GENERAL));
|
||||||
|
@ -773,6 +796,13 @@ public final class SunPKCS11 extends AuthProvider {
|
||||||
System.out.println(token.tokenInfo);
|
System.out.println(token.tokenInfo);
|
||||||
}
|
}
|
||||||
long[] supportedMechanisms = p11.C_GetMechanismList(slotID);
|
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 =
|
final Map<Descriptor,Integer> supportedAlgs =
|
||||||
new HashMap<Descriptor,Integer>();
|
new HashMap<Descriptor,Integer>();
|
||||||
for (int i = 0; i < supportedMechanisms.length; i++) {
|
for (int i = 0; i < supportedMechanisms.length; i++) {
|
||||||
|
@ -807,6 +837,9 @@ public final class SunPKCS11 extends AuthProvider {
|
||||||
supportedAlgs.put(d, integerMech);
|
supportedAlgs.put(d, integerMech);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
// See if there is something "more preferred"
|
||||||
|
// than what we currently have in the supportedAlgs
|
||||||
|
// map.
|
||||||
int intOldMech = oldMech.intValue();
|
int intOldMech = oldMech.intValue();
|
||||||
for (int j = 0; j < d.mechanisms.length; j++) {
|
for (int j = 0; j < d.mechanisms.length; j++) {
|
||||||
int nextMech = d.mechanisms[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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -31,6 +31,8 @@ import java.security.*;
|
||||||
import java.security.interfaces.*;
|
import java.security.interfaces.*;
|
||||||
import java.security.spec.*;
|
import java.security.spec.*;
|
||||||
|
|
||||||
|
import sun.security.action.GetPropertyAction;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* KeyFactory for RSA keys. Keys must be instances of PublicKey or PrivateKey
|
* KeyFactory for RSA keys. Keys must be instances of PublicKey or PrivateKey
|
||||||
* and getAlgorithm() must return "RSA". For such keys, it supports conversion
|
* 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<?> x509KeySpecClass = X509EncodedKeySpec.class;
|
||||||
private final static Class<?> pkcs8KeySpecClass = PKCS8EncodedKeySpec.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();
|
// instance used for static translateKey();
|
||||||
private final static RSAKeyFactory INSTANCE = new RSAKeyFactory();
|
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
|
* Static method to convert Key into an instance of RSAPublicKeyImpl
|
||||||
* RSAPublicKey or RSAPrivate(Crt)Key. Check the key and convert it
|
* or RSAPrivate(Crt)KeyImpl. If the key is not an RSA key or cannot be
|
||||||
* to a SunRsaSign key if necessary. If the key is not an RSA key
|
* used, throw an InvalidKeyException.
|
||||||
* 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.
|
|
||||||
*
|
*
|
||||||
* Used by RSASignature and RSACipher.
|
* Used by RSASignature and RSACipher.
|
||||||
*/
|
*/
|
||||||
public static RSAKey toRSAKey(Key key) throws InvalidKeyException {
|
public static RSAKey toRSAKey(Key key) throws InvalidKeyException {
|
||||||
if (key instanceof RSAKey) {
|
if ((key instanceof RSAPrivateKeyImpl) ||
|
||||||
RSAKey rsaKey = (RSAKey)key;
|
(key instanceof RSAPrivateCrtKeyImpl) ||
|
||||||
checkKey(rsaKey);
|
(key instanceof RSAPublicKeyImpl)) {
|
||||||
return rsaKey;
|
return (RSAKey)key;
|
||||||
} else {
|
} else {
|
||||||
return (RSAKey)INSTANCE.engineTranslateKey(key);
|
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 {
|
static void checkRSAProviderKeyLengths(int modulusLen, BigInteger exponent)
|
||||||
// check for subinterfaces, omit additional checks for our keys
|
throws InvalidKeyException {
|
||||||
if (key instanceof RSAPublicKey) {
|
checkKeyLengths(((modulusLen + 7) & ~7), exponent,
|
||||||
if (key instanceof RSAPublicKeyImpl) {
|
RSAKeyFactory.MIN_MODLEN, Integer.MAX_VALUE);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check the length of the modulus of an RSA key. We only support keys
|
* Check the length of an RSA key modulus/exponent to make sure it
|
||||||
* at least 505 bits long.
|
* 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 {
|
public static void checkKeyLengths(int modulusLen, BigInteger exponent,
|
||||||
if (modulus.bitLength() < 505) {
|
int minModulusLen, int maxModulusLen) throws InvalidKeyException {
|
||||||
// some providers may generate slightly shorter keys
|
|
||||||
// accept them if the encoding is at least 64 bytes long
|
if ((minModulusLen > 0) && (modulusLen < (minModulusLen))) {
|
||||||
throw new InvalidKeyException
|
throw new InvalidKeyException( "RSA keys must be at least " +
|
||||||
("RSA keys must be at least 512 bits long");
|
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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -47,7 +47,7 @@ public final class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
|
||||||
// public exponent to use
|
// public exponent to use
|
||||||
private BigInteger publicExponent;
|
private BigInteger publicExponent;
|
||||||
|
|
||||||
// size of the key to generate, >= 512
|
// size of the key to generate, >= RSAKeyFactory.MIN_MODLEN
|
||||||
private int keySize;
|
private int keySize;
|
||||||
|
|
||||||
// PRNG to use
|
// PRNG to use
|
||||||
|
@ -60,15 +60,16 @@ public final class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
|
||||||
|
|
||||||
// initialize the generator. See JCA doc
|
// initialize the generator. See JCA doc
|
||||||
public void initialize(int keySize, SecureRandom random) {
|
public void initialize(int keySize, SecureRandom random) {
|
||||||
if (keySize < 512) {
|
|
||||||
throw new InvalidParameterException
|
// do not allow unreasonably small or large key sizes,
|
||||||
("Key size must be at least 512 bits");
|
// probably user error
|
||||||
}
|
try {
|
||||||
if (keySize > 64 * 1024) {
|
RSAKeyFactory.checkKeyLengths(keySize, RSAKeyGenParameterSpec.F4,
|
||||||
// do not allow unreasonably large key sizes, probably user error
|
512, 64 * 1024);
|
||||||
throw new InvalidParameterException
|
} catch (InvalidKeyException e) {
|
||||||
("Key size must be 65536 bits or less");
|
throw new InvalidParameterException(e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
this.keySize = keySize;
|
this.keySize = keySize;
|
||||||
this.random = random;
|
this.random = random;
|
||||||
this.publicExponent = RSAKeyGenParameterSpec.F4;
|
this.publicExponent = RSAKeyGenParameterSpec.F4;
|
||||||
|
@ -77,35 +78,41 @@ public final class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
|
||||||
// second initialize method. See JCA doc.
|
// second initialize method. See JCA doc.
|
||||||
public void initialize(AlgorithmParameterSpec params, SecureRandom random)
|
public void initialize(AlgorithmParameterSpec params, SecureRandom random)
|
||||||
throws InvalidAlgorithmParameterException {
|
throws InvalidAlgorithmParameterException {
|
||||||
|
|
||||||
if (params instanceof RSAKeyGenParameterSpec == false) {
|
if (params instanceof RSAKeyGenParameterSpec == false) {
|
||||||
throw new InvalidAlgorithmParameterException
|
throw new InvalidAlgorithmParameterException
|
||||||
("Params must be instance of RSAKeyGenParameterSpec");
|
("Params must be instance of RSAKeyGenParameterSpec");
|
||||||
}
|
}
|
||||||
|
|
||||||
RSAKeyGenParameterSpec rsaSpec = (RSAKeyGenParameterSpec)params;
|
RSAKeyGenParameterSpec rsaSpec = (RSAKeyGenParameterSpec)params;
|
||||||
keySize = rsaSpec.getKeysize();
|
int tmpKeySize = rsaSpec.getKeysize();
|
||||||
publicExponent = rsaSpec.getPublicExponent();
|
BigInteger tmpPublicExponent = rsaSpec.getPublicExponent();
|
||||||
this.random = random;
|
|
||||||
if (keySize < 512) {
|
if (tmpPublicExponent == null) {
|
||||||
throw new InvalidAlgorithmParameterException
|
tmpPublicExponent = RSAKeyGenParameterSpec.F4;
|
||||||
("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;
|
|
||||||
} else {
|
} else {
|
||||||
if (publicExponent.compareTo(RSAKeyGenParameterSpec.F0) < 0) {
|
if (tmpPublicExponent.compareTo(RSAKeyGenParameterSpec.F0) < 0) {
|
||||||
throw new InvalidAlgorithmParameterException
|
throw new InvalidAlgorithmParameterException
|
||||||
("Public exponent must be 3 or larger");
|
("Public exponent must be 3 or larger");
|
||||||
}
|
}
|
||||||
if (publicExponent.bitLength() > keySize) {
|
if (tmpPublicExponent.bitLength() > tmpKeySize) {
|
||||||
throw new InvalidAlgorithmParameterException
|
throw new InvalidAlgorithmParameterException
|
||||||
("Public exponent must be smaller than key size");
|
("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
|
// 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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -89,7 +89,7 @@ public final class RSAPrivateCrtKeyImpl
|
||||||
*/
|
*/
|
||||||
RSAPrivateCrtKeyImpl(byte[] encoded) throws InvalidKeyException {
|
RSAPrivateCrtKeyImpl(byte[] encoded) throws InvalidKeyException {
|
||||||
decode(encoded);
|
decode(encoded);
|
||||||
RSAKeyFactory.checkKeyLength(n);
|
RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), e);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -107,7 +107,8 @@ public final class RSAPrivateCrtKeyImpl
|
||||||
this.pe = pe;
|
this.pe = pe;
|
||||||
this.qe = qe;
|
this.qe = qe;
|
||||||
this.coeff = coeff;
|
this.coeff = coeff;
|
||||||
RSAKeyFactory.checkKeyLength(n);
|
RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), e);
|
||||||
|
|
||||||
// generate the encoding
|
// generate the encoding
|
||||||
algid = rsaId;
|
algid = rsaId;
|
||||||
try {
|
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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -61,7 +61,7 @@ public final class RSAPrivateKeyImpl extends PKCS8Key implements RSAPrivateKey {
|
||||||
RSAPrivateKeyImpl(BigInteger n, BigInteger d) throws InvalidKeyException {
|
RSAPrivateKeyImpl(BigInteger n, BigInteger d) throws InvalidKeyException {
|
||||||
this.n = n;
|
this.n = n;
|
||||||
this.d = d;
|
this.d = d;
|
||||||
RSAKeyFactory.checkKeyLength(n);
|
RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), null);
|
||||||
// generate the encoding
|
// generate the encoding
|
||||||
algid = RSAPrivateCrtKeyImpl.rsaId;
|
algid = RSAPrivateCrtKeyImpl.rsaId;
|
||||||
try {
|
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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -56,10 +56,11 @@ public final class RSAPublicKeyImpl extends X509Key implements RSAPublicKey {
|
||||||
* Construct a key from its components. Used by the
|
* Construct a key from its components. Used by the
|
||||||
* RSAKeyFactory and the RSAKeyPairGenerator.
|
* RSAKeyFactory and the RSAKeyPairGenerator.
|
||||||
*/
|
*/
|
||||||
public RSAPublicKeyImpl(BigInteger n, BigInteger e) throws InvalidKeyException {
|
public RSAPublicKeyImpl(BigInteger n, BigInteger e)
|
||||||
|
throws InvalidKeyException {
|
||||||
this.n = n;
|
this.n = n;
|
||||||
this.e = e;
|
this.e = e;
|
||||||
RSAKeyFactory.checkKeyLength(n);
|
RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), e);
|
||||||
// generate the encoding
|
// generate the encoding
|
||||||
algid = RSAPrivateCrtKeyImpl.rsaId;
|
algid = RSAPrivateCrtKeyImpl.rsaId;
|
||||||
try {
|
try {
|
||||||
|
@ -80,7 +81,7 @@ public final class RSAPublicKeyImpl extends X509Key implements RSAPublicKey {
|
||||||
*/
|
*/
|
||||||
public RSAPublicKeyImpl(byte[] encoded) throws InvalidKeyException {
|
public RSAPublicKeyImpl(byte[] encoded) throws InvalidKeyException {
|
||||||
decode(encoded);
|
decode(encoded);
|
||||||
RSAKeyFactory.checkKeyLength(n);
|
RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), e);
|
||||||
}
|
}
|
||||||
|
|
||||||
// see JCA doc
|
// see JCA doc
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
# passwords. To be functional, a role must have an entry in
|
# passwords. To be functional, a role must have an entry in
|
||||||
# both the password and the access files.
|
# 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
|
# You can specify an alternate location by specifying a property in
|
||||||
# the management config file $JRE/lib/management/management.properties
|
# the management config file $JRE/lib/management/management.properties
|
||||||
# (See that file for details)
|
# (See that file for details)
|
||||||
|
@ -16,7 +16,7 @@
|
||||||
# The file format for password and access files is syntactically the same
|
# The file format for password and access files is syntactically the same
|
||||||
# as the Properties file format. The syntax is described in the Javadoc
|
# as the Properties file format. The syntax is described in the Javadoc
|
||||||
# for java.util.Properties.load.
|
# 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.
|
# a comment (like this one), or an access control entry.
|
||||||
#
|
#
|
||||||
# An access control entry consists of a role name, and an
|
# An access control entry consists of a role name, and an
|
||||||
|
@ -29,10 +29,38 @@
|
||||||
# role can read measurements but cannot perform any action
|
# role can read measurements but cannot perform any action
|
||||||
# that changes the environment of the running program.
|
# that changes the environment of the running program.
|
||||||
# "readwrite" grants access to read and write attributes of MBeans,
|
# "readwrite" grants access to read and write attributes of MBeans,
|
||||||
# to invoke operations on them, and to create or remove them.
|
# to invoke operations on them, and optionally
|
||||||
# This access should be granted to only trusted clients,
|
# to create or remove them. This access should be granted
|
||||||
# since they can potentially interfere with the smooth
|
# only to trusted clients, since they can potentially
|
||||||
# operation of a running program
|
# 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
|
# A given role should have at most one entry in this file. If a role
|
||||||
# has no entry, it has no access.
|
# has no entry, it has no access.
|
||||||
|
@ -42,7 +70,10 @@
|
||||||
#
|
#
|
||||||
# Default access control entries:
|
# Default access control entries:
|
||||||
# o The "monitorRole" role has readonly access.
|
# 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
|
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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -94,6 +94,7 @@ void band::readData(int expectedLength) {
|
||||||
assert(!valc->isMalloc);
|
assert(!valc->isMalloc);
|
||||||
}
|
}
|
||||||
xvs.init(u->rp, u->rplimit, valc);
|
xvs.init(u->rp, u->rplimit, valc);
|
||||||
|
CHECK;
|
||||||
int X = xvs.getInt();
|
int X = xvs.getInt();
|
||||||
if (valc->S() != 0) {
|
if (valc->S() != 0) {
|
||||||
assert(valc->min <= -256);
|
assert(valc->min <= -256);
|
||||||
|
@ -117,6 +118,7 @@ void band::readData(int expectedLength) {
|
||||||
byte XB_byte = (byte) XB;
|
byte XB_byte = (byte) XB;
|
||||||
byte* XB_ptr = &XB_byte;
|
byte* XB_ptr = &XB_byte;
|
||||||
cm.init(u->rp, u->rplimit, XB_ptr, 0, defc, length, null);
|
cm.init(u->rp, u->rplimit, XB_ptr, 0, defc, length, null);
|
||||||
|
CHECK;
|
||||||
} else {
|
} else {
|
||||||
NOT_PRODUCT(byte* meta_rp0 = u->meta_rp);
|
NOT_PRODUCT(byte* meta_rp0 = u->meta_rp);
|
||||||
assert(u->meta_rp != null);
|
assert(u->meta_rp != null);
|
||||||
|
@ -215,8 +217,19 @@ int band::getIntTotal() {
|
||||||
if (length == 0) return 0;
|
if (length == 0) return 0;
|
||||||
if (total_memo > 0) return total_memo-1;
|
if (total_memo > 0) return total_memo-1;
|
||||||
int total = getInt();
|
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--) {
|
for (int k = length-1; k > 0; k--) {
|
||||||
|
int prev_total = total;
|
||||||
total += vs[0].getInt();
|
total += vs[0].getInt();
|
||||||
|
if (total < prev_total) {
|
||||||
|
abort("overflow detected");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
rewind();
|
rewind();
|
||||||
total_memo = total+1;
|
total_memo = total+1;
|
||||||
|
|
|
@ -56,7 +56,7 @@ void bytes::realloc(size_t len_) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
byte* oldptr = ptr;
|
byte* oldptr = ptr;
|
||||||
ptr = (byte*)::realloc(ptr, len_+1);
|
ptr = (len_ >= PSIZE_MAX) ? null : (byte*)::realloc(ptr, len_+1);
|
||||||
if (ptr != null) {
|
if (ptr != null) {
|
||||||
mtrace('r', oldptr, 0);
|
mtrace('r', oldptr, 0);
|
||||||
mtrace('m', ptr, len_+1);
|
mtrace('m', ptr, len_+1);
|
||||||
|
@ -128,7 +128,7 @@ const char* bytes::string() {
|
||||||
// Make sure there are 'o' bytes beyond the fill pointer,
|
// Make sure there are 'o' bytes beyond the fill pointer,
|
||||||
// advance the fill pointer, and return the old fill pointer.
|
// advance the fill pointer, and return the old fill pointer.
|
||||||
byte* fillbytes::grow(size_t s) {
|
byte* fillbytes::grow(size_t s) {
|
||||||
size_t nlen = b.len+s;
|
size_t nlen = add_size(b.len, s);
|
||||||
if (nlen <= allocated) {
|
if (nlen <= allocated) {
|
||||||
b.len = nlen;
|
b.len = nlen;
|
||||||
return limit()-s;
|
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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -814,6 +814,7 @@ void coding_method::init(byte* &band_rp, byte* band_limit,
|
||||||
}
|
}
|
||||||
band_rp = vs.rp;
|
band_rp = vs.rp;
|
||||||
}
|
}
|
||||||
|
CHECK;
|
||||||
|
|
||||||
// Get an accurate upper limit now.
|
// Get an accurate upper limit now.
|
||||||
vs0.rplimit = band_rp;
|
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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -47,11 +47,13 @@
|
||||||
#define NOT_PRODUCT(xxx)
|
#define NOT_PRODUCT(xxx)
|
||||||
#define assert(p)
|
#define assert(p)
|
||||||
#define PRINTCR(args)
|
#define PRINTCR(args)
|
||||||
|
#define VERSION_STRING "%s version %s\n"
|
||||||
#else
|
#else
|
||||||
#define IF_PRODUCT(xxx)
|
#define IF_PRODUCT(xxx)
|
||||||
#define NOT_PRODUCT(xxx) xxx
|
#define NOT_PRODUCT(xxx) xxx
|
||||||
#define assert(p) ((p) || assert_failed(#p))
|
#define assert(p) ((p) || assert_failed(#p))
|
||||||
#define PRINTCR(args) u->verbose && u->printcr_if_verbose args
|
#define PRINTCR(args) u->verbose && u->printcr_if_verbose args
|
||||||
|
#define VERSION_STRING "%s version non-product %s\n"
|
||||||
extern "C" void breakpoint();
|
extern "C" void breakpoint();
|
||||||
extern int assert_failed(const char*);
|
extern int assert_failed(const char*);
|
||||||
#define BREAK (breakpoint())
|
#define BREAK (breakpoint())
|
||||||
|
@ -79,9 +81,9 @@ extern int assert_failed(const char*);
|
||||||
|
|
||||||
#define lengthof(array) (sizeof(array)/sizeof(array[0]))
|
#define lengthof(array) (sizeof(array)/sizeof(array[0]))
|
||||||
|
|
||||||
#define NEW(T, n) (T*) must_malloc((int)(sizeof(T)*(n)))
|
#define NEW(T, n) (T*) must_malloc((int)(scale_size(n, sizeof(T))))
|
||||||
#define U_NEW(T, n) (T*) u->alloc(sizeof(T)*(n))
|
#define U_NEW(T, n) (T*) u->alloc(scale_size(n, sizeof(T)))
|
||||||
#define T_NEW(T, n) (T*) u->temp_alloc(sizeof(T)*(n))
|
#define T_NEW(T, n) (T*) u->temp_alloc(scale_size(n, sizeof(T)))
|
||||||
|
|
||||||
|
|
||||||
// bytes and byte arrays
|
// 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_(y,p) _CHECK_DO((p)==null, return y)
|
||||||
#define CHECK_NULL_0(p) _CHECK_DO((p)==null, return 0)
|
#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_TRUE "true"
|
||||||
#define STR_FALSE "false"
|
#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 'J': argp += 1; break; // skip ignored -Jxxx parameter
|
||||||
|
|
||||||
case 'V':
|
case 'V':
|
||||||
fprintf(u.errstrm, "%s version %s\n", nbasename(argv[0]), sccsver);
|
fprintf(u.errstrm, VERSION_STRING, nbasename(argv[0]), sccsver);
|
||||||
exit(0);
|
exit(0);
|
||||||
|
|
||||||
case 'h':
|
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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -523,15 +523,39 @@ void unpacker::read_file_header() {
|
||||||
enum {
|
enum {
|
||||||
MAGIC_BYTES = 4,
|
MAGIC_BYTES = 4,
|
||||||
AH_LENGTH_0 = 3, //minver, majver, options are outside of archive_size
|
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)
|
AH_LENGTH = 26, //maximum archive header length (w/ all fields)
|
||||||
// Length contributions from optional header fields:
|
// Length contributions from optional header fields:
|
||||||
AH_FILE_HEADER_LEN = 5, // sizehi/lo/next/modtime/files
|
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_CP_NUMBER_LEN = 4, // int/float/long/double
|
||||||
AH_SPECIAL_FORMAT_LEN = 2, // layouts/band-headers
|
AH_SPECIAL_FORMAT_LEN = 2, // layouts/band-headers
|
||||||
AH_LENGTH_MIN = AH_LENGTH
|
AH_LENGTH_MIN = AH_LENGTH
|
||||||
-(AH_FILE_HEADER_LEN+AH_SPECIAL_FORMAT_LEN+AH_CP_NUMBER_LEN),
|
-(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
|
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);
|
bool foreign_buf = (read_input_fn == null);
|
||||||
byte initbuf[(int)FIRST_READ + (int)C_SLOP + 200]; // 200 is for JAR I/O
|
byte initbuf[(int)FIRST_READ + (int)C_SLOP + 200]; // 200 is for JAR I/O
|
||||||
if (foreign_buf) {
|
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.
|
// 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.
|
// Therefore, the caller must use only a bare minimum of read-ahead.
|
||||||
if (inbytes.len > FIRST_READ) {
|
if (inbytes.len > FIRST_READ) {
|
||||||
abort("too much pushback");
|
abort("too much read-ahead");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
input.set(initbuf, sizeof(initbuf));
|
input.set(initbuf, sizeof(initbuf));
|
||||||
|
@ -557,7 +581,7 @@ void unpacker::read_file_header() {
|
||||||
rplimit += inbytes.len;
|
rplimit += inbytes.len;
|
||||||
bytes_read += 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.
|
// but is certain not to overflow past the archive_header.
|
||||||
input.b.len = FIRST_READ;
|
input.b.len = FIRST_READ;
|
||||||
if (!ensure_input(FIRST_READ))
|
if (!ensure_input(FIRST_READ))
|
||||||
|
@ -630,25 +654,24 @@ void unpacker::read_file_header() {
|
||||||
if ((archive_options & ~OPTION_LIMIT) != 0) {
|
if ((archive_options & ~OPTION_LIMIT) != 0) {
|
||||||
fprintf(errstrm, "Warning: Illegal archive options 0x%x\n",
|
fprintf(errstrm, "Warning: Illegal archive options 0x%x\n",
|
||||||
archive_options);
|
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) {
|
if ((archive_options & AO_HAVE_FILE_HEADERS) != 0) {
|
||||||
uint hi = hdr.getInt();
|
uint hi = hdr.getInt();
|
||||||
uint lo = 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;
|
hdrVals += 2;
|
||||||
} else {
|
} else {
|
||||||
hdrValsSkipped += 2;
|
hdrValsSkipped += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (archive_size != (size_t)archive_size) {
|
|
||||||
// Silly size specified.
|
|
||||||
abort("archive too large");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now we can size the whole archive.
|
// Now we can size the whole archive.
|
||||||
// Read everything else into a mega-buffer.
|
// Read everything else into a mega-buffer.
|
||||||
rp = hdr.rp;
|
rp = hdr.rp;
|
||||||
|
@ -662,9 +685,18 @@ void unpacker::read_file_header() {
|
||||||
abort("EOF reading fixed input buffer");
|
abort("EOF reading fixed input buffer");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else if (archive_size > 0) {
|
} else if (archive_size != 0) {
|
||||||
input.set(U_NEW(byte, (size_t)(header_size_0 + archive_size + C_SLOP)),
|
if (archive_size < ARCHIVE_SIZE_MIN) {
|
||||||
(size_t) header_size_0 + (size_t)archive_size);
|
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);
|
assert(input.limit()[0] == 0);
|
||||||
// Move all the bytes we read initially into the real buffer.
|
// Move all the bytes we read initially into the real buffer.
|
||||||
input.b.copyFrom(initbuf, header_size);
|
input.b.copyFrom(initbuf, header_size);
|
||||||
|
@ -673,17 +705,17 @@ void unpacker::read_file_header() {
|
||||||
} else {
|
} else {
|
||||||
// It's more complicated and painful.
|
// It's more complicated and painful.
|
||||||
// A zero archive_size means that we must read until EOF.
|
// A zero archive_size means that we must read until EOF.
|
||||||
assert(archive_size == 0);
|
|
||||||
input.init(CHUNK*2);
|
input.init(CHUNK*2);
|
||||||
CHECK;
|
CHECK;
|
||||||
input.b.len = input.allocated;
|
input.b.len = input.allocated;
|
||||||
rp = rplimit = input.base();
|
rp = rplimit = input.base();
|
||||||
// Set up input buffer as if we already read the header:
|
// Set up input buffer as if we already read the header:
|
||||||
input.b.copyFrom(initbuf, header_size);
|
input.b.copyFrom(initbuf, header_size);
|
||||||
|
CHECK;
|
||||||
rplimit += header_size;
|
rplimit += header_size;
|
||||||
while (ensure_input(input.limit() - rp)) {
|
while (ensure_input(input.limit() - rp)) {
|
||||||
size_t dataSoFar = input_remaining();
|
size_t dataSoFar = input_remaining();
|
||||||
size_t nextSize = dataSoFar + CHUNK;
|
size_t nextSize = add_size(dataSoFar, CHUNK);
|
||||||
input.ensureSize(nextSize);
|
input.ensureSize(nextSize);
|
||||||
CHECK;
|
CHECK;
|
||||||
input.b.len = input.allocated;
|
input.b.len = input.allocated;
|
||||||
|
@ -715,8 +747,10 @@ void unpacker::read_file_header() {
|
||||||
|
|
||||||
if ((archive_options & AO_HAVE_FILE_HEADERS) != 0) {
|
if ((archive_options & AO_HAVE_FILE_HEADERS) != 0) {
|
||||||
archive_next_count = hdr.getInt();
|
archive_next_count = hdr.getInt();
|
||||||
|
CHECK_COUNT(archive_next_count);
|
||||||
archive_modtime = hdr.getInt();
|
archive_modtime = hdr.getInt();
|
||||||
file_count = hdr.getInt();
|
file_count = hdr.getInt();
|
||||||
|
CHECK_COUNT(file_count);
|
||||||
hdrVals += 3;
|
hdrVals += 3;
|
||||||
} else {
|
} else {
|
||||||
hdrValsSkipped += 3;
|
hdrValsSkipped += 3;
|
||||||
|
@ -724,7 +758,9 @@ void unpacker::read_file_header() {
|
||||||
|
|
||||||
if ((archive_options & AO_HAVE_SPECIAL_FORMATS) != 0) {
|
if ((archive_options & AO_HAVE_SPECIAL_FORMATS) != 0) {
|
||||||
band_headers_size = hdr.getInt();
|
band_headers_size = hdr.getInt();
|
||||||
|
CHECK_COUNT(band_headers_size);
|
||||||
attr_definition_count = hdr.getInt();
|
attr_definition_count = hdr.getInt();
|
||||||
|
CHECK_COUNT(attr_definition_count);
|
||||||
hdrVals += 2;
|
hdrVals += 2;
|
||||||
} else {
|
} else {
|
||||||
hdrValsSkipped += 2;
|
hdrValsSkipped += 2;
|
||||||
|
@ -744,13 +780,16 @@ void unpacker::read_file_header() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cp_counts[k] = hdr.getInt();
|
cp_counts[k] = hdr.getInt();
|
||||||
|
CHECK_COUNT(cp_counts[k]);
|
||||||
hdrVals += 1;
|
hdrVals += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ic_count = hdr.getInt();
|
ic_count = hdr.getInt();
|
||||||
|
CHECK_COUNT(ic_count);
|
||||||
default_class_minver = hdr.getInt();
|
default_class_minver = hdr.getInt();
|
||||||
default_class_majver = hdr.getInt();
|
default_class_majver = hdr.getInt();
|
||||||
class_count = hdr.getInt();
|
class_count = hdr.getInt();
|
||||||
|
CHECK_COUNT(class_count);
|
||||||
hdrVals += 4;
|
hdrVals += 4;
|
||||||
|
|
||||||
// done with archive_header
|
// done with archive_header
|
||||||
|
@ -807,7 +846,6 @@ void unpacker::read_file_header() {
|
||||||
bytes::of(band_headers.limit(), C_SLOP).clear(_meta_error);
|
bytes::of(band_headers.limit(), C_SLOP).clear(_meta_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void unpacker::finish() {
|
void unpacker::finish() {
|
||||||
if (verbose >= 1) {
|
if (verbose >= 1) {
|
||||||
fprintf(errstrm,
|
fprintf(errstrm,
|
||||||
|
@ -2117,6 +2155,7 @@ void unpacker::read_classes() {
|
||||||
|
|
||||||
field_descr.readData(field_count);
|
field_descr.readData(field_count);
|
||||||
read_attrs(ATTR_CONTEXT_FIELD, field_count);
|
read_attrs(ATTR_CONTEXT_FIELD, field_count);
|
||||||
|
CHECK;
|
||||||
|
|
||||||
method_descr.readData(method_count);
|
method_descr.readData(method_count);
|
||||||
read_attrs(ATTR_CONTEXT_METHOD, method_count);
|
read_attrs(ATTR_CONTEXT_METHOD, method_count);
|
||||||
|
@ -2124,6 +2163,7 @@ void unpacker::read_classes() {
|
||||||
CHECK;
|
CHECK;
|
||||||
|
|
||||||
read_attrs(ATTR_CONTEXT_CLASS, class_count);
|
read_attrs(ATTR_CONTEXT_CLASS, class_count);
|
||||||
|
CHECK;
|
||||||
|
|
||||||
read_code_headers();
|
read_code_headers();
|
||||||
|
|
||||||
|
@ -2150,10 +2190,12 @@ void unpacker::read_attrs(int attrc, int obj_count) {
|
||||||
assert(endsWith(xxx_flags_hi.name, "_flags_hi"));
|
assert(endsWith(xxx_flags_hi.name, "_flags_hi"));
|
||||||
if (haveLongFlags)
|
if (haveLongFlags)
|
||||||
xxx_flags_hi.readData(obj_count);
|
xxx_flags_hi.readData(obj_count);
|
||||||
|
CHECK;
|
||||||
|
|
||||||
band& xxx_flags_lo = ad.xxx_flags_lo();
|
band& xxx_flags_lo = ad.xxx_flags_lo();
|
||||||
assert(endsWith(xxx_flags_lo.name, "_flags_lo"));
|
assert(endsWith(xxx_flags_lo.name, "_flags_lo"));
|
||||||
xxx_flags_lo.readData(obj_count);
|
xxx_flags_lo.readData(obj_count);
|
||||||
|
CHECK;
|
||||||
|
|
||||||
// pre-scan flags, counting occurrences of each index bit
|
// pre-scan flags, counting occurrences of each index bit
|
||||||
julong indexMask = ad.flagIndexMask(); // which flag bits are index bits?
|
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"));
|
assert(endsWith(xxx_attr_count.name, "_attr_count"));
|
||||||
// There is one count element for each 1<<16 bit set in flags:
|
// There is one count element for each 1<<16 bit set in flags:
|
||||||
xxx_attr_count.readData(ad.predefCount(X_ATTR_OVERFLOW));
|
xxx_attr_count.readData(ad.predefCount(X_ATTR_OVERFLOW));
|
||||||
|
CHECK;
|
||||||
|
|
||||||
band& xxx_attr_indexes = ad.xxx_attr_indexes();
|
band& xxx_attr_indexes = ad.xxx_attr_indexes();
|
||||||
assert(endsWith(xxx_attr_indexes.name, "_attr_indexes"));
|
assert(endsWith(xxx_attr_indexes.name, "_attr_indexes"));
|
||||||
int overflowIndexCount = xxx_attr_count.getIntTotal();
|
int overflowIndexCount = xxx_attr_count.getIntTotal();
|
||||||
xxx_attr_indexes.readData(overflowIndexCount);
|
xxx_attr_indexes.readData(overflowIndexCount);
|
||||||
|
CHECK;
|
||||||
// pre-scan attr indexes, counting occurrences of each value
|
// pre-scan attr indexes, counting occurrences of each value
|
||||||
for (i = 0; i < overflowIndexCount; i++) {
|
for (i = 0; i < overflowIndexCount; i++) {
|
||||||
idx = xxx_attr_indexes.getInt();
|
idx = xxx_attr_indexes.getInt();
|
||||||
|
@ -2211,6 +2255,7 @@ void unpacker::read_attrs(int attrc, int obj_count) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ad.xxx_attr_calls().readData(backwardCounts);
|
ad.xxx_attr_calls().readData(backwardCounts);
|
||||||
|
CHECK;
|
||||||
|
|
||||||
// Read built-in bands.
|
// Read built-in bands.
|
||||||
// Mostly, these are hand-coded equivalents to readBandData().
|
// 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);
|
count = ad.predefCount(CLASS_ATTR_SourceFile);
|
||||||
class_SourceFile_RUN.readData(count);
|
class_SourceFile_RUN.readData(count);
|
||||||
|
CHECK;
|
||||||
|
|
||||||
count = ad.predefCount(CLASS_ATTR_EnclosingMethod);
|
count = ad.predefCount(CLASS_ATTR_EnclosingMethod);
|
||||||
class_EnclosingMethod_RC.readData(count);
|
class_EnclosingMethod_RC.readData(count);
|
||||||
class_EnclosingMethod_RDN.readData(count);
|
class_EnclosingMethod_RDN.readData(count);
|
||||||
|
CHECK;
|
||||||
|
|
||||||
count = ad.predefCount(X_ATTR_Signature);
|
count = ad.predefCount(X_ATTR_Signature);
|
||||||
class_Signature_RS.readData(count);
|
class_Signature_RS.readData(count);
|
||||||
|
CHECK;
|
||||||
|
|
||||||
ad.readBandData(X_ATTR_RuntimeVisibleAnnotations);
|
ad.readBandData(X_ATTR_RuntimeVisibleAnnotations);
|
||||||
ad.readBandData(X_ATTR_RuntimeInvisibleAnnotations);
|
ad.readBandData(X_ATTR_RuntimeInvisibleAnnotations);
|
||||||
|
|
||||||
count = ad.predefCount(CLASS_ATTR_InnerClasses);
|
count = ad.predefCount(CLASS_ATTR_InnerClasses);
|
||||||
class_InnerClasses_N.readData(count);
|
class_InnerClasses_N.readData(count);
|
||||||
|
CHECK;
|
||||||
|
|
||||||
count = class_InnerClasses_N.getIntTotal();
|
count = class_InnerClasses_N.getIntTotal();
|
||||||
class_InnerClasses_RC.readData(count);
|
class_InnerClasses_RC.readData(count);
|
||||||
class_InnerClasses_F.readData(count);
|
class_InnerClasses_F.readData(count);
|
||||||
|
CHECK;
|
||||||
// Drop remaining columns wherever flags are zero:
|
// Drop remaining columns wherever flags are zero:
|
||||||
count -= class_InnerClasses_F.getIntCount(0);
|
count -= class_InnerClasses_F.getIntCount(0);
|
||||||
class_InnerClasses_outer_RCN.readData(count);
|
class_InnerClasses_outer_RCN.readData(count);
|
||||||
class_InnerClasses_name_RUN.readData(count);
|
class_InnerClasses_name_RUN.readData(count);
|
||||||
|
CHECK;
|
||||||
|
|
||||||
count = ad.predefCount(CLASS_ATTR_ClassFile_version);
|
count = ad.predefCount(CLASS_ATTR_ClassFile_version);
|
||||||
class_ClassFile_version_minor_H.readData(count);
|
class_ClassFile_version_minor_H.readData(count);
|
||||||
class_ClassFile_version_major_H.readData(count);
|
class_ClassFile_version_major_H.readData(count);
|
||||||
|
CHECK;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ATTR_CONTEXT_FIELD:
|
case ATTR_CONTEXT_FIELD:
|
||||||
|
|
||||||
count = ad.predefCount(FIELD_ATTR_ConstantValue);
|
count = ad.predefCount(FIELD_ATTR_ConstantValue);
|
||||||
field_ConstantValue_KQ.readData(count);
|
field_ConstantValue_KQ.readData(count);
|
||||||
|
CHECK;
|
||||||
|
|
||||||
count = ad.predefCount(X_ATTR_Signature);
|
count = ad.predefCount(X_ATTR_Signature);
|
||||||
field_Signature_RS.readData(count);
|
field_Signature_RS.readData(count);
|
||||||
|
CHECK;
|
||||||
|
|
||||||
ad.readBandData(X_ATTR_RuntimeVisibleAnnotations);
|
ad.readBandData(X_ATTR_RuntimeVisibleAnnotations);
|
||||||
ad.readBandData(X_ATTR_RuntimeInvisibleAnnotations);
|
ad.readBandData(X_ATTR_RuntimeInvisibleAnnotations);
|
||||||
|
CHECK;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ATTR_CONTEXT_METHOD:
|
case ATTR_CONTEXT_METHOD:
|
||||||
|
@ -2266,15 +2322,18 @@ void unpacker::read_attrs(int attrc, int obj_count) {
|
||||||
method_Exceptions_N.readData(count);
|
method_Exceptions_N.readData(count);
|
||||||
count = method_Exceptions_N.getIntTotal();
|
count = method_Exceptions_N.getIntTotal();
|
||||||
method_Exceptions_RC.readData(count);
|
method_Exceptions_RC.readData(count);
|
||||||
|
CHECK;
|
||||||
|
|
||||||
count = ad.predefCount(X_ATTR_Signature);
|
count = ad.predefCount(X_ATTR_Signature);
|
||||||
method_Signature_RS.readData(count);
|
method_Signature_RS.readData(count);
|
||||||
|
CHECK;
|
||||||
|
|
||||||
ad.readBandData(X_ATTR_RuntimeVisibleAnnotations);
|
ad.readBandData(X_ATTR_RuntimeVisibleAnnotations);
|
||||||
ad.readBandData(X_ATTR_RuntimeInvisibleAnnotations);
|
ad.readBandData(X_ATTR_RuntimeInvisibleAnnotations);
|
||||||
ad.readBandData(METHOD_ATTR_RuntimeVisibleParameterAnnotations);
|
ad.readBandData(METHOD_ATTR_RuntimeVisibleParameterAnnotations);
|
||||||
ad.readBandData(METHOD_ATTR_RuntimeInvisibleParameterAnnotations);
|
ad.readBandData(METHOD_ATTR_RuntimeInvisibleParameterAnnotations);
|
||||||
ad.readBandData(METHOD_ATTR_AnnotationDefault);
|
ad.readBandData(METHOD_ATTR_AnnotationDefault);
|
||||||
|
CHECK;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ATTR_CONTEXT_CODE:
|
case ATTR_CONTEXT_CODE:
|
||||||
|
@ -2286,8 +2345,10 @@ void unpacker::read_attrs(int attrc, int obj_count) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
code_StackMapTable_N.readData(count);
|
code_StackMapTable_N.readData(count);
|
||||||
|
CHECK;
|
||||||
count = code_StackMapTable_N.getIntTotal();
|
count = code_StackMapTable_N.getIntTotal();
|
||||||
code_StackMapTable_frame_T.readData(count);
|
code_StackMapTable_frame_T.readData(count);
|
||||||
|
CHECK;
|
||||||
// the rest of it depends in a complicated way on frame tags
|
// the rest of it depends in a complicated way on frame tags
|
||||||
{
|
{
|
||||||
int fat_frame_count = 0;
|
int fat_frame_count = 0;
|
||||||
|
@ -2321,18 +2382,23 @@ void unpacker::read_attrs(int attrc, int obj_count) {
|
||||||
// deal completely with fat frames:
|
// deal completely with fat frames:
|
||||||
offset_count += fat_frame_count;
|
offset_count += fat_frame_count;
|
||||||
code_StackMapTable_local_N.readData(fat_frame_count);
|
code_StackMapTable_local_N.readData(fat_frame_count);
|
||||||
|
CHECK;
|
||||||
type_count += code_StackMapTable_local_N.getIntTotal();
|
type_count += code_StackMapTable_local_N.getIntTotal();
|
||||||
code_StackMapTable_stack_N.readData(fat_frame_count);
|
code_StackMapTable_stack_N.readData(fat_frame_count);
|
||||||
type_count += code_StackMapTable_stack_N.getIntTotal();
|
type_count += code_StackMapTable_stack_N.getIntTotal();
|
||||||
|
CHECK;
|
||||||
// read the rest:
|
// read the rest:
|
||||||
code_StackMapTable_offset.readData(offset_count);
|
code_StackMapTable_offset.readData(offset_count);
|
||||||
code_StackMapTable_T.readData(type_count);
|
code_StackMapTable_T.readData(type_count);
|
||||||
|
CHECK;
|
||||||
// (7) [RCH]
|
// (7) [RCH]
|
||||||
count = code_StackMapTable_T.getIntCount(7);
|
count = code_StackMapTable_T.getIntCount(7);
|
||||||
code_StackMapTable_RC.readData(count);
|
code_StackMapTable_RC.readData(count);
|
||||||
|
CHECK;
|
||||||
// (8) [PH]
|
// (8) [PH]
|
||||||
count = code_StackMapTable_T.getIntCount(8);
|
count = code_StackMapTable_T.getIntCount(8);
|
||||||
code_StackMapTable_P.readData(count);
|
code_StackMapTable_P.readData(count);
|
||||||
|
CHECK;
|
||||||
}
|
}
|
||||||
|
|
||||||
count = ad.predefCount(CODE_ATTR_LineNumberTable);
|
count = ad.predefCount(CODE_ATTR_LineNumberTable);
|
||||||
|
@ -2654,6 +2720,7 @@ void unpacker::read_code_headers() {
|
||||||
code_max_na_locals.readData();
|
code_max_na_locals.readData();
|
||||||
code_handler_count.readData();
|
code_handler_count.readData();
|
||||||
totalHandlerCount += code_handler_count.getIntTotal();
|
totalHandlerCount += code_handler_count.getIntTotal();
|
||||||
|
CHECK;
|
||||||
|
|
||||||
// Read handler specifications.
|
// Read handler specifications.
|
||||||
// Cf. PackageReader.readCodeHandlers.
|
// Cf. PackageReader.readCodeHandlers.
|
||||||
|
@ -2661,8 +2728,10 @@ void unpacker::read_code_headers() {
|
||||||
code_handler_end_PO.readData(totalHandlerCount);
|
code_handler_end_PO.readData(totalHandlerCount);
|
||||||
code_handler_catch_PO.readData(totalHandlerCount);
|
code_handler_catch_PO.readData(totalHandlerCount);
|
||||||
code_handler_class_RCN.readData(totalHandlerCount);
|
code_handler_class_RCN.readData(totalHandlerCount);
|
||||||
|
CHECK;
|
||||||
|
|
||||||
read_attrs(ATTR_CONTEXT_CODE, totalFlagsCount);
|
read_attrs(ATTR_CONTEXT_CODE, totalFlagsCount);
|
||||||
|
CHECK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool is_in_range(uint n, uint min, uint max) {
|
static inline bool is_in_range(uint n, uint min, uint max) {
|
||||||
|
|
|
@ -204,7 +204,7 @@ struct unpacker {
|
||||||
|
|
||||||
// archive header fields
|
// archive header fields
|
||||||
int magic, minver, majver;
|
int magic, minver, majver;
|
||||||
julong archive_size;
|
size_t archive_size;
|
||||||
int archive_next_count, archive_options, archive_modtime;
|
int archive_next_count, archive_options, archive_modtime;
|
||||||
int band_headers_size;
|
int band_headers_size;
|
||||||
int file_count, attr_definition_count, ic_count, class_count;
|
int file_count, attr_definition_count, ic_count, class_count;
|
||||||
|
|
|
@ -46,14 +46,13 @@
|
||||||
|
|
||||||
#include "unpack.h"
|
#include "unpack.h"
|
||||||
|
|
||||||
void* must_malloc(int size) {
|
void* must_malloc(size_t size) {
|
||||||
int msize = size;
|
size_t msize = size;
|
||||||
assert(size >= 0);
|
|
||||||
#ifdef USE_MTRACE
|
#ifdef USE_MTRACE
|
||||||
if (msize < sizeof(int))
|
if (msize >= 0 && msize < sizeof(int))
|
||||||
msize = sizeof(int); // see 0xbaadf00d below
|
msize = sizeof(int); // see 0xbaadf00d below
|
||||||
#endif
|
#endif
|
||||||
void* ptr = malloc(msize);
|
void* ptr = (msize > PSIZE_MAX) ? null : malloc(msize);
|
||||||
if (ptr != null) {
|
if (ptr != null) {
|
||||||
memset(ptr, 0, size);
|
memset(ptr, 0, size);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -25,13 +25,31 @@
|
||||||
|
|
||||||
//Definitions of our util functions
|
//Definitions of our util functions
|
||||||
|
|
||||||
void* must_malloc(int size);
|
void* must_malloc(size_t size);
|
||||||
#ifndef USE_MTRACE
|
#ifndef USE_MTRACE
|
||||||
#define mtrace(c, ptr, size)
|
#define mtrace(c, ptr, size)
|
||||||
#else
|
#else
|
||||||
void mtrace(char c, void* ptr, size_t size);
|
void mtrace(char c, void* ptr, size_t size);
|
||||||
#endif
|
#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,
|
// These may be expensive, because they have to go via Java TSD,
|
||||||
// if the optional u argument is missing.
|
// if the optional u argument is missing.
|
||||||
struct unpacker;
|
struct unpacker;
|
||||||
|
|
|
@ -722,6 +722,10 @@ DGifSetupDecompress(GifFileType * GifFile) {
|
||||||
GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
|
GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
|
||||||
|
|
||||||
READ(GifFile, &CodeSize, 1); /* Read Code size from file. */
|
READ(GifFile, &CodeSize, 1); /* Read Code size from file. */
|
||||||
|
if (CodeSize >= 12) {
|
||||||
|
/* Invalid initial code size: report failure */
|
||||||
|
return GIF_ERROR;
|
||||||
|
}
|
||||||
BitsPerPixel = CodeSize;
|
BitsPerPixel = CodeSize;
|
||||||
|
|
||||||
Private->Buf[0] = 0; /* Input Buffer empty. */
|
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
|
/* If code cannot fit into RunningBits bits, must raise its size. Note
|
||||||
* however that codes above 4095 are used for special signaling. */
|
* however that codes above 4095 are used for special signaling. */
|
||||||
if (++Private->RunningCode > Private->MaxCode1 &&
|
if (++Private->RunningCode > Private->MaxCode1) {
|
||||||
Private->RunningBits < LZ_BITS) {
|
if (Private->RunningBits < LZ_BITS) {
|
||||||
Private->MaxCode1 <<= 1;
|
Private->MaxCode1 <<= 1;
|
||||||
Private->RunningBits++;
|
Private->RunningBits++;
|
||||||
|
} else {
|
||||||
|
Private->RunningCode = Private->MaxCode1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return GIF_OK;
|
return GIF_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -191,6 +191,11 @@ Java_sun_awt_image_GifImageDecoder_parseImage(JNIEnv *env,
|
||||||
int passht = passinc;
|
int passht = passinc;
|
||||||
int len;
|
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
|
if (blockh == 0 || raslineh == 0
|
||||||
|| prefixh == 0 || suffixh == 0
|
|| prefixh == 0 || suffixh == 0
|
||||||
|| outCodeh == 0)
|
|| outCodeh == 0)
|
||||||
|
|
|
@ -216,6 +216,16 @@ printMedialibError(int status) {
|
||||||
|
|
||||||
#endif /* ! DEBUG */
|
#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 *
|
* 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;
|
cmask = (1<<src->channels)-1;
|
||||||
status = (*sMlibFns[MLIB_CONVMxN].fptr)(dst, src, kdata, w, h,
|
status = (*sMlibFns[MLIB_CONVMxN].fptr)(dst, src, kdata, w, h,
|
||||||
(w-1)/2, (h-1)/2, scale, cmask,
|
(w-1)/2, (h-1)/2, scale, cmask,
|
||||||
MLIB_EDGE_DST_NO_WRITE);
|
getMlibEdgeHint(edgeHint));
|
||||||
|
|
||||||
if (status != MLIB_SUCCESS) {
|
if (status != MLIB_SUCCESS) {
|
||||||
printMedialibError(status);
|
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;
|
cmask = (1<<src->channels)-1;
|
||||||
status = (*sMlibFns[MLIB_CONVMxN].fptr)(dst, src, kdata, w, h,
|
status = (*sMlibFns[MLIB_CONVMxN].fptr)(dst, src, kdata, w, h,
|
||||||
(w-1)/2, (h-1)/2, scale, cmask,
|
(w-1)/2, (h-1)/2, scale, cmask,
|
||||||
MLIB_EDGE_DST_NO_WRITE);
|
getMlibEdgeHint(edgeHint));
|
||||||
|
|
||||||
if (status != MLIB_SUCCESS) {
|
if (status != MLIB_SUCCESS) {
|
||||||
printMedialibError(status);
|
printMedialibError(status);
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
/* here come some very simple macros */
|
/* here come some very simple macros */
|
||||||
|
|
||||||
/* advance a pointer p by sizeof(type)*n bytes */
|
/* 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) */
|
/* advance a pointer by sizeof(type) */
|
||||||
#define INCP(type,p) INCPN(type,(p),1)
|
#define INCP(type,p) INCPN(type,(p),1)
|
||||||
|
|
|
@ -62,6 +62,15 @@ SplashStreamGifInputFunc(GifFileType * gif, GifByteType * buf, int n)
|
||||||
return rc;
|
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
|
int
|
||||||
SplashDecodeGif(Splash * splash, GifFileType * gif)
|
SplashDecodeGif(Splash * splash, GifFileType * gif)
|
||||||
{
|
{
|
||||||
|
@ -70,6 +79,7 @@ SplashDecodeGif(Splash * splash, GifFileType * gif)
|
||||||
byte_t *pBitmapBits, *pOldBitmapBits;
|
byte_t *pBitmapBits, *pOldBitmapBits;
|
||||||
int i, j;
|
int i, j;
|
||||||
int imageIndex;
|
int imageIndex;
|
||||||
|
int cx, cy, cw, ch; /* clamped coordinates */
|
||||||
const int interlacedOffset[] = { 0, 4, 2, 1, 0 }; /* The way Interlaced image should. */
|
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... */
|
const int interlacedJumps[] = { 8, 8, 4, 2, 1 }; /* be read - offsets and jumps... */
|
||||||
|
|
||||||
|
@ -79,14 +89,31 @@ SplashDecodeGif(Splash * splash, GifFileType * gif)
|
||||||
|
|
||||||
SplashCleanup(splash);
|
SplashCleanup(splash);
|
||||||
|
|
||||||
|
if (!SAFE_TO_ALLOC(gif->SWidth, splash->imageFormat.depthBytes)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
stride = gif->SWidth * splash->imageFormat.depthBytes;
|
stride = gif->SWidth * splash->imageFormat.depthBytes;
|
||||||
if (splash->byteAlignment > 1)
|
if (splash->byteAlignment > 1)
|
||||||
stride =
|
stride =
|
||||||
(stride + splash->byteAlignment - 1) & ~(splash->byteAlignment - 1);
|
(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;
|
bufferSize = stride * gif->SHeight;
|
||||||
pBitmapBits = (byte_t *) malloc(bufferSize);
|
pBitmapBits = (byte_t *) malloc(bufferSize);
|
||||||
|
if (!pBitmapBits) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
pOldBitmapBits = (byte_t *) malloc(bufferSize);
|
pOldBitmapBits = (byte_t *) malloc(bufferSize);
|
||||||
|
if (!pOldBitmapBits) {
|
||||||
|
free(pBitmapBits);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
memset(pBitmapBits, 0, bufferSize);
|
memset(pBitmapBits, 0, bufferSize);
|
||||||
|
|
||||||
splash->width = gif->SWidth;
|
splash->width = gif->SWidth;
|
||||||
|
@ -94,6 +121,11 @@ SplashDecodeGif(Splash * splash, GifFileType * gif)
|
||||||
splash->frameCount = gif->ImageCount;
|
splash->frameCount = gif->ImageCount;
|
||||||
splash->frames = (SplashImage *)
|
splash->frames = (SplashImage *)
|
||||||
malloc(sizeof(SplashImage) * gif->ImageCount);
|
malloc(sizeof(SplashImage) * gif->ImageCount);
|
||||||
|
if (!splash->frames) {
|
||||||
|
free(pBitmapBits);
|
||||||
|
free(pOldBitmapBits);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
memset(splash->frames, 0, sizeof(SplashImage) * gif->ImageCount);
|
memset(splash->frames, 0, sizeof(SplashImage) * gif->ImageCount);
|
||||||
splash->loopCount = 1;
|
splash->loopCount = 1;
|
||||||
|
|
||||||
|
@ -109,6 +141,11 @@ SplashDecodeGif(Splash * splash, GifFileType * gif)
|
||||||
int colorCount = 0;
|
int colorCount = 0;
|
||||||
rgbquad_t colorMapBuf[SPLASH_COLOR_MAP_SIZE];
|
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) {
|
||||||
if (colorMap->ColorCount <= SPLASH_COLOR_MAP_SIZE) {
|
if (colorMap->ColorCount <= SPLASH_COLOR_MAP_SIZE) {
|
||||||
colorCount = colorMap->ColorCount;
|
colorCount = colorMap->ColorCount;
|
||||||
|
@ -195,20 +232,35 @@ SplashDecodeGif(Splash * splash, GifFileType * gif)
|
||||||
for (; pass < npass; ++pass) {
|
for (; pass < npass; ++pass) {
|
||||||
int jump = interlacedJumps[pass];
|
int jump = interlacedJumps[pass];
|
||||||
int ofs = interlacedOffset[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,
|
initRect(&srcRect, 0, 0, desc->Width, numLines, 1,
|
||||||
desc->Width, pSrc, &srcFormat);
|
desc->Width, pSrc, &srcFormat);
|
||||||
initRect(&dstRect, desc->Left, desc->Top + ofs, desc->Width,
|
|
||||||
|
if (numLines > 0) {
|
||||||
|
initRect(&dstRect, cx, cy + ofs, cw,
|
||||||
numLines , jump, stride, pBitmapBits, &splash->imageFormat);
|
numLines , jump, stride, pBitmapBits, &splash->imageFormat);
|
||||||
|
|
||||||
pSrc += convertRect(&srcRect, &dstRect, CVT_ALPHATEST);
|
pSrc += convertRect(&srcRect, &dstRect, CVT_ALPHATEST);
|
||||||
}
|
}
|
||||||
|
// skip extra source data
|
||||||
|
pSrc += (numPassLines - numLines) * srcRect.stride;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// now dispose of the previous frame correctly
|
// now dispose of the previous frame correctly
|
||||||
|
|
||||||
splash->frames[imageIndex].bitmapBits =
|
splash->frames[imageIndex].bitmapBits =
|
||||||
(rgbquad_t *) malloc(bufferSize);
|
(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);
|
memcpy(splash->frames[imageIndex].bitmapBits, pBitmapBits, bufferSize);
|
||||||
|
|
||||||
SplashInitFrameShape(splash, imageIndex);
|
SplashInitFrameShape(splash, imageIndex);
|
||||||
|
@ -224,27 +276,29 @@ SplashDecodeGif(Splash * splash, GifFileType * gif)
|
||||||
{
|
{
|
||||||
ImageRect dstRect;
|
ImageRect dstRect;
|
||||||
rgbquad_t fillColor = 0; // 0 is transparent
|
rgbquad_t fillColor = 0; // 0 is transparent
|
||||||
if (transparentColor < 0) {
|
|
||||||
|
if (transparentColor > 0) {
|
||||||
fillColor= MAKE_QUAD_GIF(
|
fillColor= MAKE_QUAD_GIF(
|
||||||
colorMap->Colors[gif->SBackGroundColor], 0xff);
|
colorMap->Colors[gif->SBackGroundColor], 0xff);
|
||||||
}
|
}
|
||||||
initRect(&dstRect, desc->Left, desc->Top,
|
initRect(&dstRect,
|
||||||
desc->Width, desc->Height, 1, stride,
|
cx, cy, cw, ch,
|
||||||
|
1, stride,
|
||||||
pBitmapBits, &splash->imageFormat);
|
pBitmapBits, &splash->imageFormat);
|
||||||
fillRect(fillColor, &dstRect);
|
fillRect(fillColor, &dstRect);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GIF_DISPOSE_RESTORE:
|
case GIF_DISPOSE_RESTORE:
|
||||||
{
|
{
|
||||||
|
int lineSize = cw * splash->imageFormat.depthBytes;
|
||||||
int lineSize = desc->Width * splash->imageFormat.depthBytes;
|
if (lineSize > 0) {
|
||||||
|
int lineOffset = cx * splash->imageFormat.depthBytes;
|
||||||
for (j = 0; j < desc->Height; j++) {
|
int lineIndex = cy * stride + lineOffset;
|
||||||
int lineIndex = stride * (j + desc->Top) +
|
for (j=0; j<ch; j++) {
|
||||||
desc->Left * splash->imageFormat.depthBytes;
|
|
||||||
|
|
||||||
memcpy(pBitmapBits + lineIndex, pOldBitmapBits + lineIndex,
|
memcpy(pBitmapBits + lineIndex, pOldBitmapBits + lineIndex,
|
||||||
lineSize);
|
lineSize);
|
||||||
|
lineIndex += stride;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -155,6 +155,10 @@ int BitmapToYXBandedRectangles(ImageRect * pSrcRect, RECT_T * out);
|
||||||
|
|
||||||
void SplashInitFrameShape(Splash * splash, int imageIndex);
|
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
|
#define dbgprintf printf
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -103,9 +103,17 @@ SplashDecodePng(Splash * splash, png_rw_ptr read_func, void *io_ptr)
|
||||||
|
|
||||||
rowbytes = png_get_rowbytes(png_ptr, info_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) {
|
if ((image_data = (unsigned char *) malloc(rowbytes * height)) == NULL) {
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!SAFE_TO_ALLOC(height, sizeof(png_bytep))) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
if ((row_pointers = (png_bytepp) malloc(height * sizeof(png_bytep)))
|
if ((row_pointers = (png_bytepp) malloc(height * sizeof(png_bytep)))
|
||||||
== NULL) {
|
== NULL) {
|
||||||
goto done;
|
goto done;
|
||||||
|
@ -121,13 +129,28 @@ SplashDecodePng(Splash * splash, png_rw_ptr read_func, void *io_ptr)
|
||||||
splash->width = width;
|
splash->width = width;
|
||||||
splash->height = height;
|
splash->height = height;
|
||||||
|
|
||||||
|
if (!SAFE_TO_ALLOC(splash->width, splash->imageFormat.depthBytes)) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
stride = splash->width * splash->imageFormat.depthBytes;
|
stride = splash->width * splash->imageFormat.depthBytes;
|
||||||
|
|
||||||
|
if (!SAFE_TO_ALLOC(splash->height, stride)) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
splash->frameCount = 1;
|
splash->frameCount = 1;
|
||||||
splash->frames = (SplashImage *)
|
splash->frames = (SplashImage *)
|
||||||
malloc(sizeof(SplashImage) * splash->frameCount);
|
malloc(sizeof(SplashImage) * splash->frameCount);
|
||||||
|
|
||||||
|
if (splash->frames == NULL) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
splash->loopCount = 1;
|
splash->loopCount = 1;
|
||||||
splash->frames[0].bitmapBits = malloc(stride * splash->height);
|
splash->frames[0].bitmapBits = malloc(stride * splash->height);
|
||||||
|
if (splash->frames[0].bitmapBits == NULL) {
|
||||||
|
free(splash->frames);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
splash->frames[0].delay = 0;
|
splash->frames[0].delay = 0;
|
||||||
|
|
||||||
/* FIXME: sort out the real format */
|
/* 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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -31,6 +31,7 @@ import java.security.spec.AlgorithmParameterSpec;
|
||||||
import java.security.spec.RSAKeyGenParameterSpec;
|
import java.security.spec.RSAKeyGenParameterSpec;
|
||||||
|
|
||||||
import sun.security.jca.JCAUtil;
|
import sun.security.jca.JCAUtil;
|
||||||
|
import sun.security.rsa.RSAKeyFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RSA keypair generator.
|
* RSA keypair generator.
|
||||||
|
@ -43,8 +44,8 @@ import sun.security.jca.JCAUtil;
|
||||||
public final class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
|
public final class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
|
||||||
|
|
||||||
// Supported by Microsoft Base, Strong and Enhanced Cryptographic Providers
|
// Supported by Microsoft Base, Strong and Enhanced Cryptographic Providers
|
||||||
private static final int KEY_SIZE_MIN = 512; // disallow MSCAPI min. of 384
|
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_MAX = 16384;
|
||||||
private static final int KEY_SIZE_DEFAULT = 1024;
|
private static final int KEY_SIZE_DEFAULT = 1024;
|
||||||
|
|
||||||
// size of the key to generate, KEY_SIZE_MIN <= keySize <= KEY_SIZE_MAX
|
// 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
|
// random is always ignored
|
||||||
public void initialize(int keySize, SecureRandom random) {
|
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
|
// second initialize method. See JCA doc
|
||||||
|
@ -67,21 +75,31 @@ public final class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
|
||||||
public void initialize(AlgorithmParameterSpec params, SecureRandom random)
|
public void initialize(AlgorithmParameterSpec params, SecureRandom random)
|
||||||
throws InvalidAlgorithmParameterException {
|
throws InvalidAlgorithmParameterException {
|
||||||
|
|
||||||
|
int tmpSize;
|
||||||
if (params == null) {
|
if (params == null) {
|
||||||
checkKeySize(KEY_SIZE_DEFAULT);
|
tmpSize = KEY_SIZE_DEFAULT;
|
||||||
|
|
||||||
} else if (params instanceof RSAKeyGenParameterSpec) {
|
} else if (params instanceof RSAKeyGenParameterSpec) {
|
||||||
|
|
||||||
if (((RSAKeyGenParameterSpec) params).getPublicExponent() != null) {
|
if (((RSAKeyGenParameterSpec) params).getPublicExponent() != null) {
|
||||||
throw new InvalidAlgorithmParameterException
|
throw new InvalidAlgorithmParameterException
|
||||||
("Exponent parameter is not supported");
|
("Exponent parameter is not supported");
|
||||||
}
|
}
|
||||||
checkKeySize(((RSAKeyGenParameterSpec) params).getKeysize());
|
tmpSize = ((RSAKeyGenParameterSpec) params).getKeysize();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
throw new InvalidAlgorithmParameterException
|
throw new InvalidAlgorithmParameterException
|
||||||
("Params must be an instance of RSAKeyGenParameterSpec");
|
("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
|
// generate the keypair. See JCA doc
|
||||||
|
@ -95,18 +113,6 @@ public final class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
|
||||||
return new KeyPair(keys.getPublic(), keys.getPrivate());
|
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,
|
private static native RSAKeyPair generateRSAKeyPair(int keySize,
|
||||||
String keyContainerName);
|
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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -38,6 +38,9 @@ import java.security.SecureRandom;
|
||||||
import java.security.Signature;
|
import java.security.Signature;
|
||||||
import java.security.SignatureSpi;
|
import java.security.SignatureSpi;
|
||||||
import java.security.SignatureException;
|
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.
|
* 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
|
// 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
|
// Adjust key length due to sign bit
|
||||||
int keyBitLength = (modulusBytes[0] == 0)
|
int keyBitLength = (modulusBytes[0] == 0)
|
||||||
|
@ -132,8 +144,7 @@ abstract class RSASignature extends java.security.SignatureSpi
|
||||||
: modulusBytes.length * 8;
|
: modulusBytes.length * 8;
|
||||||
|
|
||||||
byte[] keyBlob = generatePublicKeyBlob(
|
byte[] keyBlob = generatePublicKeyBlob(
|
||||||
keyBitLength, modulusBytes,
|
keyBitLength, modulusBytes, exponentBytes);
|
||||||
rsaKey.getPublicExponent().toByteArray());
|
|
||||||
|
|
||||||
publicKey = importPublicKey(keyBlob, keyBitLength);
|
publicKey = importPublicKey(keyBlob, keyBitLength);
|
||||||
|
|
||||||
|
@ -166,12 +177,11 @@ abstract class RSASignature extends java.security.SignatureSpi
|
||||||
}
|
}
|
||||||
privateKey = (sun.security.mscapi.RSAPrivateKey) key;
|
privateKey = (sun.security.mscapi.RSAPrivateKey) key;
|
||||||
|
|
||||||
// Determine byte length from bit length
|
// Check against the local and global values to make sure
|
||||||
int keySize = (privateKey.bitLength() + 7) >> 3;
|
// the sizes are ok. Round up to nearest byte.
|
||||||
|
RSAKeyFactory.checkKeyLengths(((privateKey.bitLength() + 7) & ~7),
|
||||||
if (keySize < 64)
|
null, RSAKeyPairGenerator.KEY_SIZE_MIN,
|
||||||
throw new InvalidKeyException(
|
RSAKeyPairGenerator.KEY_SIZE_MAX);
|
||||||
"RSA keys must be at least 512 bits long");
|
|
||||||
|
|
||||||
if (needsReset) {
|
if (needsReset) {
|
||||||
messageDigest.reset();
|
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
|
# @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 PrintVersion
|
||||||
# @build UglyPrintVersion
|
# @build UglyPrintVersion
|
||||||
|
# @build ZipMeUp
|
||||||
# @run shell MultipleJRE.sh
|
# @run shell MultipleJRE.sh
|
||||||
# @summary Verify Multiple JRE version support
|
# @summary Verify Multiple JRE version support
|
||||||
# @author Joseph E. Kowalski
|
# @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.
|
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
#
|
#
|
||||||
# This code is free software; you can redistribute it and/or modify it
|
# This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -49,10 +49,25 @@ then
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
JAVAEXE="$TESTJAVA/bin/java"
|
||||||
JAVA="$TESTJAVA/bin/java -classpath $TESTCLASSES"
|
JAVA="$TESTJAVA/bin/java -classpath $TESTCLASSES"
|
||||||
JAR="$TESTJAVA/bin/jar"
|
JAR="$TESTJAVA/bin/jar"
|
||||||
OS=`uname -s`;
|
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
|
# Shell routine to test for the proper rejection of syntactically incorrect
|
||||||
# version specifications.
|
# version specifications.
|
||||||
|
@ -139,7 +154,6 @@ CreateUglyJar() {
|
||||||
$PACKAGE/UglyPrintVersion.class
|
$PACKAGE/UglyPrintVersion.class
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Constructs a jar file with a fair number of "zip directory" entries and
|
# 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
|
# the MANIFEST.MF entry at or near the end of that directory to validate
|
||||||
|
@ -262,6 +276,29 @@ LaunchVM() {
|
||||||
fi
|
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
|
# Main test sequence starts here
|
||||||
#
|
#
|
||||||
|
@ -280,14 +317,11 @@ CreateJar "" ""
|
||||||
LaunchVM "" "${RELEASE}"
|
LaunchVM "" "${RELEASE}"
|
||||||
CreateJar "" "0"
|
CreateJar "" "0"
|
||||||
LaunchVM "" "${RELEASE}"
|
LaunchVM "" "${RELEASE}"
|
||||||
case "$OS" in
|
if [ `IsWindows` = "true" ]; then
|
||||||
Windows* | CYGWIN* )
|
|
||||||
MAXIMUM_PATH=255;
|
MAXIMUM_PATH=255;
|
||||||
;;
|
else
|
||||||
*)
|
|
||||||
MAXIMUM_PATH=1024;
|
MAXIMUM_PATH=1024;
|
||||||
;;
|
fi
|
||||||
esac
|
|
||||||
|
|
||||||
PATH_LENGTH=`printf "%s" "$UGLYCLASS" | wc -c`
|
PATH_LENGTH=`printf "%s" "$UGLYCLASS" | wc -c`
|
||||||
if [ ${PATH_LENGTH} -lt ${MAXIMUM_PATH} ]; then
|
if [ ${PATH_LENGTH} -lt ${MAXIMUM_PATH} ]; then
|
||||||
|
@ -346,7 +380,6 @@ if [ -x /usr/bin/zipnote ]; then
|
||||||
LaunchVM "" "${RELEASE}"
|
LaunchVM "" "${RELEASE}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Throw some syntactically challenged (illegal) version specifiers at
|
# Throw some syntactically challenged (illegal) version specifiers at
|
||||||
# the interface. Failure (of the launcher) is success for the test.
|
# 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+.3" # Embedded modifier
|
||||||
TestSyntax "1.2.4+&1.2*&1++" # Long and invalid
|
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
|
# Because scribbling in the registry can be rather destructive, only a
|
||||||
# subset of the tests are run on Windows.
|
# subset of the tests are run on Windows.
|
||||||
#
|
#
|
||||||
case "$OS" in
|
if [ `IsWindows` = "true" ]; then
|
||||||
Windows* | CYGWIN* )
|
|
||||||
exit 0;
|
exit 0;
|
||||||
;;
|
fi
|
||||||
esac
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Additional version specifiers containing spaces. (Sigh, unable to
|
# 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