Mercurial > hg > icedtea6-hg
changeset 2978:c01c31ed2f60
Sync with upstream availability of latest security patches.
2013-03-19 Andrew John Hughes <gnu.andrew@redhat.com>
* patches/openjdk/8004341-jck_dialog_failure.patch,
* patches/openjdk/8005615-failure_to_load_logger_implementation.patch,
* patches/openjdk/8007393.patch,
* patches/openjdk/8007611.patch,
* patches/openjdk/8009641-8007675_build_fix.patch,
* patches/security/20130201/6563318.patch,
* patches/security/20130201/6664509.patch,
* patches/security/20130201/6776941.patch,
* patches/security/20130201/7141694.patch,
* patches/security/20130201/7173145.patch,
* patches/security/20130201/7186945.patch,
* patches/security/20130201/7186948.patch,
* patches/security/20130201/7186952.patch,
* patches/security/20130201/7186954.patch,
* patches/security/20130201/7192392.patch,
* patches/security/20130201/7192393.patch,
* patches/security/20130201/7192977.patch,
* patches/security/20130201/7197546.patch,
* patches/security/20130201/7200491.patch,
* patches/security/20130201/7200500.patch,
* patches/security/20130201/7201064.patch,
* patches/security/20130201/7201066.patch,
* patches/security/20130201/7201068.patch,
* patches/security/20130201/7201070.patch,
* patches/security/20130201/7201071.patch,
* patches/security/20130201/8000210.patch,
* patches/security/20130201/8000537.patch,
* patches/security/20130201/8000540.patch,
* patches/security/20130201/8000631.patch,
* patches/security/20130201/8001235.patch,
* patches/security/20130201/8001242.patch,
* patches/security/20130201/8001307.patch,
* patches/security/20130201/8001972.patch,
* patches/security/20130201/8002325.patch,
* patches/security/20130219/8006446.patch,
* patches/security/20130219/8006777.patch,
* patches/security/20130219/8007688.patch,
* patches/security/20130304/8007014.patch,
* patches/security/20130304/8007675.patch:
Remove patches available upstream.
* Makefile.am:
(JAXP_DROP_ZIP): Update to jaxp144_05.zip
with latest security fix included.
(JAXP_DROP_SHA256SUM): Likewise.
(SECURITY_PATCHES): Remove ones available
upstream (all from 2013/02/01, 2013/02/19
and 2013/03/04).
(ICEDTEA_PATCHES): Remove patches for
8005615, 8004341, 8007393 & 8007611
available upstream.
* patches/ecj/override.patch:
Add new case introduced by upstream version
of security patches (sigh...)
author | Andrew John Hughes <ahughes@redhat.com> |
---|---|
date | Wed, 20 Mar 2013 00:03:03 +0000 |
parents | 6415ddeeeb09 |
children | 635d03c5e2dc |
files | ChangeLog Makefile.am patches/ecj/override.patch patches/openjdk/8004341-jck_dialog_failure.patch patches/openjdk/8005615-failure_to_load_logger_implementation.patch patches/openjdk/8007393.patch patches/openjdk/8007611.patch patches/openjdk/8009641-8007675_build_fix.patch patches/security/20130201/6563318.patch patches/security/20130201/6664509.patch patches/security/20130201/6776941.patch patches/security/20130201/7141694.patch patches/security/20130201/7173145.patch patches/security/20130201/7186945.patch patches/security/20130201/7186948.patch patches/security/20130201/7186952.patch patches/security/20130201/7186954.patch patches/security/20130201/7192392.patch patches/security/20130201/7192393.patch patches/security/20130201/7192977.patch patches/security/20130201/7197546.patch patches/security/20130201/7200491.patch patches/security/20130201/7200500.patch patches/security/20130201/7201064.patch patches/security/20130201/7201066.patch patches/security/20130201/7201068.patch patches/security/20130201/7201070.patch patches/security/20130201/7201071.patch patches/security/20130201/8000210.patch patches/security/20130201/8000537.patch patches/security/20130201/8000540.patch patches/security/20130201/8000631.patch patches/security/20130201/8001235.patch patches/security/20130201/8001242.patch patches/security/20130201/8001307.patch patches/security/20130201/8001972.patch patches/security/20130201/8002325.patch patches/security/20130219/8006446.patch patches/security/20130219/8006777.patch patches/security/20130219/8007688.patch patches/security/20130304/8007014.patch patches/security/20130304/8007675.patch |
diffstat | 42 files changed, 111 insertions(+), 23862 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog Tue Mar 19 00:21:31 2013 +0000 +++ b/ChangeLog Wed Mar 20 00:03:03 2013 +0000 @@ -1,3 +1,59 @@ +2013-03-19 Andrew John Hughes <gnu.andrew@redhat.com> + + * patches/openjdk/8004341-jck_dialog_failure.patch, + * patches/openjdk/8005615-failure_to_load_logger_implementation.patch, + * patches/openjdk/8007393.patch, + * patches/openjdk/8007611.patch, + * patches/openjdk/8009641-8007675_build_fix.patch, + * patches/security/20130201/6563318.patch, + * patches/security/20130201/6664509.patch, + * patches/security/20130201/6776941.patch, + * patches/security/20130201/7141694.patch, + * patches/security/20130201/7173145.patch, + * patches/security/20130201/7186945.patch, + * patches/security/20130201/7186948.patch, + * patches/security/20130201/7186952.patch, + * patches/security/20130201/7186954.patch, + * patches/security/20130201/7192392.patch, + * patches/security/20130201/7192393.patch, + * patches/security/20130201/7192977.patch, + * patches/security/20130201/7197546.patch, + * patches/security/20130201/7200491.patch, + * patches/security/20130201/7200500.patch, + * patches/security/20130201/7201064.patch, + * patches/security/20130201/7201066.patch, + * patches/security/20130201/7201068.patch, + * patches/security/20130201/7201070.patch, + * patches/security/20130201/7201071.patch, + * patches/security/20130201/8000210.patch, + * patches/security/20130201/8000537.patch, + * patches/security/20130201/8000540.patch, + * patches/security/20130201/8000631.patch, + * patches/security/20130201/8001235.patch, + * patches/security/20130201/8001242.patch, + * patches/security/20130201/8001307.patch, + * patches/security/20130201/8001972.patch, + * patches/security/20130201/8002325.patch, + * patches/security/20130219/8006446.patch, + * patches/security/20130219/8006777.patch, + * patches/security/20130219/8007688.patch, + * patches/security/20130304/8007014.patch, + * patches/security/20130304/8007675.patch: + Remove patches available upstream. + * Makefile.am: + (JAXP_DROP_ZIP): Update to jaxp144_05.zip + with latest security fix included. + (JAXP_DROP_SHA256SUM): Likewise. + (SECURITY_PATCHES): Remove ones available + upstream (all from 2013/02/01, 2013/02/19 + and 2013/03/04). + (ICEDTEA_PATCHES): Remove patches for + 8005615, 8004341, 8007393 & 8007611 + available upstream. + * patches/ecj/override.patch: + Add new case introduced by upstream version + of security patches (sigh...) + 2013-03-18 Andrew John Hughes <gnu.andrew@redhat.com> * Makefile.am:
--- a/Makefile.am Tue Mar 19 00:21:31 2013 +0000 +++ b/Makefile.am Wed Mar 20 00:03:03 2013 +0000 @@ -24,8 +24,8 @@ JAF_DROP_ZIP = jdk6-jaf-b20.zip JAF_DROP_SHA256SUM = 78c7b5c9d6271e88ee46abadd018a61f1e9645f8936cc8df1617e5f4f5074012 JAXP_DROP_URL = http://icedtea.classpath.org/download/drops -JAXP_DROP_ZIP = jaxp144_04.zip -JAXP_DROP_SHA256SUM = 490f696218c1fed9cb180680af883fe309b414fec232e9cec19645e12ad0b43c +JAXP_DROP_ZIP = jaxp144_05.zip +JAXP_DROP_SHA256SUM = c1a8a5a219fa55ecbf2ad43b66514335a3e96ccad40bd2ec9165a821343b2bff OPENJDK_HG_URL = http://hg.openjdk.java.net/jdk6/jdk6 HOTSPOT_SRC_ZIP = hotspot.tar.gz @@ -245,46 +245,7 @@ ICEDTEA_FSG_PATCHES = SECURITY_PATCHES = \ - patches/security/20120830/7182135-impossible_to_use_some_editors_directly.patch \ - patches/security/20130201/7201068.patch \ - patches/security/20130201/6563318.patch \ - patches/security/20130201/6664509.patch \ - patches/security/20130201/6776941.patch \ - patches/security/20130201/7141694.patch \ - patches/security/20130201/7173145.patch \ - patches/security/20130201/7186945.patch \ - patches/security/20130201/7186948.patch \ - patches/security/20130201/7186952.patch \ - patches/security/20130201/7186954.patch \ - patches/security/20130201/7192392.patch \ - patches/security/20130201/7192393.patch \ - patches/security/20130201/7192977.patch \ - patches/security/20130201/7197546.patch \ - patches/security/20130201/7200491.patch \ - patches/security/20130201/7200500.patch \ - patches/security/20130201/7201064.patch \ - patches/security/20130201/7201066.patch \ - patches/security/20130201/7201070.patch \ - patches/security/20130201/7201071.patch \ - patches/security/20130201/8000210.patch \ - patches/security/20130201/8000537.patch \ - patches/security/20130201/8000540.patch \ - patches/security/20130201/8000631.patch \ - patches/security/20130201/8001242.patch \ - patches/security/20130201/8001972.patch \ - patches/security/20130201/8002325.patch \ - patches/security/20130201/8001235.patch \ - patches/security/20130219/8006446.patch \ - patches/security/20130219/8006777.patch \ - patches/security/20130219/8007688.patch \ - patches/security/20130304/8007014.patch \ - patches/security/20130304/8007675.patch \ - patches/openjdk/8009641-8007675_build_fix.patch - -if !WITH_ALT_HSBUILD -SECURITY_PATCHES += \ - patches/security/20130201/8001307.patch -endif + patches/security/20120830/7182135-impossible_to_use_some_editors_directly.patch SPECIAL_SECURITY_PATCH = patches/security/20120214/7112642.patch @@ -474,11 +435,7 @@ patches/openjdk/6980681-corba_deadlock.patch \ patches/openjdk/7162902-corba_fixes.patch \ patches/traceable.patch \ - patches/openjdk/8005615-failure_to_load_logger_implementation.patch \ - patches/openjdk/8004341-jck_dialog_failure.patch \ - patches/pr1319-support_giflib_5.patch \ - patches/openjdk/8007393.patch \ - patches/openjdk/8007611.patch + patches/pr1319-support_giflib_5.patch if WITH_ALT_HSBUILD ICEDTEA_PATCHES += \
--- a/patches/ecj/override.patch Tue Mar 19 00:21:31 2013 +0000 +++ b/patches/ecj/override.patch Wed Mar 20 00:03:03 2013 +0000 @@ -252,3 +252,54 @@ public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { Component c = delegate.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); +diff -Nru openjdk.orig/jdk/src/share/classes/javax/management/modelmbean/RequiredModelMBean.java openjdk/jdk/src/share/classes/javax/management/modelmbean/RequiredModelMBean.java +--- openjdk-ecj.orig/jdk/src/share/classes/javax/management/modelmbean/RequiredModelMBean.java 2013-03-19 13:40:24.027496931 +0000 ++++ openjdk-ecj/jdk/src/share/classes/javax/management/modelmbean/RequiredModelMBean.java 2013-03-19 13:40:56.968026902 +0000 +@@ -1040,7 +1040,6 @@ + + targetClass = javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Class<?>>() { + +- @Override + public Class<?> run() { + try { + ReflectUtil.checkPackageAccess(className); +@@ -1114,7 +1113,6 @@ + + javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Void>() { + +- @Override + public Void run() { + for (int i = 0; i < sig.length; i++) { + if (tracing) { +@@ -1203,7 +1201,6 @@ + final String className = opClassName; + targetClass = javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Class<?>>() { + +- @Override + public Class<?> run() { + try { + ReflectUtil.checkPackageAccess(className); +@@ -1239,7 +1236,6 @@ + AccessControlContext stack = AccessController.getContext(); + Object rslt = javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Object>() { + +- @Override + public Object run() { + try { + ReflectUtil.checkPackageAccess(method.getDeclaringClass()); +@@ -1676,7 +1672,6 @@ + + Class c = javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Class<?>>() { + +- @Override + public Class<?> run() { + try { + ReflectUtil.checkPackageAccess(respType); +@@ -2854,7 +2849,6 @@ + + Class c = javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Class<?>>() { + +- @Override + public Class<?> run() { + try { + ReflectUtil.checkPackageAccess(className);
--- a/patches/openjdk/8004341-jck_dialog_failure.patch Tue Mar 19 00:21:31 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,26 +0,0 @@ -# HG changeset patch -# User denis -# Date 1355221156 -14400 -# Node ID 090b35175a91906d75050f12a5f3e54c7da199e9 -# Parent 52029bcc00e103876c5149d7f95d9246e73d3435 -8004341: Two JCK tests fails with 7u11 b06 -Reviewed-by: serb, skoivu - -diff --git a/src/share/classes/java/awt/Dialog.java b/src/share/classes/java/awt/Dialog.java ---- openjdk/jdk/src/share/classes/java/awt/Dialog.java -+++ openjdk/jdk/src/share/classes/java/awt/Dialog.java -@@ -1631,12 +1631,13 @@ - if (localModalityType == null) { - this.modal = fields.get("modal", false); - setModal(modal); -+ } else { -+ this.modalityType = localModalityType; - } - - this.resizable = fields.get("resizable", true); - this.undecorated = fields.get("undecorated", false); - this.title = (String)fields.get("title", ""); -- this.modalityType = localModalityType; - - blockedWindows = new IdentityArrayList(); -
--- a/patches/openjdk/8005615-failure_to_load_logger_implementation.patch Tue Mar 19 00:21:31 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,542 +0,0 @@ -# HG changeset patch -# User coffeys -# Date 1360107230 0 -# Node ID cff0241d217f7b463d58ddcd0add8d41de9eb280 -# Parent dabed5898de907431b524952aade46f0b6b960aa -8005615: Java Logger fails to load tomcat logger implementation (JULI) -Reviewed-by: mchung - -diff --git a/src/share/classes/java/util/logging/LogManager.java b/src/share/classes/java/util/logging/LogManager.java ---- openjdk/jdk/src/share/classes/java/util/logging/LogManager.java -+++ openjdk/jdk/src/share/classes/java/util/logging/LogManager.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -159,7 +159,7 @@ - - // LoggerContext for system loggers and user loggers - private final LoggerContext systemContext = new SystemLoggerContext(); -- private final LoggerContext userContext = new UserLoggerContext(); -+ private final LoggerContext userContext = new LoggerContext(); - private Logger rootLogger; - - // Have we done the primordial reading of the configuration file? -@@ -197,13 +197,13 @@ - - // Create and retain Logger for the root of the namespace. - manager.rootLogger = manager.new RootLogger(); -- manager.systemContext.addLogger(manager.rootLogger); -- manager.userContext.addLogger(manager.rootLogger); -+ manager.addLogger(manager.rootLogger); -+ manager.systemContext.addLocalLogger(manager.rootLogger); - - // Adding the global Logger. Doing so in the Logger.<clinit> - // would deadlock with the LogManager.<clinit>. - Logger.global.setLogManager(manager); -- manager.systemContext.addLogger(Logger.global); -+ manager.addLogger(Logger.global); - - // We don't call readConfiguration() here, as we may be running - // very early in the JVM startup sequence. Instead readConfiguration -@@ -329,7 +329,7 @@ - - // Returns the LoggerContext for the user code (i.e. application or AppContext). - // Loggers are isolated from each AppContext. -- LoggerContext getUserContext() { -+ private LoggerContext getUserContext() { - LoggerContext context = null; - - SecurityManager sm = System.getSecurityManager(); -@@ -350,8 +350,8 @@ - if (javaAwtAccess.isMainAppContext()) { - context = userContext; - } else { -- context = new UserLoggerContext(); -- context.addLogger(manager.rootLogger); -+ context = new LoggerContext(); -+ context.addLocalLogger(manager.rootLogger); - } - javaAwtAccess.put(ecx, LoggerContext.class, context); - } -@@ -362,10 +362,6 @@ - return context; - } - -- LoggerContext getSystemContext() { -- return systemContext; -- } -- - private List<LoggerContext> contexts() { - List<LoggerContext> cxs = new ArrayList<LoggerContext>(); - cxs.add(systemContext); -@@ -373,6 +369,58 @@ - return cxs; - } - -+ // Find or create a specified logger instance. If a logger has -+ // already been created with the given name it is returned. -+ // Otherwise a new logger instance is created and registered -+ // in the LogManager global namespace. -+ // This method will always return a non-null Logger object. -+ // Synchronization is not required here. All synchronization for -+ // adding a new Logger object is handled by addLogger(). -+ // -+ // This method must delegate to the LogManager implementation to -+ // add a new Logger or return the one that has been added previously -+ // as a LogManager subclass may override the addLogger, getLogger, -+ // readConfiguration, and other methods. -+ Logger demandLogger(String name, String resourceBundleName) { -+ Logger result = getLogger(name); -+ if (result == null) { -+ // only allocate the new logger once -+ Logger newLogger = new Logger(name, resourceBundleName); -+ do { -+ if (addLogger(newLogger)) { -+ // We successfully added the new Logger that we -+ // created above so return it without refetching. -+ return newLogger; -+ } -+ -+ // We didn't add the new Logger that we created above -+ // because another thread added a Logger with the same -+ // name after our null check above and before our call -+ // to addLogger(). We have to refetch the Logger because -+ // addLogger() returns a boolean instead of the Logger -+ // reference itself. However, if the thread that created -+ // the other Logger is not holding a strong reference to -+ // the other Logger, then it is possible for the other -+ // Logger to be GC'ed after we saw it in addLogger() and -+ // before we can refetch it. If it has been GC'ed then -+ // we'll just loop around and try again. -+ result = getLogger(name); -+ } while (result == null); -+ } -+ return result; -+ } -+ -+ Logger demandSystemLogger(String name, String resourceBundleName) { -+ return systemContext.demandLogger(name, resourceBundleName); -+ } -+ -+ // LoggerContext maintains the logger namespace per context. -+ // The default LogManager implementation has one system context and user -+ // context. The system context is used to maintain the namespace for -+ // all system loggers and is queried by the system code. If a system logger -+ // doesn't exist in the user context, it'll also be added to the user context. -+ // The user context is queried by the user code and all other loggers are -+ // added in the user context. - static class LoggerContext { - // Table of named Loggers that maps names to Loggers. - -@@ -385,6 +433,12 @@ - this.root = new LogNode(null, this); - } - -+ Logger demandLogger(String name, String resourceBundleName) { -+ // a LogManager subclass may have its own implementation to add and -+ // get a Logger. So delegate to the LogManager to do the work. -+ return manager.demandLogger(name, resourceBundleName); -+ } -+ - synchronized Logger findLogger(String name) { - LoggerWeakRef ref = namedLoggers.get(name); - if (ref == null) { -@@ -399,7 +453,9 @@ - return logger; - } - -- synchronized boolean addLogger(Logger logger) { -+ // Add a logger to this context. This method will only set its level -+ // and process parent loggers. It doesn't set its handlers. -+ synchronized boolean addLocalLogger(Logger logger) { - final String name = logger.getName(); - if (name == null) { - throw new NullPointerException(); -@@ -432,9 +488,6 @@ - doSetLevel(logger, level); - } - -- // Do we have a per logger handler too? -- // Note: this will add a 200ms penalty -- manager.loadLoggerHandlers(logger, name, name + ".handlers"); - processParentHandlers(logger, name); - - // Find the new node and its parent. -@@ -471,49 +524,21 @@ - return namedLoggers.keys(); - } - -- Logger demandLogger(String name) { -- return demandLogger(name, null); -- } -- -- // Find or create a specified logger instance. If a logger has -- // already been created with the given name it is returned. -- // Otherwise a new logger instance is created and registered -- // in the LogManager global namespace. -- // This method will always return a non-null Logger object. -- // Synchronization is not required here. All synchronization for -- // adding a new Logger object is handled by addLogger(). -- Logger demandLogger(String name, String resourceBundleName) { -- Logger result = findLogger(name); -- if (result == null) { -- // only allocate the new logger once -- Logger newLogger = new Logger(name, resourceBundleName); -- do { -- if (addLogger(newLogger)) { -- // We successfully added the new Logger that we -- // created above so return it without refetching. -- return newLogger; -- } -- -- // We didn't add the new Logger that we created above -- // because another thread added a Logger with the same -- // name after our null check above and before our call -- // to addLogger(). We have to refetch the Logger because -- // addLogger() returns a boolean instead of the Logger -- // reference itself. However, if the thread that created -- // the other Logger is not holding a strong reference to -- // the other Logger, then it is possible for the other -- // Logger to be GC'ed after we saw it in addLogger() and -- // before we can refetch it. If it has been GC'ed then -- // we'll just loop around and try again. -- result = findLogger(name); -- } while (result == null); -- } -- return result; -- } -- - // If logger.getUseParentHandlers() returns 'true' and any of the logger's - // parents have levels or handlers defined, make sure they are instantiated. -- private void processParentHandlers(Logger logger, String name) { -+ private void processParentHandlers(final Logger logger, final String name) { -+ AccessController.doPrivileged(new PrivilegedAction<Void>() { -+ public Void run() { -+ if (logger != manager.rootLogger) { -+ boolean useParent = manager.getBooleanProperty(name + ".useParentHandlers", true); -+ if (!useParent) { -+ logger.setUseParentHandlers(false); -+ } -+ } -+ return null; -+ } -+ }); -+ - int ix = 1; - for (;;) { - int ix2 = name.indexOf(".", ix); -@@ -526,12 +551,12 @@ - || manager.getProperty(pname + ".handlers") != null) { - // This pname has a level/handlers definition. - // Make sure it exists. -- demandLogger(pname); -+ demandLogger(pname, null); - } - ix = ix2 + 1; - } - } -- -+ - // Gets a node in our tree of logger nodes. - // If necessary, create it. - LogNode getNode(String name) { -@@ -564,74 +589,55 @@ - } - - static class SystemLoggerContext extends LoggerContext { -- // Default resource bundle for all system loggers -- -- Logger demandLogger(String name) { -- // default to use the system logger's resource bundle -- return super.demandLogger(name, Logger.SYSTEM_LOGGER_RB_NAME); -- } -- } -- -- static class UserLoggerContext extends LoggerContext { -- -- /** -- * Returns a Logger of the given name if there is one registered -- * in this context. Otherwise, it will return the one registered -- * in the system context if there is one. The returned Logger -- * instance may be initialized with a different resourceBundleName. -- * If no such logger exists, a new Logger instance will be created -- * and registered in this context. -- */ -+ // Add a system logger in the system context's namespace as well as -+ // in the LogManager's namespace if not exist so that there is only -+ // one single logger of the given name. System loggers are visible -+ // to applications unless a logger of the same name has been added. - Logger demandLogger(String name, String resourceBundleName) { - Logger result = findLogger(name); - if (result == null) { -- // use the system logger if exists; or allocate a new logger. -- // The system logger is added to the app logger context so that -- // any child logger created in the app logger context can have -- // a system logger as its parent if already exist. -- Logger logger = manager.systemContext.findLogger(name); -- Logger newLogger = -- logger != null ? logger : new Logger(name, resourceBundleName); -+ // only allocate the new system logger once -+ Logger newLogger = new Logger(name, resourceBundleName); - do { -- if (addLogger(newLogger)) { -+ if (addLocalLogger(newLogger)) { - // We successfully added the new Logger that we - // created above so return it without refetching. -- return newLogger; -+ result = newLogger; -+ } else { -+ // We didn't add the new Logger that we created above -+ // because another thread added a Logger with the same -+ // name after our null check above and before our call -+ // to addLogger(). We have to refetch the Logger because -+ // addLogger() returns a boolean instead of the Logger -+ // reference itself. However, if the thread that created -+ // the other Logger is not holding a strong reference to -+ // the other Logger, then it is possible for the other -+ // Logger to be GC'ed after we saw it in addLogger() and -+ // before we can refetch it. If it has been GC'ed then -+ // we'll just loop around and try again. -+ result = findLogger(name); - } -- -- // We didn't add the new Logger that we created above -- // because another thread added a Logger with the same -- // name after our null check above and before our call -- // to addLogger(). We have to refetch the Logger because -- // addLogger() returns a boolean instead of the Logger -- // reference itself. However, if the thread that created -- // the other Logger is not holding a strong reference to -- // the other Logger, then it is possible for the other -- // Logger to be GC'ed after we saw it in addLogger() and -- // before we can refetch it. If it has been GC'ed then -- // we'll just loop around and try again. -- result = findLogger(name); - } while (result == null); - } -- return result; -+ // Add the system logger to the LogManager's namespace if not exists -+ // The LogManager will set its handlers via the LogManager.addLogger method. -+ if (!manager.addLogger(result) && result.getHandlers().length == 0) { -+ // if logger already exists but handlers not set -+ final Logger l = manager.getLogger(name); -+ final Logger logger = result; -+ AccessController.doPrivileged(new PrivilegedAction<Void>() { -+ public Void run() { -+ for (Handler hdl : l.getHandlers()) { -+ logger.addHandler(hdl); -+ } -+ return null; -+ } -+ }); -+ } -+ return result; - } - } - -- // Package-level method. -- // Find or create a specified logger instance. If a logger has -- // already been created with the given name it is returned. -- // Otherwise a new logger instance is created and registered -- // in the LogManager global namespace. -- synchronized Logger demandLogger(String name) { -- Logger result = getLogger(name); -- if (result == null) { -- result = new Logger(name, null); -- addLogger(result); -- result = getLogger(name); -- } -- return result; -- } -- - // Add new per logger handlers. - // We need to raise privilege here. All our decisions will - // be made based on the logging configuration, which can -@@ -640,12 +646,6 @@ - final String handlersPropertyName) { - AccessController.doPrivileged(new PrivilegedAction<Object>() { - public Object run() { -- if (logger != rootLogger) { -- boolean useParent = getBooleanProperty(name + ".useParentHandlers", true); -- if (!useParent) { -- logger.setUseParentHandlers(false); -- } -- } - - String names[] = parseClassNames(handlersPropertyName); - for (int i = 0; i < names.length; i++) { -@@ -674,10 +674,10 @@ - } - } - return null; -- }}); -+ } -+ }); - } - -- - // loggerRefQueue holds LoggerWeakRef objects for Logger objects - // that have been GC'ed. - private final ReferenceQueue<Logger> loggerRefQueue -@@ -815,10 +815,15 @@ - if (name == null) { - throw new NullPointerException(); - } -- if (systemContext.findLogger(name) != null) { -+ LoggerContext cx = getUserContext(); -+ if (cx.addLocalLogger(logger)) { -+ // Do we have a per logger handler too? -+ // Note: this will add a 200ms penalty -+ loadLoggerHandlers(logger, name, name + ".handlers"); -+ return true; -+ } else { - return false; - } -- return getUserContext().addLogger(logger); - } - - // Private method to set a level on a logger. -@@ -839,8 +844,6 @@ - }}); - } - -- -- - // Private method to set a parent on a logger. - // If necessary, we raise privilege before doing the setParent call. - private static void doSetParent(final Logger logger, final Logger parent) { -@@ -875,15 +878,7 @@ - * @return matching logger or null if none is found - */ - public Logger getLogger(String name) { -- // return the first logger added -- // -- // once a system logger is added in the system context, no one can -- // adds a logger with the same name in the global context -- // (see LogManager.addLogger). So if there is a logger in the global -- // context with the same name as one in the system context, it must be -- // added before the system logger was created. -- Logger logger = getUserContext().findLogger(name); -- return logger != null ? logger : systemContext.findLogger(name); -+ return getUserContext().findLogger(name); - } - - /** -@@ -903,11 +898,7 @@ - * @return enumeration of logger name strings - */ - public Enumeration<String> getLoggerNames() { -- // only return unique names -- Set<String> names = -- new HashSet<String>(Collections.list(systemContext.getLoggerNames())); -- names.addAll(Collections.list(getUserContext().getLoggerNames())); -- return Collections.enumeration(names); -+ return getUserContext().getLoggerNames(); - } - - /** -@@ -1229,7 +1220,6 @@ - loadLoggerHandlers(rootLogger, null, "handlers"); - } - -- - private final Permission controlPermission = new LoggingPermission("control", null); - - void checkPermission() { -@@ -1288,7 +1278,6 @@ - // that we only instantiate the global handlers when they - // are first needed. - private class RootLogger extends Logger { -- - private RootLogger() { - super("", null); - setLevel(defaultLevel); -diff --git a/src/share/classes/java/util/logging/Logger.java b/src/share/classes/java/util/logging/Logger.java ---- openjdk/jdk/src/share/classes/java/util/logging/Logger.java -+++ openjdk/jdk/src/share/classes/java/util/logging/Logger.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -29,7 +29,6 @@ - import java.util.*; - import java.security.*; - import java.lang.ref.WeakReference; --import java.util.logging.LogManager.LoggerContext; - - /** - * A Logger object is used to log messages for a specific -@@ -283,18 +282,32 @@ - // - // As an interim solution, if the immediate caller whose caller loader is - // null, we assume it's a system logger and add it to the system context. -- private static LoggerContext getLoggerContext() { -+ // These system loggers only set the resource bundle to the given -+ // resource bundle name (rather than the default system resource bundle). -+ private static class SystemLoggerHelper { -+ static boolean disableCallerCheck = getBooleanProperty("sun.util.logging.disableCallerCheck"); -+ private static boolean getBooleanProperty(final String key) { -+ String s = AccessController.doPrivileged(new PrivilegedAction<String>() { -+ public String run() { -+ return System.getProperty(key); -+ } -+ }); -+ return Boolean.valueOf(s); -+ } -+ } -+ -+ private static Logger demandLogger(String name, String resourceBundleName) { - LogManager manager = LogManager.getLogManager(); - SecurityManager sm = System.getSecurityManager(); -- if (sm != null) { -+ if (sm != null && !SystemLoggerHelper.disableCallerCheck) { - // 0: Reflection 1: Logger.getLoggerContext 2: Logger.getLogger 3: caller - final int SKIP_FRAMES = 3; - Class<?> caller = sun.reflect.Reflection.getCallerClass(SKIP_FRAMES); - if (caller.getClassLoader() == null) { -- return manager.getSystemContext(); -+ return manager.demandSystemLogger(name, resourceBundleName); - } - } -- return manager.getUserContext(); -+ return manager.demandLogger(name, resourceBundleName); - } - - /** -@@ -325,8 +338,7 @@ - * @throws NullPointerException if the name is null. - */ - public static synchronized Logger getLogger(String name) { -- LoggerContext context = getLoggerContext(); -- return context.demandLogger(name); -+ return demandLogger(name, null); - } - - /** -@@ -369,8 +381,7 @@ - * @throws NullPointerException if the name is null. - */ - public static synchronized Logger getLogger(String name, String resourceBundleName) { -- LoggerContext context = getLoggerContext(); -- Logger result = context.demandLogger(name, resourceBundleName); -+ Logger result = demandLogger(name, resourceBundleName); - if (result.resourceBundleName == null) { - // Note: we may get a MissingResourceException here. - result.setupResourceInfo(resourceBundleName); -@@ -1300,7 +1311,8 @@ - public ResourceBundle run() { - try { - return ResourceBundle.getBundle(SYSTEM_LOGGER_RB_NAME, -- locale); -+ locale, -+ ClassLoader.getSystemClassLoader()); - } catch (MissingResourceException e) { - throw new InternalError(e.toString()); - }
--- a/patches/openjdk/8007393.patch Tue Mar 19 00:21:31 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,78 +0,0 @@ - -# HG changeset patch -# User coffeys -# Date 1360860659 0 -# Node ID 828b93329939ec20530ed98f42b2966b2ea53048 -# Parent cff0241d217f7b463d58ddcd0add8d41de9eb280 -8007393: Possible race condition after JDK-6664509 -Reviewed-by: mchung - ---- openjdk/jdk/src/share/classes/java/util/logging/LogManager.java Tue Feb 05 23:33:50 2013 +0000 -+++ openjdk/jdk/src/share/classes/java/util/logging/LogManager.java Thu Feb 14 16:50:59 2013 +0000 -@@ -411,7 +411,40 @@ public class LogManager { - } - - Logger demandSystemLogger(String name, String resourceBundleName) { -- return systemContext.demandLogger(name, resourceBundleName); -+ // Add a system logger in the system context's namespace -+ final Logger sysLogger = systemContext.demandLogger(name, resourceBundleName); -+ -+ // Add the system logger to the LogManager's namespace if not exist -+ // so that there is only one single logger of the given name. -+ // System loggers are visible to applications unless a logger of -+ // the same name has been added. -+ Logger logger; -+ do { -+ // First attempt to call addLogger instead of getLogger -+ // This would avoid potential bug in custom LogManager.getLogger -+ // implementation that adds a logger if not exists -+ if (addLogger(sysLogger)) { -+ // successfully added the new system logger -+ logger = sysLogger; -+ } else { -+ logger = getLogger(name); -+ } -+ } while (logger == null); -+ -+ // LogManager will set the sysLogger's handlers via LogManager.addLogger method. -+ if (logger != sysLogger && sysLogger.getHandlers().length == 0) { -+ // if logger already exists but handlers not set -+ final Logger l = logger; -+ AccessController.doPrivileged(new PrivilegedAction<Void>() { -+ public Void run() { -+ for (Handler hdl : l.getHandlers()) { -+ sysLogger.addHandler(hdl); -+ } -+ return null; -+ } -+ }); -+ } -+ return sysLogger; - } - - // LoggerContext maintains the logger namespace per context. -@@ -619,22 +652,7 @@ public class LogManager { - } - } while (result == null); - } -- // Add the system logger to the LogManager's namespace if not exists -- // The LogManager will set its handlers via the LogManager.addLogger method. -- if (!manager.addLogger(result) && result.getHandlers().length == 0) { -- // if logger already exists but handlers not set -- final Logger l = manager.getLogger(name); -- final Logger logger = result; -- AccessController.doPrivileged(new PrivilegedAction<Void>() { -- public Void run() { -- for (Handler hdl : l.getHandlers()) { -- logger.addHandler(hdl); -- } -- return null; -- } -- }); -- } -- return result; -+ return result; - } - } - -
--- a/patches/openjdk/8007611.patch Tue Mar 19 00:21:31 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,24 +0,0 @@ - -# HG changeset patch -# User coffeys -# Date 1360861865 0 -# Node ID 25e83b78298b71abb46eb5a337ed7bddef418ca4 -# Parent 828b93329939ec20530ed98f42b2966b2ea53048 -8007611: logging behavior in applet changed -Reviewed-by: mchung - ---- openjdk/jdk/src/share/classes/java/util/logging/LogManager.java Thu Feb 14 16:50:59 2013 +0000 -+++ openjdk/jdk/src/share/classes/java/util/logging/LogManager.java Thu Feb 14 17:11:05 2013 +0000 -@@ -351,7 +351,10 @@ public class LogManager { - context = userContext; - } else { - context = new LoggerContext(); -- context.addLocalLogger(manager.rootLogger); -+ // during initialization, rootLogger is null when -+ // instantiating itself RootLogger -+ if (manager.rootLogger != null) -+ context.addLocalLogger(manager.rootLogger); - } - javaAwtAccess.put(ecx, LoggerContext.class, context); - } -
--- a/patches/openjdk/8009641-8007675_build_fix.patch Tue Mar 19 00:21:31 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,49 +0,0 @@ -# HG changeset patch -# User bae -# Date 1362669637 -10800 -# Node ID c73944a23b44ead9aa552ffaa4346bda08940ed3 -# Parent 9714f53ef17344fbcb6dc2249a7b238e6292f726 -8009641: OpenJDK 6 build broken via 8007675 fix -Reviewed-by: andrew - -diff --git a/src/share/classes/sun/java2d/cmm/lcms/LCMSTransform.java b/src/share/classes/sun/java2d/cmm/lcms/LCMSTransform.java ---- openjdk/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMSTransform.java -+++ openjdk/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMSTransform.java -@@ -572,14 +572,14 @@ - dst, dst.length/getNumOutComponents(), - LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) | - LCMSImageLayout.BYTES_SH(2), getNumOutComponents()*2); -+ -+ synchronized(this) { -+ LCMS.colorConvert(this, srcIL, dstIL); -+ } - } catch (ImageLayoutException e) { - throw new CMMException("Unable to convert data"); - } - -- synchronized(this) { -- LCMS.colorConvert(this, srcIL, dstIL); -- } -- - return dst; - } - -@@ -598,14 +598,14 @@ - dst, dst.length/getNumOutComponents(), - LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) | - LCMSImageLayout.BYTES_SH(1), getNumOutComponents()); -+ -+ synchronized(this) { -+ LCMS.colorConvert(this, srcIL, dstIL); -+ } - } catch (ImageLayoutException e) { - throw new CMMException("Unable to convert data"); - } - -- synchronized(this) { -- LCMS.colorConvert(this, srcIL, dstIL); -- } -- - return dst; - } - }
--- a/patches/security/20130201/6563318.patch Tue Mar 19 00:21:31 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -# HG changeset patch -# User coffeys -# Date 1355323250 0 -# Node ID 0da6d4cbcc77b3326756b52e6086b1262d52c214 -# Parent 042882b32f75d0e736c19f93688d37fb98d7d26d -6563318: RMI data sanitization -Reviewed-by: dmocek - -diff --git a/src/share/classes/sun/rmi/transport/proxy/CGIHandler.java b/src/share/classes/sun/rmi/transport/proxy/CGIHandler.java ---- openjdk/jdk/src/share/classes/sun/rmi/transport/proxy/CGIHandler.java -+++ openjdk/jdk/src/share/classes/sun/rmi/transport/proxy/CGIHandler.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 1996, 1998, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -150,7 +150,7 @@ public final class CGIHandler { - returnServerError(e.getMessage()); - } - else -- returnClientError("invalid command: " + command); -+ returnClientError("Invalid command."); - } catch (Exception e) { - returnServerError("internal error: " + e.getMessage()); - } -@@ -217,7 +217,7 @@ final class CGIForwardCommand implements - try { - port = Integer.parseInt(param); - } catch (NumberFormatException e) { -- throw new CGIClientException("invalid port number: " + param); -+ throw new CGIClientException("invalid port number."); - } - if (port <= 0 || port > 0xFFFF) - throw new CGIClientException("invalid port: " + port);
--- a/patches/security/20130201/6664509.patch Tue Mar 19 00:21:31 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1322 +0,0 @@ -# HG changeset patch -# User coffeys -# Date 1355432912 0 -# Node ID eed3ef0116a18e006c4e062b3c8d6d5a5e503a43 -# Parent bedb05bba7fc681e34f9c3ce03dc2daa4ec2ce28 -6664509: Add logging context -6664528: Find log level matching its name or value given at construction time -Reviewed-by: mchung - -diff --git a/src/share/classes/java/util/logging/Level.java b/src/share/classes/java/util/logging/Level.java ---- openjdk/jdk/src/share/classes/java/util/logging/Level.java -+++ openjdk/jdk/src/share/classes/java/util/logging/Level.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -24,6 +24,10 @@ - */ - - package java.util.logging; -+import java.util.ArrayList; -+import java.util.HashMap; -+import java.util.List; -+import java.util.Map; - import java.util.ResourceBundle; - - /** -@@ -59,7 +63,6 @@ import java.util.ResourceBundle; - */ - - public class Level implements java.io.Serializable { -- private static java.util.ArrayList<Level> known = new java.util.ArrayList<Level>(); - private static String defaultBundle = "sun.util.logging.resources.logging"; - - /** -@@ -76,6 +79,9 @@ public class Level implements java.io.Se - * @serial The resource bundle name to be used in localizing the level name. - */ - private final String resourceBundleName; -+ -+ // localized level name -+ private String localizedLevelName; - - /** - * OFF is a special level that can be used to turn off logging. -@@ -202,9 +208,8 @@ public class Level implements java.io.Se - this.name = name; - this.value = value; - this.resourceBundleName = resourceBundleName; -- synchronized (Level.class) { -- known.add(this); -- } -+ this.localizedLevelName = resourceBundleName == null ? name : null; -+ KnownLevel.add(this); - } - - /** -@@ -236,12 +241,76 @@ public class Level implements java.io.Se - * @return localized name - */ - public String getLocalizedName() { -+ return getLocalizedLevelName(); -+ } -+ -+ // package-private getLevelName() is used by the implementation -+ // instead of getName() to avoid calling the subclass's version -+ final String getLevelName() { -+ return this.name; -+ } -+ -+ final synchronized String getLocalizedLevelName() { -+ if (localizedLevelName != null) { -+ return localizedLevelName; -+ } -+ - try { - ResourceBundle rb = ResourceBundle.getBundle(resourceBundleName); -- return rb.getString(name); -+ localizedLevelName = rb.getString(name); - } catch (Exception ex) { -- return name; -+ localizedLevelName = name; - } -+ return localizedLevelName; -+ } -+ -+ // Returns a mirrored Level object that matches the given name as -+ // specified in the Level.parse method. Returns null if not found. -+ // -+ // It returns the same Level object as the one returned by Level.parse -+ // method if the given name is a non-localized name or integer. -+ // -+ // If the name is a localized name, findLevel and parse method may -+ // return a different level value if there is a custom Level subclass -+ // that overrides Level.getLocalizedName() to return a different string -+ // than what's returned by the default implementation. -+ // -+ static Level findLevel(String name) { -+ if (name == null) { -+ throw new NullPointerException(); -+ } -+ -+ KnownLevel level; -+ -+ // Look for a known Level with the given non-localized name. -+ level = KnownLevel.findByName(name); -+ if (level != null) { -+ return level.mirroredLevel; -+ } -+ -+ // Now, check if the given name is an integer. If so, -+ // first look for a Level with the given value and then -+ // if necessary create one. -+ try { -+ int x = Integer.parseInt(name); -+ level = KnownLevel.findByValue(x); -+ if (level == null) { -+ // add new Level -+ Level levelObject = new Level(name, x); -+ level = KnownLevel.findByValue(x); -+ } -+ return level.mirroredLevel; -+ } catch (NumberFormatException ex) { -+ // Not an integer. -+ // Drop through. -+ } -+ -+ level = KnownLevel.findByLocalizedLevelName(name); -+ if (level != null) { -+ return level.mirroredLevel; -+ } -+ -+ return null; - } - - /** -@@ -266,21 +335,15 @@ public class Level implements java.io.Se - // Serialization magic to prevent "doppelgangers". - // This is a performance optimization. - private Object readResolve() { -- synchronized (Level.class) { -- for (int i = 0; i < known.size(); i++) { -- Level other = known.get(i); -- if (this.name.equals(other.name) && this.value == other.value -- && (this.resourceBundleName == other.resourceBundleName || -- (this.resourceBundleName != null && -- this.resourceBundleName.equals(other.resourceBundleName)))) { -- return other; -- } -- } -- // Woops. Whoever sent us this object knows -- // about a new log level. Add it to our list. -- known.add(this); -- return this; -+ KnownLevel o = KnownLevel.matches(this); -+ if (o != null) { -+ return o.levelObject; - } -+ -+ // Woops. Whoever sent us this object knows -+ // about a new log level. Add it to our list. -+ Level level = new Level(this.name, this.value, this.resourceBundleName); -+ return level; - } - - /** -@@ -294,6 +357,7 @@ public class Level implements java.io.Se - * <li> "SEVERE" - * <li> "1000" - * </ul> -+ * - * @param name string to be parsed - * @throws NullPointerException if the name is null - * @throws IllegalArgumentException if the value is not valid. -@@ -313,12 +377,12 @@ public class Level implements java.io.Se - // Check that name is not null. - name.length(); - -+ KnownLevel level; -+ - // Look for a known Level with the given non-localized name. -- for (int i = 0; i < known.size(); i++) { -- Level l = known.get(i); -- if (name.equals(l.name)) { -- return l; -- } -+ level = KnownLevel.findByName(name); -+ if (level != null) { -+ return level.levelObject; - } - - // Now, check if the given name is an integer. If so, -@@ -326,27 +390,23 @@ public class Level implements java.io.Se - // if necessary create one. - try { - int x = Integer.parseInt(name); -- for (int i = 0; i < known.size(); i++) { -- Level l = known.get(i); -- if (l.value == x) { -- return l; -- } -+ level = KnownLevel.findByValue(x); -+ if (level == null) { -+ // add new Level -+ Level levelObject = new Level(name, x); -+ level = KnownLevel.findByValue(x); - } -- // Create a new Level. -- return new Level(name, x); -+ return level.levelObject; - } catch (NumberFormatException ex) { - // Not an integer. - // Drop through. - } -- -- // Finally, look for a known level with the given localized name, -+ // Finally, look for a known level with the given localized name, - // in the current default locale. - // This is relatively expensive, but not excessively so. -- for (int i = 0; i < known.size(); i++) { -- Level l = known.get(i); -- if (name.equals(l.getLocalizedName())) { -- return l; -- } -+ level = KnownLevel.findByLocalizedName(name); -+ if (level != null) { -+ return level.levelObject; - } - - // OK, we've tried everything and failed -@@ -373,4 +433,125 @@ public class Level implements java.io.Se - public int hashCode() { - return this.value; - } -+ -+ // KnownLevel class maintains the global list of all known levels. -+ // The API allows multiple custom Level instances of the same name/value -+ // be created. This class provides convenient methods to find a level -+ // by a given name, by a given value, or by a given localized name. -+ // -+ // KnownLevel wraps the following Level objects: -+ // 1. levelObject: standard Level object or custom Level object -+ // 2. mirroredLevel: Level object representing the level specified in the -+ // logging configuration. -+ // -+ // Level.getName, Level.getLocalizedName, Level.getResourceBundleName methods -+ // are non-final but the name and resource bundle name are parameters to -+ // the Level constructor. Use the mirroredLevel object instead of the -+ // levelObject to prevent the logging framework to execute foreign code -+ // implemented by untrusted Level subclass. -+ // -+ // Implementation Notes: -+ // If Level.getName, Level.getLocalizedName, Level.getResourceBundleName methods -+ // were final, the following KnownLevel implementation can be removed. -+ // Future API change should take this into consideration. -+ static final class KnownLevel { -+ private static Map<String, List<KnownLevel>> nameToLevels = -+ new HashMap<String, List<KnownLevel>>(); -+ private static Map<Integer, List<KnownLevel>> intToLevels = -+ new HashMap<Integer, List<KnownLevel>>(); -+ final Level levelObject; // instance of Level class or Level subclass -+ final Level mirroredLevel; // instance of Level class -+ KnownLevel(Level l) { -+ this.levelObject = l; -+ if (l.getClass() == Level.class) { -+ this.mirroredLevel = l; -+ } else { -+ this.mirroredLevel = new Level(l.name, l.value, l.resourceBundleName); -+ } -+ } -+ -+ static synchronized void add(Level l) { -+ // the mirroredLevel object is always added to the list -+ // before the custom Level instance -+ KnownLevel o = new KnownLevel(l); -+ List<KnownLevel> list = nameToLevels.get(l.name); -+ if (list == null) { -+ list = new ArrayList<KnownLevel>(); -+ nameToLevels.put(l.name, list); -+ } -+ list.add(o); -+ -+ list = intToLevels.get(l.value); -+ if (list == null) { -+ list = new ArrayList<KnownLevel>(); -+ intToLevels.put(l.value, list); -+ } -+ list.add(o); -+ } -+ -+ // Returns a KnownLevel with the given non-localized name. -+ static synchronized KnownLevel findByName(String name) { -+ List<KnownLevel> list = nameToLevels.get(name); -+ if (list != null) { -+ return list.get(0); -+ } -+ return null; -+ } -+ -+ // Returns a KnownLevel with the given value. -+ static synchronized KnownLevel findByValue(int value) { -+ List<KnownLevel> list = intToLevels.get(value); -+ if (list != null) { -+ return list.get(0); -+ } -+ return null; -+ } -+ -+ // Returns a KnownLevel with the given localized name matching -+ // by calling the Level.getLocalizedLevelName() method (i.e. found -+ // from the resourceBundle associated with the Level object). -+ // This method does not call Level.getLocalizedName() that may -+ // be overridden in a subclass implementation -+ static synchronized KnownLevel findByLocalizedLevelName(String name) { -+ for (List<KnownLevel> levels : nameToLevels.values()) { -+ for (KnownLevel l : levels) { -+ String lname = l.levelObject.getLocalizedLevelName(); -+ if (name.equals(lname)) { -+ return l; -+ } -+ } -+ } -+ return null; -+ } -+ -+ // Returns a KnownLevel with the given localized name matching -+ // by calling the Level.getLocalizedName() method -+ static synchronized KnownLevel findByLocalizedName(String name) { -+ for (List<KnownLevel> levels : nameToLevels.values()) { -+ for (KnownLevel l : levels) { -+ String lname = l.levelObject.getLocalizedName(); -+ if (name.equals(lname)) { -+ return l; -+ } -+ } -+ } -+ return null; -+ } -+ -+ static synchronized KnownLevel matches(Level l) { -+ List<KnownLevel> list = nameToLevels.get(l.name); -+ if (list != null) { -+ for (KnownLevel level : list) { -+ Level other = level.mirroredLevel; -+ if (l.value == other.value && -+ (l.resourceBundleName == other.resourceBundleName || -+ (l.resourceBundleName != null && -+ l.resourceBundleName.equals(other.resourceBundleName)))) { -+ return level; -+ } -+ } -+ } -+ return null; -+ } -+ } - } -diff --git a/src/share/classes/java/util/logging/LogManager.java b/src/share/classes/java/util/logging/LogManager.java ---- openjdk/jdk/src/share/classes/java/util/logging/LogManager.java -+++ openjdk/jdk/src/share/classes/java/util/logging/LogManager.java -@@ -34,6 +34,8 @@ import java.beans.PropertyChangeListener - import java.beans.PropertyChangeListener; - import java.beans.PropertyChangeSupport; - import java.net.URL; -+import sun.misc.JavaAWTAccess; -+import sun.misc.SharedSecrets; - import sun.security.action.GetPropertyAction; - - /** -@@ -155,11 +157,9 @@ public class LogManager { - = new PropertyChangeSupport(LogManager.class); - private final static Level defaultLevel = Level.INFO; - -- // Table of named Loggers that maps names to Loggers. -- private Hashtable<String,LoggerWeakRef> namedLoggers = -- new Hashtable<String,LoggerWeakRef>(); -- // Tree of named Loggers -- private LogNode root = new LogNode(null); -+ // LoggerContext for system loggers and user loggers -+ private final LoggerContext systemContext = new SystemLoggerContext(); -+ private final LoggerContext userContext = new UserLoggerContext(); - private Logger rootLogger; - - // Have we done the primordial reading of the configuration file? -@@ -197,12 +197,13 @@ public class LogManager { - - // Create and retain Logger for the root of the namespace. - manager.rootLogger = manager.new RootLogger(); -- manager.addLogger(manager.rootLogger); -+ manager.systemContext.addLogger(manager.rootLogger); -+ manager.userContext.addLogger(manager.rootLogger); - - // Adding the global Logger. Doing so in the Logger.<clinit> - // would deadlock with the LogManager.<clinit>. - Logger.global.setLogManager(manager); -- manager.addLogger(Logger.global); -+ manager.systemContext.addLogger(Logger.global); - - // We don't call readConfiguration() here, as we may be running - // very early in the JVM startup sequence. Instead readConfiguration -@@ -273,8 +274,8 @@ public class LogManager { - } - readPrimordialConfiguration = true; - try { -- AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() { -- public Object run() throws Exception { -+ AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() { -+ public Void run() throws Exception { - readConfiguration(); - return null; - } -@@ -326,6 +327,296 @@ public class LogManager { - changes.removePropertyChangeListener(l); - } - -+ // Returns the LoggerContext for the user code (i.e. application or AppContext). -+ // Loggers are isolated from each AppContext. -+ LoggerContext getUserContext() { -+ LoggerContext context = null; -+ -+ SecurityManager sm = System.getSecurityManager(); -+ JavaAWTAccess javaAwtAccess = SharedSecrets.getJavaAWTAccess(); -+ if (sm != null && javaAwtAccess != null) { -+ synchronized (javaAwtAccess) { -+ // AppContext.getAppContext() returns the system AppContext if called -+ // from a system thread but Logger.getLogger might be called from -+ // an applet code. Instead, find the AppContext of the applet code -+ // from the execution stack. -+ Object ecx = javaAwtAccess.getExecutionContext(); -+ if (ecx == null) { -+ // fall back to AppContext.getAppContext() -+ ecx = javaAwtAccess.getContext(); -+ } -+ context = (LoggerContext) javaAwtAccess.get(ecx, LoggerContext.class); -+ if (context == null) { -+ if (javaAwtAccess.isMainAppContext()) { -+ context = userContext; -+ } else { -+ context = new UserLoggerContext(); -+ context.addLogger(manager.rootLogger); -+ } -+ javaAwtAccess.put(ecx, LoggerContext.class, context); -+ } -+ } -+ } else { -+ context = userContext; -+ } -+ return context; -+ } -+ -+ LoggerContext getSystemContext() { -+ return systemContext; -+ } -+ -+ private List<LoggerContext> contexts() { -+ List<LoggerContext> cxs = new ArrayList<LoggerContext>(); -+ cxs.add(systemContext); -+ cxs.add(getUserContext()); -+ return cxs; -+ } -+ -+ static class LoggerContext { -+ // Table of named Loggers that maps names to Loggers. -+ -+ private final Hashtable<String, LoggerWeakRef> namedLoggers = -+ new Hashtable<String, LoggerWeakRef>(); -+ // Tree of named Loggers -+ private final LogNode root; -+ -+ private LoggerContext() { -+ this.root = new LogNode(null, this); -+ } -+ -+ synchronized Logger findLogger(String name) { -+ LoggerWeakRef ref = namedLoggers.get(name); -+ if (ref == null) { -+ return null; -+ } -+ Logger logger = ref.get(); -+ if (logger == null) { -+ // Hashtable holds stale weak reference -+ // to a logger which has been GC-ed. -+ removeLogger(name); -+ } -+ return logger; -+ } -+ -+ synchronized boolean addLogger(Logger logger) { -+ final String name = logger.getName(); -+ if (name == null) { -+ throw new NullPointerException(); -+ } -+ -+ // cleanup some Loggers that have been GC'ed -+ manager.drainLoggerRefQueueBounded(); -+ -+ LoggerWeakRef ref = namedLoggers.get(name); -+ if (ref != null) { -+ if (ref.get() == null) { -+ // It's possible that the Logger was GC'ed after the -+ // drainLoggerRefQueueBounded() call above so allow -+ // a new one to be registered. -+ removeLogger(name); -+ } else { -+ // We already have a registered logger with the given name. -+ return false; -+ } -+ } -+ -+ // We're adding a new logger. -+ // Note that we are creating a weak reference here. -+ ref = manager.new LoggerWeakRef(logger); -+ namedLoggers.put(name, ref); -+ -+ // Apply any initial level defined for the new logger. -+ Level level = manager.getLevelProperty(name + ".level", null); -+ if (level != null) { -+ doSetLevel(logger, level); -+ } -+ -+ // Do we have a per logger handler too? -+ // Note: this will add a 200ms penalty -+ manager.loadLoggerHandlers(logger, name, name + ".handlers"); -+ processParentHandlers(logger, name); -+ -+ // Find the new node and its parent. -+ LogNode node = getNode(name); -+ node.loggerRef = ref; -+ Logger parent = null; -+ LogNode nodep = node.parent; -+ while (nodep != null) { -+ LoggerWeakRef nodeRef = nodep.loggerRef; -+ if (nodeRef != null) { -+ parent = nodeRef.get(); -+ if (parent != null) { -+ break; -+ } -+ } -+ nodep = nodep.parent; -+ } -+ -+ if (parent != null) { -+ doSetParent(logger, parent); -+ } -+ // Walk over the children and tell them we are their new parent. -+ node.walkAndSetParent(logger); -+ // new LogNode is ready so tell the LoggerWeakRef about it -+ ref.setNode(node); -+ return true; -+ } -+ -+ void removeLogger(String name) { -+ namedLoggers.remove(name); -+ } -+ -+ synchronized Enumeration<String> getLoggerNames() { -+ return namedLoggers.keys(); -+ } -+ -+ Logger demandLogger(String name) { -+ return demandLogger(name, null); -+ } -+ -+ // Find or create a specified logger instance. If a logger has -+ // already been created with the given name it is returned. -+ // Otherwise a new logger instance is created and registered -+ // in the LogManager global namespace. -+ // This method will always return a non-null Logger object. -+ // Synchronization is not required here. All synchronization for -+ // adding a new Logger object is handled by addLogger(). -+ Logger demandLogger(String name, String resourceBundleName) { -+ Logger result = findLogger(name); -+ if (result == null) { -+ // only allocate the new logger once -+ Logger newLogger = new Logger(name, resourceBundleName); -+ do { -+ if (addLogger(newLogger)) { -+ // We successfully added the new Logger that we -+ // created above so return it without refetching. -+ return newLogger; -+ } -+ -+ // We didn't add the new Logger that we created above -+ // because another thread added a Logger with the same -+ // name after our null check above and before our call -+ // to addLogger(). We have to refetch the Logger because -+ // addLogger() returns a boolean instead of the Logger -+ // reference itself. However, if the thread that created -+ // the other Logger is not holding a strong reference to -+ // the other Logger, then it is possible for the other -+ // Logger to be GC'ed after we saw it in addLogger() and -+ // before we can refetch it. If it has been GC'ed then -+ // we'll just loop around and try again. -+ result = findLogger(name); -+ } while (result == null); -+ } -+ return result; -+ } -+ -+ // If logger.getUseParentHandlers() returns 'true' and any of the logger's -+ // parents have levels or handlers defined, make sure they are instantiated. -+ private void processParentHandlers(Logger logger, String name) { -+ int ix = 1; -+ for (;;) { -+ int ix2 = name.indexOf(".", ix); -+ if (ix2 < 0) { -+ break; -+ } -+ String pname = name.substring(0, ix2); -+ -+ if (manager.getProperty(pname + ".level") != null -+ || manager.getProperty(pname + ".handlers") != null) { -+ // This pname has a level/handlers definition. -+ // Make sure it exists. -+ demandLogger(pname); -+ } -+ ix = ix2 + 1; -+ } -+ } -+ -+ // Gets a node in our tree of logger nodes. -+ // If necessary, create it. -+ LogNode getNode(String name) { -+ if (name == null || name.equals("")) { -+ return root; -+ } -+ LogNode node = root; -+ while (name.length() > 0) { -+ int ix = name.indexOf("."); -+ String head; -+ if (ix > 0) { -+ head = name.substring(0, ix); -+ name = name.substring(ix + 1); -+ } else { -+ head = name; -+ name = ""; -+ } -+ if (node.children == null) { -+ node.children = new HashMap<String, LogNode>(); -+ } -+ LogNode child = node.children.get(head); -+ if (child == null) { -+ child = new LogNode(node, this); -+ node.children.put(head, child); -+ } -+ node = child; -+ } -+ return node; -+ } -+ } -+ -+ static class SystemLoggerContext extends LoggerContext { -+ // Default resource bundle for all system loggers -+ -+ Logger demandLogger(String name) { -+ // default to use the system logger's resource bundle -+ return super.demandLogger(name, Logger.SYSTEM_LOGGER_RB_NAME); -+ } -+ } -+ -+ static class UserLoggerContext extends LoggerContext { -+ -+ /** -+ * Returns a Logger of the given name if there is one registered -+ * in this context. Otherwise, it will return the one registered -+ * in the system context if there is one. The returned Logger -+ * instance may be initialized with a different resourceBundleName. -+ * If no such logger exists, a new Logger instance will be created -+ * and registered in this context. -+ */ -+ Logger demandLogger(String name, String resourceBundleName) { -+ Logger result = findLogger(name); -+ if (result == null) { -+ // use the system logger if exists; or allocate a new logger. -+ // The system logger is added to the app logger context so that -+ // any child logger created in the app logger context can have -+ // a system logger as its parent if already exist. -+ Logger logger = manager.systemContext.findLogger(name); -+ Logger newLogger = -+ logger != null ? logger : new Logger(name, resourceBundleName); -+ do { -+ if (addLogger(newLogger)) { -+ // We successfully added the new Logger that we -+ // created above so return it without refetching. -+ return newLogger; -+ } -+ -+ // We didn't add the new Logger that we created above -+ // because another thread added a Logger with the same -+ // name after our null check above and before our call -+ // to addLogger(). We have to refetch the Logger because -+ // addLogger() returns a boolean instead of the Logger -+ // reference itself. However, if the thread that created -+ // the other Logger is not holding a strong reference to -+ // the other Logger, then it is possible for the other -+ // Logger to be GC'ed after we saw it in addLogger() and -+ // before we can refetch it. If it has been GC'ed then -+ // we'll just loop around and try again. -+ result = findLogger(name); -+ } while (result == null); -+ } -+ return result; -+ } -+ } -+ - // Package-level method. - // Find or create a specified logger instance. If a logger has - // already been created with the given name it is returned. -@@ -339,27 +630,6 @@ public class LogManager { - result = getLogger(name); - } - return result; -- } -- -- // If logger.getUseParentHandlers() returns 'true' and any of the logger's -- // parents have levels or handlers defined, make sure they are instantiated. -- private void processParentHandlers(Logger logger, String name) { -- int ix = 1; -- for (;;) { -- int ix2 = name.indexOf(".", ix); -- if (ix2 < 0) { -- break; -- } -- String pname = name.substring(0,ix2); -- -- if (getProperty(pname+".level") != null || -- getProperty(pname+".handlers") != null) { -- // This pname has a level/handlers definition. -- // Make sure it exists. -- demandLogger(pname); -- } -- ix = ix2+1; -- } - } - - // Add new per logger handlers. -@@ -383,16 +653,17 @@ public class LogManager { - try { - Class clz = ClassLoader.getSystemClassLoader().loadClass(word); - Handler hdl = (Handler) clz.newInstance(); -- try { -- // Check if there is a property defining the -- // this handler's level. -- String levs = getProperty(word + ".level"); -- if (levs != null) { -- hdl.setLevel(Level.parse(levs)); -+ // Check if there is a property defining the -+ // this handler's level. -+ String levs = getProperty(word + ".level"); -+ if (levs != null) { -+ Level l = Level.findLevel(levs); -+ if (l != null) { -+ hdl.setLevel(l); -+ } else { -+ // Probably a bad level. Drop through. -+ System.err.println("Can't set level for " + word); - } -- } catch (Exception ex) { -- System.err.println("Can't set level for " + word); -- // Probably a bad level. Drop through. - } - // Add this Handler to the logger - logger.addHandler(hdl); -@@ -448,7 +719,7 @@ public class LogManager { - if (node != null) { - // if we have a LogNode, then we were a named Logger - // so clear namedLoggers weak ref to us -- manager.namedLoggers.remove(name); -+ node.context.removeLogger(name); - name = null; // clear our ref to the Logger's name - - node.loggerRef = null; // clear LogNode's weak ref to us -@@ -544,67 +815,11 @@ public class LogManager { - if (name == null) { - throw new NullPointerException(); - } -- -- // cleanup some Loggers that have been GC'ed -- drainLoggerRefQueueBounded(); -- -- LoggerWeakRef ref = namedLoggers.get(name); -- if (ref != null) { -- if (ref.get() == null) { -- // It's possible that the Logger was GC'ed after the -- // drainLoggerRefQueueBounded() call above so allow -- // a new one to be registered. -- namedLoggers.remove(name); -- } else { -- // We already have a registered logger with the given name. -- return false; -- } -+ if (systemContext.findLogger(name) != null) { -+ return false; - } -- -- // We're adding a new logger. -- // Note that we are creating a weak reference here. -- ref = new LoggerWeakRef(logger); -- namedLoggers.put(name, ref); -- -- // Apply any initial level defined for the new logger. -- Level level = getLevelProperty(name+".level", null); -- if (level != null) { -- doSetLevel(logger, level); -- } -- -- // Do we have a per logger handler too? -- // Note: this will add a 200ms penalty -- loadLoggerHandlers(logger, name, name+".handlers"); -- processParentHandlers(logger, name); -- -- // Find the new node and its parent. -- LogNode node = findNode(name); -- node.loggerRef = ref; -- Logger parent = null; -- LogNode nodep = node.parent; -- while (nodep != null) { -- LoggerWeakRef nodeRef = nodep.loggerRef; -- if (nodeRef != null) { -- parent = nodeRef.get(); -- if (parent != null) { -- break; -- } -- } -- nodep = nodep.parent; -- } -- -- if (parent != null) { -- doSetParent(logger, parent); -- } -- // Walk over the children and tell them we are their new parent. -- node.walkAndSetParent(logger); -- -- // new LogNode is ready so tell the LoggerWeakRef about it -- ref.setNode(node); -- -- return true; -+ return getUserContext().addLogger(logger); - } -- - - // Private method to set a level on a logger. - // If necessary, we raise privilege before doing the call. -@@ -644,36 +859,6 @@ public class LogManager { - }}); - } - -- // Find a node in our tree of logger nodes. -- // If necessary, create it. -- private LogNode findNode(String name) { -- if (name == null || name.equals("")) { -- return root; -- } -- LogNode node = root; -- while (name.length() > 0) { -- int ix = name.indexOf("."); -- String head; -- if (ix > 0) { -- head = name.substring(0,ix); -- name = name.substring(ix+1); -- } else { -- head = name; -- name = ""; -- } -- if (node.children == null) { -- node.children = new HashMap<String,LogNode>(); -- } -- LogNode child = node.children.get(head); -- if (child == null) { -- child = new LogNode(node); -- node.children.put(head, child); -- } -- node = child; -- } -- return node; -- } -- - /** - * Method to find a named logger. - * <p> -@@ -689,18 +874,16 @@ public class LogManager { - * @param name name of the logger - * @return matching logger or null if none is found - */ -- public synchronized Logger getLogger(String name) { -- LoggerWeakRef ref = namedLoggers.get(name); -- if (ref == null) { -- return null; -- } -- Logger logger = ref.get(); -- if (logger == null) { -- // Hashtable holds stale weak reference -- // to a logger which has been GC-ed. -- namedLoggers.remove(name); -- } -- return logger; -+ public Logger getLogger(String name) { -+ // return the first logger added -+ // -+ // once a system logger is added in the system context, no one can -+ // adds a logger with the same name in the global context -+ // (see LogManager.addLogger). So if there is a logger in the global -+ // context with the same name as one in the system context, it must be -+ // added before the system logger was created. -+ Logger logger = getUserContext().findLogger(name); -+ return logger != null ? logger : systemContext.findLogger(name); - } - - /** -@@ -719,8 +902,12 @@ public class LogManager { - * <p> - * @return enumeration of logger name strings - */ -- public synchronized Enumeration<String> getLoggerNames() { -- return namedLoggers.keys(); -+ public Enumeration<String> getLoggerNames() { -+ // only return unique names -+ Set<String> names = -+ new HashSet<String>(Collections.list(systemContext.getLoggerNames())); -+ names.addAll(Collections.list(getUserContext().getLoggerNames())); -+ return Collections.enumeration(names); - } - - /** -@@ -805,20 +992,20 @@ public class LogManager { - // the global handlers, if they haven't been initialized yet. - initializedGlobalHandlers = true; - } -- Enumeration enum_ = getLoggerNames(); -- while (enum_.hasMoreElements()) { -- String name = (String)enum_.nextElement(); -- resetLogger(name); -+ for (LoggerContext cx : contexts()) { -+ Enumeration<String> enum_ = cx.getLoggerNames(); -+ while (enum_.hasMoreElements()) { -+ String name = enum_.nextElement(); -+ Logger logger = cx.findLogger(name); -+ if (logger != null) { -+ resetLogger(logger); -+ } -+ } - } - } - -- - // Private method to reset an individual target logger. -- private void resetLogger(String name) { -- Logger logger = getLogger(name); -- if (logger == null) { -- return; -- } -+ private void resetLogger(Logger logger) { - // Close all the Logger's handlers. - Handler[] targets = logger.getHandlers(); - for (int i = 0; i < targets.length; i++) { -@@ -830,6 +1017,7 @@ public class LogManager { - // Problems closing a handler? Keep going... - } - } -+ String name = logger.getName(); - if (name != null && name.equals("")) { - // This is the root logger. - logger.setLevel(defaultLevel); -@@ -977,11 +1165,8 @@ public class LogManager { - if (val == null) { - return defaultValue; - } -- try { -- return Level.parse(val.trim()); -- } catch (Exception ex) { -- return defaultValue; -- } -+ Level l = Level.findLevel(val.trim()); -+ return l != null ? l : defaultValue; - } - - // Package private method to get a filter property. -@@ -1072,9 +1257,11 @@ public class LogManager { - HashMap<String,LogNode> children; - LoggerWeakRef loggerRef; - LogNode parent; -+ final LoggerContext context; - -- LogNode(LogNode parent) { -+ LogNode(LogNode parent, LoggerContext context) { - this.parent = parent; -+ this.context = context; - } - - // Recursive method to walk the tree below a node and set -@@ -1133,7 +1320,7 @@ public class LogManager { - // Private method to be called when the configuration has - // changed to apply any level settings to any pre-existing loggers. - synchronized private void setLevelsOnExistingLoggers() { -- Enumeration enum_ = props.propertyNames(); -+ Enumeration<?> enum_ = props.propertyNames(); - while (enum_.hasMoreElements()) { - String key = (String)enum_.nextElement(); - if (!key.endsWith(".level")) { -@@ -1147,11 +1334,13 @@ public class LogManager { - System.err.println("Bad level value for property: " + key); - continue; - } -- Logger l = getLogger(name); -- if (l == null) { -- continue; -+ for (LoggerContext cx : contexts()) { -+ Logger l = cx.findLogger(name); -+ if (l == null) { -+ continue; -+ } -+ l.setLevel(level); - } -- l.setLevel(level); - } - } - -diff --git a/src/share/classes/java/util/logging/Logger.java b/src/share/classes/java/util/logging/Logger.java ---- openjdk/jdk/src/share/classes/java/util/logging/Logger.java -+++ openjdk/jdk/src/share/classes/java/util/logging/Logger.java -@@ -29,6 +29,7 @@ import java.util.*; - import java.util.*; - import java.security.*; - import java.lang.ref.WeakReference; -+import java.util.logging.LogManager.LoggerContext; - - /** - * A Logger object is used to log messages for a specific -@@ -276,6 +277,26 @@ public class Logger { - } - } - -+ // Until all JDK code converted to call sun.util.logging.PlatformLogger -+ // (see 7054233), we need to determine if Logger.getLogger is to add -+ // a system logger or user logger. -+ // -+ // As an interim solution, if the immediate caller whose caller loader is -+ // null, we assume it's a system logger and add it to the system context. -+ private static LoggerContext getLoggerContext() { -+ LogManager manager = LogManager.getLogManager(); -+ SecurityManager sm = System.getSecurityManager(); -+ if (sm != null) { -+ // 0: Reflection 1: Logger.getLoggerContext 2: Logger.getLogger 3: caller -+ final int SKIP_FRAMES = 3; -+ Class<?> caller = sun.reflect.Reflection.getCallerClass(SKIP_FRAMES); -+ if (caller.getClassLoader() == null) { -+ return manager.getSystemContext(); -+ } -+ } -+ return manager.getUserContext(); -+ } -+ - /** - * Find or create a logger for a named subsystem. If a logger has - * already been created with the given name it is returned. Otherwise -@@ -304,8 +325,8 @@ public class Logger { - * @throws NullPointerException if the name is null. - */ - public static synchronized Logger getLogger(String name) { -- LogManager manager = LogManager.getLogManager(); -- return manager.demandLogger(name); -+ LoggerContext context = getLoggerContext(); -+ return context.demandLogger(name); - } - - /** -@@ -348,8 +369,8 @@ public class Logger { - * @throws NullPointerException if the name is null. - */ - public static synchronized Logger getLogger(String name, String resourceBundleName) { -- LogManager manager = LogManager.getLogManager(); -- Logger result = manager.demandLogger(name); -+ LoggerContext context = getLoggerContext(); -+ Logger result = context.demandLogger(name, resourceBundleName); - if (result.resourceBundleName == null) { - // Note: we may get a MissingResourceException here. - result.setupResourceInfo(resourceBundleName); -@@ -513,7 +534,7 @@ public class Logger { - private void doLog(LogRecord lr) { - lr.setLoggerName(name); - String ebname = getEffectiveResourceBundleName(); -- if (ebname != null) { -+ if (ebname != null && !ebname.equals(SYSTEM_LOGGER_RB_NAME)) { - lr.setResourceBundleName(ebname); - lr.setResourceBundle(findResourceBundle(ebname)); - } -@@ -1271,6 +1292,22 @@ public class Logger { - // May also return null if we can't find the resource bundle and - // there is no suitable previous cached value. - -+ static final String SYSTEM_LOGGER_RB_NAME = "sun.util.logging.resources.logging"; -+ -+ private static ResourceBundle findSystemResourceBundle(final Locale locale) { -+ // the resource bundle is in a restricted package -+ return AccessController.doPrivileged(new PrivilegedAction<ResourceBundle>() { -+ public ResourceBundle run() { -+ try { -+ return ResourceBundle.getBundle(SYSTEM_LOGGER_RB_NAME, -+ locale); -+ } catch (MissingResourceException e) { -+ throw new InternalError(e.toString()); -+ } -+ } -+ }); -+ } -+ - private synchronized ResourceBundle findResourceBundle(String name) { - // Return a null bundle for a null name. - if (name == null) { -@@ -1282,6 +1319,13 @@ public class Logger { - // Normally we should hit on our simple one entry cache. - if (catalog != null && currentLocale == catalogLocale - && name == catalogName) { -+ return catalog; -+ } -+ -+ if (name.equals(SYSTEM_LOGGER_RB_NAME)) { -+ catalog = findSystemResourceBundle(currentLocale); -+ catalogName = name; -+ catalogLocale = currentLocale; - return catalog; - } - -diff --git a/src/share/classes/java/util/logging/Logging.java b/src/share/classes/java/util/logging/Logging.java ---- openjdk/jdk/src/share/classes/java/util/logging/Logging.java -+++ openjdk/jdk/src/share/classes/java/util/logging/Logging.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -34,15 +34,15 @@ import java.util.ArrayList; - * - * The <tt>LoggingMXBean</tt> interface provides a standard - * method for management access to the individual -- * java.util.Logger objects available at runtime. -+ * {@code Logger} objects available at runtime. - * - * @author Ron Mann - * @author Mandy Chung - * @since 1.5 - * - * @see javax.management -- * @see java.util.Logger -- * @see java.util.LogManager -+ * @see Logger -+ * @see LogManager - */ - class Logging implements LoggingMXBean { - -@@ -75,7 +75,7 @@ class Logging implements LoggingMXBean { - if (level == null) { - return EMPTY_STRING; - } else { -- return level.getName(); -+ return level.getLevelName(); - } - } - -@@ -94,7 +94,10 @@ class Logging implements LoggingMXBean { - Level level = null; - if (levelName != null) { - // parse will throw IAE if logLevel is invalid -- level = Level.parse(levelName); -+ level = Level.findLevel(levelName); -+ if (level == null) { -+ throw new IllegalArgumentException("Unknown level \"" + levelName + "\""); -+ } - } - - logger.setLevel(level); -diff --git a/src/share/classes/java/util/logging/SimpleFormatter.java b/src/share/classes/java/util/logging/SimpleFormatter.java ---- openjdk/jdk/src/share/classes/java/util/logging/SimpleFormatter.java -+++ openjdk/jdk/src/share/classes/java/util/logging/SimpleFormatter.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -83,7 +83,7 @@ public class SimpleFormatter extends For - } - sb.append(lineSeparator); - String message = formatMessage(record); -- sb.append(record.getLevel().getLocalizedName()); -+ sb.append(record.getLevel().getLocalizedLevelName()); - sb.append(": "); - sb.append(message); - sb.append(lineSeparator); -diff --git a/src/share/classes/sun/awt/AppContext.java b/src/share/classes/sun/awt/AppContext.java ---- openjdk/jdk/src/share/classes/sun/awt/AppContext.java -+++ openjdk/jdk/src/share/classes/sun/awt/AppContext.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -275,7 +275,7 @@ public final class AppContext { - if ((recent != null) && (recent.thread == currentThread)) { - appContext = recent.appContext; // Cache hit - } else { -- appContext = (AppContext)AccessController.doPrivileged( -+ appContext = (AppContext)AccessController.doPrivileged( - new PrivilegedAction() { - public Object run() { - // Get the current ThreadGroup, and look for it and its -@@ -319,19 +319,25 @@ public final class AppContext { - // Before we return the main "system" AppContext, check to - // see if there's an AWTSecurityManager installed. If so, - // allow it to choose the AppContext to return. -- SecurityManager securityManager = System.getSecurityManager(); -- if ((securityManager != null) && -- (securityManager instanceof AWTSecurityManager)) { -- AWTSecurityManager awtSecMgr = -- (AWTSecurityManager)securityManager; -- AppContext secAppContext = awtSecMgr.getAppContext(); -- if (secAppContext != null) { -- appContext = secAppContext; // Return what we're told -- } -+ AppContext secAppContext = getExecutionAppContext(); -+ if (secAppContext != null) { -+ appContext = secAppContext; // Return what we're told - } - } - - return appContext; -+ } -+ -+ private final static AppContext getExecutionAppContext() { -+ SecurityManager securityManager = System.getSecurityManager(); -+ if ((securityManager != null) && -+ (securityManager instanceof AWTSecurityManager)) -+ { -+ AWTSecurityManager awtSecMgr = (AWTSecurityManager) securityManager; -+ AppContext secAppContext = awtSecMgr.getAppContext(); -+ return secAppContext; // Return what we're told -+ } -+ return null; - } - - private long DISPOSAL_TIMEOUT = 5000; // Default to 5-second timeout -@@ -786,6 +792,21 @@ public final class AppContext { - public boolean isMainAppContext() { - return (numAppContexts == 1); - } -+ public Object getContext() { -+ return getAppContext(); -+ } -+ public Object getExecutionContext() { -+ return getExecutionAppContext(); -+ } -+ public Object get(Object context, Object key) { -+ return ((AppContext)context).get(key); -+ } -+ public void put(Object context, Object key, Object value) { -+ ((AppContext)context).put(key, value); -+ } -+ public void remove(Object context, Object key) { -+ ((AppContext)context).remove(key); -+ } - }); - } - } -diff --git a/src/share/classes/sun/misc/JavaAWTAccess.java b/src/share/classes/sun/misc/JavaAWTAccess.java ---- openjdk/jdk/src/share/classes/sun/misc/JavaAWTAccess.java -+++ openjdk/jdk/src/share/classes/sun/misc/JavaAWTAccess.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -24,6 +24,14 @@ package sun.misc; - package sun.misc; - - public interface JavaAWTAccess { -+ public Object getContext(); -+ public Object getExecutionContext(); -+ -+ public Object get(Object context, Object key); -+ public void put(Object context, Object key, Object value); -+ public void remove(Object context, Object key); -+ -+ // convenience methods whose context is the object returned by getContext() - public Object get(Object key); - public void put(Object key, Object value); - public void remove(Object key); -diff --git a/src/share/lib/security/java.security b/src/share/lib/security/java.security ---- openjdk/jdk/src/share/lib/security/java.security -+++ openjdk/jdk/src/share/lib/security/java.security -@@ -129,7 +129,10 @@ system.scope=sun.security.provider.Ident - # been granted. - package.access=sun.,\ - com.sun.xml.internal.,\ -- com.sun.imageio. -+ com.sun.imageio.,\ -+ com.sun.istack.internal.,\ -+ com.sun.jmx.defaults.,\ -+ com.sun.jmx.remote.util. - - # - # List of comma-separated packages that start with or equal this string -@@ -143,7 +146,10 @@ package.access=sun.,\ - # - package.definition=sun.,\ - com.sun.xml.internal.,\ -- com.sun.imageio. -+ com.sun.imageio.,\ -+ com.sun.istack.internal.,\ -+ com.sun.jmx.defaults.,\ -+ com.sun.jmx.remote.util. - - # - # Determines whether this properties file can be appended to
--- a/patches/security/20130201/6776941.patch Tue Mar 19 00:21:31 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,272 +0,0 @@ -# HG changeset patch -# User dholmes -# Date 1350872930 14400 -# Node ID 6088f35106866940de257456c8eee21b130d5ff5 -# Parent 21487ef30163da2a96369eee80a3bf5e94612017 -6776941: Improve thread pool shutdown -Reviewed-by: dl, skoivu - -diff --git a/src/share/classes/java/util/concurrent/ThreadPoolExecutor.java b/src/share/classes/java/util/concurrent/ThreadPoolExecutor.java ---- openjdk/jdk/src/share/classes/java/util/concurrent/ThreadPoolExecutor.java -+++ openjdk/jdk/src/share/classes/java/util/concurrent/ThreadPoolExecutor.java -@@ -34,8 +34,10 @@ - */ - - package java.util.concurrent; --import java.util.concurrent.locks.*; --import java.util.concurrent.atomic.*; -+import java.util.concurrent.locks.AbstractQueuedSynchronizer; -+import java.util.concurrent.locks.Condition; -+import java.util.concurrent.locks.ReentrantLock; -+import java.util.concurrent.atomic.AtomicInteger; - import java.util.*; - - /** -@@ -491,10 +493,15 @@ public class ThreadPoolExecutor extends - * policy limiting the number of threads. Even though it is not - * treated as an error, failure to create threads may result in - * new tasks being rejected or existing ones remaining stuck in -- * the queue. On the other hand, no special precautions exist to -- * handle OutOfMemoryErrors that might be thrown while trying to -- * create threads, since there is generally no recourse from -- * within this class. -+ * the queue. -+ * -+ * We go further and preserve pool invariants even in the face of -+ * errors such as OutOfMemoryError, that might be thrown while -+ * trying to create threads. Such errors are rather common due to -+ * the need to allocate a native stack in Thread#start, and users -+ * will want to perform clean pool shutdown to clean up. There -+ * will likely be enough memory available for the cleanup code to -+ * complete without encountering yet another OutOfMemoryError. - */ - private volatile ThreadFactory threadFactory; - -@@ -568,9 +575,13 @@ public class ThreadPoolExecutor extends - * task execution. This protects against interrupts that are - * intended to wake up a worker thread waiting for a task from - * instead interrupting a task being run. We implement a simple -- * non-reentrant mutual exclusion lock rather than use ReentrantLock -- * because we do not want worker tasks to be able to reacquire the -- * lock when they invoke pool control methods like setCorePoolSize. -+ * non-reentrant mutual exclusion lock rather than use -+ * ReentrantLock because we do not want worker tasks to be able to -+ * reacquire the lock when they invoke pool control methods like -+ * setCorePoolSize. Additionally, to suppress interrupts until -+ * the thread actually starts running tasks, we initialize lock -+ * state to a negative value, and clear it upon start (in -+ * runWorker). - */ - private final class Worker - extends AbstractQueuedSynchronizer -@@ -594,6 +605,7 @@ public class ThreadPoolExecutor extends - * @param firstTask the first task (null if none) - */ - Worker(Runnable firstTask) { -+ setState(-1); // inhibit interrupts until runWorker - this.firstTask = firstTask; - this.thread = getThreadFactory().newThread(this); - } -@@ -609,7 +621,7 @@ public class ThreadPoolExecutor extends - // The value 1 represents the locked state. - - protected boolean isHeldExclusively() { -- return getState() == 1; -+ return getState() != 0; - } - - protected boolean tryAcquire(int unused) { -@@ -630,6 +642,16 @@ public class ThreadPoolExecutor extends - public boolean tryLock() { return tryAcquire(1); } - public void unlock() { release(1); } - public boolean isLocked() { return isHeldExclusively(); } -+ -+ void interruptIfStarted() { -+ Thread t; -+ if (getState() >= 0 && (t = thread) != null && !t.isInterrupted()) { -+ try { -+ t.interrupt(); -+ } catch (SecurityException ignore) { -+ } -+ } -+ } - } - - /* -@@ -729,10 +751,7 @@ public class ThreadPoolExecutor extends - mainLock.lock(); - try { - for (Worker w : workers) { -- try { -- w.thread.interrupt(); -- } catch (SecurityException ignore) { -- } -+ w.interruptIfStarted(); - } - } finally { - mainLock.unlock(); -@@ -789,19 +808,6 @@ public class ThreadPoolExecutor extends - } - - private static final boolean ONLY_ONE = true; -- -- /** -- * Ensures that unless the pool is stopping, the current thread -- * does not have its interrupt set. This requires a double-check -- * of state in case the interrupt was cleared concurrently with a -- * shutdownNow -- if so, the interrupt is re-enabled. -- */ -- private void clearInterruptsForTaskRun() { -- if (runStateLessThan(ctl.get(), STOP) && -- Thread.interrupted() && -- runStateAtLeast(ctl.get(), STOP)) -- Thread.currentThread().interrupt(); -- } - - /* - * Misc utilities, most of which are also exported to -@@ -862,12 +868,13 @@ public class ThreadPoolExecutor extends - * Checks if a new worker can be added with respect to current - * pool state and the given bound (either core or maximum). If so, - * the worker count is adjusted accordingly, and, if possible, a -- * new worker is created and started running firstTask as its -+ * new worker is created and started, running firstTask as its - * first task. This method returns false if the pool is stopped or - * eligible to shut down. It also returns false if the thread -- * factory fails to create a thread when asked, which requires a -- * backout of workerCount, and a recheck for termination, in case -- * the existence of this worker was holding up termination. -+ * factory fails to create a thread when asked. If the thread -+ * creation fails, either due to the thread factory returning -+ * null, or due to an exception (typically OutOfMemoryError in -+ * Thread#start), we roll back cleanly. - * - * @param firstTask the task the new thread should run first (or - * null if none). Workers are created with an initial first task -@@ -910,46 +917,65 @@ public class ThreadPoolExecutor extends - } - } - -- Worker w = new Worker(firstTask); -- Thread t = w.thread; -+ boolean workerStarted = false; -+ boolean workerAdded = false; -+ Worker w = null; -+ try { -+ final ReentrantLock mainLock = this.mainLock; -+ w = new Worker(firstTask); -+ final Thread t = w.thread; -+ if (t != null) { -+ mainLock.lock(); -+ try { -+ // Recheck while holding lock. -+ // Back out on ThreadFactory failure or if -+ // shut down before lock acquired. -+ int c = ctl.get(); -+ int rs = runStateOf(c); - -+ if (rs < SHUTDOWN || -+ (rs == SHUTDOWN && firstTask == null)) { -+ if (t.isAlive()) // precheck that t is startable -+ throw new IllegalThreadStateException(); -+ workers.add(w); -+ int s = workers.size(); -+ if (s > largestPoolSize) -+ largestPoolSize = s; -+ workerAdded = true; -+ } -+ } finally { -+ mainLock.unlock(); -+ } -+ if (workerAdded) { -+ t.start(); -+ workerStarted = true; -+ } -+ } -+ } finally { -+ if (! workerStarted) -+ addWorkerFailed(w); -+ } -+ return workerStarted; -+ } -+ -+ /** -+ * Rolls back the worker thread creation. -+ * - removes worker from workers, if present -+ * - decrements worker count -+ * - rechecks for termination, in case the existence of this -+ * worker was holding up termination -+ */ -+ private void addWorkerFailed(Worker w) { - final ReentrantLock mainLock = this.mainLock; - mainLock.lock(); - try { -- // Recheck while holding lock. -- // Back out on ThreadFactory failure or if -- // shut down before lock acquired. -- int c = ctl.get(); -- int rs = runStateOf(c); -- -- if (t == null || -- (rs >= SHUTDOWN && -- ! (rs == SHUTDOWN && -- firstTask == null))) { -- decrementWorkerCount(); -- tryTerminate(); -- return false; -- } -- -- workers.add(w); -- -- int s = workers.size(); -- if (s > largestPoolSize) -- largestPoolSize = s; -+ if (w != null) -+ workers.remove(w); -+ decrementWorkerCount(); -+ tryTerminate(); - } finally { - mainLock.unlock(); - } -- -- t.start(); -- // It is possible (but unlikely) for a thread to have been -- // added to workers, but not yet started, during transition to -- // STOP, which could result in a rare missed interrupt, -- // because Thread.interrupt is not guaranteed to have any effect -- // on a non-yet-started Thread (see Thread#interrupt). -- if (runStateOf(ctl.get()) == STOP && ! t.isInterrupted()) -- t.interrupt(); -- -- return true; - } - - /** -@@ -1096,15 +1122,25 @@ public class ThreadPoolExecutor extends - * @param w the worker - */ - final void runWorker(Worker w) { -+ Thread wt = Thread.currentThread(); - Runnable task = w.firstTask; - w.firstTask = null; -+ w.unlock(); // allow interrupts - boolean completedAbruptly = true; - try { - while (task != null || (task = getTask()) != null) { - w.lock(); -- clearInterruptsForTaskRun(); -+ // If pool is stopping, ensure thread is interrupted; -+ // if not, ensure thread is not interrupted. This -+ // requires a recheck in second case to deal with -+ // shutdownNow race while clearing interrupt -+ if ((runStateAtLeast(ctl.get(), STOP) || -+ (Thread.interrupted() && -+ runStateAtLeast(ctl.get(), STOP))) && -+ !wt.isInterrupted()) -+ wt.interrupt(); - try { -- beforeExecute(w.thread, task); -+ beforeExecute(wt, task); - Throwable thrown = null; - try { - task.run();
--- a/patches/security/20130201/7141694.patch Tue Mar 19 00:21:31 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,87 +0,0 @@ -# HG changeset patch -# User mbankal -# Date 1355396891 28800 -# Node ID 7eb471f1efdd127f982e53b290c1fece845a897c -# Parent 58fdb67fcacc67693fc43b5601e88bd7c216f850 -7141694: Improving CORBA internals -Reviewed-by: coffeys, ahgross - -diff --git a/src/share/classes/com/sun/corba/se/spi/orb/ORB.java b/src/share/classes/com/sun/corba/se/spi/orb/ORB.java ---- openjdk/corba/src/share/classes/com/sun/corba/se/spi/orb/ORB.java -+++ openjdk/corba/src/share/classes/com/sun/corba/se/spi/orb/ORB.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2002, 2004, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -98,6 +98,7 @@ import com.sun.corba.se.impl.presentatio - import com.sun.corba.se.impl.presentation.rmi.PresentationManagerImpl ; - - import com.sun.corba.se.impl.orbutil.ORBClassLoader ; -+import sun.awt.AppContext; - - public abstract class ORB extends com.sun.corba.se.org.omg.CORBA.ORB - implements Broker, TypeCodeFactory -@@ -173,14 +174,7 @@ public abstract class ORB extends com.su - - private MonitoringManager monitoringManager; - -- // There is only one instance of the PresentationManager -- // that is shared between all ORBs. This is necessary -- // because RMI-IIOP requires the PresentationManager in -- // places where no ORB is available, so the PresentationManager -- // must be global. It is initialized here as well. -- protected static PresentationManager globalPM = null ; -- -- static { -+ private static PresentationManager setupPresentationManager() { - staticWrapper = ORBUtilSystemException.get( - CORBALogDomains.RPC_PRESENTATION ) ; - -@@ -220,17 +214,26 @@ public abstract class ORB extends com.su - } - ) ; - -- globalPM = new PresentationManagerImpl( useDynamicStub ) ; -- globalPM.setStubFactoryFactory( false, -+ PresentationManager pm = new PresentationManagerImpl( useDynamicStub ) ; -+ pm.setStubFactoryFactory( false, - PresentationDefaults.getStaticStubFactoryFactory() ) ; -- globalPM.setStubFactoryFactory( true, dynamicStubFactoryFactory ) ; -+ pm.setStubFactoryFactory( true, dynamicStubFactoryFactory ) ; -+ return pm; - } - -- /** Get the single instance of the PresentationManager -+ /** -+ * Returns the Presentation Manager for the current thread group, using the ThreadGroup-specific -+ * AppContext to hold it. Creates and records one if needed. - */ -- public static PresentationManager getPresentationManager() -+ public static PresentationManager getPresentationManager() - { -- return globalPM ; -+ AppContext ac = AppContext.getAppContext(); -+ PresentationManager pm = (PresentationManager) ac.get(PresentationManager.class); -+ if (pm == null) { -+ pm = setupPresentationManager(); -+ ac.put(PresentationManager.class, pm); -+ } -+ return pm; - } - - /** Get the appropriate StubFactoryFactory. This -@@ -240,8 +243,9 @@ public abstract class ORB extends com.su - public static PresentationManager.StubFactoryFactory - getStubFactoryFactory() - { -- boolean useDynamicStubs = globalPM.useDynamicStubs() ; -- return globalPM.getStubFactoryFactory( useDynamicStubs ) ; -+ PresentationManager gPM = getPresentationManager(); -+ boolean useDynamicStubs = gPM.useDynamicStubs() ; -+ return gPM.getStubFactoryFactory( useDynamicStubs ) ; - } - - protected ORB()
--- a/patches/security/20130201/7173145.patch Tue Mar 19 00:21:31 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,22 +0,0 @@ -# HG changeset patch -# User anthony -# Date 1350043271 -14400 -# Node ID ce11c5c59cb8672eeddf9d5ce49563ccbc387854 -# Parent 9c2a2aae44a46e0b63b913987672d1488fa4e7a5 -7173145: Improve in-memory representation of splashscreens -Reviewed-by: bae, mschoene - -diff --git a/src/share/native/sun/awt/splashscreen/splashscreen_jpeg.c b/src/share/native/sun/awt/splashscreen/splashscreen_jpeg.c ---- openjdk/jdk/src/share/native/sun/awt/splashscreen/splashscreen_jpeg.c -+++ openjdk/jdk/src/share/native/sun/awt/splashscreen/splashscreen_jpeg.c -@@ -133,6 +133,10 @@ SplashDecodeJpeg(Splash * splash, struct - ImageFormat srcFormat; - - jpeg_read_header(cinfo, TRUE); -+ -+ // SplashScreen jpeg converter expects data in RGB format only -+ cinfo->out_color_space = JCS_RGB; -+ - jpeg_start_decompress(cinfo); - - SplashCleanup(splash);
--- a/patches/security/20130201/7186945.patch Tue Mar 19 00:21:31 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,10819 +0,0 @@ -# HG changeset patch -# User miroslawzn -# Date 1354324090 28800 -# Node ID f3f9b711bb1228f4598ded7eb0380c32eba63521 -# Parent 9bbc6817b00c3e9d4eba05d53a8a20b45947ea03 -7186945: Unpack200 improvement -7186957: Improve Pack200 data validation -7186946: Refine unpacker resource usage -Reviewed-by: ksrini - -diff --git a/src/share/classes/com/sun/java/util/jar/pack/BandStructure.java b/src/share/classes/com/sun/java/util/jar/pack/BandStructure.java ---- openjdk/jdk/src/share/classes/com/sun/java/util/jar/pack/BandStructure.java -+++ openjdk/jdk/src/share/classes/com/sun/java/util/jar/pack/BandStructure.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2001, 2005, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -22,7 +22,6 @@ - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -- - package com.sun.java.util.jar.pack; - - import java.io.*; -@@ -62,20 +61,20 @@ class BandStructure implements Constants - - /** Call this exactly once, early, to specify the archive major version. */ - public void initPackageMajver(int packageMajver) throws IOException { -- assert(packageMajver > 0 && packageMajver < 0x10000); -- if (this.packageMajver > 0) { -- throw new IOException( -- "Package majver is already initialized to " + this.packageMajver+ -- "; new setting is " + packageMajver); -- } -- this.packageMajver = packageMajver; -- adjustToMajver(); -+ assert(packageMajver > 0 && packageMajver < 0x10000); -+ if (this.packageMajver > 0) { -+ throw new IOException( -+ "Package majver is already initialized to " + this.packageMajver+ -+ "; new setting is " + packageMajver); -+ } -+ this.packageMajver = packageMajver; -+ adjustToMajver(); - } - public int getPackageMajver() { -- if (packageMajver < 0) { -- throw new RuntimeException("Package majver not yet initialized"); -- } -- return packageMajver; -+ if (packageMajver < 0) { -+ throw new RuntimeException("Package majver not yet initialized"); -+ } -+ return packageMajver; - } - - private final boolean isReader = this instanceof PackageReader; -@@ -103,163 +102,163 @@ class BandStructure implements Constants - final static Coding MDELTA5 = Coding.of(5,64,2).getDeltaCoding(); - - final private static Coding[] basicCodings = { -- // Table of "Canonical BHSD Codings" from Pack200 spec. -- null, // _meta_default -+ // Table of "Canonical BHSD Codings" from Pack200 spec. -+ null, // _meta_default - -- // Fixed-length codings: -- Coding.of(1,256,0), -- Coding.of(1,256,1), -- Coding.of(1,256,0).getDeltaCoding(), -- Coding.of(1,256,1).getDeltaCoding(), -- Coding.of(2,256,0), -- Coding.of(2,256,1), -- Coding.of(2,256,0).getDeltaCoding(), -- Coding.of(2,256,1).getDeltaCoding(), -- Coding.of(3,256,0), -- Coding.of(3,256,1), -- Coding.of(3,256,0).getDeltaCoding(), -- Coding.of(3,256,1).getDeltaCoding(), -- Coding.of(4,256,0), -- Coding.of(4,256,1), -- Coding.of(4,256,0).getDeltaCoding(), -- Coding.of(4,256,1).getDeltaCoding(), -+ // Fixed-length codings: -+ Coding.of(1,256,0), -+ Coding.of(1,256,1), -+ Coding.of(1,256,0).getDeltaCoding(), -+ Coding.of(1,256,1).getDeltaCoding(), -+ Coding.of(2,256,0), -+ Coding.of(2,256,1), -+ Coding.of(2,256,0).getDeltaCoding(), -+ Coding.of(2,256,1).getDeltaCoding(), -+ Coding.of(3,256,0), -+ Coding.of(3,256,1), -+ Coding.of(3,256,0).getDeltaCoding(), -+ Coding.of(3,256,1).getDeltaCoding(), -+ Coding.of(4,256,0), -+ Coding.of(4,256,1), -+ Coding.of(4,256,0).getDeltaCoding(), -+ Coding.of(4,256,1).getDeltaCoding(), - -- // Full-range variable-length codings: -- Coding.of(5, 4,0), -- Coding.of(5, 4,1), -- Coding.of(5, 4,2), -- Coding.of(5, 16,0), -- Coding.of(5, 16,1), -- Coding.of(5, 16,2), -- Coding.of(5, 32,0), -- Coding.of(5, 32,1), -- Coding.of(5, 32,2), -- Coding.of(5, 64,0), -- Coding.of(5, 64,1), -- Coding.of(5, 64,2), -- Coding.of(5,128,0), -- Coding.of(5,128,1), -- Coding.of(5,128,2), -+ // Full-range variable-length codings: -+ Coding.of(5, 4,0), -+ Coding.of(5, 4,1), -+ Coding.of(5, 4,2), -+ Coding.of(5, 16,0), -+ Coding.of(5, 16,1), -+ Coding.of(5, 16,2), -+ Coding.of(5, 32,0), -+ Coding.of(5, 32,1), -+ Coding.of(5, 32,2), -+ Coding.of(5, 64,0), -+ Coding.of(5, 64,1), -+ Coding.of(5, 64,2), -+ Coding.of(5,128,0), -+ Coding.of(5,128,1), -+ Coding.of(5,128,2), - -- Coding.of(5, 4,0).getDeltaCoding(), -- Coding.of(5, 4,1).getDeltaCoding(), -- Coding.of(5, 4,2).getDeltaCoding(), -- Coding.of(5, 16,0).getDeltaCoding(), -- Coding.of(5, 16,1).getDeltaCoding(), -- Coding.of(5, 16,2).getDeltaCoding(), -- Coding.of(5, 32,0).getDeltaCoding(), -- Coding.of(5, 32,1).getDeltaCoding(), -- Coding.of(5, 32,2).getDeltaCoding(), -- Coding.of(5, 64,0).getDeltaCoding(), -- Coding.of(5, 64,1).getDeltaCoding(), -- Coding.of(5, 64,2).getDeltaCoding(), -- Coding.of(5,128,0).getDeltaCoding(), -- Coding.of(5,128,1).getDeltaCoding(), -- Coding.of(5,128,2).getDeltaCoding(), -+ Coding.of(5, 4,0).getDeltaCoding(), -+ Coding.of(5, 4,1).getDeltaCoding(), -+ Coding.of(5, 4,2).getDeltaCoding(), -+ Coding.of(5, 16,0).getDeltaCoding(), -+ Coding.of(5, 16,1).getDeltaCoding(), -+ Coding.of(5, 16,2).getDeltaCoding(), -+ Coding.of(5, 32,0).getDeltaCoding(), -+ Coding.of(5, 32,1).getDeltaCoding(), -+ Coding.of(5, 32,2).getDeltaCoding(), -+ Coding.of(5, 64,0).getDeltaCoding(), -+ Coding.of(5, 64,1).getDeltaCoding(), -+ Coding.of(5, 64,2).getDeltaCoding(), -+ Coding.of(5,128,0).getDeltaCoding(), -+ Coding.of(5,128,1).getDeltaCoding(), -+ Coding.of(5,128,2).getDeltaCoding(), - -- // Variable length subrange codings: -- Coding.of(2,192,0), -- Coding.of(2,224,0), -- Coding.of(2,240,0), -- Coding.of(2,248,0), -- Coding.of(2,252,0), -+ // Variable length subrange codings: -+ Coding.of(2,192,0), -+ Coding.of(2,224,0), -+ Coding.of(2,240,0), -+ Coding.of(2,248,0), -+ Coding.of(2,252,0), - -- Coding.of(2, 8,0).getDeltaCoding(), -- Coding.of(2, 8,1).getDeltaCoding(), -- Coding.of(2, 16,0).getDeltaCoding(), -- Coding.of(2, 16,1).getDeltaCoding(), -- Coding.of(2, 32,0).getDeltaCoding(), -- Coding.of(2, 32,1).getDeltaCoding(), -- Coding.of(2, 64,0).getDeltaCoding(), -- Coding.of(2, 64,1).getDeltaCoding(), -- Coding.of(2,128,0).getDeltaCoding(), -- Coding.of(2,128,1).getDeltaCoding(), -- Coding.of(2,192,0).getDeltaCoding(), -- Coding.of(2,192,1).getDeltaCoding(), -- Coding.of(2,224,0).getDeltaCoding(), -- Coding.of(2,224,1).getDeltaCoding(), -- Coding.of(2,240,0).getDeltaCoding(), -- Coding.of(2,240,1).getDeltaCoding(), -- Coding.of(2,248,0).getDeltaCoding(), -- Coding.of(2,248,1).getDeltaCoding(), -+ Coding.of(2, 8,0).getDeltaCoding(), -+ Coding.of(2, 8,1).getDeltaCoding(), -+ Coding.of(2, 16,0).getDeltaCoding(), -+ Coding.of(2, 16,1).getDeltaCoding(), -+ Coding.of(2, 32,0).getDeltaCoding(), -+ Coding.of(2, 32,1).getDeltaCoding(), -+ Coding.of(2, 64,0).getDeltaCoding(), -+ Coding.of(2, 64,1).getDeltaCoding(), -+ Coding.of(2,128,0).getDeltaCoding(), -+ Coding.of(2,128,1).getDeltaCoding(), -+ Coding.of(2,192,0).getDeltaCoding(), -+ Coding.of(2,192,1).getDeltaCoding(), -+ Coding.of(2,224,0).getDeltaCoding(), -+ Coding.of(2,224,1).getDeltaCoding(), -+ Coding.of(2,240,0).getDeltaCoding(), -+ Coding.of(2,240,1).getDeltaCoding(), -+ Coding.of(2,248,0).getDeltaCoding(), -+ Coding.of(2,248,1).getDeltaCoding(), - -- Coding.of(3,192,0), -- Coding.of(3,224,0), -- Coding.of(3,240,0), -- Coding.of(3,248,0), -- Coding.of(3,252,0), -+ Coding.of(3,192,0), -+ Coding.of(3,224,0), -+ Coding.of(3,240,0), -+ Coding.of(3,248,0), -+ Coding.of(3,252,0), - -- Coding.of(3, 8,0).getDeltaCoding(), -- Coding.of(3, 8,1).getDeltaCoding(), -- Coding.of(3, 16,0).getDeltaCoding(), -- Coding.of(3, 16,1).getDeltaCoding(), -- Coding.of(3, 32,0).getDeltaCoding(), -- Coding.of(3, 32,1).getDeltaCoding(), -- Coding.of(3, 64,0).getDeltaCoding(), -- Coding.of(3, 64,1).getDeltaCoding(), -- Coding.of(3,128,0).getDeltaCoding(), -- Coding.of(3,128,1).getDeltaCoding(), -- Coding.of(3,192,0).getDeltaCoding(), -- Coding.of(3,192,1).getDeltaCoding(), -- Coding.of(3,224,0).getDeltaCoding(), -- Coding.of(3,224,1).getDeltaCoding(), -- Coding.of(3,240,0).getDeltaCoding(), -- Coding.of(3,240,1).getDeltaCoding(), -- Coding.of(3,248,0).getDeltaCoding(), -- Coding.of(3,248,1).getDeltaCoding(), -+ Coding.of(3, 8,0).getDeltaCoding(), -+ Coding.of(3, 8,1).getDeltaCoding(), -+ Coding.of(3, 16,0).getDeltaCoding(), -+ Coding.of(3, 16,1).getDeltaCoding(), -+ Coding.of(3, 32,0).getDeltaCoding(), -+ Coding.of(3, 32,1).getDeltaCoding(), -+ Coding.of(3, 64,0).getDeltaCoding(), -+ Coding.of(3, 64,1).getDeltaCoding(), -+ Coding.of(3,128,0).getDeltaCoding(), -+ Coding.of(3,128,1).getDeltaCoding(), -+ Coding.of(3,192,0).getDeltaCoding(), -+ Coding.of(3,192,1).getDeltaCoding(), -+ Coding.of(3,224,0).getDeltaCoding(), -+ Coding.of(3,224,1).getDeltaCoding(), -+ Coding.of(3,240,0).getDeltaCoding(), -+ Coding.of(3,240,1).getDeltaCoding(), -+ Coding.of(3,248,0).getDeltaCoding(), -+ Coding.of(3,248,1).getDeltaCoding(), - -- Coding.of(4,192,0), -- Coding.of(4,224,0), -- Coding.of(4,240,0), -- Coding.of(4,248,0), -- Coding.of(4,252,0), -+ Coding.of(4,192,0), -+ Coding.of(4,224,0), -+ Coding.of(4,240,0), -+ Coding.of(4,248,0), -+ Coding.of(4,252,0), - -- Coding.of(4, 8,0).getDeltaCoding(), -- Coding.of(4, 8,1).getDeltaCoding(), -- Coding.of(4, 16,0).getDeltaCoding(), -- Coding.of(4, 16,1).getDeltaCoding(), -- Coding.of(4, 32,0).getDeltaCoding(), -- Coding.of(4, 32,1).getDeltaCoding(), -- Coding.of(4, 64,0).getDeltaCoding(), -- Coding.of(4, 64,1).getDeltaCoding(), -- Coding.of(4,128,0).getDeltaCoding(), -- Coding.of(4,128,1).getDeltaCoding(), -- Coding.of(4,192,0).getDeltaCoding(), -- Coding.of(4,192,1).getDeltaCoding(), -- Coding.of(4,224,0).getDeltaCoding(), -- Coding.of(4,224,1).getDeltaCoding(), -- Coding.of(4,240,0).getDeltaCoding(), -- Coding.of(4,240,1).getDeltaCoding(), -- Coding.of(4,248,0).getDeltaCoding(), -- Coding.of(4,248,1).getDeltaCoding(), -+ Coding.of(4, 8,0).getDeltaCoding(), -+ Coding.of(4, 8,1).getDeltaCoding(), -+ Coding.of(4, 16,0).getDeltaCoding(), -+ Coding.of(4, 16,1).getDeltaCoding(), -+ Coding.of(4, 32,0).getDeltaCoding(), -+ Coding.of(4, 32,1).getDeltaCoding(), -+ Coding.of(4, 64,0).getDeltaCoding(), -+ Coding.of(4, 64,1).getDeltaCoding(), -+ Coding.of(4,128,0).getDeltaCoding(), -+ Coding.of(4,128,1).getDeltaCoding(), -+ Coding.of(4,192,0).getDeltaCoding(), -+ Coding.of(4,192,1).getDeltaCoding(), -+ Coding.of(4,224,0).getDeltaCoding(), -+ Coding.of(4,224,1).getDeltaCoding(), -+ Coding.of(4,240,0).getDeltaCoding(), -+ Coding.of(4,240,1).getDeltaCoding(), -+ Coding.of(4,248,0).getDeltaCoding(), -+ Coding.of(4,248,1).getDeltaCoding(), - -- null -+ null - }; - final private static HashMap basicCodingIndexes; - static { -- assert(basicCodings[_meta_default] == null); -- assert(basicCodings[_meta_canon_min] != null); -- assert(basicCodings[_meta_canon_max] != null); -- HashMap map = new HashMap(); -- for (int i = 0; i < basicCodings.length; i++) { -- Coding c = basicCodings[i]; -- if (c == null) continue; -- assert(i >= _meta_canon_min); -- assert(i <= _meta_canon_max); -- map.put(c, new Integer(i)); -- } -- basicCodingIndexes = map; -+ assert(basicCodings[_meta_default] == null); -+ assert(basicCodings[_meta_canon_min] != null); -+ assert(basicCodings[_meta_canon_max] != null); -+ HashMap map = new HashMap(); -+ for (int i = 0; i < basicCodings.length; i++) { -+ Coding c = basicCodings[i]; -+ if (c == null) continue; -+ assert(i >= _meta_canon_min); -+ assert(i <= _meta_canon_max); -+ map.put(c, new Integer(i)); -+ } -+ basicCodingIndexes = map; - } - public static Coding codingForIndex(int i) { -- return i < basicCodings.length ? basicCodings[i] : null; -+ return i < basicCodings.length ? basicCodings[i] : null; - } - public static int indexOf(Coding c) { -- Integer i = (Integer) basicCodingIndexes.get(c); -- if (i == null) return 0; -- return i.intValue(); -+ Integer i = (Integer) basicCodingIndexes.get(c); -+ if (i == null) return 0; -+ return i.intValue(); - } - public static Coding[] getBasicCodings() { -- return (Coding[]) basicCodings.clone(); -+ return (Coding[]) basicCodings.clone(); - } - - protected byte[] bandHeaderBytes; // used for input only -@@ -267,31 +266,31 @@ class BandStructure implements Constants - protected int bandHeaderBytePos0; // for debug - - protected CodingMethod getBandHeader(int XB, Coding regularCoding) { -- CodingMethod[] res = {null}; -- // push back XB onto the band header bytes -- bandHeaderBytes[--bandHeaderBytePos] = (byte) XB; -- bandHeaderBytePos0 = bandHeaderBytePos; -- // scan forward through XB and any additional band header bytes -- bandHeaderBytePos = parseMetaCoding(bandHeaderBytes, -- bandHeaderBytePos, -- regularCoding, -- res); -- return res[0]; -+ CodingMethod[] res = {null}; -+ // push back XB onto the band header bytes -+ bandHeaderBytes[--bandHeaderBytePos] = (byte) XB; -+ bandHeaderBytePos0 = bandHeaderBytePos; -+ // scan forward through XB and any additional band header bytes -+ bandHeaderBytePos = parseMetaCoding(bandHeaderBytes, -+ bandHeaderBytePos, -+ regularCoding, -+ res); -+ return res[0]; - } - - public static int parseMetaCoding(byte[] bytes, int pos, Coding dflt, CodingMethod[] res) { -- if ((bytes[pos] & 0xFF) == _meta_default) { -- res[0] = dflt; -- return pos+1; -- } -- int pos2; -- pos2 = Coding.parseMetaCoding(bytes, pos, dflt, res); -- if (pos2 > pos) return pos2; -- pos2 = PopulationCoding.parseMetaCoding(bytes, pos, dflt, res); -- if (pos2 > pos) return pos2; -- pos2 = AdaptiveCoding.parseMetaCoding(bytes, pos, dflt, res); -- if (pos2 > pos) return pos2; -- throw new RuntimeException("Bad meta-coding op "+(bytes[pos]&0xFF)); -+ if ((bytes[pos] & 0xFF) == _meta_default) { -+ res[0] = dflt; -+ return pos+1; -+ } -+ int pos2; -+ pos2 = Coding.parseMetaCoding(bytes, pos, dflt, res); -+ if (pos2 > pos) return pos2; -+ pos2 = PopulationCoding.parseMetaCoding(bytes, pos, dflt, res); -+ if (pos2 > pos) return pos2; -+ pos2 = AdaptiveCoding.parseMetaCoding(bytes, pos, dflt, res); -+ if (pos2 > pos) return pos2; -+ throw new RuntimeException("Bad meta-coding op "+(bytes[pos]&0xFF)); - } - - static final int SHORT_BAND_HEURISTIC = 100; -@@ -311,11 +310,11 @@ class BandStructure implements Constants - public static final int DONE_PHASE = 8; // done writing or reading - - static boolean phaseIsRead(int p) { -- return (p % 2) == 0; -+ return (p % 2) == 0; - } - static int phaseCmp(int p0, int p1) { -- assert((p0 % 2) == (p1 % 2) || (p0 % 8) == 0 || (p1 % 8) == 0); -- return p0 - p1; -+ assert((p0 % 2) == (p1 % 2) || (p0 % 8) == 0 || (p1 % 8) == 0); -+ return p0 - p1; - } - - /** The packed file is divided up into a number of segments. -@@ -332,7 +331,7 @@ class BandStructure implements Constants - * - * The three phases for reading a packed file are EXPECT, READ, - * and DISBURSE. -- * 1. For each band, the expected number of integers is determined. -+ * 1. For each band, the expected number of integers is determined. - * 2. The data is actually read from the file into the band. - * 3. The band pays out its values as requested, in an ad hoc order. - * -@@ -340,696 +339,695 @@ class BandStructure implements Constants - * Clearly, these phases must be properly ordered WRT each other. - */ - abstract class Band { -- private int phase = NO_PHASE; -- private final String name; -+ private int phase = NO_PHASE; -+ private final String name; - -- private int valuesExpected; -+ private int valuesExpected; - -- protected long outputSize = -1; // cache -+ protected long outputSize = -1; // cache - -- final public Coding regularCoding; -+ final public Coding regularCoding; - -- final public int seqForDebug; -- public int elementCountForDebug; -+ final public int seqForDebug; -+ public int elementCountForDebug; - - -- protected Band(String name, Coding regularCoding) { -- this.name = name; -- this.regularCoding = regularCoding; -- this.seqForDebug = ++nextSeqForDebug; -- if (verbose > 2) -- Utils.log.fine("Band "+seqForDebug+" is "+name); -- // caller must call init -- } -+ protected Band(String name, Coding regularCoding) { -+ this.name = name; -+ this.regularCoding = regularCoding; -+ this.seqForDebug = ++nextSeqForDebug; -+ if (verbose > 2) -+ Utils.log.fine("Band "+seqForDebug+" is "+name); -+ // caller must call init -+ } - -- public Band init() { -- // Cannot due this from the constructor, because constructor -- // may wish to initialize some subclass variables. -- // Set initial phase for reading or writing: -- if (isReader) -- readyToExpect(); -- else -- readyToCollect(); -- return this; -- } -+ public Band init() { -+ // Cannot due this from the constructor, because constructor -+ // may wish to initialize some subclass variables. -+ // Set initial phase for reading or writing: -+ if (isReader) -+ readyToExpect(); -+ else -+ readyToCollect(); -+ return this; -+ } - -- // common operations -- boolean isReader() { return isReader; } -- int phase() { return phase; } -- String name() { return name; } -+ // common operations -+ boolean isReader() { return isReader; } -+ int phase() { return phase; } -+ String name() { return name; } - -- /** Return -1 if data buffer not allocated, else max length. */ -- public abstract int capacity(); -+ /** Return -1 if data buffer not allocated, else max length. */ -+ public abstract int capacity(); - -- /** Allocate data buffer to specified length. */ -- protected abstract void setCapacity(int cap); -+ /** Allocate data buffer to specified length. */ -+ protected abstract void setCapacity(int cap); - -- /** Return current number of values in buffer, which must exist. */ -- public abstract int length(); -+ /** Return current number of values in buffer, which must exist. */ -+ public abstract int length(); - -- protected abstract int valuesRemainingForDebug(); -+ protected abstract int valuesRemainingForDebug(); - -- public final int valuesExpected() { -- return valuesExpected; -- } -+ public final int valuesExpected() { -+ return valuesExpected; -+ } - -- /** Write out bytes, encoding the values. */ -- public final void writeTo(OutputStream out) throws IOException { -- assert(assertReadyToWriteTo(this, out)); -- setPhase(WRITE_PHASE); -- // subclasses continue by writing their contents to output -- writeDataTo(out); -- doneWriting(); -- } -+ /** Write out bytes, encoding the values. */ -+ public final void writeTo(OutputStream out) throws IOException { -+ assert(assertReadyToWriteTo(this, out)); -+ setPhase(WRITE_PHASE); -+ // subclasses continue by writing their contents to output -+ writeDataTo(out); -+ doneWriting(); -+ } - -- abstract void chooseBandCodings() throws IOException; -+ abstract void chooseBandCodings() throws IOException; - -- public final long outputSize() { -- if (outputSize >= 0) { -- long size = outputSize; -- assert(size == computeOutputSize()); -- return size; -- } -- return computeOutputSize(); -- } -+ public final long outputSize() { -+ if (outputSize >= 0) { -+ long size = outputSize; -+ assert(size == computeOutputSize()); -+ return size; -+ } -+ return computeOutputSize(); -+ } - -- protected abstract long computeOutputSize(); -+ protected abstract long computeOutputSize(); - -- abstract protected void writeDataTo(OutputStream out) throws IOException; -+ abstract protected void writeDataTo(OutputStream out) throws IOException; - -- /** Expect a certain number of values. */ -- void expectLength(int l) { -- assert(assertPhase(this, EXPECT_PHASE)); -- assert(valuesExpected == 0); // all at once -- assert(l >= 0); -- valuesExpected = l; -- } -- /** Expect more values. (Multiple calls accumulate.) */ -- void expectMoreLength(int l) { -- assert(assertPhase(this, EXPECT_PHASE)); -- valuesExpected += l; -- } -+ /** Expect a certain number of values. */ -+ void expectLength(int l) { -+ assert(assertPhase(this, EXPECT_PHASE)); -+ assert(valuesExpected == 0); // all at once -+ assert(l >= 0); -+ valuesExpected = l; -+ } -+ /** Expect more values. (Multiple calls accumulate.) */ -+ void expectMoreLength(int l) { -+ assert(assertPhase(this, EXPECT_PHASE)); -+ valuesExpected += l; -+ } - - -- /// Phase change markers. -+ /// Phase change markers. - -- private void readyToCollect() { // called implicitly by constructor -- setCapacity(1); -- setPhase(COLLECT_PHASE); -- } -- protected void doneWriting() { -- assert(assertPhase(this, WRITE_PHASE)); -- setPhase(DONE_PHASE); -- } -- private void readyToExpect() { // called implicitly by constructor -- setPhase(EXPECT_PHASE); -- } -- /** Read in bytes, decoding the values. */ -- public final void readFrom(InputStream in) throws IOException { -- assert(assertReadyToReadFrom(this, in)); -- setCapacity(valuesExpected()); -- setPhase(READ_PHASE); -- // subclasses continue by reading their contents from input: -- readDataFrom(in); -- readyToDisburse(); -- } -- abstract protected void readDataFrom(InputStream in) throws IOException; -- protected void readyToDisburse() { -- if (verbose > 1) Utils.log.fine("readyToDisburse "+this); -- setPhase(DISBURSE_PHASE); -- } -- public void doneDisbursing() { -- assert(assertPhase(this, DISBURSE_PHASE)); -- setPhase(DONE_PHASE); -- } -- public final void doneWithUnusedBand() { -- if (isReader) { -- assert(assertPhase(this, EXPECT_PHASE)); -- assert(valuesExpected() == 0); -- // Fast forward: -- setPhase(READ_PHASE); -- setPhase(DISBURSE_PHASE); -- setPhase(DONE_PHASE); -- } else { -- setPhase(FROZEN_PHASE); -- } -- } -+ private void readyToCollect() { // called implicitly by constructor -+ setCapacity(1); -+ setPhase(COLLECT_PHASE); -+ } -+ protected void doneWriting() { -+ assert(assertPhase(this, WRITE_PHASE)); -+ setPhase(DONE_PHASE); -+ } -+ private void readyToExpect() { // called implicitly by constructor -+ setPhase(EXPECT_PHASE); -+ } -+ /** Read in bytes, decoding the values. */ -+ public final void readFrom(InputStream in) throws IOException { -+ assert(assertReadyToReadFrom(this, in)); -+ setCapacity(valuesExpected()); -+ setPhase(READ_PHASE); -+ // subclasses continue by reading their contents from input: -+ readDataFrom(in); -+ readyToDisburse(); -+ } -+ abstract protected void readDataFrom(InputStream in) throws IOException; -+ protected void readyToDisburse() { -+ if (verbose > 1) Utils.log.fine("readyToDisburse "+this); -+ setPhase(DISBURSE_PHASE); -+ } -+ public void doneDisbursing() { -+ assert(assertPhase(this, DISBURSE_PHASE)); -+ setPhase(DONE_PHASE); -+ } -+ public final void doneWithUnusedBand() { -+ if (isReader) { -+ assert(assertPhase(this, EXPECT_PHASE)); -+ assert(valuesExpected() == 0); -+ // Fast forward: -+ setPhase(READ_PHASE); -+ setPhase(DISBURSE_PHASE); -+ setPhase(DONE_PHASE); -+ } else { -+ setPhase(FROZEN_PHASE); -+ } -+ } - -- protected void setPhase(int newPhase) { -- assert(assertPhaseChangeOK(this, phase, newPhase)); -- this.phase = newPhase; -- } -+ protected void setPhase(int newPhase) { -+ assert(assertPhaseChangeOK(this, phase, newPhase)); -+ this.phase = newPhase; -+ } - -- protected int lengthForDebug = -1; // DEBUG ONLY -- public String toString() { // DEBUG ONLY -- int length = (lengthForDebug != -1 ? lengthForDebug : length()); -- String str = name; -- if (length != 0) -- str += "[" + length + "]"; -- if (elementCountForDebug != 0) -- str += "(" + elementCountForDebug + ")"; -- return str; -- } -+ protected int lengthForDebug = -1; // DEBUG ONLY -+ public String toString() { // DEBUG ONLY -+ int length = (lengthForDebug != -1 ? lengthForDebug : length()); -+ String str = name; -+ if (length != 0) -+ str += "[" + length + "]"; -+ if (elementCountForDebug != 0) -+ str += "(" + elementCountForDebug + ")"; -+ return str; -+ } - } - - class ValueBand extends Band { -- private int[] values; // must be null in EXPECT phase -- private int length; -- private int valuesDisbursed; -+ private int[] values; // must be null in EXPECT phase -+ private int length; -+ private int valuesDisbursed; - -- private CodingMethod bandCoding; -- private byte[] metaCoding; -+ private CodingMethod bandCoding; -+ private byte[] metaCoding; - -- protected ValueBand(String name, Coding regularCoding) { -- super(name, regularCoding); -- } -+ protected ValueBand(String name, Coding regularCoding) { -+ super(name, regularCoding); -+ } - -- public int capacity() { -- return values == null ? -1 : values.length; -- } -+ public int capacity() { -+ return values == null ? -1 : values.length; -+ } - -- /** Declare predicted or needed capacity. */ -- protected void setCapacity(int cap) { -- assert(length <= cap); -- if (cap == -1) { values = null; return; } -- values = realloc(values, cap); -- } -+ /** Declare predicted or needed capacity. */ -+ protected void setCapacity(int cap) { -+ assert(length <= cap); -+ if (cap == -1) { values = null; return; } -+ values = realloc(values, cap); -+ } - -- public int length() { -- return length; -- } -- protected int valuesRemainingForDebug() { -- return length - valuesDisbursed; -- } -- protected int valueAtForDebug(int i) { -- return values[i]; -- } -+ public int length() { -+ return length; -+ } -+ protected int valuesRemainingForDebug() { -+ return length - valuesDisbursed; -+ } -+ protected int valueAtForDebug(int i) { -+ return values[i]; -+ } - -- void patchValue(int i, int value) { -- // Only one use for this. -- assert(this == archive_header_S); -- assert(i == AH_ARCHIVE_SIZE_HI || i == AH_ARCHIVE_SIZE_LO); -- assert(i < length); // must have already output a dummy -- values[i] = value; -- outputSize = -1; // decache -- } -+ void patchValue(int i, int value) { -+ // Only one use for this. -+ assert(this == archive_header_S); -+ assert(i == AH_ARCHIVE_SIZE_HI || i == AH_ARCHIVE_SIZE_LO); -+ assert(i < length); // must have already output a dummy -+ values[i] = value; -+ outputSize = -1; // decache -+ } - -- protected void initializeValues(int[] values) { -- assert(assertCanChangeLength(this)); -- assert(length == 0); -- this.values = values; -- this.length = values.length; -- } -+ protected void initializeValues(int[] values) { -+ assert(assertCanChangeLength(this)); -+ assert(length == 0); -+ this.values = values; -+ this.length = values.length; -+ } - -- /** Collect one value, or store one decoded value. */ -- protected void addValue(int x) { -- assert(assertCanChangeLength(this)); -- if (length == values.length) -- setCapacity(length < 1000 ? length * 10 : length * 2); -- values[length++] = x; -- } -+ /** Collect one value, or store one decoded value. */ -+ protected void addValue(int x) { -+ assert(assertCanChangeLength(this)); -+ if (length == values.length) -+ setCapacity(length < 1000 ? length * 10 : length * 2); -+ values[length++] = x; -+ } - -- private boolean canVaryCoding() { -- if (!optVaryCodings) return false; -- if (length == 0) return false; -- // Can't read band_headers w/o the archive header: -- if (this == archive_header_0) return false; -- if (this == archive_header_S) return false; -- if (this == archive_header_1) return false; -- // BYTE1 bands can't vary codings, but the others can. -- // All that's needed for the initial escape is at least -- // 256 negative values or more than 256 non-negative values -- return (regularCoding.min() <= -256 || regularCoding.max() >= 256); -- } -+ private boolean canVaryCoding() { -+ if (!optVaryCodings) return false; -+ if (length == 0) return false; -+ // Can't read band_headers w/o the archive header: -+ if (this == archive_header_0) return false; -+ if (this == archive_header_S) return false; -+ if (this == archive_header_1) return false; -+ // BYTE1 bands can't vary codings, but the others can. -+ // All that's needed for the initial escape is at least -+ // 256 negative values or more than 256 non-negative values -+ return (regularCoding.min() <= -256 || regularCoding.max() >= 256); -+ } - -- private boolean shouldVaryCoding() { -- assert(canVaryCoding()); -- if (effort < MAX_EFFORT && length < SHORT_BAND_HEURISTIC) -- return false; -- return true; -- } -+ private boolean shouldVaryCoding() { -+ assert(canVaryCoding()); -+ if (effort < MAX_EFFORT && length < SHORT_BAND_HEURISTIC) -+ return false; -+ return true; -+ } - -- protected void chooseBandCodings() throws IOException { -- boolean canVary = canVaryCoding(); -- if (!canVary || !shouldVaryCoding()) { -- if (regularCoding.canRepresent(values, 0, length)) { -- bandCoding = regularCoding; -- } else { -- assert(canVary); -- if (verbose > 1) -- Utils.log.fine("regular coding fails in band "+name()); -- bandCoding = UNSIGNED5; -- } -- outputSize = -1; -- } else { -- int[] sizes = {0,0}; -- bandCoding = chooseCoding(values, 0, length, -- regularCoding, name(), -- sizes); -- outputSize = sizes[CodingChooser.BYTE_SIZE]; -- if (outputSize == 0) // CodingChooser failed to size it. -- outputSize = -1; -- } -+ protected void chooseBandCodings() throws IOException { -+ boolean canVary = canVaryCoding(); -+ if (!canVary || !shouldVaryCoding()) { -+ if (regularCoding.canRepresent(values, 0, length)) { -+ bandCoding = regularCoding; -+ } else { -+ assert(canVary); -+ if (verbose > 1) -+ Utils.log.fine("regular coding fails in band "+name()); -+ bandCoding = UNSIGNED5; -+ } -+ outputSize = -1; -+ } else { -+ int[] sizes = {0,0}; -+ bandCoding = chooseCoding(values, 0, length, -+ regularCoding, name(), -+ sizes); -+ outputSize = sizes[CodingChooser.BYTE_SIZE]; -+ if (outputSize == 0) // CodingChooser failed to size it. -+ outputSize = -1; -+ } - -- // Compute and save the meta-coding bytes also. -- if (bandCoding != regularCoding) { -- metaCoding = bandCoding.getMetaCoding(regularCoding); -- if (verbose > 1) { -- Utils.log.fine("alternate coding "+this+" "+bandCoding); -- } -- } else if (canVary && -- decodeEscapeValue(values[0], regularCoding) >= 0) { -- // Need an explicit default. -- metaCoding = defaultMetaCoding; -- } else { -- // Common case: Zero bytes of meta coding. -- metaCoding = noMetaCoding; -- } -- if (metaCoding.length > 0 -- && (verbose > 2 || verbose > 1 && metaCoding.length > 1)) { -- StringBuffer sb = new StringBuffer(); -- for (int i = 0; i < metaCoding.length; i++) { -- if (i == 1) sb.append(" /"); -- sb.append(" ").append(metaCoding[i] & 0xFF); -- } -- Utils.log.fine(" meta-coding "+sb); -- } -+ // Compute and save the meta-coding bytes also. -+ if (bandCoding != regularCoding) { -+ metaCoding = bandCoding.getMetaCoding(regularCoding); -+ if (verbose > 1) { -+ Utils.log.fine("alternate coding "+this+" "+bandCoding); -+ } -+ } else if (canVary && -+ decodeEscapeValue(values[0], regularCoding) >= 0) { -+ // Need an explicit default. -+ metaCoding = defaultMetaCoding; -+ } else { -+ // Common case: Zero bytes of meta coding. -+ metaCoding = noMetaCoding; -+ } -+ if (metaCoding.length > 0 -+ && (verbose > 2 || verbose > 1 && metaCoding.length > 1)) { -+ StringBuffer sb = new StringBuffer(); -+ for (int i = 0; i < metaCoding.length; i++) { -+ if (i == 1) sb.append(" /"); -+ sb.append(" ").append(metaCoding[i] & 0xFF); -+ } -+ Utils.log.fine(" meta-coding "+sb); -+ } - -- assert((outputSize < 0) || -- !(bandCoding instanceof Coding) || -- (outputSize == ((Coding)bandCoding) -- .getLength(values, 0, length))) -- : (bandCoding+" : "+ -- outputSize+" != "+ -- ((Coding)bandCoding).getLength(values, 0, length) -- +" ?= "+getCodingChooser().computeByteSize(bandCoding,values,0,length) -- ); -+ assert((outputSize < 0) || -+ !(bandCoding instanceof Coding) || -+ (outputSize == ((Coding)bandCoding) -+ .getLength(values, 0, length))) -+ : (bandCoding+" : "+ -+ outputSize+" != "+ -+ ((Coding)bandCoding).getLength(values, 0, length) -+ +" ?= "+getCodingChooser().computeByteSize(bandCoding,values,0,length) -+ ); - -- // Compute outputSize of the escape value X, if any. -- if (metaCoding.length > 0) { -- // First byte XB of meta-coding is treated specially, -- // but any other bytes go into the band headers band. -- // This must be done before any other output happens. -- if (outputSize >= 0) -- outputSize += computeEscapeSize(); // good cache -- // Other bytes go into band_headers. -- for (int i = 1; i < metaCoding.length; i++) { -- band_headers.putByte(metaCoding[i] & 0xFF); -- } -- } -- } -+ // Compute outputSize of the escape value X, if any. -+ if (metaCoding.length > 0) { -+ // First byte XB of meta-coding is treated specially, -+ // but any other bytes go into the band headers band. -+ // This must be done before any other output happens. -+ if (outputSize >= 0) -+ outputSize += computeEscapeSize(); // good cache -+ // Other bytes go into band_headers. -+ for (int i = 1; i < metaCoding.length; i++) { -+ band_headers.putByte(metaCoding[i] & 0xFF); -+ } -+ } -+ } - -- protected long computeOutputSize() { -- outputSize = getCodingChooser().computeByteSize(bandCoding, -- values, 0, length); -- assert(outputSize < Integer.MAX_VALUE); -- outputSize += computeEscapeSize(); -- return outputSize; -- } -+ protected long computeOutputSize() { -+ outputSize = getCodingChooser().computeByteSize(bandCoding, -+ values, 0, length); -+ assert(outputSize < Integer.MAX_VALUE); -+ outputSize += computeEscapeSize(); -+ return outputSize; -+ } - -- protected int computeEscapeSize() { -- if (metaCoding.length == 0) return 0; -- int XB = metaCoding[0] & 0xFF; -- int X = encodeEscapeValue(XB, regularCoding); -- return regularCoding.setD(0).getLength(X); -- } -+ protected int computeEscapeSize() { -+ if (metaCoding.length == 0) return 0; -+ int XB = metaCoding[0] & 0xFF; -+ int X = encodeEscapeValue(XB, regularCoding); -+ return regularCoding.setD(0).getLength(X); -+ } - -- protected void writeDataTo(OutputStream out) throws IOException { -- if (length == 0) return; // nothing to write -- long len0 = 0; -- if (out == outputCounter) { -- len0 = outputCounter.getCount(); -- } -- if (metaCoding.length > 0) { -- int XB = metaCoding[0] & 0xFF; -- // We need an explicit band header, either because -- // there is a non-default coding method, or because -- // the first value would be parsed as an escape value. -- int X = encodeEscapeValue(XB, regularCoding); -- //System.out.println("X="+X+" XB="+XB+" in "+this); -- regularCoding.setD(0).writeTo(out, X); -- } -- bandCoding.writeArrayTo(out, values, 0, length); -- if (out == outputCounter) { -- long len1 = outputCounter.getCount(); -- assert(outputSize == outputCounter.getCount() - len0) -- : (outputSize+" != "+outputCounter.getCount()+"-"+len0); -- } -- if (optDumpBands) dumpBand(); -- } -+ protected void writeDataTo(OutputStream out) throws IOException { -+ if (length == 0) return; // nothing to write -+ long len0 = 0; -+ if (out == outputCounter) { -+ len0 = outputCounter.getCount(); -+ } -+ if (metaCoding.length > 0) { -+ int XB = metaCoding[0] & 0xFF; -+ // We need an explicit band header, either because -+ // there is a non-default coding method, or because -+ // the first value would be parsed as an escape value. -+ int X = encodeEscapeValue(XB, regularCoding); -+ //System.out.println("X="+X+" XB="+XB+" in "+this); -+ regularCoding.setD(0).writeTo(out, X); -+ } -+ bandCoding.writeArrayTo(out, values, 0, length); -+ if (out == outputCounter) { -+ long len1 = outputCounter.getCount(); -+ assert(outputSize == outputCounter.getCount() - len0) -+ : (outputSize+" != "+outputCounter.getCount()+"-"+len0); -+ } -+ if (optDumpBands) dumpBand(); -+ } - -- protected void readDataFrom(InputStream in) throws IOException { -- length = valuesExpected(); -- if (length == 0) return; // nothing to read -- if (verbose > 1) -- Utils.log.fine("Reading band "+this); -- if (!canVaryCoding()) { -- bandCoding = regularCoding; -- metaCoding = noMetaCoding; -- } else { -- assert(in.markSupported()); // input must be buffered -- in.mark(Coding.B_MAX); -- int X = regularCoding.setD(0).readFrom(in); -- int XB = decodeEscapeValue(X, regularCoding); -- if (XB < 0) { -- // Do not consume this value. No alternate coding. -- in.reset(); -- XB = _meta_default; -- bandCoding = regularCoding; -- metaCoding = noMetaCoding; -- } else if (XB == _meta_default) { -- bandCoding = regularCoding; -- metaCoding = defaultMetaCoding; -- } else { -- if (verbose > 2) -- Utils.log.fine("found X="+X+" => XB="+XB); -- bandCoding = getBandHeader(XB, regularCoding); -- // This is really used only by dumpBands. -- int p0 = bandHeaderBytePos0; -- int p1 = bandHeaderBytePos; -- metaCoding = new byte[p1-p0]; -- System.arraycopy(bandHeaderBytes, p0, -- metaCoding, 0, metaCoding.length); -- } -- } -- if (bandCoding != regularCoding) { -- if (verbose > 1) -- Utils.log.fine(name()+": irregular coding "+bandCoding); -- } -- bandCoding.readArrayFrom(in, values, 0, length); -- if (optDumpBands) dumpBand(); -- } -+ protected void readDataFrom(InputStream in) throws IOException { -+ length = valuesExpected(); -+ if (length == 0) return; // nothing to read -+ if (verbose > 1) -+ Utils.log.fine("Reading band "+this); -+ if (!canVaryCoding()) { -+ bandCoding = regularCoding; -+ metaCoding = noMetaCoding; -+ } else { -+ assert(in.markSupported()); // input must be buffered -+ in.mark(Coding.B_MAX); -+ int X = regularCoding.setD(0).readFrom(in); -+ int XB = decodeEscapeValue(X, regularCoding); -+ if (XB < 0) { -+ // Do not consume this value. No alternate coding. -+ in.reset(); -+ XB = _meta_default; -+ bandCoding = regularCoding; -+ metaCoding = noMetaCoding; -+ } else if (XB == _meta_default) { -+ bandCoding = regularCoding; -+ metaCoding = defaultMetaCoding; -+ } else { -+ if (verbose > 2) -+ Utils.log.fine("found X="+X+" => XB="+XB); -+ bandCoding = getBandHeader(XB, regularCoding); -+ // This is really used only by dumpBands. -+ int p0 = bandHeaderBytePos0; -+ int p1 = bandHeaderBytePos; -+ metaCoding = new byte[p1-p0]; -+ System.arraycopy(bandHeaderBytes, p0, -+ metaCoding, 0, metaCoding.length); -+ } -+ } -+ if (bandCoding != regularCoding) { -+ if (verbose > 1) -+ Utils.log.fine(name()+": irregular coding "+bandCoding); -+ } -+ bandCoding.readArrayFrom(in, values, 0, length); -+ if (optDumpBands) dumpBand(); -+ } - -- public void doneDisbursing() { -- super.doneDisbursing(); -- values = null; // for GC -- } -+ public void doneDisbursing() { -+ super.doneDisbursing(); -+ values = null; // for GC -+ } - -- private void dumpBand() throws IOException { -- assert(optDumpBands); -- PrintStream ps = new PrintStream(getDumpStream(this, ".txt")); -- String irr = (bandCoding == regularCoding) ? "" : " irregular"; -- ps.print("# length="+length+ -- " size="+outputSize()+ -- irr+" coding="+bandCoding); -- if (metaCoding != noMetaCoding) { -- StringBuffer sb = new StringBuffer(); -- for (int i = 0; i < metaCoding.length; i++) { -- if (i == 1) sb.append(" /"); -- sb.append(" ").append(metaCoding[i] & 0xFF); -- } -- ps.print(" //header: "+sb); -- } -- printArrayTo(ps, values, 0, length); -- ps.close(); -- OutputStream ds = getDumpStream(this, ".bnd"); -- bandCoding.writeArrayTo(ds, values, 0, length); -- ds.close(); -- } -+ private void dumpBand() throws IOException { -+ assert(optDumpBands); -+ PrintStream ps = new PrintStream(getDumpStream(this, ".txt")); -+ String irr = (bandCoding == regularCoding) ? "" : " irregular"; -+ ps.print("# length="+length+ -+ " size="+outputSize()+ -+ irr+" coding="+bandCoding); -+ if (metaCoding != noMetaCoding) { -+ StringBuffer sb = new StringBuffer(); -+ for (int i = 0; i < metaCoding.length; i++) { -+ if (i == 1) sb.append(" /"); -+ sb.append(" ").append(metaCoding[i] & 0xFF); -+ } -+ ps.print(" //header: "+sb); -+ } -+ printArrayTo(ps, values, 0, length); -+ ps.close(); -+ OutputStream ds = getDumpStream(this, ".bnd"); -+ bandCoding.writeArrayTo(ds, values, 0, length); -+ ds.close(); -+ } - -- /** Disburse one value. */ -- protected int getValue() { -- assert(phase() == DISBURSE_PHASE); -- assert(valuesDisbursed < length); -- return values[valuesDisbursed++]; -- } -+ /** Disburse one value. */ -+ protected int getValue() { -+ assert(phase() == DISBURSE_PHASE); -+ assert(valuesDisbursed < length); -+ return values[valuesDisbursed++]; -+ } - -- /** Reset for another pass over the same value set. */ -- public void resetForSecondPass() { -- assert(phase() == DISBURSE_PHASE); -- assert(valuesDisbursed == length()); // 1st pass is complete -- valuesDisbursed = 0; -- } -+ /** Reset for another pass over the same value set. */ -+ public void resetForSecondPass() { -+ assert(phase() == DISBURSE_PHASE); -+ assert(valuesDisbursed == length()); // 1st pass is complete -+ valuesDisbursed = 0; -+ } - } - - class ByteBand extends Band { -- private ByteArrayOutputStream bytes; // input buffer -- private ByteArrayOutputStream bytesForDump; -- private InputStream in; -+ private ByteArrayOutputStream bytes; // input buffer -+ private ByteArrayOutputStream bytesForDump; -+ private InputStream in; - -- public ByteBand(String name) { -- super(name, BYTE1); -- } -+ public ByteBand(String name) { -+ super(name, BYTE1); -+ } - -- public int capacity() { -- return bytes == null ? -1 : Integer.MAX_VALUE; -- } -- protected void setCapacity(int cap) { -- assert(bytes == null); // do this just once -- bytes = new ByteArrayOutputStream(cap); -- } -- public void destroy() { -- lengthForDebug = length(); -- bytes = null; -- } -+ public int capacity() { -+ return bytes == null ? -1 : Integer.MAX_VALUE; -+ } -+ protected void setCapacity(int cap) { -+ assert(bytes == null); // do this just once -+ bytes = new ByteArrayOutputStream(cap); -+ } -+ public void destroy() { -+ lengthForDebug = length(); -+ bytes = null; -+ } - -- public int length() { -- return bytes == null ? -1 : bytes.size(); -- } -- public void reset() { -- bytes.reset(); -- } -- protected int valuesRemainingForDebug() { -- return (bytes == null) ? -1 : ((ByteArrayInputStream)in).available(); -- } -+ public int length() { -+ return bytes == null ? -1 : bytes.size(); -+ } -+ public void reset() { -+ bytes.reset(); -+ } -+ protected int valuesRemainingForDebug() { -+ return (bytes == null) ? -1 : ((ByteArrayInputStream)in).available(); -+ } - -- protected void chooseBandCodings() throws IOException { -- // No-op. -- assert(decodeEscapeValue(regularCoding.min(), regularCoding) < 0); -- assert(decodeEscapeValue(regularCoding.max(), regularCoding) < 0); -- } -+ protected void chooseBandCodings() throws IOException { -+ // No-op. -+ assert(decodeEscapeValue(regularCoding.min(), regularCoding) < 0); -+ assert(decodeEscapeValue(regularCoding.max(), regularCoding) < 0); -+ } - -- protected long computeOutputSize() { -- // do not cache -- return bytes.size(); -- } -+ protected long computeOutputSize() { -+ // do not cache -+ return bytes.size(); -+ } - -- public void writeDataTo(OutputStream out) throws IOException { -- if (length() == 0) return; -- bytes.writeTo(out); -- if (optDumpBands) dumpBand(); -- destroy(); // done with the bits! -- } -+ public void writeDataTo(OutputStream out) throws IOException { -+ if (length() == 0) return; -+ bytes.writeTo(out); -+ if (optDumpBands) dumpBand(); -+ destroy(); // done with the bits! -+ } - -- private void dumpBand() throws IOException { -- assert(optDumpBands); -- OutputStream ds = getDumpStream(this, ".bnd"); -- if (bytesForDump != null) -- bytesForDump.writeTo(ds); -- else -- bytes.writeTo(ds); -- ds.close(); -- } -+ private void dumpBand() throws IOException { -+ assert(optDumpBands); -+ OutputStream ds = getDumpStream(this, ".bnd"); -+ if (bytesForDump != null) -+ bytesForDump.writeTo(ds); -+ else -+ bytes.writeTo(ds); -+ ds.close(); -+ } - -- public void readDataFrom(InputStream in) throws IOException { -- int vex = valuesExpected(); -- if (vex == 0) return; -- if (verbose > 1) { -- lengthForDebug = vex; -- Utils.log.fine("Reading band "+this); -- lengthForDebug = -1; -- } -- byte[] buf = new byte[Math.min(vex, 1<<14)]; -- while (vex > 0) { -- int nr = in.read(buf, 0, Math.min(vex, buf.length)); -- if (nr < 0) throw new EOFException(); -- bytes.write(buf, 0, nr); -- vex -= nr; -- } -- if (optDumpBands) dumpBand(); -- } -+ public void readDataFrom(InputStream in) throws IOException { -+ int vex = valuesExpected(); -+ if (vex == 0) return; -+ if (verbose > 1) { -+ lengthForDebug = vex; -+ Utils.log.fine("Reading band "+this); -+ lengthForDebug = -1; -+ } -+ byte[] buf = new byte[Math.min(vex, 1<<14)]; -+ while (vex > 0) { -+ int nr = in.read(buf, 0, Math.min(vex, buf.length)); -+ if (nr < 0) throw new EOFException(); -+ bytes.write(buf, 0, nr); -+ vex -= nr; -+ } -+ if (optDumpBands) dumpBand(); -+ } - -- public void readyToDisburse() { -- in = new ByteArrayInputStream(bytes.toByteArray()); -- super.readyToDisburse(); -- } -+ public void readyToDisburse() { -+ in = new ByteArrayInputStream(bytes.toByteArray()); -+ super.readyToDisburse(); -+ } - -- public void doneDisbursing() { -- super.doneDisbursing(); -- if (optDumpBands -- && bytesForDump != null && bytesForDump.size() > 0) { -- try { -- dumpBand(); -- } catch (IOException ee) { -- throw new RuntimeException(ee); -- } -- } -- in = null; // GC -- bytes = null; // GC -- bytesForDump = null; // GC -- } -+ public void doneDisbursing() { -+ super.doneDisbursing(); -+ if (optDumpBands -+ && bytesForDump != null && bytesForDump.size() > 0) { -+ try { -+ dumpBand(); -+ } catch (IOException ee) { -+ throw new RuntimeException(ee); -+ } -+ } -+ in = null; // GC -+ bytes = null; // GC -+ bytesForDump = null; // GC -+ } - -- // alternative to readFrom: -- public void setInputStreamFrom(InputStream in) throws IOException { -- assert(bytes == null); -- assert(assertReadyToReadFrom(this, in)); -- setPhase(READ_PHASE); -- this.in = in; -- if (optDumpBands) { -- // Tap the stream. -- bytesForDump = new ByteArrayOutputStream(); -- this.in = new FilterInputStream(in) { -- public int read() throws IOException { -- int ch = in.read(); -- if (ch >= 0) bytesForDump.write(ch); -- return ch; -- } -- public int read(byte b[], int off, int len) throws IOException { -- int nr = in.read(b, off, len); -- if (nr >= 0) bytesForDump.write(b, off, nr); -- return nr; -- } -- }; -- } -- super.readyToDisburse(); -- } -+ // alternative to readFrom: -+ public void setInputStreamFrom(InputStream in) throws IOException { -+ assert(bytes == null); -+ assert(assertReadyToReadFrom(this, in)); -+ setPhase(READ_PHASE); -+ this.in = in; -+ if (optDumpBands) { -+ // Tap the stream. -+ bytesForDump = new ByteArrayOutputStream(); -+ this.in = new FilterInputStream(in) { -+ public int read() throws IOException { -+ int ch = in.read(); -+ if (ch >= 0) bytesForDump.write(ch); -+ return ch; -+ } -+ public int read(byte b[], int off, int len) throws IOException { -+ int nr = in.read(b, off, len); -+ if (nr >= 0) bytesForDump.write(b, off, nr); -+ return nr; -+ } -+ }; -+ } -+ super.readyToDisburse(); -+ } - -- public OutputStream collectorStream() { -- assert(phase() == COLLECT_PHASE); -- assert(bytes != null); -- return bytes; -- } -+ public OutputStream collectorStream() { -+ assert(phase() == COLLECT_PHASE); -+ assert(bytes != null); -+ return bytes; -+ } - -- public InputStream getInputStream() { -- assert(phase() == DISBURSE_PHASE); -- assert(in != null); -- return in; -- } -- public int getByte() throws IOException { -- int b = getInputStream().read(); -- if (b < 0) throw new EOFException(); -- return b; -- } -- public void putByte(int b) throws IOException { -- assert(b == (b & 0xFF)); -- collectorStream().write(b); -- } -- public String toString() { -- return "byte "+super.toString(); -- } -+ public InputStream getInputStream() { -+ assert(phase() == DISBURSE_PHASE); -+ assert(in != null); -+ return in; -+ } -+ public int getByte() throws IOException { -+ int b = getInputStream().read(); -+ if (b < 0) throw new EOFException(); -+ return b; -+ } -+ public void putByte(int b) throws IOException { -+ assert(b == (b & 0xFF)); -+ collectorStream().write(b); -+ } -+ public String toString() { -+ return "byte "+super.toString(); -+ } - } - - class IntBand extends ValueBand { -- // The usual coding for bands is 7bit/5byte/delta. -- public IntBand(String name, Coding regularCoding) { -- super(name, regularCoding); -- } -+ // The usual coding for bands is 7bit/5byte/delta. -+ public IntBand(String name, Coding regularCoding) { -+ super(name, regularCoding); -+ } - -- public void putInt(int x) { -- assert(phase() == COLLECT_PHASE); -- addValue(x); -- } -+ public void putInt(int x) { -+ assert(phase() == COLLECT_PHASE); -+ addValue(x); -+ } - -- public int getInt() { -- return getValue(); -- } -- /** Return the sum of all values in this band. */ -- public int getIntTotal() { -- assert(phase() == DISBURSE_PHASE); -- // assert that this is the whole pass; no other reads allowed -- assert(valuesRemainingForDebug() == length()); -- int total = 0; -- for (int k = length(); k > 0; k--) { -- total += getInt(); -- } -- resetForSecondPass(); -- return total; -- } -- /** Return the occurrence count of a specific value in this band. */ -- public int getIntCount(int value) { -- assert(phase() == DISBURSE_PHASE); -- // assert that this is the whole pass; no other reads allowed -- assert(valuesRemainingForDebug() == length()); -- int total = 0; -- for (int k = length(); k > 0; k--) { -- if (getInt() == value) { -- total += 1; -- } -- } -- resetForSecondPass(); -- return total; -- } -+ public int getInt() { -+ return getValue(); -+ } -+ /** Return the sum of all values in this band. */ -+ public int getIntTotal() { -+ assert(phase() == DISBURSE_PHASE); -+ // assert that this is the whole pass; no other reads allowed -+ assert(valuesRemainingForDebug() == length()); -+ int total = 0; -+ for (int k = length(); k > 0; k--) { -+ total += getInt(); -+ } -+ resetForSecondPass(); -+ return total; -+ } -+ /** Return the occurrence count of a specific value in this band. */ -+ public int getIntCount(int value) { -+ assert(phase() == DISBURSE_PHASE); -+ // assert that this is the whole pass; no other reads allowed -+ assert(valuesRemainingForDebug() == length()); -+ int total = 0; -+ for (int k = length(); k > 0; k--) { -+ if (getInt() == value) { -+ total += 1; -+ } -+ } -+ resetForSecondPass(); -+ return total; -+ } - } - - static int getIntTotal(int[] values) { -- int total = 0; -- for (int i = 0; i < values.length; i++) { -- total += values[i]; -- } -- return total; -+ int total = 0; -+ for (int i = 0; i < values.length; i++) { -+ total += values[i]; -+ } -+ return total; - } - - class CPRefBand extends ValueBand { -- Index index; -- boolean nullOK; -+ Index index; -+ boolean nullOK; - -- public CPRefBand(String name, Coding regularCoding, byte cpTag, boolean nullOK) { -- super(name, regularCoding); -- this.nullOK = nullOK; -- if (cpTag != CONSTANT_None) -- setBandIndex(this, cpTag); -- } -- public CPRefBand(String name, Coding regularCoding, byte cpTag) { -- this(name, regularCoding, cpTag, false); -- } -- public CPRefBand(String name, Coding regularCoding, Object undef) { -- this(name, regularCoding, CONSTANT_None, false); -- } -+ public CPRefBand(String name, Coding regularCoding, byte cpTag, boolean nullOK) { -+ super(name, regularCoding); -+ this.nullOK = nullOK; -+ if (cpTag != CONSTANT_None) -+ setBandIndex(this, cpTag); -+ } -+ public CPRefBand(String name, Coding regularCoding, byte cpTag) { -+ this(name, regularCoding, cpTag, false); -+ } -+ public CPRefBand(String name, Coding regularCoding, Object undef) { -+ this(name, regularCoding, CONSTANT_None, false); -+ } - -- public void setIndex(Index index) { -- this.index = index; -- } -+ public void setIndex(Index index) { -+ this.index = index; -+ } - -- protected void readDataFrom(InputStream in) throws IOException { -- super.readDataFrom(in); -- assert(assertValidCPRefs(this)); -- } -+ protected void readDataFrom(InputStream in) throws IOException { -+ super.readDataFrom(in); -+ assert(assertValidCPRefs(this)); -+ } - -- /** Write a constant pool reference. */ -- public void putRef(Entry e) { -- assert(index != null); -- addValue(encodeRefOrNull(e, index)); -- } -- public void putRef(Entry e, Index index) { -- assert(this.index == null); -- addValue(encodeRefOrNull(e, index)); -- } -- public void putRef(Entry e, byte cptag) { -- putRef(e, getCPIndex(cptag)); -- } -+ /** Write a constant pool reference. */ -+ public void putRef(Entry e) { -+ addValue(encodeRefOrNull(e, index)); -+ } -+ public void putRef(Entry e, Index index) { -+ assert(this.index == null); -+ addValue(encodeRefOrNull(e, index)); -+ } -+ public void putRef(Entry e, byte cptag) { -+ putRef(e, getCPIndex(cptag)); -+ } - -- public Entry getRef() { -- if (index == null) Utils.log.warning("No index for "+this); -- assert(index != null); -- return decodeRefOrNull(getValue(), index); -- } -- public Entry getRef(Index index) { -- assert(this.index == null); -- return decodeRefOrNull(getValue(), index); -- } -- public Entry getRef(byte cptag) { -- return getRef(getCPIndex(cptag)); -- } -+ public Entry getRef() { -+ if (index == null) Utils.log.warning("No index for "+this); -+ assert(index != null); -+ return decodeRefOrNull(getValue(), index); -+ } -+ public Entry getRef(Index index) { -+ assert(this.index == null); -+ return decodeRefOrNull(getValue(), index); -+ } -+ public Entry getRef(byte cptag) { -+ return getRef(getCPIndex(cptag)); -+ } - -- private int encodeRefOrNull(Entry e, Index index) { -- int nonNullCode; // NNC is the coding which assumes nulls are rare -- if (e == null) { -- nonNullCode = -1; // negative values are rare -- } else { -- nonNullCode = encodeRef(e, index); -- } -- // If nulls are expected, increment, to make -1 code turn to 0. -- return (nullOK ? 1 : 0) + nonNullCode; -- } -- private Entry decodeRefOrNull(int code, Index index) { -- // Inverse to encodeRefOrNull... -- int nonNullCode = code - (nullOK ? 1 : 0); -- if (nonNullCode == -1) { -- return null; -- } else { -- return decodeRef(nonNullCode, index); -- } -- } -+ private int encodeRefOrNull(Entry e, Index index) { -+ int nonNullCode; // NNC is the coding which assumes nulls are rare -+ if (e == null) { -+ nonNullCode = -1; // negative values are rare -+ } else { -+ nonNullCode = encodeRef(e, index); -+ } -+ // If nulls are expected, increment, to make -1 code turn to 0. -+ return (nullOK ? 1 : 0) + nonNullCode; -+ } -+ private Entry decodeRefOrNull(int code, Index index) { -+ // Inverse to encodeRefOrNull... -+ int nonNullCode = code - (nullOK ? 1 : 0); -+ if (nonNullCode == -1) { -+ return null; -+ } else { -+ return decodeRef(nonNullCode, index); -+ } -+ } - } - - // Bootstrap support for CPRefBands. These are needed to record -@@ -1039,51 +1037,53 @@ class BandStructure implements Constants - - - int encodeRef(Entry e, Index ix) { -- int coding = ix.indexOf(e); -- if (verbose > 2) -- Utils.log.fine("putRef "+coding+" => "+e); -- return coding; -+ if (ix == null) -+ throw new RuntimeException("null index for " + e.stringValue()); -+ int coding = ix.indexOf(e); -+ if (verbose > 2) -+ Utils.log.fine("putRef "+coding+" => "+e); -+ return coding; - } - - Entry decodeRef(int n, Index ix) { -- if (n < 0 || n >= ix.size()) -- Utils.log.warning("decoding bad ref "+n+" in "+ix); -- Entry e = ix.getEntry(n); -- if (verbose > 2) -- Utils.log.fine("getRef "+n+" => "+e); -- return e; -+ if (n < 0 || n >= ix.size()) -+ Utils.log.warning("decoding bad ref "+n+" in "+ix); -+ Entry e = ix.getEntry(n); -+ if (verbose > 2) -+ Utils.log.fine("getRef "+n+" => "+e); -+ return e; - } - - private CodingChooser codingChooser; - protected CodingChooser getCodingChooser() { -- if (codingChooser == null) { -- codingChooser = new CodingChooser(effort, basicCodings); -- if (codingChooser.stress != null -- && this instanceof PackageWriter) { -- // Twist the random state based on my first file. -- // This sends each segment off in a different direction. -- List classes = ((PackageWriter)this).pkg.classes; -- if (!classes.isEmpty()) { -- Package.Class cls = (Package.Class) classes.get(0); -- codingChooser.addStressSeed(cls.getName().hashCode()); -- } -- } -- } -- return codingChooser; -+ if (codingChooser == null) { -+ codingChooser = new CodingChooser(effort, basicCodings); -+ if (codingChooser.stress != null -+ && this instanceof PackageWriter) { -+ // Twist the random state based on my first file. -+ // This sends each segment off in a different direction. -+ List classes = ((PackageWriter)this).pkg.classes; -+ if (!classes.isEmpty()) { -+ Package.Class cls = (Package.Class) classes.get(0); -+ codingChooser.addStressSeed(cls.getName().hashCode()); -+ } -+ } -+ } -+ return codingChooser; - } - - public CodingMethod chooseCoding(int[] values, int start, int end, -- Coding regular, String bandName, -- int[] sizes) { -- assert(optVaryCodings); -- if (effort <= MIN_EFFORT) { -- return regular; -- } -- CodingChooser cc = getCodingChooser(); -- if (verbose > 1 || cc.verbose > 1) { -- Utils.log.fine("--- chooseCoding "+bandName); -- } -- return cc.choose(values, start, end, regular, sizes); -+ Coding regular, String bandName, -+ int[] sizes) { -+ assert(optVaryCodings); -+ if (effort <= MIN_EFFORT) { -+ return regular; -+ } -+ CodingChooser cc = getCodingChooser(); -+ if (verbose > 1 || cc.verbose > 1) { -+ Utils.log.fine("--- chooseCoding "+bandName); -+ } -+ return cc.choose(values, start, end, regular, sizes); - } - - static final byte[] defaultMetaCoding = { _meta_default }; -@@ -1108,201 +1108,201 @@ class BandStructure implements Constants - // Result is in [0..255] if XB was successfully extracted, else -1. - // See section "Coding Specifier Meta-Encoding" in the JSR 200 spec. - protected static int decodeEscapeValue(int X, Coding regularCoding) { -- // The first value in a band is always coded with the default coding D. -- // If this first value X is an escape value, it actually represents the -- // first (and perhaps only) byte of a meta-coding. -- // Result is in [0..255] if XB was successfully extracted, else -1. -- if (regularCoding.B() == 1 || regularCoding.L() == 0) -- return -1; // degenerate regular coding (BYTE1) -- if (regularCoding.S() != 0) { -- if (-256 <= X && X <= -1 && regularCoding.min() <= -256) { -- int XB = -1-X; -- assert(XB >= 0 && XB < 256); -- return XB; -- } -- } else { -- int L = regularCoding.L(); -- if (L <= X && X <= L+255 && regularCoding.max() >= L+255) { -- int XB = X-L; -- assert(XB >= 0 && XB < 256); -- return XB; -- } -- } -- return -1; // negative value for failure -+ // The first value in a band is always coded with the default coding D. -+ // If this first value X is an escape value, it actually represents the -+ // first (and perhaps only) byte of a meta-coding. -+ // Result is in [0..255] if XB was successfully extracted, else -1. -+ if (regularCoding.B() == 1 || regularCoding.L() == 0) -+ return -1; // degenerate regular coding (BYTE1) -+ if (regularCoding.S() != 0) { -+ if (-256 <= X && X <= -1 && regularCoding.min() <= -256) { -+ int XB = -1-X; -+ assert(XB >= 0 && XB < 256); -+ return XB; -+ } -+ } else { -+ int L = regularCoding.L(); -+ if (L <= X && X <= L+255 && regularCoding.max() >= L+255) { -+ int XB = X-L; -+ assert(XB >= 0 && XB < 256); -+ return XB; -+ } -+ } -+ return -1; // negative value for failure - } - // Inverse to decodeEscapeValue(). - protected static int encodeEscapeValue(int XB, Coding regularCoding) { -- assert(XB >= 0 && XB < 256); -- assert(regularCoding.B() > 1 && regularCoding.L() > 0); -- int X; -- if (regularCoding.S() != 0) { -- assert(regularCoding.min() <= -256); -- X = -1-XB; -- } else { -- int L = regularCoding.L(); -- assert(regularCoding.max() >= L+255); -- X = XB+L; -- } -- assert(decodeEscapeValue(X, regularCoding) == XB) -- : (regularCoding+" XB="+XB+" X="+X); -- return X; -+ assert(XB >= 0 && XB < 256); -+ assert(regularCoding.B() > 1 && regularCoding.L() > 0); -+ int X; -+ if (regularCoding.S() != 0) { -+ assert(regularCoding.min() <= -256); -+ X = -1-XB; -+ } else { -+ int L = regularCoding.L(); -+ assert(regularCoding.max() >= L+255); -+ X = XB+L; -+ } -+ assert(decodeEscapeValue(X, regularCoding) == XB) -+ : (regularCoding+" XB="+XB+" X="+X); -+ return X; - } - - static { -- boolean checkXB = false; -- assert(checkXB = true); -- if (checkXB) { -- for (int i = 0; i < basicCodings.length; i++) { -- Coding D = basicCodings[i]; -- if (D == null) continue; -- if (D.B() == 1) continue; -- if (D.L() == 0) continue; -- for (int XB = 0; XB <= 255; XB++) { -- // The following exercises decodeEscapeValue also: -- encodeEscapeValue(XB, D); -- } -- } -- } -+ boolean checkXB = false; -+ assert(checkXB = true); -+ if (checkXB) { -+ for (int i = 0; i < basicCodings.length; i++) { -+ Coding D = basicCodings[i]; -+ if (D == null) continue; -+ if (D.B() == 1) continue; -+ if (D.L() == 0) continue; -+ for (int XB = 0; XB <= 255; XB++) { -+ // The following exercises decodeEscapeValue also: -+ encodeEscapeValue(XB, D); -+ } -+ } -+ } - } - - class MultiBand extends Band { -- MultiBand(String name, Coding regularCoding) { -- super(name, regularCoding); -- } -+ MultiBand(String name, Coding regularCoding) { -+ super(name, regularCoding); -+ } - -- public Band init() { -- super.init(); -- // This is all just to keep the asserts happy: -- setCapacity(0); -- if (phase() == EXPECT_PHASE) { -- // Fast forward: -- setPhase(READ_PHASE); -- setPhase(DISBURSE_PHASE); -- } -- return this; -- } -+ public Band init() { -+ super.init(); -+ // This is all just to keep the asserts happy: -+ setCapacity(0); -+ if (phase() == EXPECT_PHASE) { -+ // Fast forward: -+ setPhase(READ_PHASE); -+ setPhase(DISBURSE_PHASE); -+ } -+ return this; -+ } - -- Band[] bands = new Band[10]; -- int bandCount = 0; -+ Band[] bands = new Band[10]; -+ int bandCount = 0; - -- int size() { -- return bandCount; -- } -- Band get(int i) { -- assert(i < bandCount); -- return bands[i]; -- } -- Band[] toArray() { -- return (Band[]) realloc(bands, bandCount); -- } -+ int size() { -+ return bandCount; -+ } -+ Band get(int i) { -+ assert(i < bandCount); -+ return bands[i]; -+ } -+ Band[] toArray() { -+ return (Band[]) realloc(bands, bandCount); -+ } - -- void add(Band b) { -- assert(bandCount == 0 || notePrevForAssert(b, bands[bandCount-1])); -- if (bandCount == bands.length) { -- bands = (Band[]) realloc(bands); -- } -- bands[bandCount++] = b; -- } -+ void add(Band b) { -+ assert(bandCount == 0 || notePrevForAssert(b, bands[bandCount-1])); -+ if (bandCount == bands.length) { -+ bands = (Band[]) realloc(bands); -+ } -+ bands[bandCount++] = b; -+ } - -- ByteBand newByteBand(String name) { -- ByteBand b = new ByteBand(name); -- b.init(); add(b); -- return b; -- } -- IntBand newIntBand(String name) { -- IntBand b = new IntBand(name, regularCoding); -- b.init(); add(b); -- return b; -- } -- IntBand newIntBand(String name, Coding regularCoding) { -- IntBand b = new IntBand(name, regularCoding); -- b.init(); add(b); -- return b; -- } -- MultiBand newMultiBand(String name, Coding regularCoding) { -- MultiBand b = new MultiBand(name, regularCoding); -- b.init(); add(b); -- return b; -- } -- CPRefBand newCPRefBand(String name, byte cpTag) { -- CPRefBand b = new CPRefBand(name, regularCoding, cpTag); -- b.init(); add(b); -- return b; -- } -- CPRefBand newCPRefBand(String name, Coding regularCoding, -- byte cpTag) { -- CPRefBand b = new CPRefBand(name, regularCoding, cpTag); -- b.init(); add(b); -- return b; -- } -- CPRefBand newCPRefBand(String name, Coding regularCoding, -- byte cpTag, boolean nullOK) { -- CPRefBand b = new CPRefBand(name, regularCoding, cpTag, nullOK); -- b.init(); add(b); -- return b; -- } -+ ByteBand newByteBand(String name) { -+ ByteBand b = new ByteBand(name); -+ b.init(); add(b); -+ return b; -+ } -+ IntBand newIntBand(String name) { -+ IntBand b = new IntBand(name, regularCoding); -+ b.init(); add(b); -+ return b; -+ } -+ IntBand newIntBand(String name, Coding regularCoding) { -+ IntBand b = new IntBand(name, regularCoding); -+ b.init(); add(b); -+ return b; -+ } -+ MultiBand newMultiBand(String name, Coding regularCoding) { -+ MultiBand b = new MultiBand(name, regularCoding); -+ b.init(); add(b); -+ return b; -+ } -+ CPRefBand newCPRefBand(String name, byte cpTag) { -+ CPRefBand b = new CPRefBand(name, regularCoding, cpTag); -+ b.init(); add(b); -+ return b; -+ } -+ CPRefBand newCPRefBand(String name, Coding regularCoding, -+ byte cpTag) { -+ CPRefBand b = new CPRefBand(name, regularCoding, cpTag); -+ b.init(); add(b); -+ return b; -+ } -+ CPRefBand newCPRefBand(String name, Coding regularCoding, -+ byte cpTag, boolean nullOK) { -+ CPRefBand b = new CPRefBand(name, regularCoding, cpTag, nullOK); -+ b.init(); add(b); -+ return b; -+ } - -- int bandCount() { return bandCount; } -+ int bandCount() { return bandCount; } - -- private int cap = -1; -- public int capacity() { return cap; } -- public void setCapacity(int cap) { this.cap = cap; } -+ private int cap = -1; -+ public int capacity() { return cap; } -+ public void setCapacity(int cap) { this.cap = cap; } - -- public int length() { return 0; } -- public int valuesRemainingForDebug() { return 0; } -+ public int length() { return 0; } -+ public int valuesRemainingForDebug() { return 0; } - -- protected void chooseBandCodings() throws IOException { -- // coding decision pass -- for (int i = 0; i < bandCount; i++) { -- Band b = bands[i]; -- b.chooseBandCodings(); -- } -- } -+ protected void chooseBandCodings() throws IOException { -+ // coding decision pass -+ for (int i = 0; i < bandCount; i++) { -+ Band b = bands[i]; -+ b.chooseBandCodings(); -+ } -+ } - -- protected long computeOutputSize() { -- // coding decision pass -- long sum = 0; -- for (int i = 0; i < bandCount; i++) { -- Band b = bands[i]; -- long bsize = b.outputSize(); -- assert(bsize >= 0) : b; -- sum += bsize; -- } -- // do not cache -- return sum; -- } -+ protected long computeOutputSize() { -+ // coding decision pass -+ long sum = 0; -+ for (int i = 0; i < bandCount; i++) { -+ Band b = bands[i]; -+ long bsize = b.outputSize(); -+ assert(bsize >= 0) : b; -+ sum += bsize; -+ } -+ // do not cache -+ return sum; -+ } - -- protected void writeDataTo(OutputStream out) throws IOException { -- long preCount = 0; -- if (outputCounter != null) preCount = outputCounter.getCount(); -- for (int i = 0; i < bandCount; i++) { -- Band b = bands[i]; -- b.writeTo(out); -- if (outputCounter != null) { -- long postCount = outputCounter.getCount(); -- long len = postCount - preCount; -- preCount = postCount; -- if ((verbose > 0 && len > 0) || verbose > 1) { -- Utils.log.info(" ...wrote "+len+" bytes from "+b); -- } -- } -- } -- } -+ protected void writeDataTo(OutputStream out) throws IOException { -+ long preCount = 0; -+ if (outputCounter != null) preCount = outputCounter.getCount(); -+ for (int i = 0; i < bandCount; i++) { -+ Band b = bands[i]; -+ b.writeTo(out); -+ if (outputCounter != null) { -+ long postCount = outputCounter.getCount(); -+ long len = postCount - preCount; -+ preCount = postCount; -+ if ((verbose > 0 && len > 0) || verbose > 1) { -+ Utils.log.info(" ...wrote "+len+" bytes from "+b); -+ } -+ } -+ } -+ } - -- protected void readDataFrom(InputStream in) throws IOException { -- assert(false); // not called? -- for (int i = 0; i < bandCount; i++) { -- Band b = bands[i]; -- b.readFrom(in); -- if ((verbose > 0 && b.length() > 0) || verbose > 1) { -- Utils.log.info(" ...read "+b); -- } -- } -- } -+ protected void readDataFrom(InputStream in) throws IOException { -+ assert(false); // not called? -+ for (int i = 0; i < bandCount; i++) { -+ Band b = bands[i]; -+ b.readFrom(in); -+ if ((verbose > 0 && b.length() > 0) || verbose > 1) { -+ Utils.log.info(" ...read "+b); -+ } -+ } -+ } - -- public String toString() { -- return "{"+bandCount()+" bands: "+super.toString()+"}"; -- } -+ public String toString() { -+ return "{"+bandCount()+" bands: "+super.toString()+"}"; -+ } - } - - /** -@@ -1310,42 +1310,42 @@ class BandStructure implements Constants - */ - private static - class ByteCounter extends FilterOutputStream { -- // (should go public under the name CountingOutputStream?) -+ // (should go public under the name CountingOutputStream?) - -- private long count; -+ private long count; - -- public ByteCounter(OutputStream out) { -- super(out); -- } -+ public ByteCounter(OutputStream out) { -+ super(out); -+ } - -- public long getCount() { return count; } -- public void setCount(long c) { count = c; } -+ public long getCount() { return count; } -+ public void setCount(long c) { count = c; } - -- public void write(int b) throws IOException { -- count++; -- if (out != null) out.write(b); -- } -- public void write(byte b[], int off, int len) throws IOException { -- count += len; -- if (out != null) out.write(b, off, len); -- } -- public String toString() { -- return String.valueOf(getCount()); -- } -+ public void write(int b) throws IOException { -+ count++; -+ if (out != null) out.write(b); -+ } -+ public void write(byte b[], int off, int len) throws IOException { -+ count += len; -+ if (out != null) out.write(b, off, len); -+ } -+ public String toString() { -+ return String.valueOf(getCount()); -+ } - } - ByteCounter outputCounter; - - void writeAllBandsTo(OutputStream out) throws IOException { -- // Wrap a byte-counter around the output stream. -- outputCounter = new ByteCounter(out); -- out = outputCounter; -- all_bands.writeTo(out); -- if (verbose > 0) { -- long nbytes = outputCounter.getCount(); -- Utils.log.info("Wrote total of "+nbytes+" bytes."); -- assert(nbytes == archiveSize0+archiveSize1); -- } -- outputCounter = null; -+ // Wrap a byte-counter around the output stream. -+ outputCounter = new ByteCounter(out); -+ out = outputCounter; -+ all_bands.writeTo(out); -+ if (verbose > 0) { -+ long nbytes = outputCounter.getCount(); -+ Utils.log.info("Wrote total of "+nbytes+" bytes."); -+ assert(nbytes == archiveSize0+archiveSize1); -+ } -+ outputCounter = null; - } - - // random AO_XXX bits, decoded from the archive header -@@ -1366,7 +1366,7 @@ class BandStructure implements Constants - static final int AH_SPECIAL_FORMAT_LEN = 2; // layouts/band-headers - static final int AH_CP_NUMBER_LEN = 4; // int/float/long/double - static final int AH_LENGTH_MIN = AH_LENGTH -- -(AH_SPECIAL_FORMAT_LEN+AH_FILE_HEADER_LEN+AH_CP_NUMBER_LEN); -+ -(AH_SPECIAL_FORMAT_LEN+AH_FILE_HEADER_LEN+AH_CP_NUMBER_LEN); - - // Common structure of attribute band groups: - static final int AB_FLAGS_HI = 0; -@@ -1376,22 +1376,22 @@ class BandStructure implements Constants - static final int AB_ATTR_CALLS = 4; - - static IntBand getAttrBand(MultiBand xxx_attr_bands, int which) { -- IntBand b = (IntBand) xxx_attr_bands.get(which); -- switch (which) { -- case AB_FLAGS_HI: -- assert(b.name().endsWith("_flags_hi")); break; -- case AB_FLAGS_LO: -- assert(b.name().endsWith("_flags_lo")); break; -- case AB_ATTR_COUNT: -- assert(b.name().endsWith("_attr_count")); break; -- case AB_ATTR_INDEXES: -- assert(b.name().endsWith("_attr_indexes")); break; -- case AB_ATTR_CALLS: -- assert(b.name().endsWith("_attr_calls")); break; -- default: -- assert(false); break; -- } -- return b; -+ IntBand b = (IntBand) xxx_attr_bands.get(which); -+ switch (which) { -+ case AB_FLAGS_HI: -+ assert(b.name().endsWith("_flags_hi")); break; -+ case AB_FLAGS_LO: -+ assert(b.name().endsWith("_flags_lo")); break; -+ case AB_ATTR_COUNT: -+ assert(b.name().endsWith("_attr_count")); break; -+ case AB_ATTR_INDEXES: -+ assert(b.name().endsWith("_attr_indexes")); break; -+ case AB_ATTR_CALLS: -+ assert(b.name().endsWith("_attr_calls")); break; -+ default: -+ assert(false); break; -+ } -+ return b; - } - - static private final boolean NULL_IS_OK = true; -@@ -1602,55 +1602,55 @@ class BandStructure implements Constants - - /** Given CP indexes, distribute tag-specific indexes to bands. */ - protected void setBandIndexes() { -- // Handle prior calls to setBandIndex: -- for (Iterator i = needPredefIndex.iterator(); i.hasNext(); ) { -- Object[] need = (Object[]) i.next(); -- CPRefBand b = (CPRefBand) need[0]; -- Byte which = (Byte) need[1]; -- b.setIndex(getCPIndex(which.byteValue())); -- } -- needPredefIndex = null; // no more predefs -+ // Handle prior calls to setBandIndex: -+ for (Iterator i = needPredefIndex.iterator(); i.hasNext(); ) { -+ Object[] need = (Object[]) i.next(); -+ CPRefBand b = (CPRefBand) need[0]; -+ Byte which = (Byte) need[1]; -+ b.setIndex(getCPIndex(which.byteValue())); -+ } -+ needPredefIndex = null; // no more predefs - -- if (verbose > 3) { -- printCDecl(all_bands); -- } -+ if (verbose > 3) { -+ printCDecl(all_bands); -+ } - } - - protected void setBandIndex(CPRefBand b, byte which) { -- Object[] need = { b, new Byte(which) }; -- if (which == CONSTANT_Literal) { -- // I.e., attribute layouts KQ (no null) or KQN (null ok). -- allKQBands.add(b); -- } else if (needPredefIndex != null) { -- needPredefIndex.add(need); -- } else { -- // Not in predefinition mode; getCPIndex now works. -- b.setIndex(getCPIndex(which)); -- } -+ Object[] need = { b, new Byte(which) }; -+ if (which == CONSTANT_Literal) { -+ // I.e., attribute layouts KQ (no null) or KQN (null ok). -+ allKQBands.add(b); -+ } else if (needPredefIndex != null) { -+ needPredefIndex.add(need); -+ } else { -+ // Not in predefinition mode; getCPIndex now works. -+ b.setIndex(getCPIndex(which)); -+ } - } - - protected void setConstantValueIndex(Class.Field f) { -- Index ix = null; -- if (f != null) { -- byte tag = f.getLiteralTag(); -- ix = getCPIndex(tag); -- if (verbose > 2) -- Utils.log.fine("setConstantValueIndex "+f+" "+ConstantPool.tagName(tag)+" => "+ix); -- assert(ix != null); -- } -- // Typically, allKQBands is the singleton of field_ConstantValue_KQ. -- for (Iterator i = allKQBands.iterator(); i.hasNext(); ) { -- CPRefBand xxx_KQ = (CPRefBand) i.next(); -- xxx_KQ.setIndex(ix); -- } -+ Index ix = null; -+ if (f != null) { -+ byte tag = f.getLiteralTag(); -+ ix = getCPIndex(tag); -+ if (verbose > 2) -+ Utils.log.fine("setConstantValueIndex "+f+" "+ConstantPool.tagName(tag)+" => "+ix); -+ assert(ix != null); -+ } -+ // Typically, allKQBands is the singleton of field_ConstantValue_KQ. -+ for (Iterator i = allKQBands.iterator(); i.hasNext(); ) { -+ CPRefBand xxx_KQ = (CPRefBand) i.next(); -+ xxx_KQ.setIndex(ix); -+ } - } - - // Table of bands which contain metadata. - protected MultiBand[] metadataBands = new MultiBand[ATTR_CONTEXT_LIMIT]; - { -- metadataBands[ATTR_CONTEXT_CLASS] = class_metadata_bands; -- metadataBands[ATTR_CONTEXT_FIELD] = field_metadata_bands; -- metadataBands[ATTR_CONTEXT_METHOD] = method_metadata_bands; -+ metadataBands[ATTR_CONTEXT_CLASS] = class_metadata_bands; -+ metadataBands[ATTR_CONTEXT_FIELD] = field_metadata_bands; -+ metadataBands[ATTR_CONTEXT_METHOD] = method_metadata_bands; - } - - // Attribute layouts. -@@ -1686,660 +1686,660 @@ class BandStructure implements Constants - // Mapping from attribute index (<32 are flag bits) to attributes. - protected ArrayList[] attrDefs = new ArrayList[ATTR_CONTEXT_LIMIT]; - { -- for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) { -- assert(attrIndexLimit[i] == 0); -- attrIndexLimit[i] = 32; // just for the sake of predefs. -- attrDefs[i] = new ArrayList(Collections.nCopies(attrIndexLimit[i], null)); -- } -+ for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) { -+ assert(attrIndexLimit[i] == 0); -+ attrIndexLimit[i] = 32; // just for the sake of predefs. -+ attrDefs[i] = new ArrayList(Collections.nCopies(attrIndexLimit[i], null)); -+ } - -- // Add predefined attribute definitions: -- attrInnerClassesEmpty = -- predefineAttribute(CLASS_ATTR_InnerClasses, ATTR_CONTEXT_CLASS, null, -- "InnerClasses", ""); -- assert(attrInnerClassesEmpty == Package.attrInnerClassesEmpty); -- predefineAttribute(CLASS_ATTR_SourceFile, ATTR_CONTEXT_CLASS, -- new Band[] { class_SourceFile_RUN }, -- "SourceFile", "RUNH"); -- predefineAttribute(CLASS_ATTR_EnclosingMethod, ATTR_CONTEXT_CLASS, -- new Band[] { -- class_EnclosingMethod_RC, -- class_EnclosingMethod_RDN -- }, -- "EnclosingMethod", "RCHRDNH"); -- attrClassFileVersion = -- predefineAttribute(CLASS_ATTR_ClassFile_version, ATTR_CONTEXT_CLASS, -- new Band[] { -- class_ClassFile_version_minor_H, -- class_ClassFile_version_major_H -- }, -- ".ClassFile.version", "HH"); -- predefineAttribute(X_ATTR_Signature, ATTR_CONTEXT_CLASS, -- new Band[] { class_Signature_RS }, -- "Signature", "RSH"); -- predefineAttribute(X_ATTR_Deprecated, ATTR_CONTEXT_CLASS, null, -- "Deprecated", ""); -- //predefineAttribute(X_ATTR_Synthetic, ATTR_CONTEXT_CLASS, null, -- // "Synthetic", ""); -- predefineAttribute(X_ATTR_OVERFLOW, ATTR_CONTEXT_CLASS, null, -- ".Overflow", ""); -- attrConstantValue = -- predefineAttribute(FIELD_ATTR_ConstantValue, ATTR_CONTEXT_FIELD, -- new Band[] { field_ConstantValue_KQ }, -- "ConstantValue", "KQH"); -- predefineAttribute(X_ATTR_Signature, ATTR_CONTEXT_FIELD, -- new Band[] { field_Signature_RS }, -- "Signature", "RSH"); -- predefineAttribute(X_ATTR_Deprecated, ATTR_CONTEXT_FIELD, null, -- "Deprecated", ""); -- //predefineAttribute(X_ATTR_Synthetic, ATTR_CONTEXT_FIELD, null, -- // "Synthetic", ""); -- predefineAttribute(X_ATTR_OVERFLOW, ATTR_CONTEXT_FIELD, null, -- ".Overflow", ""); -- attrCodeEmpty = -- predefineAttribute(METHOD_ATTR_Code, ATTR_CONTEXT_METHOD, null, -- "Code", ""); -- predefineAttribute(METHOD_ATTR_Exceptions, ATTR_CONTEXT_METHOD, -- new Band[] { -- method_Exceptions_N, -- method_Exceptions_RC -- }, -- "Exceptions", "NH[RCH]"); -- assert(attrCodeEmpty == Package.attrCodeEmpty); -- predefineAttribute(X_ATTR_Signature, ATTR_CONTEXT_METHOD, -- new Band[] { method_Signature_RS }, -- "Signature", "RSH"); -- predefineAttribute(X_ATTR_Deprecated, ATTR_CONTEXT_METHOD, null, -- "Deprecated", ""); -- //predefineAttribute(X_ATTR_Synthetic, ATTR_CONTEXT_METHOD, null, -- // "Synthetic", ""); -- predefineAttribute(X_ATTR_OVERFLOW, ATTR_CONTEXT_METHOD, null, -- ".Overflow", ""); -+ // Add predefined attribute definitions: -+ attrInnerClassesEmpty = -+ predefineAttribute(CLASS_ATTR_InnerClasses, ATTR_CONTEXT_CLASS, null, -+ "InnerClasses", ""); -+ assert(attrInnerClassesEmpty == Package.attrInnerClassesEmpty); -+ predefineAttribute(CLASS_ATTR_SourceFile, ATTR_CONTEXT_CLASS, -+ new Band[] { class_SourceFile_RUN }, -+ "SourceFile", "RUNH"); -+ predefineAttribute(CLASS_ATTR_EnclosingMethod, ATTR_CONTEXT_CLASS, -+ new Band[] { -+ class_EnclosingMethod_RC, -+ class_EnclosingMethod_RDN -+ }, -+ "EnclosingMethod", "RCHRDNH"); -+ attrClassFileVersion = -+ predefineAttribute(CLASS_ATTR_ClassFile_version, ATTR_CONTEXT_CLASS, -+ new Band[] { -+ class_ClassFile_version_minor_H, -+ class_ClassFile_version_major_H -+ }, -+ ".ClassFile.version", "HH"); -+ predefineAttribute(X_ATTR_Signature, ATTR_CONTEXT_CLASS, -+ new Band[] { class_Signature_RS }, -+ "Signature", "RSH"); -+ predefineAttribute(X_ATTR_Deprecated, ATTR_CONTEXT_CLASS, null, -+ "Deprecated", ""); -+ //predefineAttribute(X_ATTR_Synthetic, ATTR_CONTEXT_CLASS, null, -+ // "Synthetic", ""); -+ predefineAttribute(X_ATTR_OVERFLOW, ATTR_CONTEXT_CLASS, null, -+ ".Overflow", ""); -+ attrConstantValue = -+ predefineAttribute(FIELD_ATTR_ConstantValue, ATTR_CONTEXT_FIELD, -+ new Band[] { field_ConstantValue_KQ }, -+ "ConstantValue", "KQH"); -+ predefineAttribute(X_ATTR_Signature, ATTR_CONTEXT_FIELD, -+ new Band[] { field_Signature_RS }, -+ "Signature", "RSH"); -+ predefineAttribute(X_ATTR_Deprecated, ATTR_CONTEXT_FIELD, null, -+ "Deprecated", ""); -+ //predefineAttribute(X_ATTR_Synthetic, ATTR_CONTEXT_FIELD, null, -+ // "Synthetic", ""); -+ predefineAttribute(X_ATTR_OVERFLOW, ATTR_CONTEXT_FIELD, null, -+ ".Overflow", ""); -+ attrCodeEmpty = -+ predefineAttribute(METHOD_ATTR_Code, ATTR_CONTEXT_METHOD, null, -+ "Code", ""); -+ predefineAttribute(METHOD_ATTR_Exceptions, ATTR_CONTEXT_METHOD, -+ new Band[] { -+ method_Exceptions_N, -+ method_Exceptions_RC -+ }, -+ "Exceptions", "NH[RCH]"); -+ assert(attrCodeEmpty == Package.attrCodeEmpty); -+ predefineAttribute(X_ATTR_Signature, ATTR_CONTEXT_METHOD, -+ new Band[] { method_Signature_RS }, -+ "Signature", "RSH"); -+ predefineAttribute(X_ATTR_Deprecated, ATTR_CONTEXT_METHOD, null, -+ "Deprecated", ""); -+ //predefineAttribute(X_ATTR_Synthetic, ATTR_CONTEXT_METHOD, null, -+ // "Synthetic", ""); -+ predefineAttribute(X_ATTR_OVERFLOW, ATTR_CONTEXT_METHOD, null, -+ ".Overflow", ""); - -- for (int ctype = 0; ctype < ATTR_CONTEXT_LIMIT; ctype++) { -- MultiBand xxx_metadata_bands = metadataBands[ctype]; -- if (xxx_metadata_bands == null) -- continue; // no code attrs -+ for (int ctype = 0; ctype < ATTR_CONTEXT_LIMIT; ctype++) { -+ MultiBand xxx_metadata_bands = metadataBands[ctype]; -+ if (xxx_metadata_bands == null) -+ continue; // no code attrs - -- // These arguments cause the bands to be built -- // automatically for this complicated layout: -- predefineAttribute(X_ATTR_RuntimeVisibleAnnotations, -- ATTR_CONTEXT_NAME[ctype]+"_RVA_", -- xxx_metadata_bands, -- Attribute.lookup(null, ctype, -- "RuntimeVisibleAnnotations")); -- predefineAttribute(X_ATTR_RuntimeInvisibleAnnotations, -- ATTR_CONTEXT_NAME[ctype]+"_RIA_", -- xxx_metadata_bands, -- Attribute.lookup(null, ctype, -- "RuntimeInvisibleAnnotations")); -- if (ctype != ATTR_CONTEXT_METHOD) -- continue; -+ // These arguments cause the bands to be built -+ // automatically for this complicated layout: -+ predefineAttribute(X_ATTR_RuntimeVisibleAnnotations, -+ ATTR_CONTEXT_NAME[ctype]+"_RVA_", -+ xxx_metadata_bands, -+ Attribute.lookup(null, ctype, -+ "RuntimeVisibleAnnotations")); -+ predefineAttribute(X_ATTR_RuntimeInvisibleAnnotations, -+ ATTR_CONTEXT_NAME[ctype]+"_RIA_", -+ xxx_metadata_bands, -+ Attribute.lookup(null, ctype, -+ "RuntimeInvisibleAnnotations")); -+ if (ctype != ATTR_CONTEXT_METHOD) -+ continue; - -- predefineAttribute(METHOD_ATTR_RuntimeVisibleParameterAnnotations, -- "method_RVPA_", xxx_metadata_bands, -- Attribute.lookup(null, ctype, -- "RuntimeVisibleParameterAnnotations")); -- predefineAttribute(METHOD_ATTR_RuntimeInvisibleParameterAnnotations, -- "method_RIPA_", xxx_metadata_bands, -- Attribute.lookup(null, ctype, -- "RuntimeInvisibleParameterAnnotations")); -- predefineAttribute(METHOD_ATTR_AnnotationDefault, -- "method_AD_", xxx_metadata_bands, -- Attribute.lookup(null, ctype, -- "AnnotationDefault")); -- } -+ predefineAttribute(METHOD_ATTR_RuntimeVisibleParameterAnnotations, -+ "method_RVPA_", xxx_metadata_bands, -+ Attribute.lookup(null, ctype, -+ "RuntimeVisibleParameterAnnotations")); -+ predefineAttribute(METHOD_ATTR_RuntimeInvisibleParameterAnnotations, -+ "method_RIPA_", xxx_metadata_bands, -+ Attribute.lookup(null, ctype, -+ "RuntimeInvisibleParameterAnnotations")); -+ predefineAttribute(METHOD_ATTR_AnnotationDefault, -+ "method_AD_", xxx_metadata_bands, -+ Attribute.lookup(null, ctype, -+ "AnnotationDefault")); -+ } - - -- Attribute.Layout stackMapDef = Attribute.lookup(null, ATTR_CONTEXT_CODE, "StackMapTable").layout(); -- predefineAttribute(CODE_ATTR_StackMapTable, ATTR_CONTEXT_CODE, -- stackmap_bands.toArray(), -- stackMapDef.name(), stackMapDef.layout()); -+ Attribute.Layout stackMapDef = Attribute.lookup(null, ATTR_CONTEXT_CODE, "StackMapTable").layout(); -+ predefineAttribute(CODE_ATTR_StackMapTable, ATTR_CONTEXT_CODE, -+ stackmap_bands.toArray(), -+ stackMapDef.name(), stackMapDef.layout()); - -- predefineAttribute(CODE_ATTR_LineNumberTable, ATTR_CONTEXT_CODE, -- new Band[] { -- code_LineNumberTable_N, -- code_LineNumberTable_bci_P, -- code_LineNumberTable_line -- }, -- "LineNumberTable", "NH[PHH]"); -- predefineAttribute(CODE_ATTR_LocalVariableTable, ATTR_CONTEXT_CODE, -- new Band[] { -- code_LocalVariableTable_N, -- code_LocalVariableTable_bci_P, -- code_LocalVariableTable_span_O, -- code_LocalVariableTable_name_RU, -- code_LocalVariableTable_type_RS, -- code_LocalVariableTable_slot -- }, -- "LocalVariableTable", "NH[PHOHRUHRSHH]"); -- predefineAttribute(CODE_ATTR_LocalVariableTypeTable, ATTR_CONTEXT_CODE, -- new Band[] { -- code_LocalVariableTypeTable_N, -- code_LocalVariableTypeTable_bci_P, -- code_LocalVariableTypeTable_span_O, -- code_LocalVariableTypeTable_name_RU, -- code_LocalVariableTypeTable_type_RS, -- code_LocalVariableTypeTable_slot -- }, -- "LocalVariableTypeTable", "NH[PHOHRUHRSHH]"); -- predefineAttribute(X_ATTR_OVERFLOW, ATTR_CONTEXT_CODE, null, -- ".Overflow", ""); -+ predefineAttribute(CODE_ATTR_LineNumberTable, ATTR_CONTEXT_CODE, -+ new Band[] { -+ code_LineNumberTable_N, -+ code_LineNumberTable_bci_P, -+ code_LineNumberTable_line -+ }, -+ "LineNumberTable", "NH[PHH]"); -+ predefineAttribute(CODE_ATTR_LocalVariableTable, ATTR_CONTEXT_CODE, -+ new Band[] { -+ code_LocalVariableTable_N, -+ code_LocalVariableTable_bci_P, -+ code_LocalVariableTable_span_O, -+ code_LocalVariableTable_name_RU, -+ code_LocalVariableTable_type_RS, -+ code_LocalVariableTable_slot -+ }, -+ "LocalVariableTable", "NH[PHOHRUHRSHH]"); -+ predefineAttribute(CODE_ATTR_LocalVariableTypeTable, ATTR_CONTEXT_CODE, -+ new Band[] { -+ code_LocalVariableTypeTable_N, -+ code_LocalVariableTypeTable_bci_P, -+ code_LocalVariableTypeTable_span_O, -+ code_LocalVariableTypeTable_name_RU, -+ code_LocalVariableTypeTable_type_RS, -+ code_LocalVariableTypeTable_slot -+ }, -+ "LocalVariableTypeTable", "NH[PHOHRUHRSHH]"); -+ predefineAttribute(X_ATTR_OVERFLOW, ATTR_CONTEXT_CODE, null, -+ ".Overflow", ""); - -- // Clear the record of having seen these definitions, -- // so they may be redefined without error. -- for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) { -- attrDefSeen[i] = 0; -- } -+ // Clear the record of having seen these definitions, -+ // so they may be redefined without error. -+ for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) { -+ attrDefSeen[i] = 0; -+ } - -- // Set up the special masks: -- for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) { -- attrOverflowMask[i] = (1<<X_ATTR_OVERFLOW); -- attrIndexLimit[i] = 0; // will make a final decision later -- } -- attrClassFileVersionMask = (1<<CLASS_ATTR_ClassFile_version); -+ // Set up the special masks: -+ for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) { -+ attrOverflowMask[i] = (1<<X_ATTR_OVERFLOW); -+ attrIndexLimit[i] = 0; // will make a final decision later -+ } -+ attrClassFileVersionMask = (1<<CLASS_ATTR_ClassFile_version); - } - - private void adjustToMajver() { -- if (getPackageMajver() < JAVA6_PACKAGE_MAJOR_VERSION) { -- if (verbose > 0) Utils.log.fine("Legacy package version"); -- // Revoke definition of pre-1.6 attribute type. -- undefineAttribute(CODE_ATTR_StackMapTable, ATTR_CONTEXT_CODE); -- } -+ if (getPackageMajver() < JAVA6_PACKAGE_MAJOR_VERSION) { -+ if (verbose > 0) Utils.log.fine("Legacy package version"); -+ // Revoke definition of pre-1.6 attribute type. -+ undefineAttribute(CODE_ATTR_StackMapTable, ATTR_CONTEXT_CODE); -+ } - } - - protected void initAttrIndexLimit() { -- for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) { -- assert(attrIndexLimit[i] == 0); // decide on it now! -- attrIndexLimit[i] = (haveFlagsHi(i)? 63: 32); -- assert(attrDefs[i].size() == 32); // all predef indexes are <32 -- int addMore = attrIndexLimit[i] - attrDefs[i].size(); -- attrDefs[i].addAll(Collections.nCopies(addMore, null)); -- } -+ for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) { -+ assert(attrIndexLimit[i] == 0); // decide on it now! -+ attrIndexLimit[i] = (haveFlagsHi(i)? 63: 32); -+ assert(attrDefs[i].size() == 32); // all predef indexes are <32 -+ int addMore = attrIndexLimit[i] - attrDefs[i].size(); -+ attrDefs[i].addAll(Collections.nCopies(addMore, null)); -+ } - } - - protected boolean haveFlagsHi(int ctype) { -- int mask = 1<<(LG_AO_HAVE_XXX_FLAGS_HI+ctype); -- switch (ctype) { -- case ATTR_CONTEXT_CLASS: -- assert(mask == AO_HAVE_CLASS_FLAGS_HI); break; -- case ATTR_CONTEXT_FIELD: -- assert(mask == AO_HAVE_FIELD_FLAGS_HI); break; -- case ATTR_CONTEXT_METHOD: -- assert(mask == AO_HAVE_METHOD_FLAGS_HI); break; -- case ATTR_CONTEXT_CODE: -- assert(mask == AO_HAVE_CODE_FLAGS_HI); break; -- default: -- assert(false); -- } -- return testBit(archiveOptions, mask); -+ int mask = 1<<(LG_AO_HAVE_XXX_FLAGS_HI+ctype); -+ switch (ctype) { -+ case ATTR_CONTEXT_CLASS: -+ assert(mask == AO_HAVE_CLASS_FLAGS_HI); break; -+ case ATTR_CONTEXT_FIELD: -+ assert(mask == AO_HAVE_FIELD_FLAGS_HI); break; -+ case ATTR_CONTEXT_METHOD: -+ assert(mask == AO_HAVE_METHOD_FLAGS_HI); break; -+ case ATTR_CONTEXT_CODE: -+ assert(mask == AO_HAVE_CODE_FLAGS_HI); break; -+ default: -+ assert(false); -+ } -+ return testBit(archiveOptions, mask); - } - - protected ArrayList getPredefinedAttrs(int ctype) { -- assert(attrIndexLimit[ctype] != 0); -- ArrayList res = new ArrayList(attrIndexLimit[ctype]); -- // Remove nulls and non-predefs. -- for (int ai = 0; ai < attrIndexLimit[ctype]; ai++) { -- if (testBit(attrDefSeen[ctype], 1L<<ai)) continue; -- Attribute.Layout def = (Attribute.Layout) attrDefs[ctype].get(ai); -- if (def == null) continue; // unused flag bit -- assert(isPredefinedAttr(ctype, ai)); -- res.add(def); -- } -- return res; -+ assert(attrIndexLimit[ctype] != 0); -+ ArrayList res = new ArrayList(attrIndexLimit[ctype]); -+ // Remove nulls and non-predefs. -+ for (int ai = 0; ai < attrIndexLimit[ctype]; ai++) { -+ if (testBit(attrDefSeen[ctype], 1L<<ai)) continue; -+ Attribute.Layout def = (Attribute.Layout) attrDefs[ctype].get(ai); -+ if (def == null) continue; // unused flag bit -+ assert(isPredefinedAttr(ctype, ai)); -+ res.add(def); -+ } -+ return res; - } - - protected boolean isPredefinedAttr(int ctype, int ai) { -- assert(attrIndexLimit[ctype] != 0); -- // Overflow attrs are never predefined. -- if (ai >= attrIndexLimit[ctype]) return false; -- // If the bit is set, it was explicitly def'd. -- if (testBit(attrDefSeen[ctype], 1L<<ai)) return false; -- return (attrDefs[ctype].get(ai) != null); -+ assert(attrIndexLimit[ctype] != 0); -+ // Overflow attrs are never predefined. -+ if (ai >= attrIndexLimit[ctype]) return false; -+ // If the bit is set, it was explicitly def'd. -+ if (testBit(attrDefSeen[ctype], 1L<<ai)) return false; -+ return (attrDefs[ctype].get(ai) != null); - } - - protected void adjustSpecialAttrMasks() { -- // Clear special masks if new definitions have been seen for them. -- attrClassFileVersionMask &= ~ attrDefSeen[ATTR_CONTEXT_CLASS]; -- // It is possible to clear the overflow mask (bit 16). -- for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) { -- attrOverflowMask[i] &= ~ attrDefSeen[i]; -- } -+ // Clear special masks if new definitions have been seen for them. -+ attrClassFileVersionMask &= ~ attrDefSeen[ATTR_CONTEXT_CLASS]; -+ // It is possible to clear the overflow mask (bit 16). -+ for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) { -+ attrOverflowMask[i] &= ~ attrDefSeen[i]; -+ } - } - - protected Attribute makeClassFileVersionAttr(int minver, int majver) { -- byte[] bytes = { -- (byte)(minver >> 8), (byte)minver, -- (byte)(majver >> 8), (byte)majver -- }; -- return attrClassFileVersion.addContent(bytes); -+ byte[] bytes = { -+ (byte)(minver >> 8), (byte)minver, -+ (byte)(majver >> 8), (byte)majver -+ }; -+ return attrClassFileVersion.addContent(bytes); - } - - protected short[] parseClassFileVersionAttr(Attribute attr) { -- assert(attr.layout() == attrClassFileVersion); -- assert(attr.size() == 4); -- byte[] bytes = attr.bytes(); -- int minver = ((bytes[0] & 0xFF) << 8) | (bytes[1] & 0xFF); -- int majver = ((bytes[2] & 0xFF) << 8) | (bytes[3] & 0xFF); -- return new short[]{ (short) minver, (short) majver }; -+ assert(attr.layout() == attrClassFileVersion); -+ assert(attr.size() == 4); -+ byte[] bytes = attr.bytes(); -+ int minver = ((bytes[0] & 0xFF) << 8) | (bytes[1] & 0xFF); -+ int majver = ((bytes[2] & 0xFF) << 8) | (bytes[3] & 0xFF); -+ return new short[]{ (short) minver, (short) majver }; - } - - private boolean assertBandOKForElems(Band[] ab, Attribute.Layout.Element[] elems) { -- for (int i = 0; i < elems.length; i++) { -- assert(assertBandOKForElem(ab, elems[i])); -- } -- return true; -+ for (int i = 0; i < elems.length; i++) { -+ assert(assertBandOKForElem(ab, elems[i])); -+ } -+ return true; - } - private boolean assertBandOKForElem(Band[] ab, Attribute.Layout.Element e) { -- Band b = null; -- if (e.bandIndex != Attribute.NO_BAND_INDEX) -- b = ab[e.bandIndex]; -- Coding rc = UNSIGNED5; -- boolean wantIntBand = true; -- switch (e.kind) { -- case Attribute.EK_INT: -- if (e.flagTest(Attribute.EF_SIGN)) { -- rc = SIGNED5; -- } else if (e.len == 1) { -- rc = BYTE1; -- } -- break; -- case Attribute.EK_BCI: -- if (!e.flagTest(Attribute.EF_DELTA)) { -- rc = BCI5; -- } else { -- rc = BRANCH5; -- } -- break; -- case Attribute.EK_BCO: -- rc = BRANCH5; -- break; -- case Attribute.EK_FLAG: -- if (e.len == 1) rc = BYTE1; -- break; -- case Attribute.EK_REPL: -- if (e.len == 1) rc = BYTE1; -- assertBandOKForElems(ab, e.body); -- break; -- case Attribute.EK_UN: -- if (e.flagTest(Attribute.EF_SIGN)) { -- rc = SIGNED5; -- } else if (e.len == 1) { -- rc = BYTE1; -- } -- assertBandOKForElems(ab, e.body); -- break; -- case Attribute.EK_CASE: -- assert(b == null); -- assertBandOKForElems(ab, e.body); -- return true; // no direct band -- case Attribute.EK_CALL: -- assert(b == null); -- return true; // no direct band -- case Attribute.EK_CBLE: -- assert(b == null); -- assertBandOKForElems(ab, e.body); -- return true; // no direct band -- case Attribute.EK_REF: -- wantIntBand = false; -- assert(b instanceof CPRefBand); -- assert(((CPRefBand)b).nullOK == e.flagTest(Attribute.EF_NULL)); -- break; -- default: assert(false); -- } -- assert(b.regularCoding == rc) -- : (e+" // "+b); -- if (wantIntBand) -- assert(b instanceof IntBand); -- return true; -+ Band b = null; -+ if (e.bandIndex != Attribute.NO_BAND_INDEX) -+ b = ab[e.bandIndex]; -+ Coding rc = UNSIGNED5; -+ boolean wantIntBand = true; -+ switch (e.kind) { -+ case Attribute.EK_INT: -+ if (e.flagTest(Attribute.EF_SIGN)) { -+ rc = SIGNED5; -+ } else if (e.len == 1) { -+ rc = BYTE1; -+ } -+ break; -+ case Attribute.EK_BCI: -+ if (!e.flagTest(Attribute.EF_DELTA)) { -+ rc = BCI5; -+ } else { -+ rc = BRANCH5; -+ } -+ break; -+ case Attribute.EK_BCO: -+ rc = BRANCH5; -+ break; -+ case Attribute.EK_FLAG: -+ if (e.len == 1) rc = BYTE1; -+ break; -+ case Attribute.EK_REPL: -+ if (e.len == 1) rc = BYTE1; -+ assertBandOKForElems(ab, e.body); -+ break; -+ case Attribute.EK_UN: -+ if (e.flagTest(Attribute.EF_SIGN)) { -+ rc = SIGNED5; -+ } else if (e.len == 1) { -+ rc = BYTE1; -+ } -+ assertBandOKForElems(ab, e.body); -+ break; -+ case Attribute.EK_CASE: -+ assert(b == null); -+ assertBandOKForElems(ab, e.body); -+ return true; // no direct band -+ case Attribute.EK_CALL: -+ assert(b == null); -+ return true; // no direct band -+ case Attribute.EK_CBLE: -+ assert(b == null); -+ assertBandOKForElems(ab, e.body); -+ return true; // no direct band -+ case Attribute.EK_REF: -+ wantIntBand = false; -+ assert(b instanceof CPRefBand); -+ assert(((CPRefBand)b).nullOK == e.flagTest(Attribute.EF_NULL)); -+ break; -+ default: assert(false); -+ } -+ assert(b.regularCoding == rc) -+ : (e+" // "+b); -+ if (wantIntBand) -+ assert(b instanceof IntBand); -+ return true; - } - - private - Attribute.Layout predefineAttribute(int index, int ctype, Band[] ab, -- String name, String layout) { -- // Use Attribute.find to get uniquification of layouts. -- Attribute.Layout def = Attribute.find(ctype, name, layout).layout(); -- //def.predef = true; -- if (index >= 0) { -- setAttributeLayoutIndex(def, index); -- } -- if (ab == null) { -- ab = new Band[0]; -- } -- assert(attrBandTable.get(def) == null); // no redef -- attrBandTable.put(def, ab); -- assert(def.bandCount == ab.length) -- : (def+" // "+Arrays.asList(ab)); -- // Let's make sure the band types match: -- assert(assertBandOKForElems(ab, def.elems)); -- return def; -+ String name, String layout) { -+ // Use Attribute.find to get uniquification of layouts. -+ Attribute.Layout def = Attribute.find(ctype, name, layout).layout(); -+ //def.predef = true; -+ if (index >= 0) { -+ setAttributeLayoutIndex(def, index); -+ } -+ if (ab == null) { -+ ab = new Band[0]; -+ } -+ assert(attrBandTable.get(def) == null); // no redef -+ attrBandTable.put(def, ab); -+ assert(def.bandCount == ab.length) -+ : (def+" // "+Arrays.asList(ab)); -+ // Let's make sure the band types match: -+ assert(assertBandOKForElems(ab, def.elems)); -+ return def; - } - - // This version takes bandPrefix/addHere instead of prebuilt Band[] ab. - private - Attribute.Layout predefineAttribute(int index, -- String bandPrefix, MultiBand addHere, -- Attribute attr) { -- //Attribute.Layout def = Attribute.find(ctype, name, layout).layout(); -- Attribute.Layout def = attr.layout(); -- int ctype = def.ctype(); -- return predefineAttribute(index, ctype, -- makeNewAttributeBands(bandPrefix, def, -- addHere), -- def.name(), def.layout()); -+ String bandPrefix, MultiBand addHere, -+ Attribute attr) { -+ //Attribute.Layout def = Attribute.find(ctype, name, layout).layout(); -+ Attribute.Layout def = attr.layout(); -+ int ctype = def.ctype(); -+ return predefineAttribute(index, ctype, -+ makeNewAttributeBands(bandPrefix, def, -+ addHere), -+ def.name(), def.layout()); - } - - private - void undefineAttribute(int index, int ctype) { -- if (verbose > 1) { -- System.out.println("Removing predefined "+ATTR_CONTEXT_NAME[ctype]+ -- " attribute on bit "+index); -- } -- List defList = attrDefs[ctype]; -- Attribute.Layout def = (Attribute.Layout) defList.get(index); -- assert(def != null); -- defList.set(index, null); -- attrIndexTable.put(def, null); -- // Clear the def bit. (For predefs, it's already clear.) -- assert(index < 64); -- attrDefSeen[ctype] &= ~(1L<<index); -- attrFlagMask[ctype] &= ~(1L<<index); -- Band[] ab = (Band[]) attrBandTable.get(def); -- for (int j = 0; j < ab.length; j++) { -- ab[j].doneWithUnusedBand(); -- } -+ if (verbose > 1) { -+ System.out.println("Removing predefined "+ATTR_CONTEXT_NAME[ctype]+ -+ " attribute on bit "+index); -+ } -+ List defList = attrDefs[ctype]; -+ Attribute.Layout def = (Attribute.Layout) defList.get(index); -+ assert(def != null); -+ defList.set(index, null); -+ attrIndexTable.put(def, null); -+ // Clear the def bit. (For predefs, it's already clear.) -+ assert(index < 64); -+ attrDefSeen[ctype] &= ~(1L<<index); -+ attrFlagMask[ctype] &= ~(1L<<index); -+ Band[] ab = (Band[]) attrBandTable.get(def); -+ for (int j = 0; j < ab.length; j++) { -+ ab[j].doneWithUnusedBand(); -+ } - } - - // Bands which contain non-predefined attrs. - protected MultiBand[] attrBands = new MultiBand[ATTR_CONTEXT_LIMIT]; - { -- attrBands[ATTR_CONTEXT_CLASS] = class_attr_bands; -- attrBands[ATTR_CONTEXT_FIELD] = field_attr_bands; -- attrBands[ATTR_CONTEXT_METHOD] = method_attr_bands; -- attrBands[ATTR_CONTEXT_CODE] = code_attr_bands; -+ attrBands[ATTR_CONTEXT_CLASS] = class_attr_bands; -+ attrBands[ATTR_CONTEXT_FIELD] = field_attr_bands; -+ attrBands[ATTR_CONTEXT_METHOD] = method_attr_bands; -+ attrBands[ATTR_CONTEXT_CODE] = code_attr_bands; - } - - // Create bands for all non-predefined attrs. - void makeNewAttributeBands() { -- // Retract special flag bit bindings, if they were taken over. -- adjustSpecialAttrMasks(); -+ // Retract special flag bit bindings, if they were taken over. -+ adjustSpecialAttrMasks(); - -- for (int ctype = 0; ctype < ATTR_CONTEXT_LIMIT; ctype++) { -- String cname = ATTR_CONTEXT_NAME[ctype]; -- MultiBand xxx_attr_bands = attrBands[ctype]; -- long defSeen = attrDefSeen[ctype]; -- // Note: attrDefSeen is always a subset of attrFlagMask. -- assert((defSeen & ~attrFlagMask[ctype]) == 0); -- for (int i = 0; i < attrDefs[ctype].size(); i++) { -- Attribute.Layout def = (Attribute.Layout) -- attrDefs[ctype].get(i); -- if (def == null) continue; // unused flag bit -- if (def.bandCount == 0) continue; // empty attr -- if (i < attrIndexLimit[ctype] && !testBit(defSeen, 1L<<i)) { -- // There are already predefined bands here. -- assert(attrBandTable.get(def) != null); -- continue; -- } -- int base = xxx_attr_bands.size(); -- String pfx = cname+"_"+def.name()+"_"; // debug only -- if (verbose > 1) -- Utils.log.fine("Making new bands for "+def); -- Band[] newAB = makeNewAttributeBands(pfx, def, -- xxx_attr_bands); -- assert(newAB.length == def.bandCount); -- Band[] prevAB = (Band[]) attrBandTable.put(def, newAB); -- if (prevAB != null) { -- // We won't be using these predefined bands. -- for (int j = 0; j < prevAB.length; j++) { -- prevAB[j].doneWithUnusedBand(); -- } -- } -- } -- } -- //System.out.println(prevForAssertMap); -+ for (int ctype = 0; ctype < ATTR_CONTEXT_LIMIT; ctype++) { -+ String cname = ATTR_CONTEXT_NAME[ctype]; -+ MultiBand xxx_attr_bands = attrBands[ctype]; -+ long defSeen = attrDefSeen[ctype]; -+ // Note: attrDefSeen is always a subset of attrFlagMask. -+ assert((defSeen & ~attrFlagMask[ctype]) == 0); -+ for (int i = 0; i < attrDefs[ctype].size(); i++) { -+ Attribute.Layout def = (Attribute.Layout) -+ attrDefs[ctype].get(i); -+ if (def == null) continue; // unused flag bit -+ if (def.bandCount == 0) continue; // empty attr -+ if (i < attrIndexLimit[ctype] && !testBit(defSeen, 1L<<i)) { -+ // There are already predefined bands here. -+ assert(attrBandTable.get(def) != null); -+ continue; -+ } -+ int base = xxx_attr_bands.size(); -+ String pfx = cname+"_"+def.name()+"_"; // debug only -+ if (verbose > 1) -+ Utils.log.fine("Making new bands for "+def); -+ Band[] newAB = makeNewAttributeBands(pfx, def, -+ xxx_attr_bands); -+ assert(newAB.length == def.bandCount); -+ Band[] prevAB = (Band[]) attrBandTable.put(def, newAB); -+ if (prevAB != null) { -+ // We won't be using these predefined bands. -+ for (int j = 0; j < prevAB.length; j++) { -+ prevAB[j].doneWithUnusedBand(); -+ } -+ } -+ } -+ } -+ //System.out.println(prevForAssertMap); - } - private - Band[] makeNewAttributeBands(String pfx, Attribute.Layout def, -- MultiBand addHere) { -- int base = addHere.size(); -- makeNewAttributeBands(pfx, def.elems, addHere); -- int nb = addHere.size() - base; -- Band[] newAB = new Band[nb]; -- for (int i = 0; i < nb; i++) { -- newAB[i] = addHere.get(base+i); -- } -- return newAB; -+ MultiBand addHere) { -+ int base = addHere.size(); -+ makeNewAttributeBands(pfx, def.elems, addHere); -+ int nb = addHere.size() - base; -+ Band[] newAB = new Band[nb]; -+ for (int i = 0; i < nb; i++) { -+ newAB[i] = addHere.get(base+i); -+ } -+ return newAB; - } - // Recursive helper, operates on a "body" or other sequence of elems: - private - void makeNewAttributeBands(String pfx, Attribute.Layout.Element[] elems, -- MultiBand ab) { -- for (int i = 0; i < elems.length; i++) { -- Attribute.Layout.Element e = elems[i]; -- String name = pfx+ab.size()+"_"+e.layout; -- { -- int tem; -- if ((tem = name.indexOf('[')) > 0) -- name = name.substring(0, tem); -- if ((tem = name.indexOf('(')) > 0) -- name = name.substring(0, tem); -- if (name.endsWith("H")) -- name = name.substring(0, name.length()-1); -- } -- Band nb; -- switch (e.kind) { -- case Attribute.EK_INT: -- nb = newElemBand(e, name, ab); -- break; -- case Attribute.EK_BCI: -- if (!e.flagTest(Attribute.EF_DELTA)) { -- // PH: transmit R(bci), store bci -- nb = ab.newIntBand(name, BCI5); -- } else { -- // POH: transmit D(R(bci)), store bci -- nb = ab.newIntBand(name, BRANCH5); -- } -- // Note: No case for BYTE1 here. -- break; -- case Attribute.EK_BCO: -- // OH: transmit D(R(bci)), store D(bci) -- nb = ab.newIntBand(name, BRANCH5); -- // Note: No case for BYTE1 here. -- break; -- case Attribute.EK_FLAG: -- assert(!e.flagTest(Attribute.EF_SIGN)); -- nb = newElemBand(e, name, ab); -- break; -- case Attribute.EK_REPL: -- assert(!e.flagTest(Attribute.EF_SIGN)); -- nb = newElemBand(e, name, ab); -- makeNewAttributeBands(pfx, e.body, ab); -- break; -- case Attribute.EK_UN: -- nb = newElemBand(e, name, ab); -- makeNewAttributeBands(pfx, e.body, ab); -- break; -- case Attribute.EK_CASE: -- if (!e.flagTest(Attribute.EF_BACK)) { -- // If it's not a duplicate body, make the bands. -- makeNewAttributeBands(pfx, e.body, ab); -- } -- continue; // no new band to make -- case Attribute.EK_REF: -- byte refKind = e.refKind; -- boolean nullOK = e.flagTest(Attribute.EF_NULL); -- nb = ab.newCPRefBand(name, UNSIGNED5, refKind, nullOK); -- // Note: No case for BYTE1 here. -- break; -- case Attribute.EK_CALL: -- continue; // no new band to make -- case Attribute.EK_CBLE: -- makeNewAttributeBands(pfx, e.body, ab); -- continue; // no new band to make -- default: assert(false); continue; -- } -- if (verbose > 1) { -- Utils.log.fine("New attribute band "+nb); -- } -- } -+ MultiBand ab) { -+ for (int i = 0; i < elems.length; i++) { -+ Attribute.Layout.Element e = elems[i]; -+ String name = pfx+ab.size()+"_"+e.layout; -+ { -+ int tem; -+ if ((tem = name.indexOf('[')) > 0) -+ name = name.substring(0, tem); -+ if ((tem = name.indexOf('(')) > 0) -+ name = name.substring(0, tem); -+ if (name.endsWith("H")) -+ name = name.substring(0, name.length()-1); -+ } -+ Band nb; -+ switch (e.kind) { -+ case Attribute.EK_INT: -+ nb = newElemBand(e, name, ab); -+ break; -+ case Attribute.EK_BCI: -+ if (!e.flagTest(Attribute.EF_DELTA)) { -+ // PH: transmit R(bci), store bci -+ nb = ab.newIntBand(name, BCI5); -+ } else { -+ // POH: transmit D(R(bci)), store bci -+ nb = ab.newIntBand(name, BRANCH5); -+ } -+ // Note: No case for BYTE1 here. -+ break; -+ case Attribute.EK_BCO: -+ // OH: transmit D(R(bci)), store D(bci) -+ nb = ab.newIntBand(name, BRANCH5); -+ // Note: No case for BYTE1 here. -+ break; -+ case Attribute.EK_FLAG: -+ assert(!e.flagTest(Attribute.EF_SIGN)); -+ nb = newElemBand(e, name, ab); -+ break; -+ case Attribute.EK_REPL: -+ assert(!e.flagTest(Attribute.EF_SIGN)); -+ nb = newElemBand(e, name, ab); -+ makeNewAttributeBands(pfx, e.body, ab); -+ break; -+ case Attribute.EK_UN: -+ nb = newElemBand(e, name, ab); -+ makeNewAttributeBands(pfx, e.body, ab); -+ break; -+ case Attribute.EK_CASE: -+ if (!e.flagTest(Attribute.EF_BACK)) { -+ // If it's not a duplicate body, make the bands. -+ makeNewAttributeBands(pfx, e.body, ab); -+ } -+ continue; // no new band to make -+ case Attribute.EK_REF: -+ byte refKind = e.refKind; -+ boolean nullOK = e.flagTest(Attribute.EF_NULL); -+ nb = ab.newCPRefBand(name, UNSIGNED5, refKind, nullOK); -+ // Note: No case for BYTE1 here. -+ break; -+ case Attribute.EK_CALL: -+ continue; // no new band to make -+ case Attribute.EK_CBLE: -+ makeNewAttributeBands(pfx, e.body, ab); -+ continue; // no new band to make -+ default: assert(false); continue; -+ } -+ if (verbose > 1) { -+ Utils.log.fine("New attribute band "+nb); -+ } -+ } - } - private - Band newElemBand(Attribute.Layout.Element e, String name, MultiBand ab) { -- if (e.flagTest(Attribute.EF_SIGN)) { -- return ab.newIntBand(name, SIGNED5); -- } else if (e.len == 1) { -- return ab.newIntBand(name, BYTE1); // Not ByteBand, please. -- } else { -- return ab.newIntBand(name, UNSIGNED5); -- } -+ if (e.flagTest(Attribute.EF_SIGN)) { -+ return ab.newIntBand(name, SIGNED5); -+ } else if (e.len == 1) { -+ return ab.newIntBand(name, BYTE1); // Not ByteBand, please. -+ } else { -+ return ab.newIntBand(name, UNSIGNED5); -+ } - } - - protected int setAttributeLayoutIndex(Attribute.Layout def, int index) { -- int ctype = def.ctype; -- assert(ATTR_INDEX_OVERFLOW <= index && index < attrIndexLimit[ctype]); -- List defList = attrDefs[ctype]; -- if (index == ATTR_INDEX_OVERFLOW) { -- // Overflow attribute. -- index = defList.size(); -- defList.add(def); -- if (verbose > 0) -- Utils.log.info("Adding new attribute at "+def +": "+index); -- attrIndexTable.put(def, new Integer(index)); -- return index; -- } -+ int ctype = def.ctype; -+ assert(ATTR_INDEX_OVERFLOW <= index && index < attrIndexLimit[ctype]); -+ List defList = attrDefs[ctype]; -+ if (index == ATTR_INDEX_OVERFLOW) { -+ // Overflow attribute. -+ index = defList.size(); -+ defList.add(def); -+ if (verbose > 0) -+ Utils.log.info("Adding new attribute at "+def +": "+index); -+ attrIndexTable.put(def, new Integer(index)); -+ return index; -+ } - -- // Detect redefinitions: -- if (testBit(attrDefSeen[ctype], 1L<<index)) { -- throw new RuntimeException("Multiple explicit definition at "+index+": "+def); -- } -- attrDefSeen[ctype] |= (1L<<index); -+ // Detect redefinitions: -+ if (testBit(attrDefSeen[ctype], 1L<<index)) { -+ throw new RuntimeException("Multiple explicit definition at "+index+": "+def); -+ } -+ attrDefSeen[ctype] |= (1L<<index); - -- // Adding a new fixed attribute. -- assert(0 <= index && index < attrIndexLimit[ctype]); -- if (verbose > (attrClassFileVersionMask == 0? 2:0)) -- Utils.log.fine("Fixing new attribute at "+index -- +": "+def -- +(defList.get(index) == null? "": -- "; replacing "+defList.get(index))); -- attrFlagMask[ctype] |= (1L<<index); -- // Remove index binding of any previous fixed attr. -- attrIndexTable.put(defList.get(index), null); -- defList.set(index, def); -- attrIndexTable.put(def, new Integer(index)); -- return index; -+ // Adding a new fixed attribute. -+ assert(0 <= index && index < attrIndexLimit[ctype]); -+ if (verbose > (attrClassFileVersionMask == 0? 2:0)) -+ Utils.log.fine("Fixing new attribute at "+index -+ +": "+def -+ +(defList.get(index) == null? "": -+ "; replacing "+defList.get(index))); -+ attrFlagMask[ctype] |= (1L<<index); -+ // Remove index binding of any previous fixed attr. -+ attrIndexTable.put(defList.get(index), null); -+ defList.set(index, def); -+ attrIndexTable.put(def, new Integer(index)); -+ return index; - } - - // encodings found in the code_headers band - private static final int[][] shortCodeLimits = { -- { 12, 12 }, // s<12, l<12, e=0 [1..144] -- { 8, 8 }, // s<8, l<8, e=1 [145..208] -- { 7, 7 }, // s<7, l<7, e=2 [209..256] -+ { 12, 12 }, // s<12, l<12, e=0 [1..144] -+ { 8, 8 }, // s<8, l<8, e=1 [145..208] -+ { 7, 7 }, // s<7, l<7, e=2 [209..256] - }; - public final int shortCodeHeader_h_limit = shortCodeLimits.length; - - // return 0 if it won't encode, else a number in [1..255] - static int shortCodeHeader(Code code) { -- int s = code.max_stack; -- int l0 = code.max_locals; -- int h = code.handler_class.length; -- if (h >= shortCodeLimits.length) return LONG_CODE_HEADER; -- int siglen = code.getMethod().getArgumentSize(); -- assert(l0 >= siglen); // enough locals for signature! -- if (l0 < siglen) return LONG_CODE_HEADER; -- int l1 = l0 - siglen; // do not count locals required by the signature -- int lims = shortCodeLimits[h][0]; -- int liml = shortCodeLimits[h][1]; -- if (s >= lims || l1 >= liml) return LONG_CODE_HEADER; -- int sc = shortCodeHeader_h_base(h); -- sc += s + lims*l1; -- if (sc > 255) return LONG_CODE_HEADER; -- assert(shortCodeHeader_max_stack(sc) == s); -- assert(shortCodeHeader_max_na_locals(sc) == l1); -- assert(shortCodeHeader_handler_count(sc) == h); -- return sc; -+ int s = code.max_stack; -+ int l0 = code.max_locals; -+ int h = code.handler_class.length; -+ if (h >= shortCodeLimits.length) return LONG_CODE_HEADER; -+ int siglen = code.getMethod().getArgumentSize(); -+ assert(l0 >= siglen); // enough locals for signature! -+ if (l0 < siglen) return LONG_CODE_HEADER; -+ int l1 = l0 - siglen; // do not count locals required by the signature -+ int lims = shortCodeLimits[h][0]; -+ int liml = shortCodeLimits[h][1]; -+ if (s >= lims || l1 >= liml) return LONG_CODE_HEADER; -+ int sc = shortCodeHeader_h_base(h); -+ sc += s + lims*l1; -+ if (sc > 255) return LONG_CODE_HEADER; -+ assert(shortCodeHeader_max_stack(sc) == s); -+ assert(shortCodeHeader_max_na_locals(sc) == l1); -+ assert(shortCodeHeader_handler_count(sc) == h); -+ return sc; - } - - static final int LONG_CODE_HEADER = 0; - static int shortCodeHeader_handler_count(int sc) { -- assert(sc > 0 && sc <= 255); -- for (int h = 0; ; h++) { -- if (sc < shortCodeHeader_h_base(h+1)) -- return h; -- } -+ assert(sc > 0 && sc <= 255); -+ for (int h = 0; ; h++) { -+ if (sc < shortCodeHeader_h_base(h+1)) -+ return h; -+ } - } - static int shortCodeHeader_max_stack(int sc) { -- int h = shortCodeHeader_handler_count(sc); -- int lims = shortCodeLimits[h][0]; -- return (sc - shortCodeHeader_h_base(h)) % lims; -+ int h = shortCodeHeader_handler_count(sc); -+ int lims = shortCodeLimits[h][0]; -+ return (sc - shortCodeHeader_h_base(h)) % lims; - } - static int shortCodeHeader_max_na_locals(int sc) { -- int h = shortCodeHeader_handler_count(sc); -- int lims = shortCodeLimits[h][0]; -- return (sc - shortCodeHeader_h_base(h)) / lims; -+ int h = shortCodeHeader_handler_count(sc); -+ int lims = shortCodeLimits[h][0]; -+ return (sc - shortCodeHeader_h_base(h)) / lims; - } - - private static int shortCodeHeader_h_base(int h) { -- assert(h <= shortCodeLimits.length); -- int sc = 1; -- for (int h0 = 0; h0 < h; h0++) { -- int lims = shortCodeLimits[h0][0]; -- int liml = shortCodeLimits[h0][1]; -- sc += lims * liml; -- } -- return sc; -+ assert(h <= shortCodeLimits.length); -+ int sc = 1; -+ for (int h0 = 0; h0 < h; h0++) { -+ int lims = shortCodeLimits[h0][0]; -+ int liml = shortCodeLimits[h0][1]; -+ sc += lims * liml; -+ } -+ return sc; - } - - // utilities for accessing the bc_label band: - protected void putLabel(IntBand bc_label, Code c, int pc, int targetPC) { -- bc_label.putInt(c.encodeBCI(targetPC) - c.encodeBCI(pc)); -+ bc_label.putInt(c.encodeBCI(targetPC) - c.encodeBCI(pc)); - } - protected int getLabel(IntBand bc_label, Code c, int pc) { -- return c.decodeBCI(bc_label.getInt() + c.encodeBCI(pc)); -+ return c.decodeBCI(bc_label.getInt() + c.encodeBCI(pc)); - } - - protected CPRefBand getCPRefOpBand(int bc) { -- switch (Instruction.getCPRefOpTag(bc)) { -- case CONSTANT_Class: -- return bc_classref; -- case CONSTANT_Fieldref: -- return bc_fieldref; -- case CONSTANT_Methodref: -- return bc_methodref; -- case CONSTANT_InterfaceMethodref: -- return bc_imethodref; -- case CONSTANT_Literal: -- switch (bc) { -- case _ildc: case _ildc_w: -- return bc_intref; -- case _fldc: case _fldc_w: -- return bc_floatref; -- case _lldc2_w: -- return bc_longref; -- case _dldc2_w: -- return bc_doubleref; -- case _aldc: case _aldc_w: -- return bc_stringref; -- case _cldc: case _cldc_w: -- return bc_classref; -- } -- break; -- } -- assert(false); -- return null; -+ switch (Instruction.getCPRefOpTag(bc)) { -+ case CONSTANT_Class: -+ return bc_classref; -+ case CONSTANT_Fieldref: -+ return bc_fieldref; -+ case CONSTANT_Methodref: -+ return bc_methodref; -+ case CONSTANT_InterfaceMethodref: -+ return bc_imethodref; -+ case CONSTANT_Literal: -+ switch (bc) { -+ case _ildc: case _ildc_w: -+ return bc_intref; -+ case _fldc: case _fldc_w: -+ return bc_floatref; -+ case _lldc2_w: -+ return bc_longref; -+ case _dldc2_w: -+ return bc_doubleref; -+ case _aldc: case _aldc_w: -+ return bc_stringref; -+ case _cldc: case _cldc_w: -+ return bc_classref; -+ } -+ break; -+ } -+ assert(false); -+ return null; - } - - protected CPRefBand selfOpRefBand(int self_bc) { -- assert(Instruction.isSelfLinkerOp(self_bc)); -- int idx = (self_bc - _self_linker_op); -- boolean isSuper = (idx >= _self_linker_super_flag); -- if (isSuper) idx -= _self_linker_super_flag; -- boolean isAload = (idx >= _self_linker_aload_flag); -- if (isAload) idx -= _self_linker_aload_flag; -- int origBC = _first_linker_op + idx; -- boolean isField = Instruction.isFieldOp(origBC); -- if (!isSuper) -- return isField? bc_thisfield: bc_thismethod; -- else -- return isField? bc_superfield: bc_supermethod; -+ assert(Instruction.isSelfLinkerOp(self_bc)); -+ int idx = (self_bc - _self_linker_op); -+ boolean isSuper = (idx >= _self_linker_super_flag); -+ if (isSuper) idx -= _self_linker_super_flag; -+ boolean isAload = (idx >= _self_linker_aload_flag); -+ if (isAload) idx -= _self_linker_aload_flag; -+ int origBC = _first_linker_op + idx; -+ boolean isField = Instruction.isFieldOp(origBC); -+ if (!isSuper) -+ return isField? bc_thisfield: bc_thismethod; -+ else -+ return isField? bc_superfield: bc_supermethod; - } - - //////////////////////////////////////////////////////////////////// -@@ -2347,317 +2347,319 @@ class BandStructure implements Constants - static int nextSeqForDebug; - static File dumpDir; - static OutputStream getDumpStream(Band b, String ext) throws IOException { -- return getDumpStream(b.name, b.seqForDebug, ext, b); -+ return getDumpStream(b.name, b.seqForDebug, ext, b); - } - static OutputStream getDumpStream(Index ix, String ext) throws IOException { -- if (ix.size() == 0) return new ByteArrayOutputStream(); -- int seq = ConstantPool.TAG_ORDER[ix.cpMap[0].tag]; -- return getDumpStream(ix.debugName, seq, ext, ix); -+ if (ix.size() == 0) return new ByteArrayOutputStream(); -+ int seq = ConstantPool.TAG_ORDER[ix.cpMap[0].tag]; -+ return getDumpStream(ix.debugName, seq, ext, ix); - } - static OutputStream getDumpStream(String name, int seq, String ext, Object b) throws IOException { -- if (dumpDir == null) { -- dumpDir = File.createTempFile("BD_", "", new File(".")); -- dumpDir.delete(); -- if (dumpDir.mkdir()) -- Utils.log.info("Dumping bands to "+dumpDir); -- } -- name = name.replace('(', ' ').replace(')', ' '); -- name = name.replace('/', ' '); -- name = name.replace('*', ' '); -- name = name.trim().replace(' ','_'); -- name = ((10000+seq) + "_" + name).substring(1); -- File dumpFile = new File(dumpDir, name+ext); -- Utils.log.info("Dumping "+b+" to "+dumpFile); -- return new BufferedOutputStream(new FileOutputStream(dumpFile)); -+ if (dumpDir == null) { -+ dumpDir = File.createTempFile("BD_", "", new File(".")); -+ dumpDir.delete(); -+ if (dumpDir.mkdir()) -+ Utils.log.info("Dumping bands to "+dumpDir); -+ } -+ name = name.replace('(', ' ').replace(')', ' '); -+ name = name.replace('/', ' '); -+ name = name.replace('*', ' '); -+ name = name.trim().replace(' ','_'); -+ name = ((10000+seq) + "_" + name).substring(1); -+ File dumpFile = new File(dumpDir, name+ext); -+ Utils.log.info("Dumping "+b+" to "+dumpFile); -+ return new BufferedOutputStream(new FileOutputStream(dumpFile)); - } - - // DEBUG ONLY: Validate me at each length change. - static boolean assertCanChangeLength(Band b) { -- switch (b.phase) { -- case COLLECT_PHASE: -- case READ_PHASE: -- return true; -- } -- return false; -+ switch (b.phase) { -+ case COLLECT_PHASE: -+ case READ_PHASE: -+ return true; -+ } -+ return false; - } - - // DEBUG ONLY: Validate a phase. - static boolean assertPhase(Band b, int phaseExpected) { -- if (b.phase() != phaseExpected) { -- Utils.log.warning("phase expected "+phaseExpected+" was "+b.phase()+" in "+b); -- return false; -- } -- return true; -+ if (b.phase() != phaseExpected) { -+ Utils.log.warning("phase expected "+phaseExpected+" was "+b.phase()+" in "+b); -+ return false; -+ } -+ return true; - } - - - // DEBUG ONLY: Tells whether verbosity is turned on. - static int verbose() { -- return Utils.currentPropMap().getInteger(Utils.DEBUG_VERBOSE); -+ return Utils.currentPropMap().getInteger(Utils.DEBUG_VERBOSE); - } - - - // DEBUG ONLY: Validate me at each phase change. - static boolean assertPhaseChangeOK(Band b, int p0, int p1) { -- switch (p0*10+p1) { -- /// Writing phases: -- case NO_PHASE*10+COLLECT_PHASE: -- // Ready to collect data from the input classes. -- assert(!b.isReader()); -- assert(b.capacity() >= 0); -- assert(b.length() == 0); -- return true; -- case COLLECT_PHASE*10+FROZEN_PHASE: -- case FROZEN_PHASE*10+FROZEN_PHASE: -- assert(b.length() == 0); -- return true; -- case COLLECT_PHASE*10+WRITE_PHASE: -- case FROZEN_PHASE*10+WRITE_PHASE: -- // Data is all collected. Ready to write bytes to disk. -- return true; -- case WRITE_PHASE*10+DONE_PHASE: -- // Done writing to disk. Ready to reset, in principle. -- return true; -+ switch (p0*10+p1) { -+ /// Writing phases: -+ case NO_PHASE*10+COLLECT_PHASE: -+ // Ready to collect data from the input classes. -+ assert(!b.isReader()); -+ assert(b.capacity() >= 0); -+ assert(b.length() == 0); -+ return true; -+ case COLLECT_PHASE*10+FROZEN_PHASE: -+ case FROZEN_PHASE*10+FROZEN_PHASE: -+ assert(b.length() == 0); -+ return true; -+ case COLLECT_PHASE*10+WRITE_PHASE: -+ case FROZEN_PHASE*10+WRITE_PHASE: -+ // Data is all collected. Ready to write bytes to disk. -+ return true; -+ case WRITE_PHASE*10+DONE_PHASE: -+ // Done writing to disk. Ready to reset, in principle. -+ return true; - -- /// Reading phases: -- case NO_PHASE*10+EXPECT_PHASE: -- assert(b.isReader()); -- assert(b.capacity() < 0); -- return true; -- case EXPECT_PHASE*10+READ_PHASE: -- // Ready to read values from disk. -- assert(Math.max(0,b.capacity()) >= b.valuesExpected()); -- assert(b.length() <= 0); -- return true; -- case READ_PHASE*10+DISBURSE_PHASE: -- // Ready to disburse values. -- assert(b.valuesRemainingForDebug() == b.length()); -- return true; -- case DISBURSE_PHASE*10+DONE_PHASE: -- // Done disbursing values. Ready to reset, in principle. -- assert(assertDoneDisbursing(b)); -- return true; -- } -- if (p0 == p1) -- Utils.log.warning("Already in phase "+p0); -- else -- Utils.log.warning("Unexpected phase "+p0+" -> "+p1); -- return false; -+ /// Reading phases: -+ case NO_PHASE*10+EXPECT_PHASE: -+ assert(b.isReader()); -+ assert(b.capacity() < 0); -+ return true; -+ case EXPECT_PHASE*10+READ_PHASE: -+ // Ready to read values from disk. -+ assert(Math.max(0,b.capacity()) >= b.valuesExpected()); -+ assert(b.length() <= 0); -+ return true; -+ case READ_PHASE*10+DISBURSE_PHASE: -+ // Ready to disburse values. -+ assert(b.valuesRemainingForDebug() == b.length()); -+ return true; -+ case DISBURSE_PHASE*10+DONE_PHASE: -+ // Done disbursing values. Ready to reset, in principle. -+ assert(assertDoneDisbursing(b)); -+ return true; -+ } -+ if (p0 == p1) -+ Utils.log.warning("Already in phase "+p0); -+ else -+ Utils.log.warning("Unexpected phase "+p0+" -> "+p1); -+ return false; - } - - static private boolean assertDoneDisbursing(Band b) { -- if (b.phase != DISBURSE_PHASE) { -- Utils.log.warning("assertDoneDisbursing: still in phase "+b.phase+": "+b); -- if (verbose() <= 1) return false; // fail now -- } -- int left = b.valuesRemainingForDebug(); -- if (left > 0) { -- Utils.log.warning("assertDoneDisbursing: "+left+" values left in "+b); -- if (verbose() <= 1) return false; // fail now -- } -- if (b instanceof MultiBand) { -- MultiBand mb = (MultiBand) b; -- for (int i = 0; i < mb.bandCount; i++) { -- Band sub = mb.bands[i]; -- if (sub.phase != DONE_PHASE) { -- Utils.log.warning("assertDoneDisbursing: sub-band still in phase "+sub.phase+": "+sub); -- if (verbose() <= 1) return false; // fail now -- } -- } -- } -- return true; -+ if (b.phase != DISBURSE_PHASE) { -+ Utils.log.warning("assertDoneDisbursing: still in phase "+b.phase+": "+b); -+ if (verbose() <= 1) return false; // fail now -+ } -+ int left = b.valuesRemainingForDebug(); -+ if (left > 0) { -+ Utils.log.warning("assertDoneDisbursing: "+left+" values left in "+b); -+ if (verbose() <= 1) return false; // fail now -+ } -+ if (b instanceof MultiBand) { -+ MultiBand mb = (MultiBand) b; -+ for (int i = 0; i < mb.bandCount; i++) { -+ Band sub = mb.bands[i]; -+ if (sub.phase != DONE_PHASE) { -+ Utils.log.warning("assertDoneDisbursing: sub-band still in phase "+sub.phase+": "+sub); -+ if (verbose() <= 1) return false; // fail now -+ } -+ } -+ } -+ return true; - } - - static private void printCDecl(Band b) { -- if (b instanceof MultiBand) { -- MultiBand mb = (MultiBand) b; -- for (int i = 0; i < mb.bandCount; i++) { -- printCDecl(mb.bands[i]); -- } -- return; -- } -- String ixS = "NULL"; -- if (b instanceof CPRefBand) { -- Index ix = ((CPRefBand)b).index; -- if (ix != null) ixS = "INDEX("+ix.debugName+")"; -- } -- Coding[] knownc = { BYTE1, CHAR3, BCI5, BRANCH5, UNSIGNED5, -- UDELTA5, SIGNED5, DELTA5, MDELTA5 }; -- String[] knowns = { "BYTE1", "CHAR3", "BCI5", "BRANCH5", "UNSIGNED5", -- "UDELTA5", "SIGNED5", "DELTA5", "MDELTA5" }; -- Coding rc = b.regularCoding; -- int rci = Arrays.asList(knownc).indexOf(rc); -- String cstr; -- if (rci >= 0) -- cstr = knowns[rci]; -- else -- cstr = "CODING"+rc.keyString(); -- System.out.println(" BAND_INIT(\""+b.name()+"\"" -- +", "+cstr+", "+ixS+"),"); -+ if (b instanceof MultiBand) { -+ MultiBand mb = (MultiBand) b; -+ for (int i = 0; i < mb.bandCount; i++) { -+ printCDecl(mb.bands[i]); -+ } -+ return; -+ } -+ String ixS = "NULL"; -+ if (b instanceof CPRefBand) { -+ Index ix = ((CPRefBand)b).index; -+ if (ix != null) ixS = "INDEX("+ix.debugName+")"; -+ } -+ Coding[] knownc = { BYTE1, CHAR3, BCI5, BRANCH5, UNSIGNED5, -+ UDELTA5, SIGNED5, DELTA5, MDELTA5 }; -+ String[] knowns = { "BYTE1", "CHAR3", "BCI5", "BRANCH5", "UNSIGNED5", -+ "UDELTA5", "SIGNED5", "DELTA5", "MDELTA5" }; -+ Coding rc = b.regularCoding; -+ int rci = Arrays.asList(knownc).indexOf(rc); -+ String cstr; -+ if (rci >= 0) -+ cstr = knowns[rci]; -+ else -+ cstr = "CODING"+rc.keyString(); -+ System.out.println(" BAND_INIT(\""+b.name()+"\"" -+ +", "+cstr+", "+ixS+"),"); - } - - private HashMap prevForAssertMap; - - // DEBUG ONLY: Record something about the band order. - boolean notePrevForAssert(Band b, Band p) { -- if (prevForAssertMap == null) -- prevForAssertMap = new HashMap(); -- prevForAssertMap.put(b, p); -- return true; -+ if (prevForAssertMap == null) -+ prevForAssertMap = new HashMap(); -+ prevForAssertMap.put(b, p); -+ return true; - } - - // DEBUG ONLY: Validate next input band. - private boolean assertReadyToReadFrom(Band b, InputStream in) throws IOException { -- Band p = (Band) prevForAssertMap.get(b); -- // Any previous band must be done reading before this one starts. -- if (p != null && phaseCmp(p.phase(), DISBURSE_PHASE) < 0) { -- Utils.log.warning("Previous band not done reading."); -- Utils.log.info(" Previous band: "+p); -- Utils.log.info(" Next band: "+b); -- Thread.dumpStack(); -- assert(verbose > 0); // die unless verbose is true -- } -- String name = b.name; -- if (optDebugBands && !name.startsWith("(")) { -- // Verify synchronization between reader & writer: -- StringBuffer buf = new StringBuffer(); -- int ch; -- while ((ch = in.read()) > 0) -- buf.append((char)ch); -- String inName = buf.toString(); -- if (!inName.equals(name)) { -- StringBuffer sb = new StringBuffer(); -- sb.append("Expected "+name+" but read: "); -- inName += (char)ch; -- while (inName.length() < 10) -- inName += (char)in.read(); -- for (int i = 0; i < inName.length(); i++) -- sb.append(inName.charAt(i)); -- Utils.log.warning(sb.toString()); -- return false; -- } -- } -- return true; -+ Band p = (Band) prevForAssertMap.get(b); -+ // Any previous band must be done reading before this one starts. -+ if (p != null && phaseCmp(p.phase(), DISBURSE_PHASE) < 0) { -+ Utils.log.warning("Previous band not done reading."); -+ Utils.log.info(" Previous band: "+p); -+ Utils.log.info(" Next band: "+b); -+ Thread.dumpStack(); -+ assert(verbose > 0); // die unless verbose is true -+ } -+ String name = b.name; -+ if (optDebugBands && !name.startsWith("(")) { -+ // Verify synchronization between reader & writer: -+ StringBuffer buf = new StringBuffer(); -+ int ch; -+ while ((ch = in.read()) > 0) -+ buf.append((char)ch); -+ String inName = buf.toString(); -+ if (!inName.equals(name)) { -+ StringBuffer sb = new StringBuffer(); -+ sb.append("Expected "+name+" but read: "); -+ inName += (char)ch; -+ while (inName.length() < 10) -+ inName += (char)in.read(); -+ for (int i = 0; i < inName.length(); i++) -+ sb.append(inName.charAt(i)); -+ Utils.log.warning(sb.toString()); -+ return false; -+ } -+ } -+ return true; - } - - // DEBUG ONLY: Make sure a bunch of cprefs are correct. - private boolean assertValidCPRefs(CPRefBand b) { -- if (b.index == null) return true; -- int limit = b.index.size()+1; -- for (int i = 0; i < b.length(); i++) { -- int v = b.valueAtForDebug(i); -- if (v < 0 || v >= limit) { -- Utils.log.warning("CP ref out of range "+ -- "["+i+"] = "+v+" in "+b); -- return false; -- } -- } -- return true; -+ if (b.index == null) return true; -+ int limit = b.index.size()+1; -+ for (int i = 0; i < b.length(); i++) { -+ int v = b.valueAtForDebug(i); -+ if (v < 0 || v >= limit) { -+ Utils.log.warning("CP ref out of range "+ -+ "["+i+"] = "+v+" in "+b); -+ return false; -+ } -+ } -+ return true; - } - - // DEBUG ONLY: Maybe write a debugging cookie to next output band. - private boolean assertReadyToWriteTo(Band b, OutputStream out) throws IOException { -- Band p = (Band) prevForAssertMap.get(b); -- // Any previous band must be done writing before this one starts. -- if (p != null && phaseCmp(p.phase(), DONE_PHASE) < 0) { -- Utils.log.warning("Previous band not done writing."); -- Utils.log.info(" Previous band: "+p); -- Utils.log.info(" Next band: "+b); -- Thread.dumpStack(); -- assert(verbose > 0); // die unless verbose is true -- } -- String name = b.name; -- if (optDebugBands && !name.startsWith("(")) { -- // Verify synchronization between reader & writer: -- for (int j = 0; j < name.length(); j++) { -- out.write((byte)name.charAt(j)); -- } -- out.write((byte)0); -- } -- return true; -+ Band p = (Band) prevForAssertMap.get(b); -+ // Any previous band must be done writing before this one starts. -+ if (p != null && phaseCmp(p.phase(), DONE_PHASE) < 0) { -+ Utils.log.warning("Previous band not done writing."); -+ Utils.log.info(" Previous band: "+p); -+ Utils.log.info(" Next band: "+b); -+ Thread.dumpStack(); -+ assert(verbose > 0); // die unless verbose is true -+ } -+ String name = b.name; -+ if (optDebugBands && !name.startsWith("(")) { -+ // Verify synchronization between reader & writer: -+ for (int j = 0; j < name.length(); j++) { -+ out.write((byte)name.charAt(j)); -+ } -+ out.write((byte)0); -+ } -+ return true; - } - - protected static boolean testBit(int flags, int bitMask) { -- return (flags & bitMask) != 0; -+ return (flags & bitMask) != 0; - } - protected static int setBit(int flags, int bitMask, boolean z) { -- return z ? (flags | bitMask) : (flags &~ bitMask); -+ return z ? (flags | bitMask) : (flags &~ bitMask); - } - protected static boolean testBit(long flags, long bitMask) { -- return (flags & bitMask) != 0; -+ return (flags & bitMask) != 0; - } - protected static long setBit(long flags, long bitMask, boolean z) { -- return z ? (flags | bitMask) : (flags &~ bitMask); -+ return z ? (flags | bitMask) : (flags &~ bitMask); - } - - - static void printArrayTo(PrintStream ps, int[] values, int start, int end) { -- int len = end-start; -- for (int i = 0; i < len; i++) { -- if (i % 10 == 0) -- ps.println(); -- else -- ps.print(" "); -- ps.print(values[start+i]); -- } -- ps.println(); -+ int len = end-start; -+ for (int i = 0; i < len; i++) { -+ if (i % 10 == 0) -+ ps.println(); -+ else -+ ps.print(" "); -+ ps.print(values[start+i]); -+ } -+ ps.println(); - } - - static void printArrayTo(PrintStream ps, Entry[] cpMap, int start, int end) { -- StringBuffer buf = new StringBuffer(); -- int len = end-start; -- for (int i = 0; i < len; i++) { -- String s = cpMap[start+i].stringValue(); -- buf.setLength(0); -- for (int j = 0; j < s.length(); j++) { -- char ch = s.charAt(j); -- if (!(ch < ' ' || ch > '~' || ch == '\\')) { -- buf.append(ch); -- } else if (ch == '\n') { -- buf.append("\\n"); -- } else if (ch == '\t') { -- buf.append("\\t"); -- } else if (ch == '\r') { -- buf.append("\\r"); -- } else { -- buf.append("\\x"+Integer.toHexString(ch)); -- } -- } -- ps.println(buf); -- } -+ StringBuffer buf = new StringBuffer(); -+ int len = end-start; -+ for (int i = 0; i < len; i++) { -+ String s = cpMap[start+i].stringValue(); -+ buf.setLength(0); -+ for (int j = 0; j < s.length(); j++) { -+ char ch = s.charAt(j); -+ if (!(ch < ' ' || ch > '~' || ch == '\\')) { -+ buf.append(ch); -+ } else if (ch == '\n') { -+ buf.append("\\n"); -+ } else if (ch == '\t') { -+ buf.append("\\t"); -+ } else if (ch == '\r') { -+ buf.append("\\r"); -+ } else { -+ buf.append("\\x"+Integer.toHexString(ch)); -+ } -+ } -+ ps.println(buf); -+ } - } - - - // Utilities for reallocating: - protected static Object[] realloc(Object[] a, int len) { -- java.lang.Class elt = a.getClass().getComponentType(); -- Object[] na = (Object[]) java.lang.reflect.Array.newInstance(elt, len); -- System.arraycopy(a, 0, na, 0, Math.min(a.length, len)); -- return na; -+ java.lang.Class elt = a.getClass().getComponentType(); -+ Object[] na = (Object[]) java.lang.reflect.Array.newInstance(elt, len); -+ System.arraycopy(a, 0, na, 0, Math.min(a.length, len)); -+ return na; - } - protected static Object[] realloc(Object[] a) { -- return realloc(a, Math.max(10, a.length*2)); -+ return realloc(a, Math.max(10, a.length*2)); - } - static private int[] noInts = {}; - protected static int[] realloc(int[] a, int len) { -- if (len == 0) return noInts; -- if (a == null) return new int[len]; -- int[] na = new int[len]; -- System.arraycopy(a, 0, na, 0, Math.min(a.length, len)); -- return na; -+ if (len == 0) return noInts; -+ if (a == null) return new int[len]; -+ int[] na = new int[len]; -+ System.arraycopy(a, 0, na, 0, Math.min(a.length, len)); -+ return na; - } - protected static int[] realloc(int[] a) { -- return realloc(a, Math.max(10, a.length*2)); -+ return realloc(a, Math.max(10, a.length*2)); - } - static private byte[] noBytes = {}; - protected static byte[] realloc(byte[] a, int len) { -- if (len == 0) return noBytes; -- if (a == null) return new byte[len]; -- byte[] na = new byte[len]; -- System.arraycopy(a, 0, na, 0, Math.min(a.length, len)); -- return na; -+ if (len == 0) return noBytes; -+ if (a == null) return new byte[len]; -+ byte[] na = new byte[len]; -+ System.arraycopy(a, 0, na, 0, Math.min(a.length, len)); -+ return na; - } - protected static byte[] realloc(byte[] a) { -- return realloc(a, Math.max(10, a.length*2)); -+ return realloc(a, Math.max(10, a.length*2)); - } - } -+ -+ -diff --git a/src/share/classes/com/sun/java/util/jar/pack/ConstantPool.java b/src/share/classes/com/sun/java/util/jar/pack/ConstantPool.java ---- openjdk/jdk/src/share/classes/com/sun/java/util/jar/pack/ConstantPool.java -+++ openjdk/jdk/src/share/classes/com/sun/java/util/jar/pack/ConstantPool.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2001, 2003, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -22,7 +22,7 @@ - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -- -+ - package com.sun.java.util.jar.pack; - - import java.io.*; -@@ -37,7 +37,7 @@ class ConstantPool implements Constants - private ConstantPool() {} // do not instantiate - - static int verbose() { -- return Utils.currentPropMap().getInteger(Utils.DEBUG_VERBOSE); -+ return Utils.currentPropMap().getInteger(Utils.DEBUG_VERBOSE); - } - - // Uniquification tables for factory methods: -@@ -53,659 +53,659 @@ class ConstantPool implements Constants - * Also used to back up more complex constant pool entries, like Class. - */ - public static synchronized Utf8Entry getUtf8Entry(String value) { -- Utf8Entry e = (Utf8Entry) utf8Entries.get(value); -- if (e == null) { -- e = new Utf8Entry(value); -- utf8Entries.put(e.stringValue(), e); -- } -- return e; -+ Utf8Entry e = (Utf8Entry) utf8Entries.get(value); -+ if (e == null) { -+ e = new Utf8Entry(value); -+ utf8Entries.put(e.stringValue(), e); -+ } -+ return e; - } - /** Factory for Class constants. */ - public static synchronized ClassEntry getClassEntry(String name) { -- ClassEntry e = (ClassEntry) classEntries.get(name); -- if (e == null) { -- e = (ClassEntry) new ClassEntry(getUtf8Entry(name)); -- assert(name.equals(e.stringValue())); -- classEntries.put(e.stringValue(), e); -- } -- return e; -+ ClassEntry e = (ClassEntry) classEntries.get(name); -+ if (e == null) { -+ e = (ClassEntry) new ClassEntry(getUtf8Entry(name)); -+ assert(name.equals(e.stringValue())); -+ classEntries.put(e.stringValue(), e); -+ } -+ return e; - } - /** Factory for literal constants (String, Integer, etc.). */ - public static synchronized LiteralEntry getLiteralEntry(Comparable value) { -- LiteralEntry e = (LiteralEntry) literalEntries.get(value); -- if (e == null) { -- if (value instanceof String) -- e = new StringEntry(getUtf8Entry((String)value)); -- else -- e = new NumberEntry((Number)value); -- literalEntries.put(value, e); -- } -- return e; -+ LiteralEntry e = (LiteralEntry) literalEntries.get(value); -+ if (e == null) { -+ if (value instanceof String) -+ e = new StringEntry(getUtf8Entry((String)value)); -+ else -+ e = new NumberEntry((Number)value); -+ literalEntries.put(value, e); -+ } -+ return e; - } - /** Factory for literal constants (String, Integer, etc.). */ - public static synchronized StringEntry getStringEntry(String value) { -- return (StringEntry) getLiteralEntry(value); -+ return (StringEntry) getLiteralEntry(value); - } - - /** Factory for signature (type) constants. */ - public static synchronized SignatureEntry getSignatureEntry(String type) { -- SignatureEntry e = (SignatureEntry) signatureEntries.get(type); -- if (e == null) { -- e = new SignatureEntry(type); -- assert(e.stringValue().equals(type)); -- signatureEntries.put(type, e); -- } -- return e; -+ SignatureEntry e = (SignatureEntry) signatureEntries.get(type); -+ if (e == null) { -+ e = new SignatureEntry(type); -+ assert(e.stringValue().equals(type)); -+ signatureEntries.put(type, e); -+ } -+ return e; - } - // Convenience overloading. - public static SignatureEntry getSignatureEntry(Utf8Entry formRef, ClassEntry[] classRefs) { -- return getSignatureEntry(SignatureEntry.stringValueOf(formRef, classRefs)); -+ return getSignatureEntry(SignatureEntry.stringValueOf(formRef, classRefs)); - } - - /** Factory for descriptor (name-and-type) constants. */ - public static synchronized DescriptorEntry getDescriptorEntry(Utf8Entry nameRef, SignatureEntry typeRef) { -- String key = DescriptorEntry.stringValueOf(nameRef, typeRef); -- DescriptorEntry e = (DescriptorEntry) descriptorEntries.get(key); -- if (e == null) { -- e = new DescriptorEntry(nameRef, typeRef); -- assert(e.stringValue().equals(key)) -- : (e.stringValue()+" != "+(key)); -- descriptorEntries.put(key, e); -- } -- return e; -+ String key = DescriptorEntry.stringValueOf(nameRef, typeRef); -+ DescriptorEntry e = (DescriptorEntry) descriptorEntries.get(key); -+ if (e == null) { -+ e = new DescriptorEntry(nameRef, typeRef); -+ assert(e.stringValue().equals(key)) -+ : (e.stringValue()+" != "+(key)); -+ descriptorEntries.put(key, e); -+ } -+ return e; - } - // Convenience overloading. - public static DescriptorEntry getDescriptorEntry(Utf8Entry nameRef, Utf8Entry typeRef) { -- return getDescriptorEntry(nameRef, getSignatureEntry(typeRef.stringValue())); -+ return getDescriptorEntry(nameRef, getSignatureEntry(typeRef.stringValue())); - } - - /** Factory for member reference constants. */ - public static synchronized MemberEntry getMemberEntry(byte tag, ClassEntry classRef, DescriptorEntry descRef) { -- String key = MemberEntry.stringValueOf(tag, classRef, descRef); -- MemberEntry e = (MemberEntry) memberEntries.get(key); -- if (e == null) { -- e = new MemberEntry(tag, classRef, descRef); -- assert(e.stringValue().equals(key)) -- : (e.stringValue()+" != "+(key)); -- memberEntries.put(key, e); -- } -- return e; -+ String key = MemberEntry.stringValueOf(tag, classRef, descRef); -+ MemberEntry e = (MemberEntry) memberEntries.get(key); -+ if (e == null) { -+ e = new MemberEntry(tag, classRef, descRef); -+ assert(e.stringValue().equals(key)) -+ : (e.stringValue()+" != "+(key)); -+ memberEntries.put(key, e); -+ } -+ return e; - } - - - /** Entries in the constant pool. */ - public static abstract - class Entry implements Comparable { -- protected final byte tag; // a CONSTANT_foo code -- protected int valueHash; // cached hashCode -+ protected final byte tag; // a CONSTANT_foo code -+ protected int valueHash; // cached hashCode - -- protected Entry(byte tag) { -- this.tag = tag; -- } -+ protected Entry(byte tag) { -+ this.tag = tag; -+ } - -- public final byte getTag() { -- return tag; -- } -+ public final byte getTag() { -+ return tag; -+ } - -- public Entry getRef(int i) { -- return null; -- } -+ public Entry getRef(int i) { -+ return null; -+ } - -- public boolean sameTagAs(Object o) { -- return (o instanceof Entry) && ((Entry)o).tag == tag; -- } -- public boolean eq(Entry that) { // same reference -- assert(that != null); -- return this == that || this.equals(that); -- } -+ public boolean sameTagAs(Object o) { -+ return (o instanceof Entry) && ((Entry)o).tag == tag; -+ } -+ public boolean eq(Entry that) { // same reference -+ assert(that != null); -+ return this == that || this.equals(that); -+ } - -- // Equality of Entries is value-based. -- public abstract boolean equals(Object o); -- public final int hashCode() { -- if (valueHash == 0) { -- valueHash = computeValueHash(); -- if (valueHash == 0) valueHash = 1; -- } -- return valueHash; -- } -- protected abstract int computeValueHash(); -+ // Equality of Entries is value-based. -+ public abstract boolean equals(Object o); -+ public final int hashCode() { -+ if (valueHash == 0) { -+ valueHash = computeValueHash(); -+ if (valueHash == 0) valueHash = 1; -+ } -+ return valueHash; -+ } -+ protected abstract int computeValueHash(); - -- public abstract int compareTo(Object o); -+ public abstract int compareTo(Object o); - -- protected int superCompareTo(Object o) { -- Entry that = (Entry) o; -+ protected int superCompareTo(Object o) { -+ Entry that = (Entry) o; - -- if (this.tag != that.tag) { -- return TAG_ORDER[this.tag] - TAG_ORDER[that.tag]; -- } -+ if (this.tag != that.tag) { -+ return TAG_ORDER[this.tag] - TAG_ORDER[that.tag]; -+ } - -- return 0; // subclasses must refine this -- } -+ return 0; // subclasses must refine this -+ } - -- public final boolean isDoubleWord() { -- return tag == CONSTANT_Double || tag == CONSTANT_Long; -- } -+ public final boolean isDoubleWord() { -+ return tag == CONSTANT_Double || tag == CONSTANT_Long; -+ } - -- public final boolean tagMatches(int tag) { -- return (this.tag == tag); -- } -+ public final boolean tagMatches(int tag) { -+ return (this.tag == tag); -+ } - -- public String toString() { -- String valuePrint = stringValue(); -- if (verbose() > 4) { -- if (valueHash != 0) -- valuePrint += " hash="+valueHash; -- valuePrint += " id="+System.identityHashCode(this); -- } -- return tagName(tag)+"="+valuePrint; -- } -- public abstract String stringValue(); -+ public String toString() { -+ String valuePrint = stringValue(); -+ if (verbose() > 4) { -+ if (valueHash != 0) -+ valuePrint += " hash="+valueHash; -+ valuePrint += " id="+System.identityHashCode(this); -+ } -+ return tagName(tag)+"="+valuePrint; -+ } -+ public abstract String stringValue(); - } - - public static - class Utf8Entry extends Entry { -- final String value; -+ final String value; - -- Utf8Entry(String value) { -- super(CONSTANT_Utf8); -- this.value = value.intern(); -- hashCode(); // force computation of valueHash -- } -- protected int computeValueHash() { -- return value.hashCode(); -- } -- public boolean equals(Object o) { -- if (!sameTagAs(o)) return false; -- // Use reference equality of interned strings: -- return ((Utf8Entry)o).value == value; -- } -- public int compareTo(Object o) { -- int x = superCompareTo(o); -- if (x == 0) { -- x = value.compareTo(((Utf8Entry)o).value); -- } -- return x; -- } -- public String stringValue() { -- return value; -- } -+ Utf8Entry(String value) { -+ super(CONSTANT_Utf8); -+ this.value = value.intern(); -+ hashCode(); // force computation of valueHash -+ } -+ protected int computeValueHash() { -+ return value.hashCode(); -+ } -+ public boolean equals(Object o) { -+ if (!sameTagAs(o)) return false; -+ // Use reference equality of interned strings: -+ return ((Utf8Entry)o).value == value; -+ } -+ public int compareTo(Object o) { -+ int x = superCompareTo(o); -+ if (x == 0) { -+ x = value.compareTo(((Utf8Entry)o).value); -+ } -+ return x; -+ } -+ public String stringValue() { -+ return value; -+ } - } - - static boolean isMemberTag(byte tag) { -- switch (tag) { -- case CONSTANT_Fieldref: -- case CONSTANT_Methodref: -- case CONSTANT_InterfaceMethodref: -- return true; -- } -- return false; -+ switch (tag) { -+ case CONSTANT_Fieldref: -+ case CONSTANT_Methodref: -+ case CONSTANT_InterfaceMethodref: -+ return true; -+ } -+ return false; - } - - static byte numberTagOf(Number value) { -- if (value instanceof Integer) return CONSTANT_Integer; -- if (value instanceof Float) return CONSTANT_Float; -- if (value instanceof Long) return CONSTANT_Long; -- if (value instanceof Double) return CONSTANT_Double; -- throw new RuntimeException("bad literal value "+value); -+ if (value instanceof Integer) return CONSTANT_Integer; -+ if (value instanceof Float) return CONSTANT_Float; -+ if (value instanceof Long) return CONSTANT_Long; -+ if (value instanceof Double) return CONSTANT_Double; -+ throw new RuntimeException("bad literal value "+value); - } - - public static abstract - class LiteralEntry extends Entry { -- protected LiteralEntry(byte tag) { -- super(tag); -- } -+ protected LiteralEntry(byte tag) { -+ super(tag); -+ } - -- public abstract Comparable literalValue(); -+ public abstract Comparable literalValue(); - } - - public static - class NumberEntry extends LiteralEntry { -- final Number value; -- NumberEntry(Number value) { -- super(numberTagOf(value)); -- this.value = value; -- hashCode(); // force computation of valueHash -- } -- protected int computeValueHash() { -- return value.hashCode(); -- } -+ final Number value; -+ NumberEntry(Number value) { -+ super(numberTagOf(value)); -+ this.value = value; -+ hashCode(); // force computation of valueHash -+ } -+ protected int computeValueHash() { -+ return value.hashCode(); -+ } - -- public boolean equals(Object o) { -- if (!sameTagAs(o)) return false; -- return (((NumberEntry)o).value).equals(value); -- } -- public int compareTo(Object o) { -- int x = superCompareTo(o); -- if (x == 0) { -- x = ((Comparable)value).compareTo(((NumberEntry)o).value); -- } -- return x; -- } -- public Number numberValue() { -- return value; -- } -- public Comparable literalValue() { -- return (Comparable) value; -- } -- public String stringValue() { -- return value.toString(); -- } -+ public boolean equals(Object o) { -+ if (!sameTagAs(o)) return false; -+ return (((NumberEntry)o).value).equals(value); -+ } -+ public int compareTo(Object o) { -+ int x = superCompareTo(o); -+ if (x == 0) { -+ x = ((Comparable)value).compareTo(((NumberEntry)o).value); -+ } -+ return x; -+ } -+ public Number numberValue() { -+ return value; -+ } -+ public Comparable literalValue() { -+ return (Comparable) value; -+ } -+ public String stringValue() { -+ return value.toString(); -+ } - } - - public static - class StringEntry extends LiteralEntry { -- final Utf8Entry ref; -- public Entry getRef(int i) { return i == 0 ? ref : null; } -+ final Utf8Entry ref; -+ public Entry getRef(int i) { return i == 0 ? ref : null; } - -- StringEntry(Entry ref) { -- super(CONSTANT_String); -- this.ref = (Utf8Entry) ref; -- hashCode(); // force computation of valueHash -- } -- protected int computeValueHash() { -- return ref.hashCode() + tag; -- } -- public boolean equals(Object o) { -- if (!sameTagAs(o)) return false; -- return ((StringEntry)o).ref.eq(ref); -- } -- public int compareTo(Object o) { -- int x = superCompareTo(o); -- if (x == 0) { -- x = ref.compareTo(((StringEntry)o).ref); -- } -- return x; -- } -- public Comparable literalValue() { -- return ref.stringValue(); -- } -- public String stringValue() { -- return ref.stringValue(); -- } -+ StringEntry(Entry ref) { -+ super(CONSTANT_String); -+ this.ref = (Utf8Entry) ref; -+ hashCode(); // force computation of valueHash -+ } -+ protected int computeValueHash() { -+ return ref.hashCode() + tag; -+ } -+ public boolean equals(Object o) { -+ if (!sameTagAs(o)) return false; -+ return ((StringEntry)o).ref.eq(ref); -+ } -+ public int compareTo(Object o) { -+ int x = superCompareTo(o); -+ if (x == 0) { -+ x = ref.compareTo(((StringEntry)o).ref); -+ } -+ return x; -+ } -+ public Comparable literalValue() { -+ return ref.stringValue(); -+ } -+ public String stringValue() { -+ return ref.stringValue(); -+ } - } - - public static - class ClassEntry extends Entry { -- final Utf8Entry ref; -- public Entry getRef(int i) { return i == 0 ? ref : null; } -+ final Utf8Entry ref; -+ public Entry getRef(int i) { return i == 0 ? ref : null; } - -- protected int computeValueHash() { -- return ref.hashCode() + tag; -- } -- ClassEntry(Entry ref) { -- super(CONSTANT_Class); -- this.ref = (Utf8Entry) ref; -- hashCode(); // force computation of valueHash -- } -- public boolean equals(Object o) { -- if (!sameTagAs(o)) return false; -- return ((ClassEntry)o).ref.eq(ref); -- } -- public int compareTo(Object o) { -- int x = superCompareTo(o); -- if (x == 0) { -- x = ref.compareTo(((ClassEntry)o).ref); -- } -- return x; -- } -- public String stringValue() { -- return ref.stringValue(); -- } -+ protected int computeValueHash() { -+ return ref.hashCode() + tag; -+ } -+ ClassEntry(Entry ref) { -+ super(CONSTANT_Class); -+ this.ref = (Utf8Entry) ref; -+ hashCode(); // force computation of valueHash -+ } -+ public boolean equals(Object o) { -+ if (!sameTagAs(o)) return false; -+ return ((ClassEntry)o).ref.eq(ref); -+ } -+ public int compareTo(Object o) { -+ int x = superCompareTo(o); -+ if (x == 0) { -+ x = ref.compareTo(((ClassEntry)o).ref); -+ } -+ return x; -+ } -+ public String stringValue() { -+ return ref.stringValue(); -+ } - } - - public static - class DescriptorEntry extends Entry { -- final Utf8Entry nameRef; -- final SignatureEntry typeRef; -- public Entry getRef(int i) { -- if (i == 0) return nameRef; -- if (i == 1) return typeRef; -- return null; -- } -- DescriptorEntry(Entry nameRef, Entry typeRef) { -- super(CONSTANT_NameandType); -- if (typeRef instanceof Utf8Entry) { -- typeRef = getSignatureEntry(typeRef.stringValue()); -- } -- this.nameRef = (Utf8Entry) nameRef; -- this.typeRef = (SignatureEntry) typeRef; -- hashCode(); // force computation of valueHash -- } -- protected int computeValueHash() { -- int hc2 = typeRef.hashCode(); -- return (nameRef.hashCode() + (hc2 << 8)) ^ hc2; -- } -- public boolean equals(Object o) { -- if (!sameTagAs(o)) return false; -- DescriptorEntry that = (DescriptorEntry)o; -- return this.nameRef.eq(that.nameRef) -- && this.typeRef.eq(that.typeRef); -- } -- public int compareTo(Object o) { -- int x = superCompareTo(o); -- if (x == 0) { -- DescriptorEntry that = (DescriptorEntry)o; -- // Primary key is typeRef, not nameRef. -- x = this.typeRef.compareTo(that.typeRef); -- if (x == 0) -- x = this.nameRef.compareTo(that.nameRef); -- } -- return x; -- } -- public String stringValue() { -- return stringValueOf(nameRef, typeRef); -- } -- static -- String stringValueOf(Entry nameRef, Entry typeRef) { -- return typeRef.stringValue()+","+nameRef.stringValue(); -- } -+ final Utf8Entry nameRef; -+ final SignatureEntry typeRef; -+ public Entry getRef(int i) { -+ if (i == 0) return nameRef; -+ if (i == 1) return typeRef; -+ return null; -+ } -+ DescriptorEntry(Entry nameRef, Entry typeRef) { -+ super(CONSTANT_NameandType); -+ if (typeRef instanceof Utf8Entry) { -+ typeRef = getSignatureEntry(typeRef.stringValue()); -+ } -+ this.nameRef = (Utf8Entry) nameRef; -+ this.typeRef = (SignatureEntry) typeRef; -+ hashCode(); // force computation of valueHash -+ } -+ protected int computeValueHash() { -+ int hc2 = typeRef.hashCode(); -+ return (nameRef.hashCode() + (hc2 << 8)) ^ hc2; -+ } -+ public boolean equals(Object o) { -+ if (!sameTagAs(o)) return false; -+ DescriptorEntry that = (DescriptorEntry)o; -+ return this.nameRef.eq(that.nameRef) -+ && this.typeRef.eq(that.typeRef); -+ } -+ public int compareTo(Object o) { -+ int x = superCompareTo(o); -+ if (x == 0) { -+ DescriptorEntry that = (DescriptorEntry)o; -+ // Primary key is typeRef, not nameRef. -+ x = this.typeRef.compareTo(that.typeRef); -+ if (x == 0) -+ x = this.nameRef.compareTo(that.nameRef); -+ } -+ return x; -+ } -+ public String stringValue() { -+ return stringValueOf(nameRef, typeRef); -+ } -+ static -+ String stringValueOf(Entry nameRef, Entry typeRef) { -+ return typeRef.stringValue()+","+nameRef.stringValue(); -+ } - -- public String prettyString() { -- return nameRef.stringValue()+typeRef.prettyString(); -- } -+ public String prettyString() { -+ return nameRef.stringValue()+typeRef.prettyString(); -+ } - -- public boolean isMethod() { -- return typeRef.isMethod(); -- } -+ public boolean isMethod() { -+ return typeRef.isMethod(); -+ } - -- public byte getLiteralTag() { -- return typeRef.getLiteralTag(); -- } -+ public byte getLiteralTag() { -+ return typeRef.getLiteralTag(); -+ } - } - - public static - class MemberEntry extends Entry { -- final ClassEntry classRef; -- final DescriptorEntry descRef; -- public Entry getRef(int i) { -- if (i == 0) return classRef; -- if (i == 1) return descRef; -- return null; -- } -- protected int computeValueHash() { -- int hc2 = descRef.hashCode(); -- return (classRef.hashCode() + (hc2 << 8)) ^ hc2; -- } -+ final ClassEntry classRef; -+ final DescriptorEntry descRef; -+ public Entry getRef(int i) { -+ if (i == 0) return classRef; -+ if (i == 1) return descRef; -+ return null; -+ } -+ protected int computeValueHash() { -+ int hc2 = descRef.hashCode(); -+ return (classRef.hashCode() + (hc2 << 8)) ^ hc2; -+ } - -- MemberEntry(byte tag, ClassEntry classRef, DescriptorEntry descRef) { -- super(tag); -- assert(isMemberTag(tag)); -- this.classRef = classRef; -- this.descRef = descRef; -- hashCode(); // force computation of valueHash -- } -- public boolean equals(Object o) { -- if (!sameTagAs(o)) return false; -- MemberEntry that = (MemberEntry)o; -- return this.classRef.eq(that.classRef) -- && this.descRef.eq(that.descRef); -- } -- public int compareTo(Object o) { -- int x = superCompareTo(o); -- if (x == 0) { -- MemberEntry that = (MemberEntry)o; -- // Primary key is classRef. -- x = this.classRef.compareTo(that.classRef); -- if (x == 0) -- x = this.descRef.compareTo(that.descRef); -- } -- return x; -- } -- public String stringValue() { -- return stringValueOf(tag, classRef, descRef); -- } -- static -- String stringValueOf(byte tag, ClassEntry classRef, DescriptorEntry descRef) { -- assert(isMemberTag(tag)); -- String pfx; -- switch (tag) { -- case CONSTANT_Fieldref: pfx = "Field:"; break; -- case CONSTANT_Methodref: pfx = "Method:"; break; -- case CONSTANT_InterfaceMethodref: pfx = "IMethod:"; break; -- default: pfx = tag+"???"; break; -- } -- return pfx+classRef.stringValue()+","+descRef.stringValue(); -- } -+ MemberEntry(byte tag, ClassEntry classRef, DescriptorEntry descRef) { -+ super(tag); -+ assert(isMemberTag(tag)); -+ this.classRef = classRef; -+ this.descRef = descRef; -+ hashCode(); // force computation of valueHash -+ } -+ public boolean equals(Object o) { -+ if (!sameTagAs(o)) return false; -+ MemberEntry that = (MemberEntry)o; -+ return this.classRef.eq(that.classRef) -+ && this.descRef.eq(that.descRef); -+ } -+ public int compareTo(Object o) { -+ int x = superCompareTo(o); -+ if (x == 0) { -+ MemberEntry that = (MemberEntry)o; -+ // Primary key is classRef. -+ x = this.classRef.compareTo(that.classRef); -+ if (x == 0) -+ x = this.descRef.compareTo(that.descRef); -+ } -+ return x; -+ } -+ public String stringValue() { -+ return stringValueOf(tag, classRef, descRef); -+ } -+ static -+ String stringValueOf(byte tag, ClassEntry classRef, DescriptorEntry descRef) { -+ assert(isMemberTag(tag)); -+ String pfx; -+ switch (tag) { -+ case CONSTANT_Fieldref: pfx = "Field:"; break; -+ case CONSTANT_Methodref: pfx = "Method:"; break; -+ case CONSTANT_InterfaceMethodref: pfx = "IMethod:"; break; -+ default: pfx = tag+"???"; break; -+ } -+ return pfx+classRef.stringValue()+","+descRef.stringValue(); -+ } - -- public boolean isMethod() { -- return descRef.isMethod(); -- } -+ public boolean isMethod() { -+ return descRef.isMethod(); -+ } - } - - public static - class SignatureEntry extends Entry { -- final Utf8Entry formRef; -- final ClassEntry[] classRefs; -- String value; -- Utf8Entry asUtf8Entry; -- public Entry getRef(int i) { -- if (i == 0) return formRef; -- return i-1 < classRefs.length ? classRefs[i-1] : null; -- } -- SignatureEntry(String value) { -- super(CONSTANT_Signature); -- value = value.intern(); // always do this -- this.value = value; -- String[] parts = structureSignature(value); -- formRef = getUtf8Entry(parts[0]); -- classRefs = new ClassEntry[parts.length-1]; -- for (int i = 1; i < parts.length; i++) -- classRefs[i-1] = getClassEntry(parts[i]); -- hashCode(); // force computation of valueHash -- } -- protected int computeValueHash() { -- stringValue(); // force computation of value -- return value.hashCode() + tag; -- } -+ final Utf8Entry formRef; -+ final ClassEntry[] classRefs; -+ String value; -+ Utf8Entry asUtf8Entry; -+ public Entry getRef(int i) { -+ if (i == 0) return formRef; -+ return i-1 < classRefs.length ? classRefs[i-1] : null; -+ } -+ SignatureEntry(String value) { -+ super(CONSTANT_Signature); -+ value = value.intern(); // always do this -+ this.value = value; -+ String[] parts = structureSignature(value); -+ formRef = getUtf8Entry(parts[0]); -+ classRefs = new ClassEntry[parts.length-1]; -+ for (int i = 1; i < parts.length; i++) -+ classRefs[i-1] = getClassEntry(parts[i]); -+ hashCode(); // force computation of valueHash -+ } -+ protected int computeValueHash() { -+ stringValue(); // force computation of value -+ return value.hashCode() + tag; -+ } - -- public Utf8Entry asUtf8Entry() { -- if (asUtf8Entry == null) { -- asUtf8Entry = getUtf8Entry(stringValue()); -- } -- return asUtf8Entry; -- } -+ public Utf8Entry asUtf8Entry() { -+ if (asUtf8Entry == null) { -+ asUtf8Entry = getUtf8Entry(stringValue()); -+ } -+ return asUtf8Entry; -+ } - -- public boolean equals(Object o) { -- if (!sameTagAs(o)) return false; -- return ((SignatureEntry)o).value == value; -- } -- public int compareTo(Object o) { -- int x = superCompareTo(o); -- if (x == 0) { -- SignatureEntry that = (SignatureEntry)o; -- x = compareSignatures(this.value, that.value); -- } -- return x; -- } -- public String stringValue() { -- if (value == null) { -- value = stringValueOf(formRef, classRefs); -- } -- return value; -- } -- static -- String stringValueOf(Utf8Entry formRef, ClassEntry[] classRefs) { -- String[] parts = new String[1+classRefs.length]; -- parts[0] = formRef.stringValue(); -- for (int i = 1; i < parts.length; i++) -- parts[i] = classRefs[i-1].stringValue(); -- return flattenSignature(parts).intern(); -- } -+ public boolean equals(Object o) { -+ if (!sameTagAs(o)) return false; -+ return ((SignatureEntry)o).value == value; -+ } -+ public int compareTo(Object o) { -+ int x = superCompareTo(o); -+ if (x == 0) { -+ SignatureEntry that = (SignatureEntry)o; -+ x = compareSignatures(this.value, that.value); -+ } -+ return x; -+ } -+ public String stringValue() { -+ if (value == null) { -+ value = stringValueOf(formRef, classRefs); -+ } -+ return value; -+ } -+ static -+ String stringValueOf(Utf8Entry formRef, ClassEntry[] classRefs) { -+ String[] parts = new String[1+classRefs.length]; -+ parts[0] = formRef.stringValue(); -+ for (int i = 1; i < parts.length; i++) -+ parts[i] = classRefs[i-1].stringValue(); -+ return flattenSignature(parts).intern(); -+ } - -- public int computeSize(boolean countDoublesTwice) { -- String form = formRef.stringValue(); -- int min = 0; -- int max = 1; -- if (isMethod()) { -- min = 1; -- max = form.indexOf(')'); -- } -- int size = 0; -- for (int i = min; i < max; i++) { -- switch (form.charAt(i)) { -- case 'D': -- case 'J': -- if (countDoublesTwice) size++; -- break; -- case '[': -- // Skip rest of array info. -- while (form.charAt(i) == '[') ++i; -- break; -- case ';': -- continue; -- default: -- assert(0 <= JAVA_SIGNATURE_CHARS.indexOf(form.charAt(i))); -- break; -- } -- size++; -- } -- return size; -- } -- public boolean isMethod() { -- return formRef.stringValue().charAt(0) == '('; -- } -- public byte getLiteralTag() { -- switch (formRef.stringValue().charAt(0)) { -- case 'L': return CONSTANT_String; -- case 'I': return CONSTANT_Integer; -- case 'J': return CONSTANT_Long; -- case 'F': return CONSTANT_Float; -- case 'D': return CONSTANT_Double; -- case 'B': case 'S': case 'C': case 'Z': -- return CONSTANT_Integer; -- } -- assert(false); -- return CONSTANT_None; -- } -- public String prettyString() { -- String s; -- if (isMethod()) { -- s = formRef.stringValue(); -- s = s.substring(0, 1+s.indexOf(')')); -- } else { -- s = "/" + formRef.stringValue(); -- } -- int i; -- while ((i = s.indexOf(';')) >= 0) -- s = s.substring(0,i) + s.substring(i+1); -- return s; -- } -+ public int computeSize(boolean countDoublesTwice) { -+ String form = formRef.stringValue(); -+ int min = 0; -+ int max = 1; -+ if (isMethod()) { -+ min = 1; -+ max = form.indexOf(')'); -+ } -+ int size = 0; -+ for (int i = min; i < max; i++) { -+ switch (form.charAt(i)) { -+ case 'D': -+ case 'J': -+ if (countDoublesTwice) size++; -+ break; -+ case '[': -+ // Skip rest of array info. -+ while (form.charAt(i) == '[') ++i; -+ break; -+ case ';': -+ continue; -+ default: -+ assert(0 <= JAVA_SIGNATURE_CHARS.indexOf(form.charAt(i))); -+ break; -+ } -+ size++; -+ } -+ return size; -+ } -+ public boolean isMethod() { -+ return formRef.stringValue().charAt(0) == '('; -+ } -+ public byte getLiteralTag() { -+ switch (formRef.stringValue().charAt(0)) { -+ case 'L': return CONSTANT_String; -+ case 'I': return CONSTANT_Integer; -+ case 'J': return CONSTANT_Long; -+ case 'F': return CONSTANT_Float; -+ case 'D': return CONSTANT_Double; -+ case 'B': case 'S': case 'C': case 'Z': -+ return CONSTANT_Integer; -+ } -+ assert(false); -+ return CONSTANT_None; -+ } -+ public String prettyString() { -+ String s; -+ if (isMethod()) { -+ s = formRef.stringValue(); -+ s = s.substring(0, 1+s.indexOf(')')); -+ } else { -+ s = "/" + formRef.stringValue(); -+ } -+ int i; -+ while ((i = s.indexOf(';')) >= 0) -+ s = s.substring(0,i) + s.substring(i+1); -+ return s; -+ } - } - - static int compareSignatures(String s1, String s2) { -- return compareSignatures(s1, s2, null, null); -+ return compareSignatures(s1, s2, null, null); - } - static int compareSignatures(String s1, String s2, String[] p1, String[] p2) { -- final int S1_COMES_FIRST = -1; -- final int S2_COMES_FIRST = +1; -- char c1 = s1.charAt(0); -- char c2 = s2.charAt(0); -- // fields before methods (because there are fewer of them) -- if (c1 != '(' && c2 == '(') return S1_COMES_FIRST; -- if (c2 != '(' && c1 == '(') return S2_COMES_FIRST; -- if (p1 == null) p1 = structureSignature(s1); -- if (p2 == null) p2 = structureSignature(s2); -- /* -- // non-classes before classes (because there are fewer of them) -- if (p1.length == 1 && p2.length > 1) return S1_COMES_FIRST; -- if (p2.length == 1 && p1.length > 1) return S2_COMES_FIRST; -- // all else being equal, use the same comparison as for Utf8 strings -- return s1.compareTo(s2); -- */ -- if (p1.length != p2.length) return p1.length - p2.length; -- int length = p1.length; -- for (int i = length; --i >= 0; ) { -- int res = p1[i].compareTo(p2[i]); -- if (res != 0) return res; -- } -- assert(s1.equals(s2)); -- return 0; -+ final int S1_COMES_FIRST = -1; -+ final int S2_COMES_FIRST = +1; -+ char c1 = s1.charAt(0); -+ char c2 = s2.charAt(0); -+ // fields before methods (because there are fewer of them) -+ if (c1 != '(' && c2 == '(') return S1_COMES_FIRST; -+ if (c2 != '(' && c1 == '(') return S2_COMES_FIRST; -+ if (p1 == null) p1 = structureSignature(s1); -+ if (p2 == null) p2 = structureSignature(s2); -+ /* -+ // non-classes before classes (because there are fewer of them) -+ if (p1.length == 1 && p2.length > 1) return S1_COMES_FIRST; -+ if (p2.length == 1 && p1.length > 1) return S2_COMES_FIRST; -+ // all else being equal, use the same comparison as for Utf8 strings -+ return s1.compareTo(s2); -+ */ -+ if (p1.length != p2.length) return p1.length - p2.length; -+ int length = p1.length; -+ for (int i = length; --i >= 0; ) { -+ int res = p1[i].compareTo(p2[i]); -+ if (res != 0) return res; -+ } -+ assert(s1.equals(s2)); -+ return 0; - } - - static int countClassParts(Utf8Entry formRef) { -- int num = 0; -- String s = formRef.stringValue(); -- for (int i = 0; i < s.length(); i++) { -- if (s.charAt(i) == 'L') ++num; -- } -- return num; -+ int num = 0; -+ String s = formRef.stringValue(); -+ for (int i = 0; i < s.length(); i++) { -+ if (s.charAt(i) == 'L') ++num; -+ } -+ return num; - } - - static String flattenSignature(String[] parts) { -- String form = parts[0]; -- if (parts.length == 1) return form; -- int len = form.length(); -- for (int i = 1; i < parts.length; i++) { -- len += parts[i].length(); -- } -- char[] sig = new char[len]; -- int j = 0; -- int k = 1; -- for (int i = 0; i < form.length(); i++) { -- char ch = form.charAt(i); -- sig[j++] = ch; -- if (ch == 'L') { -- String cls = parts[k++]; -- cls.getChars(0, cls.length(), sig, j); -- j += cls.length(); -- //sig[j++] = ';'; -- } -- } -- assert(j == len); -- assert(k == parts.length); -- return new String(sig); -+ String form = parts[0]; -+ if (parts.length == 1) return form; -+ int len = form.length(); -+ for (int i = 1; i < parts.length; i++) { -+ len += parts[i].length(); -+ } -+ char[] sig = new char[len]; -+ int j = 0; -+ int k = 1; -+ for (int i = 0; i < form.length(); i++) { -+ char ch = form.charAt(i); -+ sig[j++] = ch; -+ if (ch == 'L') { -+ String cls = parts[k++]; -+ cls.getChars(0, cls.length(), sig, j); -+ j += cls.length(); -+ //sig[j++] = ';'; -+ } -+ } -+ assert(j == len); -+ assert(k == parts.length); -+ return new String(sig); - } - - static private int skipClassNameChars(String sig, int i) { -- int len = sig.length(); -- for (; i < len; i++) { -- char ch = sig.charAt(i); -- if (ch <= ' ') break; -- if (ch >= ';' && ch <= '@') break; -- } -- return i; -+ int len = sig.length(); -+ for (; i < len; i++) { -+ char ch = sig.charAt(i); -+ if (ch <= ' ') break; -+ if (ch >= ';' && ch <= '@') break; -+ } -+ return i; - } - - static String[] structureSignature(String sig) { -- sig = sig.intern(); -+ sig = sig.intern(); - -- int formLen = 0; -- int nparts = 1; -- for (int i = 0; i < sig.length(); i++) { -- char ch = sig.charAt(i); -- formLen++; -- if (ch == 'L') { -- nparts++; -- int i2 = skipClassNameChars(sig, i+1); -- i = i2-1; // keep the semicolon in the form -- int i3 = sig.indexOf('<', i+1); -- if (i3 > 0 && i3 < i2) -- i = i3-1; -- } -- } -- char[] form = new char[formLen]; -- if (nparts == 1) { -- String[] parts = { sig }; -- return parts; -- } -- String[] parts = new String[nparts]; -- int j = 0; -- int k = 1; -- for (int i = 0; i < sig.length(); i++) { -- char ch = sig.charAt(i); -- form[j++] = ch; -- if (ch == 'L') { -- int i2 = skipClassNameChars(sig, i+1); -- parts[k++] = sig.substring(i+1, i2); -- i = i2; -- --i; // keep the semicolon in the form -- } -- } -- assert(j == formLen); -- assert(k == parts.length); -- parts[0] = new String(form); -- //assert(flattenSignature(parts).equals(sig)); -- return parts; -+ int formLen = 0; -+ int nparts = 1; -+ for (int i = 0; i < sig.length(); i++) { -+ char ch = sig.charAt(i); -+ formLen++; -+ if (ch == 'L') { -+ nparts++; -+ int i2 = skipClassNameChars(sig, i+1); -+ i = i2-1; // keep the semicolon in the form -+ int i3 = sig.indexOf('<', i+1); -+ if (i3 > 0 && i3 < i2) -+ i = i3-1; -+ } -+ } -+ char[] form = new char[formLen]; -+ if (nparts == 1) { -+ String[] parts = { sig }; -+ return parts; -+ } -+ String[] parts = new String[nparts]; -+ int j = 0; -+ int k = 1; -+ for (int i = 0; i < sig.length(); i++) { -+ char ch = sig.charAt(i); -+ form[j++] = ch; -+ if (ch == 'L') { -+ int i2 = skipClassNameChars(sig, i+1); -+ parts[k++] = sig.substring(i+1, i2); -+ i = i2; -+ --i; // keep the semicolon in the form -+ } -+ } -+ assert(j == formLen); -+ assert(k == parts.length); -+ parts[0] = new String(form); -+ //assert(flattenSignature(parts).equals(sig)); -+ return parts; - } - - // Handy constants: -@@ -715,182 +715,182 @@ class ConstantPool implements Constants - /** An Index is a mapping between CP entries and small integers. */ - public static - class Index extends AbstractList { -- protected String debugName; -- protected Entry[] cpMap; -- protected boolean flattenSigs; -- protected Entry[] getMap() { -- return cpMap; -- } -- protected Index(String debugName) { -- this.debugName = debugName; -- } -- protected Index(String debugName, Entry[] cpMap) { -- this(debugName); -- setMap(cpMap); -- } -- protected void setMap(Entry[] cpMap) { -- clearIndex(); -- this.cpMap = cpMap; -- } -- protected Index(String debugName, Collection cpMapList) { -- this(debugName); -- setMap(cpMapList); -- } -- protected void setMap(Collection cpMapList) { -- cpMap = new Entry[cpMapList.size()]; -- cpMapList.toArray(cpMap); -- setMap(cpMap); -- } -- public int size() { -- return cpMap.length; -- } -- public Object get(int i) { -- return cpMap[i]; -- } -- public Entry getEntry(int i) { -- // same as get(), with covariant return type -- return cpMap[i]; -- } -+ protected String debugName; -+ protected Entry[] cpMap; -+ protected boolean flattenSigs; -+ protected Entry[] getMap() { -+ return cpMap; -+ } -+ protected Index(String debugName) { -+ this.debugName = debugName; -+ } -+ protected Index(String debugName, Entry[] cpMap) { -+ this(debugName); -+ setMap(cpMap); -+ } -+ protected void setMap(Entry[] cpMap) { -+ clearIndex(); -+ this.cpMap = cpMap; -+ } -+ protected Index(String debugName, Collection cpMapList) { -+ this(debugName); -+ setMap(cpMapList); -+ } -+ protected void setMap(Collection cpMapList) { -+ cpMap = new Entry[cpMapList.size()]; -+ cpMapList.toArray(cpMap); -+ setMap(cpMap); -+ } -+ public int size() { -+ return cpMap.length; -+ } -+ public Object get(int i) { -+ return cpMap[i]; -+ } -+ public Entry getEntry(int i) { -+ // same as get(), with covariant return type -+ return cpMap[i]; -+ } - -- // Find index of e in cpMap, or return -1 if none. -- // -- // As a special hack, if flattenSigs, signatures are -- // treated as equivalent entries of cpMap. This is wrong -- // fron a Collection point of view, because contains() -- // reports true for signatures, but the iterator() -- // never produces them! -- private int findIndexOf(Entry e) { -- if (indexKey == null) initializeIndex(); -- int probe = findIndexLocation(e); -- if (indexKey[probe] != e) { -- if (flattenSigs && e.tag == CONSTANT_Signature) { -- SignatureEntry se = (SignatureEntry) e; -- return findIndexOf(se.asUtf8Entry()); -- } -- return -1; -- } -- int index = indexValue[probe]; -- assert(e.equals(cpMap[index])); -- return index; -- } -- public boolean contains(Entry e) { -- return findIndexOf(e) >= 0; -- } -- // Find index of e in cpMap. Should not return -1. -- public int indexOf(Entry e) { -- int index = findIndexOf(e); -- if (index < 0 && verbose() > 0) { -- System.out.println("not found: "+e); -- System.out.println(" in: "+this.dumpString()); -- Thread.dumpStack(); -- } -- assert(index >= 0); -- return index; -- } -- public boolean contains(Object e) { -- return findIndexOf((Entry)e) >= 0; -- } -- public int indexOf(Object e) { -- return findIndexOf((Entry)e); -- } -- public int lastIndexOf(Object e) { -- return indexOf(e); -- } -+ // Find index of e in cpMap, or return -1 if none. -+ // -+ // As a special hack, if flattenSigs, signatures are -+ // treated as equivalent entries of cpMap. This is wrong -+ // fron a Collection point of view, because contains() -+ // reports true for signatures, but the iterator() -+ // never produces them! -+ private int findIndexOf(Entry e) { -+ if (indexKey == null) initializeIndex(); -+ int probe = findIndexLocation(e); -+ if (indexKey[probe] != e) { -+ if (flattenSigs && e.tag == CONSTANT_Signature) { -+ SignatureEntry se = (SignatureEntry) e; -+ return findIndexOf(se.asUtf8Entry()); -+ } -+ return -1; -+ } -+ int index = indexValue[probe]; -+ assert(e.equals(cpMap[index])); -+ return index; -+ } -+ public boolean contains(Entry e) { -+ return findIndexOf(e) >= 0; -+ } -+ // Find index of e in cpMap. Should not return -1. -+ public int indexOf(Entry e) { -+ int index = findIndexOf(e); -+ if (index < 0 && verbose() > 0) { -+ System.out.println("not found: "+e); -+ System.out.println(" in: "+this.dumpString()); -+ Thread.dumpStack(); -+ } -+ assert(index >= 0); -+ return index; -+ } -+ public boolean contains(Object e) { -+ return findIndexOf((Entry)e) >= 0; -+ } -+ public int indexOf(Object e) { -+ return findIndexOf((Entry)e); -+ } -+ public int lastIndexOf(Object e) { -+ return indexOf(e); -+ } - -- public boolean assertIsSorted() { -- for (int i = 1; i < cpMap.length; i++) { -- if (cpMap[i-1].compareTo(cpMap[i]) > 0) { -- System.out.println("Not sorted at "+(i-1)+"/"+i+": "+this.dumpString()); -- return false; -- } -- } -- return true; -- } -+ public boolean assertIsSorted() { -+ for (int i = 1; i < cpMap.length; i++) { -+ if (cpMap[i-1].compareTo(cpMap[i]) > 0) { -+ System.out.println("Not sorted at "+(i-1)+"/"+i+": "+this.dumpString()); -+ return false; -+ } -+ } -+ return true; -+ } - -- // internal hash table -- protected Entry[] indexKey; -- protected int[] indexValue; -- protected void clearIndex() { -- indexKey = null; -- indexValue = null; -- } -- private int findIndexLocation(Entry e) { -- int size = indexKey.length; -- int hash = e.hashCode(); -- int probe = hash & (size - 1); -- int stride = ((hash >>> 8) | 1) & (size - 1); -- for (;;) { -- Entry e1 = indexKey[probe]; -- if (e1 == e || e1 == null) -- return probe; -- probe += stride; -- if (probe >= size) probe -= size; -- } -- } -- private void initializeIndex() { -- if (verbose() > 2) -- System.out.println("initialize Index "+debugName+" ["+size()+"]"); -- int hsize0 = (int)((cpMap.length + 10) * 1.5); -- int hsize = 1; -- while (hsize < hsize0) hsize <<= 1; -- indexKey = new Entry[hsize]; -- indexValue = new int[hsize]; -- for (int i = 0; i < cpMap.length; i++) { -- Entry e = cpMap[i]; -- if (e == null) continue; -- int probe = findIndexLocation(e); -- assert(indexKey[probe] == null); // e has unique index -- indexKey[probe] = e; -- indexValue[probe] = i; -- } -- } -- public Object[] toArray(Object[] a) { -- int sz = size(); -- if (a.length < sz) return super.toArray(a); -- System.arraycopy(cpMap, 0, a, 0, sz); -- if (a.length > sz) a[sz] = null; -- return a; -- } -- public Object[] toArray() { -- return toArray(new Entry[size()]); -- } -- public Object clone() { -- return new Index(debugName, (Entry[]) cpMap.clone()); -- } -- public String toString() { -- return "Index "+debugName+" ["+size()+"]"; -- } -- public String dumpString() { -- String s = toString(); -- s += " {\n"; -- for (int i = 0; i < cpMap.length; i++) { -- s += " "+i+": "+cpMap[i]+"\n"; -- } -- s += "}"; -- return s; -- } -+ // internal hash table -+ protected Entry[] indexKey; -+ protected int[] indexValue; -+ protected void clearIndex() { -+ indexKey = null; -+ indexValue = null; -+ } -+ private int findIndexLocation(Entry e) { -+ int size = indexKey.length; -+ int hash = e.hashCode(); -+ int probe = hash & (size - 1); -+ int stride = ((hash >>> 8) | 1) & (size - 1); -+ for (;;) { -+ Entry e1 = indexKey[probe]; -+ if (e1 == e || e1 == null) -+ return probe; -+ probe += stride; -+ if (probe >= size) probe -= size; -+ } -+ } -+ private void initializeIndex() { -+ if (verbose() > 2) -+ System.out.println("initialize Index "+debugName+" ["+size()+"]"); -+ int hsize0 = (int)((cpMap.length + 10) * 1.5); -+ int hsize = 1; -+ while (hsize < hsize0) hsize <<= 1; -+ indexKey = new Entry[hsize]; -+ indexValue = new int[hsize]; -+ for (int i = 0; i < cpMap.length; i++) { -+ Entry e = cpMap[i]; -+ if (e == null) continue; -+ int probe = findIndexLocation(e); -+ assert(indexKey[probe] == null); // e has unique index -+ indexKey[probe] = e; -+ indexValue[probe] = i; -+ } -+ } -+ public Object[] toArray(Object[] a) { -+ int sz = size(); -+ if (a.length < sz) return super.toArray(a); -+ System.arraycopy(cpMap, 0, a, 0, sz); -+ if (a.length > sz) a[sz] = null; -+ return a; -+ } -+ public Object[] toArray() { -+ return toArray(new Entry[size()]); -+ } -+ public Object clone() { -+ return new Index(debugName, (Entry[]) cpMap.clone()); -+ } -+ public String toString() { -+ return "Index "+debugName+" ["+size()+"]"; -+ } -+ public String dumpString() { -+ String s = toString(); -+ s += " {\n"; -+ for (int i = 0; i < cpMap.length; i++) { -+ s += " "+i+": "+cpMap[i]+"\n"; -+ } -+ s += "}"; -+ return s; -+ } - } - - // Index methods. - - public static - Index makeIndex(String debugName, Entry[] cpMap) { -- return new Index(debugName, cpMap); -+ return new Index(debugName, cpMap); - } - - public static - Index makeIndex(String debugName, Collection cpMapList) { -- return new Index(debugName, cpMapList); -+ return new Index(debugName, cpMapList); - } - - /** Sort this index (destructively) into canonical order. */ - public static - void sort(Index ix) { -- // %%% Should move this into class Index. -- ix.clearIndex(); -- Arrays.sort(ix.cpMap); -- if (verbose() > 2) -- System.out.println("sorted "+ix.dumpString()); -+ // %%% Should move this into class Index. -+ ix.clearIndex(); -+ Arrays.sort(ix.cpMap); -+ if (verbose() > 2) -+ System.out.println("sorted "+ix.dumpString()); - } - - /** Return a set of indexes partitioning these entries. -@@ -900,210 +900,212 @@ class ConstantPool implements Constants - */ - public static - Index[] partition(Index ix, int[] keys) { -- // %%% Should move this into class Index. -- ArrayList parts = new ArrayList(); -- Entry[] cpMap = ix.cpMap; -- assert(keys.length == cpMap.length); -- for (int i = 0; i < keys.length; i++) { -- int key = keys[i]; -- if (key < 0) continue; -- while (key >= parts.size()) parts.add(null); -- ArrayList part = (ArrayList) parts.get(key); -- if (part == null) { -- parts.set(key, part = new ArrayList()); -- } -- part.add(cpMap[i]); -- } -- Index[] indexes = new Index[parts.size()]; -- for (int key = 0; key < indexes.length; key++) { -- ArrayList part = (ArrayList) parts.get(key); -- if (part == null) continue; -- indexes[key] = new Index(ix.debugName+"/part#"+key, part); -- assert(indexes[key].indexOf(part.get(0)) == 0); -- } -- return indexes; -+ // %%% Should move this into class Index. -+ ArrayList parts = new ArrayList(); -+ Entry[] cpMap = ix.cpMap; -+ assert(keys.length == cpMap.length); -+ for (int i = 0; i < keys.length; i++) { -+ int key = keys[i]; -+ if (key < 0) continue; -+ while (key >= parts.size()) parts.add(null); -+ ArrayList part = (ArrayList) parts.get(key); -+ if (part == null) { -+ parts.set(key, part = new ArrayList()); -+ } -+ part.add(cpMap[i]); -+ } -+ Index[] indexes = new Index[parts.size()]; -+ for (int key = 0; key < indexes.length; key++) { -+ ArrayList part = (ArrayList) parts.get(key); -+ if (part == null) continue; -+ indexes[key] = new Index(ix.debugName+"/part#"+key, part); -+ assert(indexes[key].indexOf(part.get(0)) == 0); -+ } -+ return indexes; - } - public static - Index[] partitionByTag(Index ix) { -- // Partition by tag. -- Entry[] cpMap = ix.cpMap; -- int[] keys = new int[cpMap.length]; -- for (int i = 0; i < keys.length; i++) { -- Entry e = cpMap[i]; -- keys[i] = (e == null)? -1: e.tag; -- } -- Index[] byTag = partition(ix, keys); -- for (int tag = 0; tag < byTag.length; tag++) { -- if (byTag[tag] == null) continue; -- byTag[tag].debugName = tagName(tag); -- } -- if (byTag.length < CONSTANT_Limit) { -- Index[] longer = new Index[CONSTANT_Limit]; -- System.arraycopy(byTag, 0, longer, 0, byTag.length); -- byTag = longer; -- } -- return byTag; -+ // Partition by tag. -+ Entry[] cpMap = ix.cpMap; -+ int[] keys = new int[cpMap.length]; -+ for (int i = 0; i < keys.length; i++) { -+ Entry e = cpMap[i]; -+ keys[i] = (e == null)? -1: e.tag; -+ } -+ Index[] byTag = partition(ix, keys); -+ for (int tag = 0; tag < byTag.length; tag++) { -+ if (byTag[tag] == null) continue; -+ byTag[tag].debugName = tagName(tag); -+ } -+ if (byTag.length < CONSTANT_Limit) { -+ Index[] longer = new Index[CONSTANT_Limit]; -+ System.arraycopy(byTag, 0, longer, 0, byTag.length); -+ byTag = longer; -+ } -+ return byTag; - } - - /** Coherent group of constant pool indexes. */ - public static - class IndexGroup { -- private Index indexUntyped; -- private Index[] indexByTag = new Index[CONSTANT_Limit]; -- private int[] untypedFirstIndexByTag; -- private int totalSize; -- private Index[][] indexByTagAndClass; -+ private Index indexUntyped; -+ private Index[] indexByTag = new Index[CONSTANT_Limit]; -+ private int[] untypedFirstIndexByTag; -+ private int totalSize; -+ private Index[][] indexByTagAndClass; - -- /** Index of all CP entries of all types, in definition order. */ -- public Index getUntypedIndex() { -- if (indexUntyped == null) { -- untypedIndexOf(null); // warm up untypedFirstIndexByTag -- Entry[] cpMap = new Entry[totalSize]; -- for (int tag = 0; tag < indexByTag.length; tag++) { -- Index ix = indexByTag[tag]; -- if (ix == null) continue; -- int ixLen = ix.cpMap.length; -- if (ixLen == 0) continue; -- int fillp = untypedFirstIndexByTag[tag]; -- assert(cpMap[fillp] == null); -- assert(cpMap[fillp+ixLen-1] == null); -- System.arraycopy(ix.cpMap, 0, cpMap, fillp, ixLen); -- } -- indexUntyped = new Index("untyped", cpMap); -- } -- return indexUntyped; -- } -+ /** Index of all CP entries of all types, in definition order. */ -+ public Index getUntypedIndex() { -+ if (indexUntyped == null) { -+ untypedIndexOf(null); // warm up untypedFirstIndexByTag -+ Entry[] cpMap = new Entry[totalSize]; -+ for (int tag = 0; tag < indexByTag.length; tag++) { -+ Index ix = indexByTag[tag]; -+ if (ix == null) continue; -+ int ixLen = ix.cpMap.length; -+ if (ixLen == 0) continue; -+ int fillp = untypedFirstIndexByTag[tag]; -+ assert(cpMap[fillp] == null); -+ assert(cpMap[fillp+ixLen-1] == null); -+ System.arraycopy(ix.cpMap, 0, cpMap, fillp, ixLen); -+ } -+ indexUntyped = new Index("untyped", cpMap); -+ } -+ return indexUntyped; -+ } - -- public int untypedIndexOf(Entry e) { -- if (untypedFirstIndexByTag == null) { -- untypedFirstIndexByTag = new int[CONSTANT_Limit]; -- int fillp = 0; -- for (int i = 0; i < TAGS_IN_ORDER.length; i++) { -- byte tag = TAGS_IN_ORDER[i]; -- Index ix = indexByTag[tag]; -- if (ix == null) continue; -- int ixLen = ix.cpMap.length; -- untypedFirstIndexByTag[tag] = fillp; -- fillp += ixLen; -- } -- totalSize = fillp; -- } -- if (e == null) return -1; -- int tag = e.tag; -- Index ix = indexByTag[tag]; -- if (ix == null) return -1; -- int idx = ix.findIndexOf(e); -- if (idx >= 0) -- idx += untypedFirstIndexByTag[tag]; -- return idx; -- } -+ public int untypedIndexOf(Entry e) { -+ if (untypedFirstIndexByTag == null) { -+ untypedFirstIndexByTag = new int[CONSTANT_Limit]; -+ int fillp = 0; -+ for (int i = 0; i < TAGS_IN_ORDER.length; i++) { -+ byte tag = TAGS_IN_ORDER[i]; -+ Index ix = indexByTag[tag]; -+ if (ix == null) continue; -+ int ixLen = ix.cpMap.length; -+ untypedFirstIndexByTag[tag] = fillp; -+ fillp += ixLen; -+ } -+ totalSize = fillp; -+ } -+ if (e == null) return -1; -+ int tag = e.tag; -+ Index ix = indexByTag[tag]; -+ if (ix == null) return -1; -+ int idx = ix.findIndexOf(e); -+ if (idx >= 0) -+ idx += untypedFirstIndexByTag[tag]; -+ return idx; -+ } - -- public void initIndexByTag(byte tag, Index ix) { -- assert(indexByTag[tag] == null); // do not init twice -- Entry[] cpMap = ix.cpMap; -- for (int i = 0; i < cpMap.length; i++) { -- // It must be a homogeneous Entry set. -- assert(cpMap[i].tag == tag); -- } -- if (tag == CONSTANT_Utf8) { -- // Special case: First Utf8 must always be empty string. -- assert(cpMap.length == 0 || cpMap[0].stringValue().equals("")); -- } -- indexByTag[tag] = ix; -- // decache indexes derived from this one: -- untypedFirstIndexByTag = null; -- indexUntyped = null; -- if (indexByTagAndClass != null) -- indexByTagAndClass[tag] = null; -- } -+ public void initIndexByTag(byte tag, Index ix) { -+ assert(indexByTag[tag] == null); // do not init twice -+ Entry[] cpMap = ix.cpMap; -+ for (int i = 0; i < cpMap.length; i++) { -+ // It must be a homogeneous Entry set. -+ assert(cpMap[i].tag == tag); -+ } -+ if (tag == CONSTANT_Utf8) { -+ // Special case: First Utf8 must always be empty string. -+ assert(cpMap.length == 0 || cpMap[0].stringValue().equals("")); -+ } -+ indexByTag[tag] = ix; -+ // decache indexes derived from this one: -+ untypedFirstIndexByTag = null; -+ indexUntyped = null; -+ if (indexByTagAndClass != null) -+ indexByTagAndClass[tag] = null; -+ } - -- /** Index of all CP entries of a given tag. */ -- public Index getIndexByTag(byte tag) { -- if (tag == CONSTANT_All) { -- return getUntypedIndex(); -- } -- Index ix = indexByTag[tag]; -- if (ix == null) { -- // Make an empty one by default. -- ix = new Index(tagName(tag), new Entry[0]); -- indexByTag[tag] = ix; -- } -- return ix; -- } -+ /** Index of all CP entries of a given tag. */ -+ public Index getIndexByTag(byte tag) { -+ if (tag == CONSTANT_All) { -+ return getUntypedIndex(); -+ } -+ Index ix = indexByTag[tag]; -+ if (ix == null) { -+ // Make an empty one by default. -+ ix = new Index(tagName(tag), new Entry[0]); -+ indexByTag[tag] = ix; -+ } -+ return ix; -+ } - -- /** Index of all CP entries of a given tag and class. */ -- public Index getMemberIndex(byte tag, ClassEntry classRef) { -- if (indexByTagAndClass == null) -- indexByTagAndClass = new Index[CONSTANT_Limit][]; -- Index allClasses = getIndexByTag(CONSTANT_Class); -- Index[] perClassIndexes = indexByTagAndClass[tag]; -- if (perClassIndexes == null) { -- // Create the partition now. -- // Divide up all entries of the given tag according to their class. -- Index allMembers = getIndexByTag(tag); -- int[] whichClasses = new int[allMembers.size()]; -- for (int i = 0; i < whichClasses.length; i++) { -- MemberEntry e = (MemberEntry) allMembers.get(i); -- int whichClass = allClasses.indexOf(e.classRef); -- whichClasses[i] = whichClass; -- } -- perClassIndexes = partition(allMembers, whichClasses); -- for (int i = 0; i < perClassIndexes.length; i++) -- assert(perClassIndexes[i]==null -- || perClassIndexes[i].assertIsSorted()); -- indexByTagAndClass[tag] = perClassIndexes; -- } -- int whichClass = allClasses.indexOf(classRef); -- return perClassIndexes[whichClass]; -- } -+ /** Index of all CP entries of a given tag and class. */ -+ public Index getMemberIndex(byte tag, ClassEntry classRef) { -+ if (classRef == null) -+ throw new RuntimeException("missing class reference for " + tagName(tag)); -+ if (indexByTagAndClass == null) -+ indexByTagAndClass = new Index[CONSTANT_Limit][]; -+ Index allClasses = getIndexByTag(CONSTANT_Class); -+ Index[] perClassIndexes = indexByTagAndClass[tag]; -+ if (perClassIndexes == null) { -+ // Create the partition now. -+ // Divide up all entries of the given tag according to their class. -+ Index allMembers = getIndexByTag(tag); -+ int[] whichClasses = new int[allMembers.size()]; -+ for (int i = 0; i < whichClasses.length; i++) { -+ MemberEntry e = (MemberEntry) allMembers.get(i); -+ int whichClass = allClasses.indexOf(e.classRef); -+ whichClasses[i] = whichClass; -+ } -+ perClassIndexes = partition(allMembers, whichClasses); -+ for (int i = 0; i < perClassIndexes.length; i++) -+ assert(perClassIndexes[i]==null -+ || perClassIndexes[i].assertIsSorted()); -+ indexByTagAndClass[tag] = perClassIndexes; -+ } -+ int whichClass = allClasses.indexOf(classRef); -+ return perClassIndexes[whichClass]; -+ } - -- // Given the sequence of all methods of the given name and class, -- // produce the ordinal of this particular given overloading. -- public int getOverloadingIndex(MemberEntry methodRef) { -- Index ix = getMemberIndex(methodRef.tag, methodRef.classRef); -- Utf8Entry nameRef = methodRef.descRef.nameRef; -- int ord = 0; -- for (int i = 0; i < ix.cpMap.length; i++) { -- MemberEntry e = (MemberEntry) ix.cpMap[i]; -- if (e.equals(methodRef)) -- return ord; -- if (e.descRef.nameRef.equals(nameRef)) -- // Found a different overloading. Increment the ordinal. -- ord++; -- } -- throw new RuntimeException("should not reach here"); -- } -+ // Given the sequence of all methods of the given name and class, -+ // produce the ordinal of this particular given overloading. -+ public int getOverloadingIndex(MemberEntry methodRef) { -+ Index ix = getMemberIndex(methodRef.tag, methodRef.classRef); -+ Utf8Entry nameRef = methodRef.descRef.nameRef; -+ int ord = 0; -+ for (int i = 0; i < ix.cpMap.length; i++) { -+ MemberEntry e = (MemberEntry) ix.cpMap[i]; -+ if (e.equals(methodRef)) -+ return ord; -+ if (e.descRef.nameRef.equals(nameRef)) -+ // Found a different overloading. Increment the ordinal. -+ ord++; -+ } -+ throw new RuntimeException("should not reach here"); -+ } - -- // Inverse of getOverloadingIndex -- public MemberEntry getOverloadingForIndex(byte tag, ClassEntry classRef, String name, int which) { -- assert(name == name.intern()); -- Index ix = getMemberIndex(tag, classRef); -- int ord = 0; -- for (int i = 0; i < ix.cpMap.length; i++) { -- MemberEntry e = (MemberEntry) ix.cpMap[i]; -- if (e.descRef.nameRef.stringValue() == name) { -- if (ord == which) return e; -- ord++; -- } -- } -- throw new RuntimeException("should not reach here"); -- } -+ // Inverse of getOverloadingIndex -+ public MemberEntry getOverloadingForIndex(byte tag, ClassEntry classRef, String name, int which) { -+ assert(name == name.intern()); -+ Index ix = getMemberIndex(tag, classRef); -+ int ord = 0; -+ for (int i = 0; i < ix.cpMap.length; i++) { -+ MemberEntry e = (MemberEntry) ix.cpMap[i]; -+ if (e.descRef.nameRef.stringValue() == name) { -+ if (ord == which) return e; -+ ord++; -+ } -+ } -+ throw new RuntimeException("should not reach here"); -+ } - -- public boolean haveNumbers() { -- for (byte tag = CONSTANT_Integer; tag <= CONSTANT_Double; tag++) { -- switch (tag) { -- case CONSTANT_Integer: -- case CONSTANT_Float: -- case CONSTANT_Long: -- case CONSTANT_Double: -- break; -- default: -- assert(false); -- } -- if (getIndexByTag(tag).size() > 0) return true; -- } -- return false; -- } -+ public boolean haveNumbers() { -+ for (byte tag = CONSTANT_Integer; tag <= CONSTANT_Double; tag++) { -+ switch (tag) { -+ case CONSTANT_Integer: -+ case CONSTANT_Float: -+ case CONSTANT_Long: -+ case CONSTANT_Double: -+ break; -+ default: -+ assert(false); -+ } -+ if (getIndexByTag(tag).size() > 0) return true; -+ } -+ return false; -+ } - - } - -@@ -1114,84 +1116,84 @@ class ConstantPool implements Constants - */ - public static - void completeReferencesIn(Set cpRefs, boolean flattenSigs) { -- cpRefs.remove(null); -- for (ListIterator work = -- new ArrayList(cpRefs).listIterator(cpRefs.size()); -- work.hasPrevious(); ) { -- Entry e = (Entry) work.previous(); -- work.remove(); // pop stack -- assert(e != null); -- if (flattenSigs && e.tag == CONSTANT_Signature) { -- SignatureEntry se = (SignatureEntry) e; -- Utf8Entry ue = se.asUtf8Entry(); -- // Totally replace e by se. -- cpRefs.remove(se); -- cpRefs.add(ue); -- e = ue; // do not descend into the sig -- } -- // Recursively add the refs of e to cpRefs: -- for (int i = 0; ; i++) { -- Entry re = e.getRef(i); -- if (re == null) -- break; // no more refs in e -- if (cpRefs.add(re)) // output the ref -- work.add(re); // push stack, if a new ref -- } -- } -+ cpRefs.remove(null); -+ for (ListIterator work = -+ new ArrayList(cpRefs).listIterator(cpRefs.size()); -+ work.hasPrevious(); ) { -+ Entry e = (Entry) work.previous(); -+ work.remove(); // pop stack -+ assert(e != null); -+ if (flattenSigs && e.tag == CONSTANT_Signature) { -+ SignatureEntry se = (SignatureEntry) e; -+ Utf8Entry ue = se.asUtf8Entry(); -+ // Totally replace e by se. -+ cpRefs.remove(se); -+ cpRefs.add(ue); -+ e = ue; // do not descend into the sig -+ } -+ // Recursively add the refs of e to cpRefs: -+ for (int i = 0; ; i++) { -+ Entry re = e.getRef(i); -+ if (re == null) -+ break; // no more refs in e -+ if (cpRefs.add(re)) // output the ref -+ work.add(re); // push stack, if a new ref -+ } -+ } - } - - static double percent(int num, int den) { -- return (int)((10000.0*num)/den + 0.5) / 100.0; -+ return (int)((10000.0*num)/den + 0.5) / 100.0; - } - - public static String tagName(int tag) { -- switch (tag) { -- case CONSTANT_Utf8: return "Utf8"; -- case CONSTANT_Integer: return "Integer"; -- case CONSTANT_Float: return "Float"; -- case CONSTANT_Long: return "Long"; -- case CONSTANT_Double: return "Double"; -- case CONSTANT_Class: return "Class"; -- case CONSTANT_String: return "String"; -- case CONSTANT_Fieldref: return "Fieldref"; -- case CONSTANT_Methodref: return "Methodref"; -- case CONSTANT_InterfaceMethodref: return "InterfaceMethodref"; -- case CONSTANT_NameandType: return "NameandType"; -+ switch (tag) { -+ case CONSTANT_Utf8: return "Utf8"; -+ case CONSTANT_Integer: return "Integer"; -+ case CONSTANT_Float: return "Float"; -+ case CONSTANT_Long: return "Long"; -+ case CONSTANT_Double: return "Double"; -+ case CONSTANT_Class: return "Class"; -+ case CONSTANT_String: return "String"; -+ case CONSTANT_Fieldref: return "Fieldref"; -+ case CONSTANT_Methodref: return "Methodref"; -+ case CONSTANT_InterfaceMethodref: return "InterfaceMethodref"; -+ case CONSTANT_NameandType: return "NameandType"; - -- // pseudo-tags: -- case CONSTANT_All: return "*All"; -- case CONSTANT_None: return "*None"; -- case CONSTANT_Signature: return "*Signature"; -- } -- return "tag#"+tag; -+ // pseudo-tags: -+ case CONSTANT_All: return "*All"; -+ case CONSTANT_None: return "*None"; -+ case CONSTANT_Signature: return "*Signature"; -+ } -+ return "tag#"+tag; - } - - // archive constant pool definition order - static final byte TAGS_IN_ORDER[] = { -- CONSTANT_Utf8, -- CONSTANT_Integer, // cp_Int -- CONSTANT_Float, -- CONSTANT_Long, -- CONSTANT_Double, -- CONSTANT_String, -- CONSTANT_Class, -- CONSTANT_Signature, -- CONSTANT_NameandType, // cp_Descr -- CONSTANT_Fieldref, // cp_Field -- CONSTANT_Methodref, // cp_Method -- CONSTANT_InterfaceMethodref // cp_Imethod -+ CONSTANT_Utf8, -+ CONSTANT_Integer, // cp_Int -+ CONSTANT_Float, -+ CONSTANT_Long, -+ CONSTANT_Double, -+ CONSTANT_String, -+ CONSTANT_Class, -+ CONSTANT_Signature, -+ CONSTANT_NameandType, // cp_Descr -+ CONSTANT_Fieldref, // cp_Field -+ CONSTANT_Methodref, // cp_Method -+ CONSTANT_InterfaceMethodref // cp_Imethod - }; - static final byte TAG_ORDER[]; - static { -- TAG_ORDER = new byte[CONSTANT_Limit]; -- for (int i = 0; i < TAGS_IN_ORDER.length; i++) { -- TAG_ORDER[TAGS_IN_ORDER[i]] = (byte)(i+1); -- } -- /* -- System.out.println("TAG_ORDER[] = {"); -- for (int i = 0; i < TAG_ORDER.length; i++) -- System.out.println(" "+TAG_ORDER[i]+","); -- System.out.println("};"); -- */ -+ TAG_ORDER = new byte[CONSTANT_Limit]; -+ for (int i = 0; i < TAGS_IN_ORDER.length; i++) { -+ TAG_ORDER[TAGS_IN_ORDER[i]] = (byte)(i+1); -+ } -+ /* -+ System.out.println("TAG_ORDER[] = {"); -+ for (int i = 0; i < TAG_ORDER.length; i++) -+ System.out.println(" "+TAG_ORDER[i]+","); -+ System.out.println("};"); -+ */ - } - } -diff --git a/src/share/classes/com/sun/java/util/jar/pack/NativeUnpack.java b/src/share/classes/com/sun/java/util/jar/pack/NativeUnpack.java ---- openjdk/jdk/src/share/classes/com/sun/java/util/jar/pack/NativeUnpack.java -+++ openjdk/jdk/src/share/classes/com/sun/java/util/jar/pack/NativeUnpack.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -22,7 +22,6 @@ - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -- - - package com.sun.java.util.jar.pack; - -@@ -81,239 +80,246 @@ class NativeUnpack { - private PropMap _props; - - static { -- // If loading from stand alone build uncomment this. -- // System.loadLibrary("unpack"); -- java.security.AccessController.doPrivileged( -- new sun.security.action.LoadLibraryAction("unpack")); -- initIDs(); -+ // If loading from stand alone build uncomment this. -+ // System.loadLibrary("unpack"); -+ java.security.AccessController.doPrivileged( -+ new sun.security.action.LoadLibraryAction("unpack")); -+ initIDs(); - } -- -+ - NativeUnpack(UnpackerImpl p200) { -- super(); -- _p200 = p200; -- _props = p200._props; -- p200._nunp = this; -+ super(); -+ _p200 = p200; -+ _props = p200._props; -+ p200._nunp = this; - } - - // for JNI callbacks - static private Object currentInstance() { -- UnpackerImpl p200 = (UnpackerImpl) Utils.currentInstance.get(); -- return (p200 == null)? null: p200._nunp; -+ UnpackerImpl p200 = (UnpackerImpl) Utils.currentInstance.get(); -+ return (p200 == null)? null: p200._nunp; -+ } -+ -+ private synchronized long getUnpackerPtr() { -+ return unpackerPtr; - } - - // Callback from the unpacker engine to get more data. - private long readInputFn(ByteBuffer pbuf, long minlen) throws IOException { -- if (in == null) return 0; // nothing is readable -- long maxlen = pbuf.capacity() - pbuf.position(); -- assert(minlen <= maxlen); // don't talk nonsense -- long numread = 0; -- int steps = 0; -- while (numread < minlen) { -- steps++; -- // read available input, up to buf.length or maxlen -- int readlen = _buf.length; -- if (readlen > (maxlen - numread)) -- readlen = (int)(maxlen - numread); -- int nr = in.read(_buf, 0, readlen); -- if (nr <= 0) break; -- numread += nr; -- assert(numread <= maxlen); -- // %%% get rid of this extra copy by using nio? -- pbuf.put(_buf, 0, nr); -- } -- if (_verbose > 1) -- Utils.log.fine("readInputFn("+minlen+","+maxlen+") => "+numread+" steps="+steps); -- if (maxlen > 100) { -- _estByteLimit = _byteCount + maxlen; -- } else { -- _estByteLimit = (_byteCount + numread) * 20; -- } -- _byteCount += numread; -- updateProgress(); -- return numread; -+ if (in == null) return 0; // nothing is readable -+ long maxlen = pbuf.capacity() - pbuf.position(); -+ assert(minlen <= maxlen); // don't talk nonsense -+ long numread = 0; -+ int steps = 0; -+ while (numread < minlen) { -+ steps++; -+ // read available input, up to buf.length or maxlen -+ int readlen = _buf.length; -+ if (readlen > (maxlen - numread)) -+ readlen = (int)(maxlen - numread); -+ int nr = in.read(_buf, 0, readlen); -+ if (nr <= 0) break; -+ numread += nr; -+ assert(numread <= maxlen); -+ // %%% get rid of this extra copy by using nio? -+ pbuf.put(_buf, 0, nr); -+ } -+ if (_verbose > 1) -+ Utils.log.fine("readInputFn("+minlen+","+maxlen+") => "+numread+" steps="+steps); -+ if (maxlen > 100) { -+ _estByteLimit = _byteCount + maxlen; -+ } else { -+ _estByteLimit = (_byteCount + numread) * 20; -+ } -+ _byteCount += numread; -+ updateProgress(); -+ return numread; - } - - private void updateProgress() { -- // Progress is a combination of segment reading and file writing. -- final double READ_WT = 0.33; -- final double WRITE_WT = 0.67; -- double readProgress = _segCount; -- if (_estByteLimit > 0 && _byteCount > 0) -- readProgress += (double)_byteCount / _estByteLimit; -- double writeProgress = _fileCount; -- double scaledProgress -- = READ_WT * readProgress / Math.max(_estSegLimit,1) -- + WRITE_WT * writeProgress / Math.max(_estFileLimit,1); -- int percent = (int) Math.round(100*scaledProgress); -- if (percent > 100) percent = 100; -- if (percent > _prevPercent) { -- _prevPercent = percent; -- _props.setInteger(Pack200.Unpacker.PROGRESS, percent); -- if (_verbose > 0) -- Utils.log.info("progress = "+percent); -- } -+ // Progress is a combination of segment reading and file writing. -+ final double READ_WT = 0.33; -+ final double WRITE_WT = 0.67; -+ double readProgress = _segCount; -+ if (_estByteLimit > 0 && _byteCount > 0) -+ readProgress += (double)_byteCount / _estByteLimit; -+ double writeProgress = _fileCount; -+ double scaledProgress -+ = READ_WT * readProgress / Math.max(_estSegLimit,1) -+ + WRITE_WT * writeProgress / Math.max(_estFileLimit,1); -+ int percent = (int) Math.round(100*scaledProgress); -+ if (percent > 100) percent = 100; -+ if (percent > _prevPercent) { -+ _prevPercent = percent; -+ _props.setInteger(Pack200.Unpacker.PROGRESS, percent); -+ if (_verbose > 0) -+ Utils.log.info("progress = "+percent); -+ } - } - - private void copyInOption(String opt) { -- String val = _props.getProperty(opt); -- if (_verbose > 0) -- Utils.log.info("set "+opt+"="+val); -- if (val != null) { -- boolean set = setOption(opt, val); -- if (!set) -- Utils.log.warning("Invalid option "+opt+"="+val); -- } -+ String val = _props.getProperty(opt); -+ if (_verbose > 0) -+ Utils.log.info("set "+opt+"="+val); -+ if (val != null) { -+ boolean set = setOption(opt, val); -+ if (!set) -+ Utils.log.warning("Invalid option "+opt+"="+val); -+ } - } - - void run(InputStream inRaw, JarOutputStream jstream, -- ByteBuffer presetInput) throws IOException { -- BufferedInputStream in = new BufferedInputStream(inRaw); -- this.in = in; // for readInputFn to see -- _verbose = _props.getInteger(Utils.DEBUG_VERBOSE); -- // Fix for BugId: 4902477, -unpack.modification.time = 1059010598000 -+ ByteBuffer presetInput) throws IOException { -+ BufferedInputStream in = new BufferedInputStream(inRaw); -+ this.in = in; // for readInputFn to see -+ _verbose = _props.getInteger(Utils.DEBUG_VERBOSE); -+ // Fix for BugId: 4902477, -unpack.modification.time = 1059010598000 - // TODO eliminate and fix in unpack.cpp -+ -+ final int modtime = Pack200.Packer.KEEP.equals(_props.getProperty(Utils.UNPACK_MODIFICATION_TIME, "0")) ? -+ Constants.NO_MODTIME : _props.getTime(Utils.UNPACK_MODIFICATION_TIME); - -- final int modtime = Pack200.Packer.KEEP.equals(_props.getProperty(Utils.UNPACK_MODIFICATION_TIME, "0")) ? -- Constants.NO_MODTIME : _props.getTime(Utils.UNPACK_MODIFICATION_TIME); -+ copyInOption(Utils.DEBUG_VERBOSE); -+ copyInOption(Pack200.Unpacker.DEFLATE_HINT); -+ if (modtime == Constants.NO_MODTIME) // Dont pass KEEP && NOW -+ copyInOption(Utils.UNPACK_MODIFICATION_TIME); -+ updateProgress(); // reset progress bar -+ for (;;) { -+ // Read the packed bits. -+ long counts = start(presetInput, 0); -+ _byteCount = _estByteLimit = 0; // reset partial scan counts -+ ++_segCount; // just finished scanning a whole segment... -+ int nextSeg = (int)( counts >>> 32 ); -+ int nextFile = (int)( counts >>> 0 ); - -- copyInOption(Utils.DEBUG_VERBOSE); -- copyInOption(Pack200.Unpacker.DEFLATE_HINT); -- if (modtime == Constants.NO_MODTIME) // Dont pass KEEP && NOW -- copyInOption(Utils.UNPACK_MODIFICATION_TIME); -- updateProgress(); // reset progress bar -- for (;;) { -- // Read the packed bits. -- long counts = start(presetInput, 0); -- _byteCount = _estByteLimit = 0; // reset partial scan counts -- ++_segCount; // just finished scanning a whole segment... -- int nextSeg = (int)( counts >>> 32 ); -- int nextFile = (int)( counts >>> 0 ); -+ // Estimate eventual total number of segments and files. -+ _estSegLimit = _segCount + nextSeg; -+ double filesAfterThisSeg = _fileCount + nextFile; -+ _estFileLimit = (int)( (filesAfterThisSeg * -+ _estSegLimit) / _segCount ); - -- // Estimate eventual total number of segments and files. -- _estSegLimit = _segCount + nextSeg; -- double filesAfterThisSeg = _fileCount + nextFile; -- _estFileLimit = (int)( (filesAfterThisSeg * -- _estSegLimit) / _segCount ); -+ // Write the files. -+ int[] intParts = { 0,0, 0, 0 }; -+ // intParts = {size.hi/lo, mod, defl} -+ Object[] parts = { intParts, null, null, null }; -+ // parts = { {intParts}, name, data0/1 } -+ while (getNextFile(parts)) { -+ //BandStructure.printArrayTo(System.out, intParts, 0, parts.length); -+ String name = (String) parts[1]; -+ long size = ( (long)intParts[0] << 32) -+ + (((long)intParts[1] << 32) >>> 32); - -- // Write the files. -- int[] intParts = { 0,0, 0, 0 }; -- // intParts = {size.hi/lo, mod, defl} -- Object[] parts = { intParts, null, null, null }; -- // parts = { {intParts}, name, data0/1 } -- while (getNextFile(parts)) { -- //BandStructure.printArrayTo(System.out, intParts, 0, parts.length); -- String name = (String) parts[1]; -- long size = ( (long)intParts[0] << 32) -- + (((long)intParts[1] << 32) >>> 32); -- -- long mtime = (modtime != Constants.NO_MODTIME ) ? -- modtime : intParts[2] ; -- boolean deflateHint = (intParts[3] != 0); -- ByteBuffer data0 = (ByteBuffer) parts[2]; -- ByteBuffer data1 = (ByteBuffer) parts[3]; -- writeEntry(jstream, name, mtime, size, deflateHint, -- data0, data1); -- ++_fileCount; -- updateProgress(); -- } -- long consumed = finish(); -- if (_verbose > 0) -- Utils.log.info("bytes consumed = "+consumed); -- presetInput = getUnusedInput(); -- if (presetInput == null && -- !Utils.isPackMagic(Utils.readMagic(in))) { -- break; -- } -- if (_verbose > 0 ) { -- if (presetInput != null) -- Utils.log.info("unused input = "+presetInput); -- } -- } -+ long mtime = (modtime != Constants.NO_MODTIME ) ? -+ modtime : intParts[2] ; -+ boolean deflateHint = (intParts[3] != 0); -+ ByteBuffer data0 = (ByteBuffer) parts[2]; -+ ByteBuffer data1 = (ByteBuffer) parts[3]; -+ writeEntry(jstream, name, mtime, size, deflateHint, -+ data0, data1); -+ ++_fileCount; -+ updateProgress(); -+ } -+ long consumed = finish(); -+ if (_verbose > 0) -+ Utils.log.info("bytes consumed = "+consumed); -+ presetInput = getUnusedInput(); -+ if (presetInput == null && -+ !Utils.isPackMagic(Utils.readMagic(in))) { -+ break; -+ } -+ if (_verbose > 0 ) { -+ if (presetInput != null) -+ Utils.log.info("unused input = "+presetInput); -+ } -+ } - } - - void run(InputStream in, JarOutputStream jstream) throws IOException { -- run(in, jstream, null); -+ run(in, jstream, null); - } - - void run(File inFile, JarOutputStream jstream) throws IOException { -- // %%% maybe memory-map the file, and pass it straight into unpacker -- ByteBuffer mappedFile = null; -- FileInputStream fis = new FileInputStream(inFile); -- run(fis, jstream, mappedFile); -- fis.close(); -- // Note: caller is responsible to finish with jstream. -+ // %%% maybe memory-map the file, and pass it straight into unpacker -+ ByteBuffer mappedFile = null; -+ FileInputStream fis = new FileInputStream(inFile); -+ run(fis, jstream, mappedFile); -+ fis.close(); -+ // Note: caller is responsible to finish with jstream. - } -+ -+ private void writeEntry(JarOutputStream j, String name, -+ long mtime, long lsize, boolean deflateHint, -+ ByteBuffer data0, ByteBuffer data1) throws IOException { -+ int size = (int)lsize; -+ if (size != lsize) -+ throw new IOException("file too large: "+lsize); - -- private void writeEntry(JarOutputStream j, String name, -- long mtime, long lsize, boolean deflateHint, -- ByteBuffer data0, ByteBuffer data1) throws IOException { -- int size = (int)lsize; -- if (size != lsize) -- throw new IOException("file too large: "+lsize); -+ CRC32 crc32 = _crc32; - -- CRC32 crc32 = _crc32; -+ if (_verbose > 1) -+ Utils.log.fine("Writing entry: "+name+" size="+size -+ +(deflateHint?" deflated":"")); - -- if (_verbose > 1) -- Utils.log.fine("Writing entry: "+name+" size="+size -- +(deflateHint?" deflated":"")); -+ if (_buf.length < size) { -+ int newSize = size; -+ while (newSize < _buf.length) { -+ newSize <<= 1; -+ if (newSize <= 0) { -+ newSize = size; -+ break; -+ } -+ } -+ _buf = new byte[newSize]; -+ } -+ assert(_buf.length >= size); - -- if (_buf.length < size) { -- int newSize = size; -- while (newSize < _buf.length) { -- newSize <<= 1; -- if (newSize <= 0) { -- newSize = size; -- break; -- } -- } -- _buf = new byte[newSize]; -- } -- assert(_buf.length >= size); -+ int fillp = 0; -+ if (data0 != null) { -+ int size0 = data0.capacity(); -+ data0.get(_buf, fillp, size0); -+ fillp += size0; -+ } -+ if (data1 != null) { -+ int size1 = data1.capacity(); -+ data1.get(_buf, fillp, size1); -+ fillp += size1; -+ } -+ while (fillp < size) { -+ // Fill in rest of data from the stream itself. -+ int nr = in.read(_buf, fillp, size - fillp); -+ if (nr <= 0) throw new IOException("EOF at end of archive"); -+ fillp += nr; -+ } - -- int fillp = 0; -- if (data0 != null) { -- int size0 = data0.capacity(); -- data0.get(_buf, fillp, size0); -- fillp += size0; -- } -- if (data1 != null) { -- int size1 = data1.capacity(); -- data1.get(_buf, fillp, size1); -- fillp += size1; -- } -- while (fillp < size) { -- // Fill in rest of data from the stream itself. -- int nr = in.read(_buf, fillp, size - fillp); -- if (nr <= 0) throw new IOException("EOF at end of archive"); -- fillp += nr; -- } -+ ZipEntry z = new ZipEntry(name); -+ z.setTime( (long)mtime * 1000); -+ -+ if (size == 0) { -+ z.setMethod(ZipOutputStream.STORED); -+ z.setSize(0); -+ z.setCrc(0); -+ z.setCompressedSize(0); -+ } else if (!deflateHint) { -+ z.setMethod(ZipOutputStream.STORED); -+ z.setSize(size); -+ z.setCompressedSize(size); -+ crc32.reset(); -+ crc32.update(_buf, 0, size); -+ z.setCrc(crc32.getValue()); -+ } else { -+ z.setMethod(Deflater.DEFLATED); -+ z.setSize(size); -+ } - -- ZipEntry z = new ZipEntry(name); -- z.setTime( (long)mtime * 1000); -+ j.putNextEntry(z); - -- if (size == 0) { -- z.setMethod(ZipOutputStream.STORED); -- z.setSize(0); -- z.setCrc(0); -- z.setCompressedSize(0); -- } else if (!deflateHint) { -- z.setMethod(ZipOutputStream.STORED); -- z.setSize(size); -- z.setCompressedSize(size); -- crc32.reset(); -- crc32.update(_buf, 0, size); -- z.setCrc(crc32.getValue()); -- } else { -- z.setMethod(Deflater.DEFLATED); -- z.setSize(size); -- } -+ if (size > 0) -+ j.write(_buf, 0, size); - -- j.putNextEntry(z); -- -- if (size > 0) -- j.write(_buf, 0, size); -- -- j.closeEntry(); -- if (_verbose > 0) Utils.log.info("Writing " + Utils.zeString(z)); -+ j.closeEntry(); -+ if (_verbose > 0) Utils.log.info("Writing " + Utils.zeString(z)); - } - } -+ -+ -+ -diff --git a/src/share/classes/com/sun/java/util/jar/pack/PackerImpl.java b/src/share/classes/com/sun/java/util/jar/pack/PackerImpl.java ---- openjdk/jdk/src/share/classes/com/sun/java/util/jar/pack/PackerImpl.java -+++ openjdk/jdk/src/share/classes/com/sun/java/util/jar/pack/PackerImpl.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -22,7 +22,6 @@ - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -- - package com.sun.java.util.jar.pack; - - import java.util.*; -@@ -48,9 +47,9 @@ public class PackerImpl implements Pack2 - * the packer engines. - */ - public PackerImpl() { -- _props = new PropMap(); -- //_props.getProperty() consults defaultProps invisibly. -- //_props.putAll(defaultProps); -+ _props = new PropMap(); -+ //_props.getProperty() consults defaultProps invisibly. -+ //_props.putAll(defaultProps); - } - - -@@ -62,7 +61,7 @@ public class PackerImpl implements Pack2 - * @return A sorted association of option key strings to option values. - */ - public SortedMap properties() { -- return _props; -+ return _props; - } - - -@@ -76,24 +75,24 @@ public class PackerImpl implements Pack2 - * @param out an OutputStream - * @exception IOException if an error is encountered. - */ -- public void pack(JarFile in, OutputStream out) throws IOException { -- assert(Utils.currentInstance.get() == null); -- TimeZone tz = (_props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE)) ? null : -- TimeZone.getDefault(); -- try { -- Utils.currentInstance.set(this); -- if (tz != null) TimeZone.setDefault(TimeZone.getTimeZone("UTC")); -+ public synchronized void pack(JarFile in, OutputStream out) throws IOException { -+ assert(Utils.currentInstance.get() == null); -+ TimeZone tz = (_props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE)) ? null : -+ TimeZone.getDefault(); -+ try { -+ Utils.currentInstance.set(this); -+ if (tz != null) TimeZone.setDefault(TimeZone.getTimeZone("UTC")); - -- if ("0".equals(_props.getProperty(Pack200.Packer.EFFORT))) { -- Utils.copyJarFile(in, out); -- } else { -- (new DoPack()).run(in, out); -- in.close(); -- } -- } finally { -- Utils.currentInstance.set(null); -- if (tz != null) TimeZone.setDefault(tz); -- } -+ if ("0".equals(_props.getProperty(Pack200.Packer.EFFORT))) { -+ Utils.copyJarFile(in, out); -+ } else { -+ (new DoPack()).run(in, out); -+ in.close(); -+ } -+ } finally { -+ Utils.currentInstance.set(null); -+ if (tz != null) TimeZone.setDefault(tz); -+ } - } - - /** -@@ -110,39 +109,39 @@ public class PackerImpl implements Pack2 - * @param out an OutputStream - * @exception IOException if an error is encountered. - */ -- public void pack(JarInputStream in, OutputStream out) throws IOException { -- assert(Utils.currentInstance.get() == null); -- TimeZone tz = (_props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE)) ? null : -- TimeZone.getDefault(); -- try { -- Utils.currentInstance.set(this); -- if (tz != null) TimeZone.setDefault(TimeZone.getTimeZone("UTC")); -- if ("0".equals(_props.getProperty(Pack200.Packer.EFFORT))) { -- Utils.copyJarFile(in, out); -- } else { -- (new DoPack()).run(in, out); -- in.close(); -- } -- } finally { -- Utils.currentInstance.set(null); -- if (tz != null) TimeZone.setDefault(tz); -+ public synchronized void pack(JarInputStream in, OutputStream out) throws IOException { -+ assert(Utils.currentInstance.get() == null); -+ TimeZone tz = (_props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE)) ? null : -+ TimeZone.getDefault(); -+ try { -+ Utils.currentInstance.set(this); -+ if (tz != null) TimeZone.setDefault(TimeZone.getTimeZone("UTC")); -+ if ("0".equals(_props.getProperty(Pack200.Packer.EFFORT))) { -+ Utils.copyJarFile(in, out); -+ } else { -+ (new DoPack()).run(in, out); -+ in.close(); -+ } -+ } finally { -+ Utils.currentInstance.set(null); -+ if (tz != null) TimeZone.setDefault(tz); - -- } -+ } - } - /** - * Register a listener for changes to options. -- * @param listener An object to be invoked when a property is changed. -+ * @param listener An object to be invoked when a property is changed. - */ - public void addPropertyChangeListener(PropertyChangeListener listener) { -- _props.addListener(listener); -+ _props.addListener(listener); - } - - /** - * Remove a listener for the PropertyChange event. -- * @param listener The PropertyChange listener to be removed. -+ * @param listener The PropertyChange listener to be removed. - */ - public void removePropertyChangeListener(PropertyChangeListener listener) { -- _props.removeListener(listener); -+ _props.removeListener(listener); - } - - -@@ -151,471 +150,478 @@ public class PackerImpl implements Pack2 - - // The packer worker. - private class DoPack { -- final int verbose = _props.getInteger(Utils.DEBUG_VERBOSE); -+ final int verbose = _props.getInteger(Utils.DEBUG_VERBOSE); - -- { -- _props.setInteger(Pack200.Packer.PROGRESS, 0); -- if (verbose > 0) Utils.log.info(_props.toString()); -- } -+ { -+ _props.setInteger(Pack200.Packer.PROGRESS, 0); -+ if (verbose > 0) Utils.log.info(_props.toString()); -+ } - -- // Here's where the bits are collected before getting packed: -- final Package pkg = new Package(); -+ // Here's where the bits are collected before getting packed: -+ final Package pkg = new Package(); - -- final String unknownAttrCommand; -- { -- String uaMode = _props.getProperty(Pack200.Packer.UNKNOWN_ATTRIBUTE, Pack200.Packer.PASS); -- if (!(Pack200.Packer.STRIP.equals(uaMode) || -- Pack200.Packer.PASS.equals(uaMode) || -- Pack200.Packer.ERROR.equals(uaMode))) { -- throw new RuntimeException("Bad option: " + Pack200.Packer.UNKNOWN_ATTRIBUTE + " = " + uaMode); -- } -- unknownAttrCommand = uaMode.intern(); -- } -+ final String unknownAttrCommand; -+ { -+ String uaMode = _props.getProperty(Pack200.Packer.UNKNOWN_ATTRIBUTE, Pack200.Packer.PASS); -+ if (!(Pack200.Packer.STRIP.equals(uaMode) || -+ Pack200.Packer.PASS.equals(uaMode) || -+ Pack200.Packer.ERROR.equals(uaMode))) { -+ throw new RuntimeException("Bad option: " + Pack200.Packer.UNKNOWN_ATTRIBUTE + " = " + uaMode); -+ } -+ unknownAttrCommand = uaMode.intern(); -+ } - -- final HashMap attrDefs; -- final HashMap attrCommands; -- { -- HashMap attrDefs = new HashMap(); -- HashMap attrCommands = new HashMap(); -- String[] keys = { -- Pack200.Packer.CLASS_ATTRIBUTE_PFX, -- Pack200.Packer.FIELD_ATTRIBUTE_PFX, -- Pack200.Packer.METHOD_ATTRIBUTE_PFX, -- Pack200.Packer.CODE_ATTRIBUTE_PFX -- }; -- int[] ctypes = { -- Constants.ATTR_CONTEXT_CLASS, -- Constants.ATTR_CONTEXT_FIELD, -- Constants.ATTR_CONTEXT_METHOD, -- Constants.ATTR_CONTEXT_CODE -- }; -- for (int i = 0; i < ctypes.length; i++) { -- String pfx = keys[i]; -- Map map = _props.prefixMap(pfx); -- for (Iterator j = map.keySet().iterator(); j.hasNext(); ) { -- String key = (String) j.next(); -- assert(key.startsWith(pfx)); -- String name = key.substring(pfx.length()); -- String layout = _props.getProperty(key); -- Object lkey = Attribute.keyForLookup(ctypes[i], name); -- if (Pack200.Packer.STRIP.equals(layout) || -- Pack200.Packer.PASS.equals(layout) || -- Pack200.Packer.ERROR.equals(layout)) { -- attrCommands.put(lkey, layout.intern()); -- } else { -- Attribute.define(attrDefs, ctypes[i], name, layout); -- if (verbose > 1) { -- Utils.log.fine("Added layout for "+Constants.ATTR_CONTEXT_NAME[i]+" attribute "+name+" = "+layout); -- } -- assert(attrDefs.containsKey(lkey)); -- } -- } -- } -- if (attrDefs.size() > 0) -- this.attrDefs = attrDefs; -- else -- this.attrDefs = null; -- if (attrCommands.size() > 0) -- this.attrCommands = attrCommands; -- else -- this.attrCommands = null; -- } -+ final HashMap attrDefs; -+ final HashMap attrCommands; -+ { -+ HashMap attrDefs = new HashMap(); -+ HashMap attrCommands = new HashMap(); -+ String[] keys = { -+ Pack200.Packer.CLASS_ATTRIBUTE_PFX, -+ Pack200.Packer.FIELD_ATTRIBUTE_PFX, -+ Pack200.Packer.METHOD_ATTRIBUTE_PFX, -+ Pack200.Packer.CODE_ATTRIBUTE_PFX -+ }; -+ int[] ctypes = { -+ Constants.ATTR_CONTEXT_CLASS, -+ Constants.ATTR_CONTEXT_FIELD, -+ Constants.ATTR_CONTEXT_METHOD, -+ Constants.ATTR_CONTEXT_CODE -+ }; -+ for (int i = 0; i < ctypes.length; i++) { -+ String pfx = keys[i]; -+ Map map = _props.prefixMap(pfx); -+ for (Iterator j = map.keySet().iterator(); j.hasNext(); ) { -+ String key = (String) j.next(); -+ assert(key.startsWith(pfx)); -+ String name = key.substring(pfx.length()); -+ String layout = _props.getProperty(key); -+ Object lkey = Attribute.keyForLookup(ctypes[i], name); -+ if (Pack200.Packer.STRIP.equals(layout) || -+ Pack200.Packer.PASS.equals(layout) || -+ Pack200.Packer.ERROR.equals(layout)) { -+ attrCommands.put(lkey, layout.intern()); -+ } else { -+ Attribute.define(attrDefs, ctypes[i], name, layout); -+ if (verbose > 1) { -+ Utils.log.fine("Added layout for "+Constants.ATTR_CONTEXT_NAME[i]+" attribute "+name+" = "+layout); -+ } -+ assert(attrDefs.containsKey(lkey)); -+ } -+ } -+ } -+ if (attrDefs.size() > 0) -+ this.attrDefs = attrDefs; -+ else -+ this.attrDefs = null; -+ if (attrCommands.size() > 0) -+ this.attrCommands = attrCommands; -+ else -+ this.attrCommands = null; -+ } - -- final boolean keepFileOrder -- = _props.getBoolean(Pack200.Packer.KEEP_FILE_ORDER); -- final boolean keepClassOrder -- = _props.getBoolean(Utils.PACK_KEEP_CLASS_ORDER); -+ final boolean keepFileOrder -+ = _props.getBoolean(Pack200.Packer.KEEP_FILE_ORDER); -+ final boolean keepClassOrder -+ = _props.getBoolean(Utils.PACK_KEEP_CLASS_ORDER); - -- final boolean keepModtime -- = Pack200.Packer.KEEP.equals(_props.getProperty(Pack200.Packer.MODIFICATION_TIME)); -- final boolean latestModtime -- = Pack200.Packer.LATEST.equals(_props.getProperty(Pack200.Packer.MODIFICATION_TIME)); -- final boolean keepDeflateHint -- = Pack200.Packer.KEEP.equals(_props.getProperty(Pack200.Packer.DEFLATE_HINT)); -- { -- if (!keepModtime && !latestModtime) { -- int modtime = _props.getTime(Pack200.Packer.MODIFICATION_TIME); -- if (modtime != Constants.NO_MODTIME) { -- pkg.default_modtime = modtime; -- } -- } -- if (!keepDeflateHint) { -- boolean deflate_hint = _props.getBoolean(Pack200.Packer.DEFLATE_HINT); -- if (deflate_hint) { -- pkg.default_options |= Constants.AO_DEFLATE_HINT; -- } -- } -- } -+ final boolean keepModtime -+ = Pack200.Packer.KEEP.equals(_props.getProperty(Pack200.Packer.MODIFICATION_TIME)); -+ final boolean latestModtime -+ = Pack200.Packer.LATEST.equals(_props.getProperty(Pack200.Packer.MODIFICATION_TIME)); -+ final boolean keepDeflateHint -+ = Pack200.Packer.KEEP.equals(_props.getProperty(Pack200.Packer.DEFLATE_HINT)); -+ { -+ if (!keepModtime && !latestModtime) { -+ int modtime = _props.getTime(Pack200.Packer.MODIFICATION_TIME); -+ if (modtime != Constants.NO_MODTIME) { -+ pkg.default_modtime = modtime; -+ } -+ } -+ if (!keepDeflateHint) { -+ boolean deflate_hint = _props.getBoolean(Pack200.Packer.DEFLATE_HINT); -+ if (deflate_hint) { -+ pkg.default_options |= Constants.AO_DEFLATE_HINT; -+ } -+ } -+ } - -- long totalOutputSize = 0; -- int segmentCount = 0; -- long segmentTotalSize = 0; -- long segmentSize = 0; // running counter -- final long segmentLimit; -- { -- long limit; -- if (_props.getProperty(Pack200.Packer.SEGMENT_LIMIT, "").equals("")) -- limit = -1; -- else -- limit = _props.getLong(Pack200.Packer.SEGMENT_LIMIT); -- limit = Math.min(Integer.MAX_VALUE, limit); -- limit = Math.max(-1, limit); -- if (limit == -1) -- limit = Long.MAX_VALUE; -- segmentLimit = limit; -- } -+ long totalOutputSize = 0; -+ int segmentCount = 0; -+ long segmentTotalSize = 0; -+ long segmentSize = 0; // running counter -+ final long segmentLimit; -+ { -+ long limit; -+ if (_props.getProperty(Pack200.Packer.SEGMENT_LIMIT, "").equals("")) -+ limit = -1; -+ else -+ limit = _props.getLong(Pack200.Packer.SEGMENT_LIMIT); -+ limit = Math.min(Integer.MAX_VALUE, limit); -+ limit = Math.max(-1, limit); -+ if (limit == -1) -+ limit = Long.MAX_VALUE; -+ segmentLimit = limit; -+ } - -- final List passFiles; // parsed pack.pass.file options -- { -- // Which class files will be passed through? -- passFiles = _props.getProperties(Pack200.Packer.PASS_FILE_PFX); -- for (ListIterator i = passFiles.listIterator(); i.hasNext(); ) { -- String file = (String) i.next(); -- if (file == null) { i.remove(); continue; } -- file = Utils.getJarEntryName(file); // normalize '\\' to '/' -- if (file.endsWith("/")) -- file = file.substring(0, file.length()-1); -- i.set(file); -- } -- if (verbose > 0) Utils.log.info("passFiles = " + passFiles); -- } -+ final List passFiles; // parsed pack.pass.file options -+ { -+ // Which class files will be passed through? -+ passFiles = _props.getProperties(Pack200.Packer.PASS_FILE_PFX); -+ for (ListIterator i = passFiles.listIterator(); i.hasNext(); ) { -+ String file = (String) i.next(); -+ if (file == null) { i.remove(); continue; } -+ file = Utils.getJarEntryName(file); // normalize '\\' to '/' -+ if (file.endsWith("/")) -+ file = file.substring(0, file.length()-1); -+ i.set(file); -+ } -+ if (verbose > 0) Utils.log.info("passFiles = " + passFiles); -+ } - -- { -- // Fill in permitted range of major/minor version numbers. -- int ver; -- if ((ver = _props.getInteger(Utils.COM_PREFIX+"min.class.majver")) != 0) -- pkg.min_class_majver = (short) ver; -- if ((ver = _props.getInteger(Utils.COM_PREFIX+"min.class.minver")) != 0) -- pkg.min_class_minver = (short) ver; -- if ((ver = _props.getInteger(Utils.COM_PREFIX+"max.class.majver")) != 0) -- pkg.max_class_majver = (short) ver; -- if ((ver = _props.getInteger(Utils.COM_PREFIX+"max.class.minver")) != 0) -- pkg.max_class_minver = (short) ver; -- if ((ver = _props.getInteger(Utils.COM_PREFIX+"package.minver")) != 0) -- pkg.package_minver = (short) ver; -- if ((ver = _props.getInteger(Utils.COM_PREFIX+"package.majver")) != 0) -- pkg.package_majver = (short) ver; -- } -+ { -+ // Fill in permitted range of major/minor version numbers. -+ int ver; -+ if ((ver = _props.getInteger(Utils.COM_PREFIX+"min.class.majver")) != 0) -+ pkg.min_class_majver = (short) ver; -+ if ((ver = _props.getInteger(Utils.COM_PREFIX+"min.class.minver")) != 0) -+ pkg.min_class_minver = (short) ver; -+ if ((ver = _props.getInteger(Utils.COM_PREFIX+"max.class.majver")) != 0) -+ pkg.max_class_majver = (short) ver; -+ if ((ver = _props.getInteger(Utils.COM_PREFIX+"max.class.minver")) != 0) -+ pkg.max_class_minver = (short) ver; -+ if ((ver = _props.getInteger(Utils.COM_PREFIX+"package.minver")) != 0) -+ pkg.package_minver = (short) ver; -+ if ((ver = _props.getInteger(Utils.COM_PREFIX+"package.majver")) != 0) -+ pkg.package_majver = (short) ver; -+ } - -- { -- // Hook for testing: Forces use of special archive modes. -- int opt = _props.getInteger(Utils.COM_PREFIX+"archive.options"); -- if (opt != 0) -- pkg.default_options |= opt; -- } -+ { -+ // Hook for testing: Forces use of special archive modes. -+ int opt = _props.getInteger(Utils.COM_PREFIX+"archive.options"); -+ if (opt != 0) -+ pkg.default_options |= opt; -+ } - -- // (Done collecting options from _props.) -+ // (Done collecting options from _props.) - -- boolean isClassFile(String name) { -- if (!name.endsWith(".class")) return false; -- for (String prefix = name; ; ) { -- if (passFiles.contains(prefix)) return false; -- int chop = prefix.lastIndexOf('/'); -- if (chop < 0) break; -- prefix = prefix.substring(0, chop); -- } -- return true; -- } -+ boolean isClassFile(String name) { -+ if (!name.endsWith(".class")) return false; -+ for (String prefix = name; ; ) { -+ if (passFiles.contains(prefix)) return false; -+ int chop = prefix.lastIndexOf('/'); -+ if (chop < 0) break; -+ prefix = prefix.substring(0, chop); -+ } -+ return true; -+ } - -- boolean isMetaInfFile(String name) { -- return name.startsWith("/" + Utils.METAINF) || -- name.startsWith(Utils.METAINF); -- } -+ boolean isMetaInfFile(String name) { -+ return name.startsWith("/" + Utils.METAINF) || -+ name.startsWith(Utils.METAINF); -+ } - -- // Get a new package, based on the old one. -- private void makeNextPackage() { -- pkg.reset(); -- } -+ // Get a new package, based on the old one. -+ private void makeNextPackage() { -+ pkg.reset(); -+ } - -- class InFile { -- final String name; -- final JarFile jf; -- final JarEntry je; -- final File f; -- int modtime = Constants.NO_MODTIME; -- int options; -- InFile(String name) { -- this.name = Utils.getJarEntryName(name); -- this.f = new File(name); -- this.jf = null; -- this.je = null; -- int timeSecs = getModtime(f.lastModified()); -- if (keepModtime && timeSecs != Constants.NO_MODTIME) { -- this.modtime = timeSecs; -- } else if (latestModtime && timeSecs > pkg.default_modtime) { -- pkg.default_modtime = timeSecs; -- } -- } -- InFile(JarFile jf, JarEntry je) { -- this.name = Utils.getJarEntryName(je.getName()); -- this.f = null; -- this.jf = jf; -- this.je = je; -- int timeSecs = getModtime(je.getTime()); -- if (keepModtime && timeSecs != Constants.NO_MODTIME) { -- this.modtime = timeSecs; -- } else if (latestModtime && timeSecs > pkg.default_modtime) { -- pkg.default_modtime = timeSecs; -- } -- if (keepDeflateHint && je.getMethod() == JarEntry.DEFLATED) { -- options |= Constants.FO_DEFLATE_HINT; -- } -- } -- InFile(JarEntry je) { -- this(null, je); -- } -- long getInputLength() { -- long len = (je != null)? je.getSize(): f.length(); -- assert(len >= 0) : this+".len="+len; -- // Bump size by pathname length and modtime/def-hint bytes. -- return Math.max(0, len) + name.length() + 5; -- } -- int getModtime(long timeMillis) { -- // Convert milliseconds to seconds. -- long seconds = (timeMillis+500) / 1000; -- if ((int)seconds == seconds) { -- return (int)seconds; -- } else { -- Utils.log.warning("overflow in modtime for "+f); -- return Constants.NO_MODTIME; -- } -- } -- void copyTo(Package.File file) { -- if (modtime != Constants.NO_MODTIME) -- file.modtime = modtime; -- file.options |= options; -- } -- InputStream getInputStream() throws IOException { -- if (jf != null) -- return jf.getInputStream(je); -- else -- return new FileInputStream(f); -- } -+ class InFile { -+ final String name; -+ final JarFile jf; -+ final JarEntry je; -+ final File f; -+ int modtime = Constants.NO_MODTIME; -+ int options; -+ InFile(String name) { -+ this.name = Utils.getJarEntryName(name); -+ this.f = new File(name); -+ this.jf = null; -+ this.je = null; -+ int timeSecs = getModtime(f.lastModified()); -+ if (keepModtime && timeSecs != Constants.NO_MODTIME) { -+ this.modtime = timeSecs; -+ } else if (latestModtime && timeSecs > pkg.default_modtime) { -+ pkg.default_modtime = timeSecs; -+ } -+ } -+ InFile(JarFile jf, JarEntry je) { -+ this.name = Utils.getJarEntryName(je.getName()); -+ this.f = null; -+ this.jf = jf; -+ this.je = je; -+ int timeSecs = getModtime(je.getTime()); -+ if (keepModtime && timeSecs != Constants.NO_MODTIME) { -+ this.modtime = timeSecs; -+ } else if (latestModtime && timeSecs > pkg.default_modtime) { -+ pkg.default_modtime = timeSecs; -+ } -+ if (keepDeflateHint && je.getMethod() == JarEntry.DEFLATED) { -+ options |= Constants.FO_DEFLATE_HINT; -+ } -+ } -+ InFile(JarEntry je) { -+ this(null, je); -+ } -+ long getInputLength() { -+ long len = (je != null)? je.getSize(): f.length(); -+ assert(len >= 0) : this+".len="+len; -+ // Bump size by pathname length and modtime/def-hint bytes. -+ return Math.max(0, len) + name.length() + 5; -+ } -+ int getModtime(long timeMillis) { -+ // Convert milliseconds to seconds. -+ long seconds = (timeMillis+500) / 1000; -+ if ((int)seconds == seconds) { -+ return (int)seconds; -+ } else { -+ Utils.log.warning("overflow in modtime for "+f); -+ return Constants.NO_MODTIME; -+ } -+ } -+ void copyTo(Package.File file) { -+ if (modtime != Constants.NO_MODTIME) -+ file.modtime = modtime; -+ file.options |= options; -+ } -+ InputStream getInputStream() throws IOException { -+ if (jf != null) -+ return jf.getInputStream(je); -+ else -+ return new FileInputStream(f); -+ } - -- public String toString() { -- return name; -- } -- } -+ public String toString() { -+ return name; -+ } -+ } - -- private int nread = 0; // used only if (verbose > 0) -- private void noteRead(InFile f) { -- nread++; -- if (verbose > 2) -- Utils.log.fine("...read "+f.name); -- if (verbose > 0 && (nread % 1000) == 0) -- Utils.log.info("Have read "+nread+" files..."); -- } -+ private int nread = 0; // used only if (verbose > 0) -+ private void noteRead(InFile f) { -+ nread++; -+ if (verbose > 2) -+ Utils.log.fine("...read "+f.name); -+ if (verbose > 0 && (nread % 1000) == 0) -+ Utils.log.info("Have read "+nread+" files..."); -+ } - -- void run(JarInputStream in, OutputStream out) throws IOException { -- // First thing we do is get the manifest, as JIS does -- // not provide the Manifest as an entry. -- if (in.getManifest() != null) { -- ByteArrayOutputStream tmp = new ByteArrayOutputStream(); -- in.getManifest().write(tmp); -- InputStream tmpIn = new ByteArrayInputStream(tmp.toByteArray()); -- pkg.addFile(readFile(JarFile.MANIFEST_NAME, tmpIn)); -- } -- for (JarEntry je; (je = in.getNextJarEntry()) != null; ) { -- InFile inFile = new InFile(je); -+ void run(JarInputStream in, OutputStream out) throws IOException { -+ // First thing we do is get the manifest, as JIS does -+ // not provide the Manifest as an entry. -+ if (in.getManifest() != null) { -+ ByteArrayOutputStream tmp = new ByteArrayOutputStream(); -+ in.getManifest().write(tmp); -+ InputStream tmpIn = new ByteArrayInputStream(tmp.toByteArray()); -+ pkg.addFile(readFile(JarFile.MANIFEST_NAME, tmpIn)); -+ } -+ for (JarEntry je; (je = in.getNextJarEntry()) != null; ) { -+ InFile inFile = new InFile(je); - -- String name = inFile.name; -- Package.File bits = readFile(name, in); -- Package.File file = null; -- // (5078608) : discount the resource files in META-INF -- // from segment computation. -- long inflen = (isMetaInfFile(name)) ? 0L : -- inFile.getInputLength(); -+ String name = inFile.name; -+ Package.File bits = readFile(name, in); -+ Package.File file = null; -+ // (5078608) : discount the resource files in META-INF -+ // from segment computation. -+ long inflen = (isMetaInfFile(name)) ? 0L : -+ inFile.getInputLength(); - -- if ((segmentSize += inflen) > segmentLimit) { -- segmentSize -= inflen; -- int nextCount = -1; // don't know; it's a stream -- flushPartial(out, nextCount); -- } -- if (verbose > 1) -- Utils.log.fine("Reading " + name); -+ if ((segmentSize += inflen) > segmentLimit) { -+ segmentSize -= inflen; -+ int nextCount = -1; // don't know; it's a stream -+ flushPartial(out, nextCount); -+ } -+ if (verbose > 1) -+ Utils.log.fine("Reading " + name); - -- assert(je.isDirectory() == name.endsWith("/")); -+ assert(je.isDirectory() == name.endsWith("/")); - -- if (isClassFile(name)) { -- file = readClass(name, bits.getInputStream()); -- } -- if (file == null) { -- file = bits; -- pkg.addFile(file); -- } -- inFile.copyTo(file); -- noteRead(inFile); -- } -- flushAll(out); -- } -+ if (isClassFile(name)) { -+ file = readClass(name, bits.getInputStream()); -+ } -+ if (file == null) { -+ file = bits; -+ pkg.addFile(file); -+ } -+ inFile.copyTo(file); -+ noteRead(inFile); -+ } -+ flushAll(out); -+ } - -- void run(JarFile in, OutputStream out) throws IOException { -- List inFiles = scanJar(in); -+ void run(JarFile in, OutputStream out) throws IOException { -+ List inFiles = scanJar(in); - -- if (verbose > 0) -- Utils.log.info("Reading " + inFiles.size() + " files..."); -+ if (verbose > 0) -+ Utils.log.info("Reading " + inFiles.size() + " files..."); - -- int numDone = 0; -- for (Iterator i = inFiles.iterator(); i.hasNext(); ) { -- InFile inFile = (InFile) i.next(); -- String name = inFile.name; -- // (5078608) : discount the resource files completely from segmenting -- long inflen = (isMetaInfFile(name)) ? 0L : -- inFile.getInputLength() ; -- if ((segmentSize += inflen) > segmentLimit) { -- segmentSize -= inflen; -- // Estimate number of remaining segments: -- float filesDone = numDone+1; -- float segsDone = segmentCount+1; -- float filesToDo = inFiles.size() - filesDone; -- float segsToDo = filesToDo * (segsDone/filesDone); -- if (verbose > 1) -- Utils.log.fine("Estimated segments to do: "+segsToDo); -- flushPartial(out, (int) Math.ceil(segsToDo)); -- } -- InputStream strm = inFile.getInputStream(); -- if (verbose > 1) -- Utils.log.fine("Reading " + name); -- Package.File file = null; -- if (isClassFile(name)) { -- file = readClass(name, strm); -- if (file == null) { -- strm.close(); -- strm = inFile.getInputStream(); -- } -- } -- if (file == null) { -- file = readFile(name, strm); -- pkg.addFile(file); -- } -- inFile.copyTo(file); -- strm.close(); // tidy up -- noteRead(inFile); -- numDone += 1; -- } -- flushAll(out); -- } -+ int numDone = 0; -+ for (Iterator i = inFiles.iterator(); i.hasNext(); ) { -+ InFile inFile = (InFile) i.next(); -+ String name = inFile.name; -+ // (5078608) : discount the resource files completely from segmenting -+ long inflen = (isMetaInfFile(name)) ? 0L : -+ inFile.getInputLength() ; -+ if ((segmentSize += inflen) > segmentLimit) { -+ segmentSize -= inflen; -+ // Estimate number of remaining segments: -+ float filesDone = numDone+1; -+ float segsDone = segmentCount+1; -+ float filesToDo = inFiles.size() - filesDone; -+ float segsToDo = filesToDo * (segsDone/filesDone); -+ if (verbose > 1) -+ Utils.log.fine("Estimated segments to do: "+segsToDo); -+ flushPartial(out, (int) Math.ceil(segsToDo)); -+ } -+ InputStream strm = inFile.getInputStream(); -+ if (verbose > 1) -+ Utils.log.fine("Reading " + name); -+ Package.File file = null; -+ if (isClassFile(name)) { -+ file = readClass(name, strm); -+ if (file == null) { -+ strm.close(); -+ strm = inFile.getInputStream(); -+ } -+ } -+ if (file == null) { -+ file = readFile(name, strm); -+ pkg.addFile(file); -+ } -+ inFile.copyTo(file); -+ strm.close(); // tidy up -+ noteRead(inFile); -+ numDone += 1; -+ } -+ flushAll(out); -+ } - -- Package.File readClass(String fname, InputStream in) throws IOException { -- Package.Class cls = pkg.new Class(fname); -- in = new BufferedInputStream(in); -- ClassReader reader = new ClassReader(cls, in); -- reader.setAttrDefs(attrDefs); -- reader.setAttrCommands(attrCommands); -- reader.unknownAttrCommand = unknownAttrCommand; -- try { -- reader.read(); -- } catch (Attribute.FormatException ee) { -- // He passed up the category to us in layout. -- if (ee.layout.equals(Pack200.Packer.PASS)) { -- Utils.log.warning("Passing class file uncompressed due to unrecognized attribute: "+fname); -- Utils.log.info(ee.toString()); -- return null; -- } -- // Otherwise, it must be an error. -- throw ee; -- } -- pkg.addClass(cls); -- return cls.file; -- } -+ Package.File readClass(String fname, InputStream in) throws IOException { -+ Package.Class cls = pkg.new Class(fname); -+ in = new BufferedInputStream(in); -+ ClassReader reader = new ClassReader(cls, in); -+ reader.setAttrDefs(attrDefs); -+ reader.setAttrCommands(attrCommands); -+ reader.unknownAttrCommand = unknownAttrCommand; -+ try { -+ reader.read(); -+ } catch (Attribute.FormatException ee) { -+ // He passed up the category to us in layout. -+ if (ee.layout.equals(Pack200.Packer.PASS)) { -+ Utils.log.warning("Passing class file uncompressed due to unrecognized attribute: "+fname); -+ Utils.log.info(ee.toString()); -+ return null; -+ } -+ // Otherwise, it must be an error. -+ throw ee; -+ } -+ pkg.addClass(cls); -+ return cls.file; -+ } - -- // Read raw data. -- Package.File readFile(String fname, InputStream in) throws IOException { -+ // Read raw data. -+ Package.File readFile(String fname, InputStream in) throws IOException { - -- Package.File file = pkg.new File(fname); -- file.readFrom(in); -- if (file.isDirectory() && file.getFileLength() != 0) -- throw new IllegalArgumentException("Non-empty directory: "+file.getFileName()); -- return file; -- } -+ Package.File file = pkg.new File(fname); -+ file.readFrom(in); -+ if (file.isDirectory() && file.getFileLength() != 0) -+ throw new IllegalArgumentException("Non-empty directory: "+file.getFileName()); -+ return file; -+ } - -- void flushPartial(OutputStream out, int nextCount) throws IOException { -- if (pkg.files.size() == 0 && pkg.classes.size() == 0) { -- return; // do not flush an empty segment -- } -- flushPackage(out, Math.max(1, nextCount)); -- _props.setInteger(Pack200.Packer.PROGRESS, 25); -- // In case there will be another segment: -- makeNextPackage(); -- segmentCount += 1; -- segmentTotalSize += segmentSize; -- segmentSize = 0; -- } -+ void flushPartial(OutputStream out, int nextCount) throws IOException { -+ if (pkg.files.size() == 0 && pkg.classes.size() == 0) { -+ return; // do not flush an empty segment -+ } -+ flushPackage(out, Math.max(1, nextCount)); -+ _props.setInteger(Pack200.Packer.PROGRESS, 25); -+ // In case there will be another segment: -+ makeNextPackage(); -+ segmentCount += 1; -+ segmentTotalSize += segmentSize; -+ segmentSize = 0; -+ } - -- void flushAll(OutputStream out) throws IOException { -- _props.setInteger(Pack200.Packer.PROGRESS, 50); -- flushPackage(out, 0); -- out.flush(); -- _props.setInteger(Pack200.Packer.PROGRESS, 100); -- segmentCount += 1; -- segmentTotalSize += segmentSize; -- segmentSize = 0; -- if (verbose > 0 && segmentCount > 1) { -- Utils.log.info("Transmitted " -- +segmentTotalSize+" input bytes in " -- +segmentCount+" segments totaling " -- +totalOutputSize+" bytes"); -- } -- } -+ void flushAll(OutputStream out) throws IOException { -+ _props.setInteger(Pack200.Packer.PROGRESS, 50); -+ flushPackage(out, 0); -+ out.flush(); -+ _props.setInteger(Pack200.Packer.PROGRESS, 100); -+ segmentCount += 1; -+ segmentTotalSize += segmentSize; -+ segmentSize = 0; -+ if (verbose > 0 && segmentCount > 1) { -+ Utils.log.info("Transmitted " -+ +segmentTotalSize+" input bytes in " -+ +segmentCount+" segments totaling " -+ +totalOutputSize+" bytes"); -+ } -+ } - - -- /** Write all information in the current package segment -- * to the output stream. -- */ -- void flushPackage(OutputStream out, int nextCount) throws IOException { -- int nfiles = pkg.files.size(); -- if (!keepFileOrder) { -- // Keeping the order of classes costs about 1% -- // Keeping the order of all files costs something more. -- if (verbose > 1) Utils.log.fine("Reordering files."); -- boolean stripDirectories = true; -- pkg.reorderFiles(keepClassOrder, stripDirectories); -- } else { -- // Package builder must have created a stub for each class. -- assert(pkg.files.containsAll(pkg.getClassStubs())); -- // Order of stubs in file list must agree with classes. -- List res = pkg.files; -- assert((res = new ArrayList(pkg.files)) -- .retainAll(pkg.getClassStubs()) || true); -- assert(res.equals(pkg.getClassStubs())); -- } -- pkg.trimStubs(); -+ /** Write all information in the current package segment -+ * to the output stream. -+ */ -+ void flushPackage(OutputStream out, int nextCount) throws IOException { -+ int nfiles = pkg.files.size(); -+ if (!keepFileOrder) { -+ // Keeping the order of classes costs about 1% -+ // Keeping the order of all files costs something more. -+ if (verbose > 1) Utils.log.fine("Reordering files."); -+ boolean stripDirectories = true; -+ pkg.reorderFiles(keepClassOrder, stripDirectories); -+ } else { -+ // Package builder must have created a stub for each class. -+ assert(pkg.files.containsAll(pkg.getClassStubs())); -+ // Order of stubs in file list must agree with classes. -+ List res = pkg.files; -+ assert((res = new ArrayList(pkg.files)) -+ .retainAll(pkg.getClassStubs()) || true); -+ assert(res.equals(pkg.getClassStubs())); -+ } -+ pkg.trimStubs(); - -- // Do some stripping, maybe. -- if (_props.getBoolean(Utils.COM_PREFIX+"strip.debug")) pkg.stripAttributeKind("Debug"); -- if (_props.getBoolean(Utils.COM_PREFIX+"strip.compile")) pkg.stripAttributeKind("Compile"); -- if (_props.getBoolean(Utils.COM_PREFIX+"strip.constants")) pkg.stripAttributeKind("Constant"); -- if (_props.getBoolean(Utils.COM_PREFIX+"strip.exceptions")) pkg.stripAttributeKind("Exceptions"); -- if (_props.getBoolean(Utils.COM_PREFIX+"strip.innerclasses")) pkg.stripAttributeKind("InnerClasses"); -+ // Do some stripping, maybe. -+ if (_props.getBoolean(Utils.COM_PREFIX+"strip.debug")) pkg.stripAttributeKind("Debug"); -+ if (_props.getBoolean(Utils.COM_PREFIX+"strip.compile")) pkg.stripAttributeKind("Compile"); -+ if (_props.getBoolean(Utils.COM_PREFIX+"strip.constants")) pkg.stripAttributeKind("Constant"); -+ if (_props.getBoolean(Utils.COM_PREFIX+"strip.exceptions")) pkg.stripAttributeKind("Exceptions"); -+ if (_props.getBoolean(Utils.COM_PREFIX+"strip.innerclasses")) pkg.stripAttributeKind("InnerClasses"); - -- // Must choose an archive version; PackageWriter does not. -- if (pkg.package_majver <= 0) pkg.choosePackageVersion(); -+ // Must choose an archive version; PackageWriter does not. -+ if (pkg.package_majver <= 0) pkg.choosePackageVersion(); - -- PackageWriter pw = new PackageWriter(pkg, out); -- pw.archiveNextCount = nextCount; -- pw.write(); -- out.flush(); -- if (verbose > 0) { -- long outSize = pw.archiveSize0+pw.archiveSize1; -- totalOutputSize += outSize; -- long inSize = segmentSize; -- Utils.log.info("Transmitted " -- +nfiles+" files of " -- +inSize+" input bytes in a segment of " -- +outSize+" bytes"); -- } -- } -+ PackageWriter pw = new PackageWriter(pkg, out); -+ pw.archiveNextCount = nextCount; -+ pw.write(); -+ out.flush(); -+ if (verbose > 0) { -+ long outSize = pw.archiveSize0+pw.archiveSize1; -+ totalOutputSize += outSize; -+ long inSize = segmentSize; -+ Utils.log.info("Transmitted " -+ +nfiles+" files of " -+ +inSize+" input bytes in a segment of " -+ +outSize+" bytes"); -+ } -+ } - -- List scanJar(JarFile jf) throws IOException { -- // Collect jar entries, preserving order. -- List inFiles = new ArrayList(); -- for (Enumeration e = jf.entries(); e.hasMoreElements(); ) { -- JarEntry je = (JarEntry) e.nextElement(); -- InFile inFile = new InFile(jf, je); -- assert(je.isDirectory() == inFile.name.endsWith("/")); -- inFiles.add(inFile); -- } -- return inFiles; -- } -+ List scanJar(JarFile jf) throws IOException { -+ // Collect jar entries, preserving order. -+ List inFiles = new ArrayList(); -+ for (Enumeration e = jf.entries(); e.hasMoreElements(); ) { -+ JarEntry je = (JarEntry) e.nextElement(); -+ InFile inFile = new InFile(jf, je); -+ assert(je.isDirectory() == inFile.name.endsWith("/")); -+ inFiles.add(inFile); -+ } -+ return inFiles; -+ } - } - } -+ -+ -+ -+ -+ -+ -+ -diff --git a/src/share/classes/com/sun/java/util/jar/pack/UnpackerImpl.java b/src/share/classes/com/sun/java/util/jar/pack/UnpackerImpl.java ---- openjdk/jdk/src/share/classes/com/sun/java/util/jar/pack/UnpackerImpl.java -+++ openjdk/jdk/src/share/classes/com/sun/java/util/jar/pack/UnpackerImpl.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -41,53 +41,53 @@ import java.beans.PropertyChangeEvent; - - - public class UnpackerImpl implements Pack200.Unpacker { -- -- -+ -+ - /** - * Register a listener for changes to options. - * @param listener An object to be invoked when a property is changed. - */ - public void addPropertyChangeListener(PropertyChangeListener listener) { -- _props.addListener(listener); -+ _props.addListener(listener); - } -- -- -+ -+ - /** - * Remove a listener for the PropertyChange event. - * @param listener The PropertyChange listener to be removed. - */ - public void removePropertyChangeListener(PropertyChangeListener listener) { -- _props.removeListener(listener); -+ _props.removeListener(listener); - } -- -+ - public UnpackerImpl() { -- _props = new PropMap(); -- //_props.getProperty() consults defaultProps invisibly. -- //_props.putAll(defaultProps); -+ _props = new PropMap(); -+ //_props.getProperty() consults defaultProps invisibly. -+ //_props.putAll(defaultProps); - } -- -+ - // Private stuff. - final PropMap _props; - -- -+ - /** - * Get the set of options for the pack and unpack engines. - * @return A sorted association of option key strings to option values. - */ - public SortedMap properties() { -- return _props; -+ return _props; - } -- -+ - // Back-pointer to NativeUnpacker, when active. - Object _nunp; -- -- -+ -+ - public String toString() { -- return Utils.getVersionString(); -+ return Utils.getVersionString(); - } -- -+ - //Driver routines -- -+ - // The unpack worker... - /** - * Takes a packed-stream InputStream, and writes to a JarOutputStream. Internally -@@ -99,36 +99,36 @@ public class UnpackerImpl implements Pac - * @param out a JarOutputStream. - * @exception IOException if an error is encountered. - */ -- public void unpack(InputStream in0, JarOutputStream out) throws IOException { -- assert(Utils.currentInstance.get() == null); -- TimeZone tz = (_props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE)) ? null : -- TimeZone.getDefault(); -- -- try { -- Utils.currentInstance.set(this); -- if (tz != null) TimeZone.setDefault(TimeZone.getTimeZone("UTC")); -- final int verbose = _props.getInteger(Utils.DEBUG_VERBOSE); -- BufferedInputStream in = new BufferedInputStream(in0); -- if (Utils.isJarMagic(Utils.readMagic(in))) { -- if (verbose > 0) -- Utils.log.info("Copying unpacked JAR file..."); -- Utils.copyJarFile(new JarInputStream(in), out); -- } else if (_props.getBoolean(Utils.DEBUG_DISABLE_NATIVE)) { -- (new DoUnpack()).run(in, out); -- in.close(); -- Utils.markJarFile(out); -- } else { -- (new NativeUnpack(this)).run(in, out); -- in.close(); -- Utils.markJarFile(out); -- } -- } finally { -- _nunp = null; -- Utils.currentInstance.set(null); -- if (tz != null) TimeZone.setDefault(tz); -- } -+ public synchronized void unpack(InputStream in0, JarOutputStream out) throws IOException { -+ assert(Utils.currentInstance.get() == null); -+ TimeZone tz = (_props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE)) ? null : -+ TimeZone.getDefault(); -+ -+ try { -+ Utils.currentInstance.set(this); -+ if (tz != null) TimeZone.setDefault(TimeZone.getTimeZone("UTC")); -+ final int verbose = _props.getInteger(Utils.DEBUG_VERBOSE); -+ BufferedInputStream in = new BufferedInputStream(in0); -+ if (Utils.isJarMagic(Utils.readMagic(in))) { -+ if (verbose > 0) -+ Utils.log.info("Copying unpacked JAR file..."); -+ Utils.copyJarFile(new JarInputStream(in), out); -+ } else if (_props.getBoolean(Utils.DEBUG_DISABLE_NATIVE)) { -+ (new DoUnpack()).run(in, out); -+ in.close(); -+ Utils.markJarFile(out); -+ } else { -+ (new NativeUnpack(this)).run(in, out); -+ in.close(); -+ Utils.markJarFile(out); -+ } -+ } finally { -+ _nunp = null; -+ Utils.currentInstance.set(null); -+ if (tz != null) TimeZone.setDefault(tz); -+ } - } -- -+ - /** - * Takes an input File containing the pack file, and generates a JarOutputStream. - * <p> -@@ -137,121 +137,121 @@ public class UnpackerImpl implements Pac - * @param out a JarOutputStream. - * @exception IOException if an error is encountered. - */ -- public void unpack(File in, JarOutputStream out) throws IOException { -- // Use the stream-based implementation. -- // %%% Reconsider if native unpacker learns to memory-map the file. -- FileInputStream instr = new FileInputStream(in); -- unpack(instr, out); -- if (_props.getBoolean(Utils.UNPACK_REMOVE_PACKFILE)) { -- in.delete(); -- } -+ public synchronized void unpack(File in, JarOutputStream out) throws IOException { -+ // Use the stream-based implementation. -+ // %%% Reconsider if native unpacker learns to memory-map the file. -+ FileInputStream instr = new FileInputStream(in); -+ unpack(instr, out); -+ if (_props.getBoolean(Utils.UNPACK_REMOVE_PACKFILE)) { -+ in.delete(); -+ } - } -- -+ - private class DoUnpack { -- final int verbose = _props.getInteger(Utils.DEBUG_VERBOSE); -- -- { -- _props.setInteger(Pack200.Unpacker.PROGRESS, 0); -- } -- -- // Here's where the bits are read from disk: -- final Package pkg = new Package(); -- -- final boolean keepModtime -- = Pack200.Packer.KEEP.equals(_props.getProperty(Utils.UNPACK_MODIFICATION_TIME, Pack200.Packer.KEEP)); -- final boolean keepDeflateHint -- = Pack200.Packer.KEEP.equals(_props.getProperty(Pack200.Unpacker.DEFLATE_HINT, Pack200.Packer.KEEP)); -- final int modtime; -- final boolean deflateHint; -- { -- if (!keepModtime) { -- modtime = _props.getTime(Utils.UNPACK_MODIFICATION_TIME); -- } else { -- modtime = pkg.default_modtime; -- } -- -- deflateHint = (keepDeflateHint) ? false : -- _props.getBoolean(java.util.jar.Pack200.Unpacker.DEFLATE_HINT); -- } -- -- // Checksum apparatus. -- final CRC32 crc = new CRC32(); -- final ByteArrayOutputStream bufOut = new ByteArrayOutputStream(); -- final OutputStream crcOut = new CheckedOutputStream(bufOut, crc); -- -- public void run(BufferedInputStream in, JarOutputStream out) throws IOException { -- if (verbose > 0) { -- _props.list(System.out); -- } -- for (int seg = 1; ; seg++) { -- unpackSegment(in, out); -- -- // Try to get another segment. -- if (!Utils.isPackMagic(Utils.readMagic(in))) break; -- if (verbose > 0) -- Utils.log.info("Finished segment #"+seg); -- } -- } -- -- private void unpackSegment(InputStream in, JarOutputStream out) throws IOException { -- _props.setProperty(java.util.jar.Pack200.Unpacker.PROGRESS,"0"); -- // Process the output directory or jar output. -- new PackageReader(pkg, in).read(); -- -- if (_props.getBoolean("unpack.strip.debug")) pkg.stripAttributeKind("Debug"); -- if (_props.getBoolean("unpack.strip.compile")) pkg.stripAttributeKind("Compile"); -- _props.setProperty(java.util.jar.Pack200.Unpacker.PROGRESS,"50"); -- pkg.ensureAllClassFiles(); -- // Now write out the files. -- HashSet classesToWrite = new HashSet(pkg.getClasses()); -- for (Iterator i = pkg.getFiles().iterator(); i.hasNext(); ) { -- Package.File file = (Package.File) i.next(); -- String name = file.nameString; -- JarEntry je = new JarEntry(Utils.getJarEntryName(name)); -- boolean deflate; -- -- deflate = (keepDeflateHint) ? (((file.options & Constants.FO_DEFLATE_HINT) != 0) || -- ((pkg.default_options & Constants.AO_DEFLATE_HINT) != 0)) : -- deflateHint; -- -- boolean needCRC = !deflate; // STORE mode requires CRC -- -- if (needCRC) crc.reset(); -- bufOut.reset(); -- if (file.isClassStub()) { -- Package.Class cls = file.getStubClass(); -- assert(cls != null); -- new ClassWriter(cls, needCRC ? crcOut : bufOut).write(); -- classesToWrite.remove(cls); // for an error check -- } else { -- // collect data & maybe CRC -- file.writeTo(needCRC ? crcOut : bufOut); -- } -- je.setMethod(deflate ? JarEntry.DEFLATED : JarEntry.STORED); -- if (needCRC) { -- if (verbose > 0) -- Utils.log.info("stored size="+bufOut.size()+" and crc="+crc.getValue()); -- -- je.setMethod(JarEntry.STORED); -- je.setSize(bufOut.size()); -- je.setCrc(crc.getValue()); -- } -- if (keepModtime) { -- je.setTime(file.modtime); -- // Convert back to milliseconds -- je.setTime((long)file.modtime * 1000); -- } else { -- je.setTime((long)modtime * 1000); -- } -- out.putNextEntry(je); -- bufOut.writeTo(out); -- out.closeEntry(); -- if (verbose > 0) -- Utils.log.info("Writing "+Utils.zeString((ZipEntry)je)); -- } -- assert(classesToWrite.isEmpty()); -- _props.setProperty(java.util.jar.Pack200.Unpacker.PROGRESS,"100"); -- pkg.reset(); // reset for the next segment, if any -- } -+ final int verbose = _props.getInteger(Utils.DEBUG_VERBOSE); -+ -+ { -+ _props.setInteger(Pack200.Unpacker.PROGRESS, 0); -+ } -+ -+ // Here's where the bits are read from disk: -+ final Package pkg = new Package(); -+ -+ final boolean keepModtime -+ = Pack200.Packer.KEEP.equals(_props.getProperty(Utils.UNPACK_MODIFICATION_TIME, Pack200.Packer.KEEP)); -+ final boolean keepDeflateHint -+ = Pack200.Packer.KEEP.equals(_props.getProperty(Pack200.Unpacker.DEFLATE_HINT, Pack200.Packer.KEEP)); -+ final int modtime; -+ final boolean deflateHint; -+ { -+ if (!keepModtime) { -+ modtime = _props.getTime(Utils.UNPACK_MODIFICATION_TIME); -+ } else { -+ modtime = pkg.default_modtime; -+ } -+ -+ deflateHint = (keepDeflateHint) ? false : -+ _props.getBoolean(java.util.jar.Pack200.Unpacker.DEFLATE_HINT); -+ } -+ -+ // Checksum apparatus. -+ final CRC32 crc = new CRC32(); -+ final ByteArrayOutputStream bufOut = new ByteArrayOutputStream(); -+ final OutputStream crcOut = new CheckedOutputStream(bufOut, crc); -+ -+ public void run(BufferedInputStream in, JarOutputStream out) throws IOException { -+ if (verbose > 0) { -+ _props.list(System.out); -+ } -+ for (int seg = 1; ; seg++) { -+ unpackSegment(in, out); -+ -+ // Try to get another segment. -+ if (!Utils.isPackMagic(Utils.readMagic(in))) break; -+ if (verbose > 0) -+ Utils.log.info("Finished segment #"+seg); -+ } -+ } -+ -+ private void unpackSegment(InputStream in, JarOutputStream out) throws IOException { -+ _props.setProperty(java.util.jar.Pack200.Unpacker.PROGRESS,"0"); -+ // Process the output directory or jar output. -+ new PackageReader(pkg, in).read(); -+ -+ if (_props.getBoolean("unpack.strip.debug")) pkg.stripAttributeKind("Debug"); -+ if (_props.getBoolean("unpack.strip.compile")) pkg.stripAttributeKind("Compile"); -+ _props.setProperty(java.util.jar.Pack200.Unpacker.PROGRESS,"50"); -+ pkg.ensureAllClassFiles(); -+ // Now write out the files. -+ HashSet classesToWrite = new HashSet(pkg.getClasses()); -+ for (Iterator i = pkg.getFiles().iterator(); i.hasNext(); ) { -+ Package.File file = (Package.File) i.next(); -+ String name = file.nameString; -+ JarEntry je = new JarEntry(Utils.getJarEntryName(name)); -+ boolean deflate; -+ -+ deflate = (keepDeflateHint) ? (((file.options & Constants.FO_DEFLATE_HINT) != 0) || -+ ((pkg.default_options & Constants.AO_DEFLATE_HINT) != 0)) : -+ deflateHint; -+ -+ boolean needCRC = !deflate; // STORE mode requires CRC -+ -+ if (needCRC) crc.reset(); -+ bufOut.reset(); -+ if (file.isClassStub()) { -+ Package.Class cls = file.getStubClass(); -+ assert(cls != null); -+ new ClassWriter(cls, needCRC ? crcOut : bufOut).write(); -+ classesToWrite.remove(cls); // for an error check -+ } else { -+ // collect data & maybe CRC -+ file.writeTo(needCRC ? crcOut : bufOut); -+ } -+ je.setMethod(deflate ? JarEntry.DEFLATED : JarEntry.STORED); -+ if (needCRC) { -+ if (verbose > 0) -+ Utils.log.info("stored size="+bufOut.size()+" and crc="+crc.getValue()); -+ -+ je.setMethod(JarEntry.STORED); -+ je.setSize(bufOut.size()); -+ je.setCrc(crc.getValue()); -+ } -+ if (keepModtime) { -+ je.setTime(file.modtime); -+ // Convert back to milliseconds -+ je.setTime((long)file.modtime * 1000); -+ } else { -+ je.setTime((long)modtime * 1000); -+ } -+ out.putNextEntry(je); -+ bufOut.writeTo(out); -+ out.closeEntry(); -+ if (verbose > 0) -+ Utils.log.info("Writing "+Utils.zeString((ZipEntry)je)); -+ } -+ assert(classesToWrite.isEmpty()); -+ _props.setProperty(java.util.jar.Pack200.Unpacker.PROGRESS,"100"); -+ pkg.reset(); // reset for the next segment, if any -+ } - } - } -diff --git a/src/share/native/com/sun/java/util/jar/pack/bands.cpp b/src/share/native/com/sun/java/util/jar/pack/bands.cpp ---- openjdk/jdk/src/share/native/com/sun/java/util/jar/pack/bands.cpp -+++ openjdk/jdk/src/share/native/com/sun/java/util/jar/pack/bands.cpp -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2002, 2009, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -81,11 +81,11 @@ void band::readData(int expectedLength) - assert(defc->B() > 1 && defc->L() > 0); - // must have already read from previous band: - assert(bn >= BAND_LIMIT || bn <= 0 -- || bn == e_cp_Utf8_big_chars -- || endsWith(name, "_lo") // preceded by _hi conditional band -- || bn == e_file_options // preceded by conditional band -- || u->rp == u->all_bands[bn-1].maxRP() -- || u->all_bands[bn-1].defc == null); -+ || bn == e_cp_Utf8_big_chars -+ || endsWith(name, "_lo") // preceded by _hi conditional band -+ || bn == e_file_options // preceded by conditional band -+ || u->rp == u->all_bands[bn-1].maxRP() -+ || u->all_bands[bn-1].defc == null); - - value_stream xvs; - coding* valc = defc; -@@ -136,7 +136,7 @@ void band::readData(int expectedLength) - - #ifndef PRODUCT - printcr(3,"readFrom %s at %p [%d values, %d bytes, cp=%d/%d]", -- (name?name:"(band)"), minRP(), length, size(), cp1, cp2); -+ (name?name:"(band)"), minRP(), length, size(), cp1, cp2); - if (u->verbose_bands || u->verbose >= 4) dump(); - - if (ix != null && u->verbose != 0 && length > 0) { -@@ -187,10 +187,14 @@ void band::setIndexByTag(byte tag) { - - entry* band::getRefCommon(cpindex* ix_, bool nullOKwithCaller) { - CHECK_0; -+ if (ix_ == NULL) { -+ abort("no index"); -+ return NULL; -+ } - assert(ix_->ixTag == ixTag -- || (ixTag == CONSTANT_Literal -- && ix_->ixTag >= CONSTANT_Integer -- && ix_->ixTag <= CONSTANT_String)); -+ || (ixTag == CONSTANT_Literal -+ && ix_->ixTag >= CONSTANT_Integer -+ && ix_->ixTag <= CONSTANT_String)); - int n = vs[0].getInt() - nullOK; - // Note: band-local nullOK means null encodes as 0. - // But nullOKwithCaller means caller is willing to tolerate a null. -@@ -245,9 +249,9 @@ int band::getIntCount(int tag) { - hist0 = U_NEW(int, (HIST0_MAX - HIST0_MIN)+1); - CHECK_0; - for (int k = length; k > 0; k--) { -- int x = vs[0].getInt(); -- if (x >= HIST0_MIN && x <= HIST0_MAX) -- hist0[x - HIST0_MIN] += 1; -+ int x = vs[0].getInt(); -+ if (x >= HIST0_MIN && x <= HIST0_MAX) -+ hist0[x - HIST0_MIN] += 1; - } - rewind(); - } -@@ -262,7 +266,7 @@ int band::getIntCount(int tag) { - } - - #define INDEX_INIT(tag, nullOK, subindex) \ -- ((tag) + (subindex)*SUBINDEX_BIT + (nullOK)*256) -+ ((tag) + (subindex)*SUBINDEX_BIT + (nullOK)*256) - - #define INDEX(tag) INDEX_INIT(tag, 0, 0) - #define NULL_OR_INDEX(tag) INDEX_INIT(tag, 1, 0) -@@ -437,13 +441,13 @@ const band_init all_band_inits[] = { - {0} - }; - #define NUM_BAND_INITS \ -- (sizeof(all_band_inits)/sizeof(all_band_inits[0])) -+ (sizeof(all_band_inits)/sizeof(all_band_inits[0])) - - band* band::makeBands(unpacker* u) { - band* all_bands = U_NEW(band, BAND_LIMIT); - for (int i = 0; i < BAND_LIMIT; i++) { - assert((byte*)&all_band_inits[i+1] -- < (byte*)all_band_inits+sizeof(all_band_inits)); -+ < (byte*)all_band_inits+sizeof(all_band_inits)); - const band_init& bi = all_band_inits[i]; - band& b = all_bands[i]; - coding* defc = coding::findBySpec(bi.defc); -@@ -472,3 +476,5 @@ void band::initIndexes(unpacker* u) { - } - } - } -+ -+ -diff --git a/src/share/native/com/sun/java/util/jar/pack/bands.h b/src/share/native/com/sun/java/util/jar/pack/bands.h ---- openjdk/jdk/src/share/native/com/sun/java/util/jar/pack/bands.h -+++ openjdk/jdk/src/share/native/com/sun/java/util/jar/pack/bands.h -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2002, 2005, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -22,7 +22,7 @@ - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -- -+ - // -*- C++ -*- - struct entry; - struct cpindex; -@@ -50,7 +50,7 @@ struct band { - - // properties for attribute layout elements: - byte le_kind; // EK_XXX -- byte le_bci; // 0,EK_BCI,EK_BCD,EK_BCO -+ byte le_bci; // 0,EK_BCI,EK_BCD,EK_BCO - byte le_back; // ==EF_BACK - byte le_len; // 0,1,2,4 (size in classfile), or call addr - band** le_body; // body of repl, union, call (null-terminated) -@@ -101,8 +101,8 @@ struct band { - - int getByte() { assert(ix == null); return vs[0].getByte(); } - int getInt() { assert(ix == null); return vs[0].getInt(); } -- entry* getRefN() { assert(ix != null); return getRefCommon(ix, true); } -- entry* getRef() { assert(ix != null); return getRefCommon(ix, false); } -+ entry* getRefN() { return getRefCommon(ix, true); } -+ entry* getRef() { return getRefCommon(ix, false); } - entry* getRefUsing(cpindex* ix2) - { assert(ix == null); return getRefCommon(ix2, true); } - entry* getRefCommon(cpindex* ix, bool nullOK); -diff --git a/src/share/native/com/sun/java/util/jar/pack/defines.h b/src/share/native/com/sun/java/util/jar/pack/defines.h ---- openjdk/jdk/src/share/native/com/sun/java/util/jar/pack/defines.h -+++ openjdk/jdk/src/share/native/com/sun/java/util/jar/pack/defines.h -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2001, 2009, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -22,10 +22,10 @@ - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -- -+ - // random definitions - --#ifdef _MSC_VER -+#ifdef _MSC_VER - #include <windows.h> - #include <winuser.h> - #else -@@ -94,15 +94,15 @@ typedef unsigned int uLong; // Historica - #else - typedef unsigned long uLong; - #endif --#ifdef _MSC_VER --typedef LONGLONG jlong; --typedef DWORDLONG julong; --#define MKDIR(dir) mkdir(dir) --#define getpid() _getpid() --#define PATH_MAX MAX_PATH --#define dup2(a,b) _dup2(a,b) -+#ifdef _MSC_VER -+typedef LONGLONG jlong; -+typedef DWORDLONG julong; -+#define MKDIR(dir) mkdir(dir) -+#define getpid() _getpid() -+#define PATH_MAX MAX_PATH -+#define dup2(a,b) _dup2(a,b) - #define strcasecmp(s1, s2) _stricmp(s1,s2) --#define tempname _tempname -+#define tempname _tempname - #define sleep Sleep - #else - typedef signed char byte; -@@ -123,37 +123,40 @@ enum { false, true }; - - #define null (0) - --#ifndef __sparc -+#ifndef __sparc - #define intptr_t jlong - #endif - - #define ptrlowbits(x) ((int) (intptr_t)(x)) - -+/* Back and forth from jlong to pointer */ -+#define ptr2jlong(x) ((jlong)(size_t)(void*)(x)) -+#define jlong2ptr(x) ((void*)(size_t)(x)) - - // Keys used by Java: --#define UNPACK_DEFLATE_HINT "unpack.deflate.hint" -+#define UNPACK_DEFLATE_HINT "unpack.deflate.hint" - --#define COM_PREFIX "com.sun.java.util.jar.pack." --#define UNPACK_MODIFICATION_TIME COM_PREFIX"unpack.modification.time" --#define DEBUG_VERBOSE COM_PREFIX"verbose" -+#define COM_PREFIX "com.sun.java.util.jar.pack." -+#define UNPACK_MODIFICATION_TIME COM_PREFIX"unpack.modification.time" -+#define DEBUG_VERBOSE COM_PREFIX"verbose" - --#define ZIP_ARCHIVE_MARKER_COMMENT "PACK200" -+#define ZIP_ARCHIVE_MARKER_COMMENT "PACK200" - - // The following are not known to the Java classes: --#define UNPACK_LOG_FILE COM_PREFIX"unpack.log.file" --#define UNPACK_REMOVE_PACKFILE COM_PREFIX"unpack.remove.packfile" -+#define UNPACK_LOG_FILE COM_PREFIX"unpack.log.file" -+#define UNPACK_REMOVE_PACKFILE COM_PREFIX"unpack.remove.packfile" - - - // Called from unpacker layers --#define _CHECK_DO(t,x) { if (t) {x;} } -+#define _CHECK_DO(t,x) { if (t) {x;} } - --#define CHECK _CHECK_DO(aborting(), return) --#define CHECK_(y) _CHECK_DO(aborting(), return y) --#define CHECK_0 _CHECK_DO(aborting(), return 0) -+#define CHECK _CHECK_DO(aborting(), return) -+#define CHECK_(y) _CHECK_DO(aborting(), return y) -+#define CHECK_0 _CHECK_DO(aborting(), return 0) - --#define CHECK_NULL(p) _CHECK_DO((p)==null, return) --#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(p) _CHECK_DO((p)==null, return) -+#define CHECK_NULL_(y,p) _CHECK_DO((p)==null, return y) -+#define CHECK_NULL_0(p) _CHECK_DO((p)==null, return 0) - - #define CHECK_COUNT(t) if (t < 0){abort("bad value count");} CHECK - -diff --git a/src/share/native/com/sun/java/util/jar/pack/jni.cpp b/src/share/native/com/sun/java/util/jar/pack/jni.cpp ---- openjdk/jdk/src/share/native/com/sun/java/util/jar/pack/jni.cpp -+++ openjdk/jdk/src/share/native/com/sun/java/util/jar/pack/jni.cpp -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -43,6 +43,9 @@ - #include "bands.h" - #include "constants.h" - #include "zip.h" -+ -+#include "jni_util.h" -+ - #include "unpack.h" - - -@@ -50,17 +53,19 @@ static jmethodID currentInstMID; - static jmethodID currentInstMID; - static jmethodID readInputMID; - static jclass NIclazz; -+static jmethodID getUnpackerPtrMID; - - static char* dbg = null; - - #define THROW_IOE(x) JNU_ThrowIOException(env,x) - - static jlong read_input_via_jni(unpacker* self, -- void* buf, jlong minlen, jlong maxlen); -- -+ void* buf, jlong minlen, jlong maxlen); -+ - static unpacker* get_unpacker(JNIEnv *env, jobject pObj, bool noCreate=false) { -- unpacker* uPtr = (unpacker*) env->GetLongField(pObj, unpackerPtrFID); -- //fprintf(stderr, "get_unpacker(%p) uPtr=%p\n", pObj, uPtr); -+ unpacker* uPtr; -+ jlong p = env->CallLongMethod(pObj, getUnpackerPtrMID); -+ uPtr = (unpacker*)jlong2ptr(p); - if (uPtr == null) { - if (noCreate) return null; - uPtr = new unpacker(); -@@ -89,11 +94,15 @@ static unpacker* get_unpacker() { - if (env == null) - return null; - jobject pObj = env->CallStaticObjectMethod(NIclazz, currentInstMID); -- //fprintf(stderr, "get_unpacker() pObj=%p\n", pObj); -- if (pObj == null) -- return null; -- // Got pObj and env; now do it the easy way. -- return get_unpacker(env, pObj); -+ //fprintf(stderr, "get_unpacker0() pObj=%p\n", pObj); -+ if (pObj != null) { -+ // Got pObj and env; now do it the easy way. -+ return get_unpacker(env, pObj); -+ } -+ // this should really not happen, if it does something is seriously -+ // wrong throw an exception -+ THROW_IOE(ERROR_INTERNAL); -+ return null; - } - - static void free_unpacker(JNIEnv *env, jobject pObj, unpacker* uPtr) { -@@ -113,36 +122,47 @@ unpacker* unpacker::current() { - - // Callback for fetching data, Java style. Calls NativeUnpack.readInputFn(). - static jlong read_input_via_jni(unpacker* self, -- void* buf, jlong minlen, jlong maxlen) { -+ void* buf, jlong minlen, jlong maxlen) { - JNIEnv* env = (JNIEnv*) self->jnienv; - jobject pbuf = env->NewDirectByteBuffer(buf, maxlen); - return env->CallLongMethod((jobject) self->jniobj, readInputMID, -- pbuf, minlen); -+ pbuf, minlen); - } - --JNIEXPORT void JNICALL -+JNIEXPORT void JNICALL - Java_com_sun_java_util_jar_pack_NativeUnpack_initIDs(JNIEnv *env, jclass clazz) { -+#ifndef PRODUCT - dbg = getenv("DEBUG_ATTACH"); - while( dbg != null) { sleep(10); } -+#endif - NIclazz = (jclass) env->NewGlobalRef(clazz); - unpackerPtrFID = env->GetFieldID(clazz, "unpackerPtr", "J"); - currentInstMID = env->GetStaticMethodID(clazz, "currentInstance", -- "()Ljava/lang/Object;"); -+ "()Ljava/lang/Object;"); - readInputMID = env->GetMethodID(clazz, "readInputFn", -- "(Ljava/nio/ByteBuffer;J)J"); -+ "(Ljava/nio/ByteBuffer;J)J"); -+ -+ getUnpackerPtrMID = env->GetMethodID(clazz, "getUnpackerPtr", "()J"); -+ - if (unpackerPtrFID == null || - currentInstMID == null || - readInputMID == null || -- NIclazz == null) { -+ NIclazz == null || -+ getUnpackerPtrMID == null) { - THROW_IOE("cannot init class members"); - } - } - --JNIEXPORT jlong JNICALL -+JNIEXPORT jlong JNICALL - Java_com_sun_java_util_jar_pack_NativeUnpack_start(JNIEnv *env, jobject pObj, -- jobject pBuf, jlong offset) { -- unpacker* uPtr = get_unpacker(env, pObj); -- -+ jobject pBuf, jlong offset) { -+ // try to get the unpacker pointer the hard way first, we do this to ensure -+ // valid object pointers and env is intact, if not now is good time to bail. -+ unpacker* uPtr = get_unpacker(); -+ //fprintf(stderr, "start(%p) uPtr=%p initializing\n", pObj, uPtr); -+ if (uPtr == null) { -+ return -1; -+ } - // redirect our io to the default log file or whatever. - uPtr->redirect_stdio(); - -@@ -158,6 +178,13 @@ Java_com_sun_java_util_jar_pack_NativeUn - else - { buf = (char*)buf + (size_t)offset; buflen -= (size_t)offset; } - } -+ -+ // before we start off we make sure there is no other error by the time we -+ // get here -+ if (uPtr->aborting()) { -+ THROW_IOE(uPtr->get_abort_message()); -+ return 0; -+ } - - uPtr->start(buf, buflen); - if (uPtr->aborting()) { -@@ -166,13 +193,13 @@ Java_com_sun_java_util_jar_pack_NativeUn - } - - return ((jlong) -- uPtr->get_segments_remaining() << 32) -+ uPtr->get_segments_remaining() << 32) - + uPtr->get_files_remaining(); - } - --JNIEXPORT jboolean JNICALL --Java_com_sun_java_util_jar_pack_NativeUnpack_getNextFile(JNIEnv *env, jobject pObj, -- jobjectArray pParts) { -+JNIEXPORT jboolean JNICALL -+Java_com_sun_java_util_jar_pack_NativeUnpack_getNextFile(JNIEnv *env, jobject pObj, -+ jobjectArray pParts) { - - unpacker* uPtr = get_unpacker(env, pObj); - unpacker::file* filep = uPtr->get_next_file(); -@@ -201,19 +228,19 @@ Java_com_sun_java_util_jar_pack_NativeUn - jobject pDataBuf = null; - if (filep->data[0].len > 0) - pDataBuf = env->NewDirectByteBuffer(filep->data[0].ptr, -- filep->data[0].len); -+ filep->data[0].len); - env->SetObjectArrayElement(pParts, pidx++, pDataBuf); - pDataBuf = null; - if (filep->data[1].len > 0) - pDataBuf = env->NewDirectByteBuffer(filep->data[1].ptr, -- filep->data[1].len); -+ filep->data[1].len); - env->SetObjectArrayElement(pParts, pidx++, pDataBuf); - - return true; - } - - --JNIEXPORT jobject JNICALL -+JNIEXPORT jobject JNICALL - Java_com_sun_java_util_jar_pack_NativeUnpack_getUnusedInput(JNIEnv *env, jobject pObj) { - unpacker* uPtr = get_unpacker(env, pObj); - unpacker::file* filep = &uPtr->cur_file; -@@ -225,14 +252,18 @@ Java_com_sun_java_util_jar_pack_NativeUn - - // We have fetched all the files. - // Now swallow up any remaining input. -- if (uPtr->input_remaining() == 0) -+ if (uPtr->input_remaining() == 0) { - return null; -- else -- return env->NewDirectByteBuffer(uPtr->input_scan(), -- uPtr->input_remaining()); -+ } -+ else { -+ bytes remaining_bytes; -+ remaining_bytes.malloc(uPtr->input_remaining()); -+ remaining_bytes.copyFrom(uPtr->input_scan(), uPtr->input_remaining()); -+ return env->NewDirectByteBuffer(remaining_bytes.ptr, remaining_bytes.len); -+ } - } - --JNIEXPORT jlong JNICALL -+JNIEXPORT jlong JNICALL - Java_com_sun_java_util_jar_pack_NativeUnpack_finish(JNIEnv *env, jobject pObj) { - unpacker* uPtr = get_unpacker(env, pObj, false); - if (uPtr == null) return 0; -@@ -241,9 +272,9 @@ Java_com_sun_java_util_jar_pack_NativeUn - return consumed; - } - --JNIEXPORT jboolean JNICALL --Java_com_sun_java_util_jar_pack_NativeUnpack_setOption(JNIEnv *env, jobject pObj, -- jstring pProp, jstring pValue) { -+JNIEXPORT jboolean JNICALL -+Java_com_sun_java_util_jar_pack_NativeUnpack_setOption(JNIEnv *env, jobject pObj, -+ jstring pProp, jstring pValue) { - unpacker* uPtr = get_unpacker(env, pObj); - const char* prop = env->GetStringUTFChars(pProp, JNI_FALSE); - const char* value = env->GetStringUTFChars(pValue, JNI_FALSE); -@@ -253,9 +284,9 @@ Java_com_sun_java_util_jar_pack_NativeUn - return retval; - } - --JNIEXPORT jstring JNICALL --Java_com_sun_java_util_jar_pack_NativeUnpack_getOption(JNIEnv *env, jobject pObj, -- jstring pProp) { -+JNIEXPORT jstring JNICALL -+Java_com_sun_java_util_jar_pack_NativeUnpack_getOption(JNIEnv *env, jobject pObj, -+ jstring pProp) { - - unpacker* uPtr = get_unpacker(env, pObj); - const char* prop = env->GetStringUTFChars(pProp, JNI_FALSE); -diff --git a/src/share/native/com/sun/java/util/jar/pack/unpack.cpp b/src/share/native/com/sun/java/util/jar/pack/unpack.cpp ---- openjdk/jdk/src/share/native/com/sun/java/util/jar/pack/unpack.cpp -+++ openjdk/jdk/src/share/native/com/sun/java/util/jar/pack/unpack.cpp -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -38,7 +38,7 @@ - #include <time.h> - - -- -+ - - #include "defines.h" - #include "bytes.h" -@@ -185,9 +185,9 @@ struct entry { - || (tag2 == CONSTANT_Utf8 && tag == CONSTANT_Signature) - #ifndef PRODUCT - || (tag2 == CONSTANT_Literal -- && tag >= CONSTANT_Integer && tag <= CONSTANT_String && tag != CONSTANT_Class) -+ && tag >= CONSTANT_Integer && tag <= CONSTANT_String && tag != CONSTANT_Class) - || (tag2 == CONSTANT_Member -- && tag >= CONSTANT_Fieldref && tag <= CONSTANT_InterfaceMethodref) -+ && tag >= CONSTANT_Fieldref && tag <= CONSTANT_InterfaceMethodref) - #endif - ; - } -@@ -238,9 +238,9 @@ int entry::typeSize() { - // else fall through - case 'L': - sigp = strchr(sigp, ';'); -- if (sigp == null) { -- unpack_abort("bad data"); -- return 0; -+ if (sigp == null) { -+ unpack_abort("bad data"); -+ return 0; - } - sigp += 1; - break; -@@ -252,11 +252,13 @@ int entry::typeSize() { - } - - inline cpindex* cpool::getFieldIndex(entry* classRef) { -+ if (classRef == NULL) { abort("missing class reference"); return NULL; } - assert(classRef->tagMatches(CONSTANT_Class)); - assert((uint)classRef->inord < tag_count[CONSTANT_Class]); - return &member_indexes[classRef->inord*2+0]; - } - inline cpindex* cpool::getMethodIndex(entry* classRef) { -+ if (classRef == NULL) { abort("missing class reference"); return NULL; } - assert(classRef->tagMatches(CONSTANT_Class)); - assert((uint)classRef->inord < tag_count[CONSTANT_Class]); - return &member_indexes[classRef->inord*2+1]; -@@ -512,11 +514,10 @@ void unpacker::read_file_header() { - AH_CP_NUMBER_LEN = 4, // int/float/long/double - AH_SPECIAL_FORMAT_LEN = 2, // layouts/band-headers - AH_LENGTH_MIN = AH_LENGTH -- -(AH_FILE_HEADER_LEN+AH_SPECIAL_FORMAT_LEN+AH_CP_NUMBER_LEN), -- ARCHIVE_SIZE_MIN = AH_LENGTH_MIN - (AH_LENGTH_0 + AH_ARCHIVE_SIZE_LEN), -+ -(AH_FILE_HEADER_LEN+AH_SPECIAL_FORMAT_LEN+AH_CP_NUMBER_LEN), -+ ARCHIVE_SIZE_MIN = AH_LENGTH_MIN - (AH_LENGTH_0 + AH_ARCHIVE_SIZE_LEN), - FIRST_READ = MAGIC_BYTES + AH_LENGTH_MIN - }; -- - - assert(AH_LENGTH_MIN == 15); // # of UNSIGNED5 fields required after archive_magic - assert(ARCHIVE_SIZE_MIN == 10); // # of UNSIGNED5 fields required after archive_size -@@ -580,15 +581,15 @@ void unpacker::read_file_header() { - for (;;) { - jarout->write_data(rp, input_remaining()); - if (foreign_buf) -- break; // one-time use of a passed in buffer -+ break; // one-time use of a passed in buffer - if (input.size() < CHUNK) { -- // Get some breathing room. -- input.set(U_NEW(byte, (size_t) CHUNK + C_SLOP), (size_t) CHUNK); -- CHECK; -+ // Get some breathing room. -+ input.set(U_NEW(byte, (size_t) CHUNK + C_SLOP), (size_t) CHUNK); -+ CHECK; - } - rp = rplimit = input.base(); - if (!ensure_input(1)) -- break; -+ break; - } - jarout->closeJarFile(false); - #endif -@@ -612,16 +613,16 @@ void unpacker::read_file_header() { - hdrVals += 2; - - if (magic != JAVA_PACKAGE_MAGIC || -- (majver != JAVA5_PACKAGE_MAJOR_VERSION && -- majver != JAVA6_PACKAGE_MAJOR_VERSION) || -- (minver != JAVA5_PACKAGE_MINOR_VERSION && -+ (majver != JAVA5_PACKAGE_MAJOR_VERSION && -+ majver != JAVA6_PACKAGE_MAJOR_VERSION) || -+ (minver != JAVA5_PACKAGE_MINOR_VERSION && - minver != JAVA6_PACKAGE_MINOR_VERSION)) { - char message[200]; - sprintf(message, "@" ERROR_FORMAT ": magic/ver = " -- "%08X/%d.%d should be %08X/%d.%d OR %08X/%d.%d\n", -- magic, majver, minver, -- JAVA_PACKAGE_MAGIC, JAVA5_PACKAGE_MAJOR_VERSION, JAVA5_PACKAGE_MINOR_VERSION, -- JAVA_PACKAGE_MAGIC, JAVA6_PACKAGE_MAJOR_VERSION, JAVA6_PACKAGE_MINOR_VERSION); -+ "%08X/%d.%d should be %08X/%d.%d OR %08X/%d.%d\n", -+ magic, majver, minver, -+ JAVA_PACKAGE_MAGIC, JAVA5_PACKAGE_MAJOR_VERSION, JAVA5_PACKAGE_MINOR_VERSION, -+ JAVA_PACKAGE_MAGIC, JAVA6_PACKAGE_MAJOR_VERSION, JAVA6_PACKAGE_MINOR_VERSION); - abort(message); - } - CHECK; -@@ -635,7 +636,7 @@ void unpacker::read_file_header() { - #undef ORBIT - if ((archive_options & ~OPTION_LIMIT) != 0) { - fprintf(errstrm, "Warning: Illegal archive options 0x%x\n", -- archive_options); -+ archive_options); - abort("illegal archive options"); - return; - } -@@ -675,7 +676,7 @@ void unpacker::read_file_header() { - 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; -@@ -756,9 +757,9 @@ void unpacker::read_file_header() { - case CONSTANT_Float: - case CONSTANT_Long: - case CONSTANT_Double: -- cp_counts[k] = 0; -- hdrValsSkipped += 1; -- continue; -+ cp_counts[k] = 0; -+ hdrValsSkipped += 1; -+ continue; - } - } - cp_counts[k] = hdr.getInt(); -@@ -813,7 +814,7 @@ void unpacker::read_file_header() { - bytes band_headers; - // The "1+" allows an initial byte to be pushed on the front. - band_headers.set(1+U_NEW(byte, 1+band_headers_size+C_SLOP), -- band_headers_size); -+ band_headers_size); - CHECK; - // Start scanning band headers here: - band_headers.copyFrom(rp, band_headers.len); -@@ -874,7 +875,7 @@ void cpool::init(unpacker* u_, int count - IMPLICIT_ENTRY_COUNT = 1 // empty Utf8 string - }; - if (len >= (1<<29) || len < 0 -- || next_entry >= CP_SIZE_LIMIT+IMPLICIT_ENTRY_COUNT) { -+ || next_entry >= CP_SIZE_LIMIT+IMPLICIT_ENTRY_COUNT) { - abort("archive too large: constant pool limit exceeded"); - return; - } -@@ -935,9 +936,9 @@ static byte* skip_Utf8_chars(byte* cp, i - int ch = *cp & 0xFF; - if ((ch & 0xC0) != 0x80) { - if (len-- == 0) -- return cp; -+ return cp; - if (ch < 0x80 && len == 0) -- return cp+1; -+ return cp+1; - } - } - } -@@ -963,9 +964,9 @@ static int compare_Utf8_chars(bytes& b1, - if (c1 == 0xC0 && (p1[i+1] & 0xFF) == 0x80) c1 = 0; - if (c2 == 0xC0 && (p2[i+1] & 0xFF) == 0x80) c2 = 0; - if (c0 == 0xC0) { -- assert(((c1|c2) & 0xC0) == 0x80); // c1 & c2 are extension chars -- if (c1 == 0x80) c1 = 0; // will sort below c2 -- if (c2 == 0x80) c2 = 0; // will sort below c1 -+ assert(((c1|c2) & 0xC0) == 0x80); // c1 & c2 are extension chars -+ if (c1 == 0x80) c1 = 0; // will sort below c2 -+ if (c2 == 0x80) c2 = 0; // will sort below c1 - } - return c1 - c2; - } -@@ -1024,9 +1025,9 @@ void unpacker::read_Utf8_values(entry* c - chars.malloc(size3); - } else { - if (!charbuf.canAppend(size3+1)) { -- assert(charbuf.allocated == 0 || tmallocs.contains(charbuf.base())); -- charbuf.init(CHUNK); // Reset to new buffer. -- tmallocs.add(charbuf.base()); -+ assert(charbuf.allocated == 0 || tmallocs.contains(charbuf.base())); -+ charbuf.init(CHUNK); // Reset to new buffer. -+ tmallocs.add(charbuf.base()); - } - chars.set(charbuf.grow(size3+1), size3); - } -@@ -1191,9 +1192,9 @@ void unpacker::read_single_refs(band& cp - // Maintain cross-reference: - entry* &htref = cp.hashTabRef(indexTag, e.value.b); - if (htref == null) { -- // Note that if two identical classes are transmitted, -- // the first is taken to be the canonical one. -- htref = &e; -+ // Note that if two identical classes are transmitted, -+ // the first is taken to be the canonical one. -+ htref = &e; - } - } - } -@@ -1202,7 +1203,7 @@ void unpacker::read_single_refs(band& cp - - maybe_inline - void unpacker::read_double_refs(band& cp_band, byte ref1Tag, byte ref2Tag, -- entry* cpMap, int len) { -+ entry* cpMap, int len) { - band& cp_band1 = cp_band; - band& cp_band2 = cp_band.nextBand(); - cp_band1.setIndexByTag(ref1Tag); -@@ -1214,6 +1215,7 @@ void unpacker::read_double_refs(band& cp - entry& e = cpMap[i]; - e.refs = U_NEW(entry*, e.nrefs = 2); - e.refs[0] = cp_band1.getRef(); -+ CHECK; - e.refs[1] = cp_band2.getRef(); - CHECK; - } -@@ -1302,23 +1304,23 @@ void unpacker::read_cp() { - break; - case CONSTANT_NameandType: - read_double_refs(cp_Descr_name /*& cp_Descr_type*/, -- CONSTANT_Utf8, CONSTANT_Signature, -- cpMap, len); -+ CONSTANT_Utf8, CONSTANT_Signature, -+ cpMap, len); - break; - case CONSTANT_Fieldref: - read_double_refs(cp_Field_class /*& cp_Field_desc*/, -- CONSTANT_Class, CONSTANT_NameandType, -- cpMap, len); -+ CONSTANT_Class, CONSTANT_NameandType, -+ cpMap, len); - break; - case CONSTANT_Methodref: - read_double_refs(cp_Method_class /*& cp_Method_desc*/, -- CONSTANT_Class, CONSTANT_NameandType, -- cpMap, len); -+ CONSTANT_Class, CONSTANT_NameandType, -+ cpMap, len); - break; - case CONSTANT_InterfaceMethodref: - read_double_refs(cp_Imethod_class /*& cp_Imethod_desc*/, -- CONSTANT_Class, CONSTANT_NameandType, -- cpMap, len); -+ CONSTANT_Class, CONSTANT_NameandType, -+ cpMap, len); - break; - default: - assert(false); -@@ -1384,8 +1386,8 @@ inline - inline - unpacker::layout_definition* - unpacker::attr_definitions::defineLayout(int idx, -- entry* nameEntry, -- const char* layout) { -+ entry* nameEntry, -+ const char* layout) { - const char* name = nameEntry->value.b.strval(); - layout_definition* lo = defineLayout(idx, name, layout); - CHECK_0; -@@ -1395,8 +1397,8 @@ unpacker::attr_definitions::defineLayout - - unpacker::layout_definition* - unpacker::attr_definitions::defineLayout(int idx, -- const char* name, -- const char* layout) { -+ const char* name, -+ const char* layout) { - assert(flag_limit != 0); // must be set up already - if (idx >= 0) { - // Fixed attr. -@@ -1419,12 +1421,12 @@ unpacker::attr_definitions::defineLayout - } - CHECK_0; - layouts.get(idx) = lo; -- return lo; -+ return lo; - } - - band** - unpacker::attr_definitions::buildBands(unpacker::layout_definition* lo) { -- int i; -+ int i; - if (lo->elems != null) - return lo->bands(); - if (lo->layout[0] == '\0') { -@@ -1448,11 +1450,11 @@ unpacker::attr_definitions::buildBands(u - int num_callables = 0; - if (hasCallables) { - while (bands[num_callables] != null) { -- if (bands[num_callables]->le_kind != EK_CBLE) { -- abort("garbage mixed with callables"); -- break; -- } -- num_callables += 1; -+ if (bands[num_callables]->le_kind != EK_CBLE) { -+ abort("garbage mixed with callables"); -+ break; -+ } -+ num_callables += 1; - } - } - for (i = 0; i < calls_to_link.length(); i++) { -@@ -1461,8 +1463,8 @@ unpacker::attr_definitions::buildBands(u - // Determine the callee. - int call_num = call.le_len; - if (call_num < 0 || call_num >= num_callables) { -- abort("bad call in layout"); -- break; -+ abort("bad call in layout"); -+ break; - } - band& cble = *bands[call_num]; - // Link the call to it. -@@ -1540,7 +1542,7 @@ unpacker::attr_definitions::buildBands(u - - const char* - unpacker::attr_definitions::parseIntLayout(const char* lp, band* &res, -- byte le_kind, bool can_be_signed) { -+ byte le_kind, bool can_be_signed) { - const char* lp0 = lp; - band* b = U_NEW(band, 1); - CHECK_(lp); -@@ -1619,7 +1621,7 @@ unpacker::attr_definitions::popBody(int - - const char* - unpacker::attr_definitions::parseLayout(const char* lp, band** &res, -- int curCble) { -+ int curCble) { - const char* lp0 = lp; - int bs_base = band_stack.length(); - bool top_level = (bs_base == 0); -@@ -1636,18 +1638,18 @@ unpacker::attr_definitions::parseLayout( - break; - case 'P': - { -- int le_bci = EK_BCI; -- if (*lp == 'O') { -- ++lp; -- le_bci = EK_BCID; -- } -- assert(*lp != 'S'); // no PSH, etc. -- lp = parseIntLayout(lp, b, EK_INT); -- b->le_bci = le_bci; -- if (le_bci == EK_BCI) -- b->defc = coding::findBySpec(BCI5_spec); -- else -- b->defc = coding::findBySpec(BRANCH5_spec); -+ int le_bci = EK_BCI; -+ if (*lp == 'O') { -+ ++lp; -+ le_bci = EK_BCID; -+ } -+ assert(*lp != 'S'); // no PSH, etc. -+ lp = parseIntLayout(lp, b, EK_INT); -+ b->le_bci = le_bci; -+ if (le_bci == EK_BCI) -+ b->defc = coding::findBySpec(BCI5_spec); -+ else -+ b->defc = coding::findBySpec(BRANCH5_spec); - } - break; - case 'O': -@@ -1665,25 +1667,25 @@ unpacker::attr_definitions::parseLayout( - case 'T': // union: 'T' any_int union_case* '(' ')' '[' body ']' - lp = parseIntLayout(lp, b, EK_UN, can_be_signed); - { -- int union_base = band_stack.length(); -- for (;;) { // for each case -- band& k_case = *U_NEW(band, 1); -- CHECK_(lp); -- band_stack.add(&k_case); -- k_case.le_kind = EK_CASE; -- k_case.bn = bands_made++; -- if (*lp++ != '(') { -- abort("bad union case"); -- return ""; -- } -- if (*lp++ != ')') { -- --lp; // reparse -- // Read some case values. (Use band_stack for temp. storage.) -- int case_base = band_stack.length(); -- for (;;) { -- int caseval = 0; -- lp = parseNumeral(lp, caseval); -- band_stack.add((void*)caseval); -+ int union_base = band_stack.length(); -+ for (;;) { // for each case -+ band& k_case = *U_NEW(band, 1); -+ CHECK_(lp); -+ band_stack.add(&k_case); -+ k_case.le_kind = EK_CASE; -+ k_case.bn = bands_made++; -+ if (*lp++ != '(') { -+ abort("bad union case"); -+ return ""; -+ } -+ if (*lp++ != ')') { -+ --lp; // reparse -+ // Read some case values. (Use band_stack for temp. storage.) -+ int case_base = band_stack.length(); -+ for (;;) { -+ int caseval = 0; -+ lp = parseNumeral(lp, caseval); -+ band_stack.add((void*)caseval); - if (*lp == '-') { - // new in version 160, allow (1-5) for (1,2,3,4,5) - if (u->majver < JAVA6_PACKAGE_MAJOR_VERSION) { -@@ -1706,111 +1708,111 @@ unpacker::attr_definitions::parseLayout( - if (caseval == caselimit) break; - } - } -- if (*lp != ',') break; -- lp++; -- } -- if (*lp++ != ')') { -- abort("bad case label"); -- return ""; -- } -- // save away the case labels -- int ntags = band_stack.length() - case_base; -- int* tags = U_NEW(int, add_size(ntags, 1)); -- CHECK_(lp); -- k_case.le_casetags = tags; -- *tags++ = ntags; -- for (int i = 0; i < ntags; i++) { -- *tags++ = ptrlowbits(band_stack.get(case_base+i)); -- } -- band_stack.popTo(case_base); -- CHECK_(lp); -- } -- // Got le_casetags. Now grab the body. -- assert(*lp == '['); -- ++lp; -- lp = parseLayout(lp, k_case.le_body, curCble); -- CHECK_(lp); -- if (k_case.le_casetags == null) break; // done -- } -- b->le_body = popBody(union_base); -+ if (*lp != ',') break; -+ lp++; -+ } -+ if (*lp++ != ')') { -+ abort("bad case label"); -+ return ""; -+ } -+ // save away the case labels -+ int ntags = band_stack.length() - case_base; -+ int* tags = U_NEW(int, add_size(ntags, 1)); -+ CHECK_(lp); -+ k_case.le_casetags = tags; -+ *tags++ = ntags; -+ for (int i = 0; i < ntags; i++) { -+ *tags++ = ptrlowbits(band_stack.get(case_base+i)); -+ } -+ band_stack.popTo(case_base); -+ CHECK_(lp); -+ } -+ // Got le_casetags. Now grab the body. -+ assert(*lp == '['); -+ ++lp; -+ lp = parseLayout(lp, k_case.le_body, curCble); -+ CHECK_(lp); -+ if (k_case.le_casetags == null) break; // done -+ } -+ b->le_body = popBody(union_base); - } - break; - case '(': // call: '(' -?NN* ')' - { -- band& call = *U_NEW(band, 1); -- CHECK_(lp); -- band_stack.add(&call); -- call.le_kind = EK_CALL; -- call.bn = bands_made++; -- call.le_body = U_NEW(band*, 2); // fill in later -- int call_num = 0; -- lp = parseNumeral(lp, call_num); -- call.le_back = (call_num <= 0); -- call_num += curCble; // numeral is self-relative offset -- call.le_len = call_num; //use le_len as scratch -- calls_to_link.add(&call); -- CHECK_(lp); -- if (*lp++ != ')') { -- abort("bad call label"); -- return ""; -+ band& call = *U_NEW(band, 1); -+ CHECK_(lp); -+ band_stack.add(&call); -+ call.le_kind = EK_CALL; -+ call.bn = bands_made++; -+ call.le_body = U_NEW(band*, 2); // fill in later -+ int call_num = 0; -+ lp = parseNumeral(lp, call_num); -+ call.le_back = (call_num <= 0); -+ call_num += curCble; // numeral is self-relative offset -+ call.le_len = call_num; //use le_len as scratch -+ calls_to_link.add(&call); -+ CHECK_(lp); -+ if (*lp++ != ')') { -+ abort("bad call label"); -+ return ""; - } - } - break; - case 'K': // reference_type: constant_ref - case 'R': // reference_type: schema_ref - { -- int ixTag = CONSTANT_None; -- if (lp[-1] == 'K') { -- switch (*lp++) { -- case 'I': ixTag = CONSTANT_Integer; break; -- case 'J': ixTag = CONSTANT_Long; break; -- case 'F': ixTag = CONSTANT_Float; break; -- case 'D': ixTag = CONSTANT_Double; break; -- case 'S': ixTag = CONSTANT_String; break; -- case 'Q': ixTag = CONSTANT_Literal; break; -- } -- } else { -- switch (*lp++) { -- case 'C': ixTag = CONSTANT_Class; break; -- case 'S': ixTag = CONSTANT_Signature; break; -- case 'D': ixTag = CONSTANT_NameandType; break; -- case 'F': ixTag = CONSTANT_Fieldref; break; -- case 'M': ixTag = CONSTANT_Methodref; break; -- case 'I': ixTag = CONSTANT_InterfaceMethodref; break; -- case 'U': ixTag = CONSTANT_Utf8; break; //utf8_ref -- case 'Q': ixTag = CONSTANT_All; break; //untyped_ref -- } -- } -- if (ixTag == CONSTANT_None) { -- abort("bad reference layout"); -- break; -- } -- bool nullOK = false; -- if (*lp == 'N') { -- nullOK = true; -- lp++; -- } -- lp = parseIntLayout(lp, b, EK_REF); -- b->defc = coding::findBySpec(UNSIGNED5_spec); -- b->initRef(ixTag, nullOK); -+ int ixTag = CONSTANT_None; -+ if (lp[-1] == 'K') { -+ switch (*lp++) { -+ case 'I': ixTag = CONSTANT_Integer; break; -+ case 'J': ixTag = CONSTANT_Long; break; -+ case 'F': ixTag = CONSTANT_Float; break; -+ case 'D': ixTag = CONSTANT_Double; break; -+ case 'S': ixTag = CONSTANT_String; break; -+ case 'Q': ixTag = CONSTANT_Literal; break; -+ } -+ } else { -+ switch (*lp++) { -+ case 'C': ixTag = CONSTANT_Class; break; -+ case 'S': ixTag = CONSTANT_Signature; break; -+ case 'D': ixTag = CONSTANT_NameandType; break; -+ case 'F': ixTag = CONSTANT_Fieldref; break; -+ case 'M': ixTag = CONSTANT_Methodref; break; -+ case 'I': ixTag = CONSTANT_InterfaceMethodref; break; -+ case 'U': ixTag = CONSTANT_Utf8; break; //utf8_ref -+ case 'Q': ixTag = CONSTANT_All; break; //untyped_ref -+ } -+ } -+ if (ixTag == CONSTANT_None) { -+ abort("bad reference layout"); -+ break; -+ } -+ bool nullOK = false; -+ if (*lp == 'N') { -+ nullOK = true; -+ lp++; -+ } -+ lp = parseIntLayout(lp, b, EK_REF); -+ b->defc = coding::findBySpec(UNSIGNED5_spec); -+ b->initRef(ixTag, nullOK); - } - break; - case '[': - { -- // [callable1][callable2]... -- if (!top_level) { -- abort("bad nested callable"); -- break; -- } -- curCble += 1; -- NOT_PRODUCT(int call_num = band_stack.length() - bs_base); -- band& cble = *U_NEW(band, 1); -- CHECK_(lp); -- band_stack.add(&cble); -- cble.le_kind = EK_CBLE; -- NOT_PRODUCT(cble.le_len = call_num); -- cble.bn = bands_made++; -- lp = parseLayout(lp, cble.le_body, curCble); -+ // [callable1][callable2]... -+ if (!top_level) { -+ abort("bad nested callable"); -+ break; -+ } -+ curCble += 1; -+ NOT_PRODUCT(int call_num = band_stack.length() - bs_base); -+ band& cble = *U_NEW(band, 1); -+ CHECK_(lp); -+ band_stack.add(&cble); -+ cble.le_kind = EK_CBLE; -+ NOT_PRODUCT(cble.le_len = call_num); -+ cble.bn = bands_made++; -+ lp = parseLayout(lp, cble.le_body, curCble); - } - break; - case ']': -@@ -1880,10 +1882,10 @@ void unpacker::read_attr_defs() { - "(115)[RUH]" - "(91)[NH[(0)]]" - "(64)[" -- // nested annotation: -- "RSH" -- "NH[RUH(0)]" -- "]" -+ // nested annotation: -+ "RSH" -+ "NH[RUH(0)]" -+ "]" - "()[]" - "]" - ); -@@ -1897,16 +1899,16 @@ void unpacker::read_attr_defs() { - for (i = 0; i < ATTR_CONTEXT_LIMIT; i++) { - attr_definitions& ad = attr_defs[i]; - ad.defineLayout(X_ATTR_RuntimeVisibleAnnotations, -- "RuntimeVisibleAnnotations", md_layout_A); -+ "RuntimeVisibleAnnotations", md_layout_A); - ad.defineLayout(X_ATTR_RuntimeInvisibleAnnotations, -- "RuntimeInvisibleAnnotations", md_layout_A); -+ "RuntimeInvisibleAnnotations", md_layout_A); - if (i != ATTR_CONTEXT_METHOD) continue; - ad.defineLayout(METHOD_ATTR_RuntimeVisibleParameterAnnotations, -- "RuntimeVisibleParameterAnnotations", md_layout_P); -+ "RuntimeVisibleParameterAnnotations", md_layout_P); - ad.defineLayout(METHOD_ATTR_RuntimeInvisibleParameterAnnotations, -- "RuntimeInvisibleParameterAnnotations", md_layout_P); -+ "RuntimeInvisibleParameterAnnotations", md_layout_P); - ad.defineLayout(METHOD_ATTR_AnnotationDefault, -- "AnnotationDefault", md_layout_V); -+ "AnnotationDefault", md_layout_V); - } - - attr_definition_headers.readData(attr_definition_count); -@@ -1939,6 +1941,7 @@ void unpacker::read_attr_defs() { - int attrc = ADH_BYTE_CONTEXT(header); - int idx = ADH_BYTE_INDEX(header); - entry* name = attr_definition_name.getRef(); -+ CHECK; - entry* layout = attr_definition_layout.getRef(); - CHECK; - attr_defs[attrc].defineLayout(idx, name, layout->value.b.strval()); -@@ -2043,7 +2046,9 @@ void unpacker::read_ics() { - if (ics[i].name == NO_ENTRY_YET) { - // Long form. - ics[i].outer = ic_outer_class.getRefN(); -+ CHECK; - ics[i].name = ic_name.getRefN(); -+ CHECK; - } else { - // Fill in outer and name based on inner. - bytes& n = ics[i].inner->value.b; -@@ -2058,48 +2063,48 @@ void unpacker::read_ics() { - int pkglen = lastIndexOf(SLASH_MIN, SLASH_MAX, n, nlen) + 1; - dollar2 = lastIndexOf(DOLLAR_MIN, DOLLAR_MAX, n, nlen); - if (dollar2 < 0) { -- abort(); -- return; -+ abort(); -+ return; - } - assert(dollar2 >= pkglen); - if (isDigitString(n, dollar2+1, nlen)) { -- // n = (<pkg>/)*<outer>$<number> -- number = n.slice(dollar2+1, nlen); -- name.set(null,0); -- dollar1 = dollar2; -+ // n = (<pkg>/)*<outer>$<number> -+ number = n.slice(dollar2+1, nlen); -+ name.set(null,0); -+ dollar1 = dollar2; - } else if (pkglen < (dollar1 -- = lastIndexOf(DOLLAR_MIN, DOLLAR_MAX, n, dollar2-1)) -- && isDigitString(n, dollar1+1, dollar2)) { -- // n = (<pkg>/)*<outer>$<number>$<name> -- number = n.slice(dollar1+1, dollar2); -- name = n.slice(dollar2+1, nlen); -+ = lastIndexOf(DOLLAR_MIN, DOLLAR_MAX, n, dollar2-1)) -+ && isDigitString(n, dollar1+1, dollar2)) { -+ // n = (<pkg>/)*<outer>$<number>$<name> -+ number = n.slice(dollar1+1, dollar2); -+ name = n.slice(dollar2+1, nlen); - } else { -- // n = (<pkg>/)*<outer>$<name> -- dollar1 = dollar2; -- number.set(null,0); -- name = n.slice(dollar2+1, nlen); -+ // n = (<pkg>/)*<outer>$<name> -+ dollar1 = dollar2; -+ number.set(null,0); -+ name = n.slice(dollar2+1, nlen); - } - if (number.ptr == null) -- pkgOuter = n.slice(0, dollar1); -+ pkgOuter = n.slice(0, dollar1); - else -- pkgOuter.set(null,0); -+ pkgOuter.set(null,0); - printcr(5,"=> %s$ 0%s $%s", -- pkgOuter.string(), number.string(), name.string()); -+ pkgOuter.string(), number.string(), name.string()); - - if (pkgOuter.ptr != null) -- ics[i].outer = cp.ensureClass(pkgOuter); -+ ics[i].outer = cp.ensureClass(pkgOuter); - - if (name.ptr != null) -- ics[i].name = cp.ensureUtf8(name); -+ ics[i].name = cp.ensureUtf8(name); - } - - // update child/sibling list - if (ics[i].outer != null) { - uint outord = ics[i].outer->inord; - if (outord != NO_INORD) { -- assert(outord < cp.tag_count[CONSTANT_Class]); -- ics[i].next_sibling = ic_child_index[outord]; -- ic_child_index[outord] = &ics[i]; -+ assert(outord < cp.tag_count[CONSTANT_Class]); -+ ics[i].next_sibling = ic_child_index[outord]; -+ ic_child_index[outord] = &ics[i]; - } - } - } -@@ -2149,7 +2154,7 @@ void unpacker::read_classes() { - read_code_headers(); - - printcr(1,"scanned %d classes, %d fields, %d methods, %d code headers", -- class_count, field_count, method_count, code_count); -+ class_count, field_count, method_count, code_count); - } - - maybe_inline -@@ -2226,11 +2231,11 @@ void unpacker::read_attrs(int attrc, int - band** bands = ad.buildBands(lo); - CHECK; - if (lo->hasCallables()) { -- for (i = 0; bands[i] != null; i++) { -- if (bands[i]->le_back) { -- assert(bands[i]->le_kind == EK_CBLE); -- backwardCounts += 1; -- } -+ for (i = 0; bands[i] != null; i++) { -+ if (bands[i]->le_back) { -+ assert(bands[i]->le_kind == EK_CBLE); -+ backwardCounts += 1; -+ } - } - } - } -@@ -2427,7 +2432,7 @@ void unpacker::attr_definitions::readBan - layout_definition* lo = getLayout(idx); - if (lo != null) { - printcr(1, "counted %d [redefined = %d predefined = %d] attributes of type %s.%s", -- count, isRedefined(idx), isPredefined(idx), -+ count, isRedefined(idx), isPredefined(idx), - ATTR_CONTEXT_NAME[attrc], lo->name); - } - bool hasCallables = lo->hasCallables(); -@@ -2444,10 +2449,10 @@ void unpacker::attr_definitions::readBan - band& j_cble = *bands[j]; - assert(j_cble.le_kind == EK_CBLE); - if (j_cble.le_back) { -- // Add in the predicted effects of backward calls, too. -- int back_calls = xxx_attr_calls().getInt(); -- j_cble.expectMoreLength(back_calls); -- // In a moment, more forward calls may increment j_cble.length. -+ // Add in the predicted effects of backward calls, too. -+ int back_calls = xxx_attr_calls().getInt(); -+ j_cble.expectMoreLength(back_calls); -+ // In a moment, more forward calls may increment j_cble.length. - } - } - // Now consult whichever callables have non-zero entry counts. -@@ -2467,38 +2472,38 @@ void unpacker::attr_definitions::readBan - switch (b.le_kind) { - case EK_REPL: - { -- int reps = b.getIntTotal(); -- readBandData(b.le_body, reps); -+ int reps = b.getIntTotal(); -+ readBandData(b.le_body, reps); - } - break; - case EK_UN: - { -- int remaining = count; -- for (k = 0; b.le_body[k] != null; k++) { -- band& k_case = *b.le_body[k]; -- int k_count = 0; -- if (k_case.le_casetags == null) { -- k_count = remaining; // last (empty) case -- } else { -- int* tags = k_case.le_casetags; -- int ntags = *tags++; // 1st element is length (why not?) -- while (ntags-- > 0) { -- int tag = *tags++; -- k_count += b.getIntCount(tag); -- } -- } -- readBandData(k_case.le_body, k_count); -- remaining -= k_count; -- } -- assert(remaining == 0); -+ int remaining = count; -+ for (k = 0; b.le_body[k] != null; k++) { -+ band& k_case = *b.le_body[k]; -+ int k_count = 0; -+ if (k_case.le_casetags == null) { -+ k_count = remaining; // last (empty) case -+ } else { -+ int* tags = k_case.le_casetags; -+ int ntags = *tags++; // 1st element is length (why not?) -+ while (ntags-- > 0) { -+ int tag = *tags++; -+ k_count += b.getIntCount(tag); -+ } -+ } -+ readBandData(k_case.le_body, k_count); -+ remaining -= k_count; -+ } -+ assert(remaining == 0); - } - break; - case EK_CALL: - // Push the count forward, if it is not a backward call. - if (!b.le_back) { -- band& cble = *b.le_body[0]; -- assert(cble.le_kind == EK_CBLE); -- cble.expectMoreLength(count); -+ band& cble = *b.le_body[0]; -+ assert(cble.le_kind == EK_CBLE); -+ cble.expectMoreLength(count); - } - break; - case EK_CBLE: -@@ -2522,12 +2527,12 @@ band** findMatchingCase(int matchTag, ba - int* tags = k_case.le_casetags; - int ntags = *tags++; // 1st element is length - for (; ntags > 0; ntags--) { -- int tag = *tags++; -- if (tag == matchTag) -- break; -+ int tag = *tags++; -+ if (tag == matchTag) -+ break; - } - if (ntags == 0) -- continue; // does not match -+ continue; // does not match - } - return k_case.le_body; - } -@@ -2549,46 +2554,47 @@ void unpacker::putlayout(band** body) { - if (b.defc != null) { - // It has data, so unparse an element. - if (b.ixTag != CONSTANT_None) { -- assert(le_kind == EK_REF); -- if (b.ixTag == CONSTANT_Literal) -- e = b.getRefUsing(cp.getKQIndex()); -- else -- e = b.getRefN(); -- switch (b.le_len) { -- case 0: break; -- case 1: putu1ref(e); break; -- case 2: putref(e); break; -- case 4: putu2(0); putref(e); break; -- default: assert(false); -- } -+ assert(le_kind == EK_REF); -+ if (b.ixTag == CONSTANT_Literal) -+ e = b.getRefUsing(cp.getKQIndex()); -+ else -+ e = b.getRefN(); -+ CHECK; -+ switch (b.le_len) { -+ case 0: break; -+ case 1: putu1ref(e); break; -+ case 2: putref(e); break; -+ case 4: putu2(0); putref(e); break; -+ default: assert(false); -+ } - } else { -- assert(le_kind == EK_INT || le_kind == EK_REPL || le_kind == EK_UN); -- x = b.getInt(); -- -- assert(!b.le_bci || prevBCI == to_bci(prevBII)); -- switch (b.le_bci) { -- case EK_BCI: // PH: transmit R(bci), store bci -- x = to_bci(prevBII = x); -- prevBCI = x; -- break; -- case EK_BCID: // POH: transmit D(R(bci)), store bci -- x = to_bci(prevBII += x); -- prevBCI = x; -- break; -- case EK_BCO: // OH: transmit D(R(bci)), store D(bci) -- x = to_bci(prevBII += x) - prevBCI; -- prevBCI += x; -- break; -- } -- assert(!b.le_bci || prevBCI == to_bci(prevBII)); -- -- switch (b.le_len) { -- case 0: break; -- case 1: putu1(x); break; -- case 2: putu2(x); break; -- case 4: putu4(x); break; -- default: assert(false); -- } -+ assert(le_kind == EK_INT || le_kind == EK_REPL || le_kind == EK_UN); -+ x = b.getInt(); -+ -+ assert(!b.le_bci || prevBCI == to_bci(prevBII)); -+ switch (b.le_bci) { -+ case EK_BCI: // PH: transmit R(bci), store bci -+ x = to_bci(prevBII = x); -+ prevBCI = x; -+ break; -+ case EK_BCID: // POH: transmit D(R(bci)), store bci -+ x = to_bci(prevBII += x); -+ prevBCI = x; -+ break; -+ case EK_BCO: // OH: transmit D(R(bci)), store D(bci) -+ x = to_bci(prevBII += x) - prevBCI; -+ prevBCI += x; -+ break; -+ } -+ assert(!b.le_bci || prevBCI == to_bci(prevBII)); -+ -+ switch (b.le_len) { -+ case 0: break; -+ case 1: putu1(x); break; -+ case 2: putu2(x); break; -+ case 4: putu4(x); break; -+ default: assert(false); -+ } - } - } - -@@ -2597,7 +2603,7 @@ void unpacker::putlayout(band** body) { - case EK_REPL: - // x is the repeat count - while (x-- > 0) { -- putlayout(b.le_body); -+ putlayout(b.le_body); - } - break; - case EK_UN: -@@ -2606,10 +2612,10 @@ void unpacker::putlayout(band** body) { - break; - case EK_CALL: - { -- band& cble = *b.le_body[0]; -- assert(cble.le_kind == EK_CBLE); -- assert(cble.le_len == b.le_len); -- putlayout(cble.le_body); -+ band& cble = *b.le_body[0]; -+ assert(cble.le_kind == EK_CBLE); -+ assert(cble.le_len == b.le_len); -+ putlayout(cble.le_body); - } - break; - -@@ -2635,7 +2641,7 @@ void unpacker::read_files() { - // FO_IS_CLASS_STUB might be set, causing overlap between classes and files - for (int i = 0; i < file_count; i++) { - if ((file_options.getInt() & FO_IS_CLASS_STUB) != 0) { -- allFiles -= 1; // this one counts as both class and file -+ allFiles -= 1; // this one counts as both class and file - } - } - file_options.rewind(); -@@ -2646,9 +2652,9 @@ void unpacker::read_files() { - - maybe_inline - void unpacker::get_code_header(int& max_stack, -- int& max_na_locals, -- int& handler_count, -- int& cflags) { -+ int& max_na_locals, -+ int& handler_count, -+ int& cflags) { - int sc = code_headers.getByte(); - if (sc == 0) { - max_stack = max_na_locals = handler_count = cflags = -1; -@@ -2801,7 +2807,7 @@ inline // called exactly once => inline - inline // called exactly once => inline - void unpacker::read_bcs() { - printcr(3, "reading compressed bytecodes and operands for %d codes...", -- code_count); -+ code_count); - - // read from bc_codes and bc_case_count - fillbytes all_switch_ops; -@@ -2822,80 +2828,80 @@ void unpacker::read_bcs() { - // Scan one method: - for (;;) { - if (opptr+2 > oplimit) { -- rp = opptr; -- ensure_input(2); -- oplimit = rplimit; -- rp = rp0; // back up -+ rp = opptr; -+ ensure_input(2); -+ oplimit = rplimit; -+ rp = rp0; // back up - } - if (opptr == oplimit) { abort(); break; } - int bc = *opptr++ & 0xFF; - bool isWide = false; - if (bc == bc_wide) { -- if (opptr == oplimit) { abort(); break; } -- bc = *opptr++ & 0xFF; -- isWide = true; -+ if (opptr == oplimit) { abort(); break; } -+ bc = *opptr++ & 0xFF; -+ isWide = true; - } - // Adjust expectations of various band sizes. - switch (bc) { - case bc_tableswitch: - case bc_lookupswitch: -- all_switch_ops.addByte(bc); -- break; -+ all_switch_ops.addByte(bc); -+ break; - case bc_iinc: -- bc_local.expectMoreLength(1); -- bc_which = isWide ? &bc_short : &bc_byte; -- bc_which->expectMoreLength(1); -- break; -+ bc_local.expectMoreLength(1); -+ bc_which = isWide ? &bc_short : &bc_byte; -+ bc_which->expectMoreLength(1); -+ break; - case bc_sipush: -- bc_short.expectMoreLength(1); -- break; -+ bc_short.expectMoreLength(1); -+ break; - case bc_bipush: -- bc_byte.expectMoreLength(1); -- break; -+ bc_byte.expectMoreLength(1); -+ break; - case bc_newarray: -- bc_byte.expectMoreLength(1); -- break; -+ bc_byte.expectMoreLength(1); -+ break; - case bc_multianewarray: -- assert(ref_band_for_op(bc) == &bc_classref); -- bc_classref.expectMoreLength(1); -- bc_byte.expectMoreLength(1); -- break; -+ assert(ref_band_for_op(bc) == &bc_classref); -+ bc_classref.expectMoreLength(1); -+ bc_byte.expectMoreLength(1); -+ break; - case bc_ref_escape: -- bc_escrefsize.expectMoreLength(1); -- bc_escref.expectMoreLength(1); -- break; -+ bc_escrefsize.expectMoreLength(1); -+ bc_escref.expectMoreLength(1); -+ break; - case bc_byte_escape: -- bc_escsize.expectMoreLength(1); -- // bc_escbyte will have to be counted too -- break; -+ bc_escsize.expectMoreLength(1); -+ // bc_escbyte will have to be counted too -+ break; - default: -- if (is_invoke_init_op(bc)) { -- bc_initref.expectMoreLength(1); -- break; -- } -- bc_which = ref_band_for_self_op(bc, isAload, junkBC); -- if (bc_which != null) { -- bc_which->expectMoreLength(1); -- break; -- } -- if (is_branch_op(bc)) { -- bc_label.expectMoreLength(1); -- break; -- } -- bc_which = ref_band_for_op(bc); -- if (bc_which != null) { -- bc_which->expectMoreLength(1); -- assert(bc != bc_multianewarray); // handled elsewhere -- break; -- } -- if (is_local_slot_op(bc)) { -- bc_local.expectMoreLength(1); -- break; -- } -- break; -+ if (is_invoke_init_op(bc)) { -+ bc_initref.expectMoreLength(1); -+ break; -+ } -+ bc_which = ref_band_for_self_op(bc, isAload, junkBC); -+ if (bc_which != null) { -+ bc_which->expectMoreLength(1); -+ break; -+ } -+ if (is_branch_op(bc)) { -+ bc_label.expectMoreLength(1); -+ break; -+ } -+ bc_which = ref_band_for_op(bc); -+ if (bc_which != null) { -+ bc_which->expectMoreLength(1); -+ assert(bc != bc_multianewarray); // handled elsewhere -+ break; -+ } -+ if (is_local_slot_op(bc)) { -+ bc_local.expectMoreLength(1); -+ break; -+ } -+ break; - case bc_end_marker: -- // Increment k and test against code_count. -- goto doneScanningMethod; -+ // Increment k and test against code_count. -+ goto doneScanningMethod; - } - } - doneScanningMethod:{} -@@ -2929,15 +2935,15 @@ void unpacker::read_bcs() { - bc_escbyte.readData(bc_escsize.getIntTotal()); - - printcr(3, "scanned %d opcode and %d operand bytes for %d codes...", -- (int)(bc_codes.size()), -- (int)(bc_escsize.maxRP() - bc_case_value.minRP()), -- code_count); -+ (int)(bc_codes.size()), -+ (int)(bc_escsize.maxRP() - bc_case_value.minRP()), -+ code_count); - } - - void unpacker::read_bands() { - byte* rp0 = rp; - int i; -- -+ CHECK; - read_file_header(); - CHECK; - -@@ -3063,8 +3069,8 @@ void cpool::expandSignatures() { - int c = form.ptr[j]; - buf.addByte(c); - if (c == 'L') { -- entry* cls = e.refs[refnum++]; -- buf.append(cls->className()->asUtf8()); -+ entry* cls = e.refs[refnum++]; -+ buf.append(cls->className()->asUtf8()); - } - } - assert(refnum == e.nrefs); -@@ -3099,7 +3105,7 @@ void cpool::expandSignatures() { - for (int j = 0; j < e.nrefs; j++) { - entry*& e2 = e.refs[j]; - if (e2 != null && e2->tag == CONSTANT_Signature) -- e2 = e2->refs[0]; -+ e2 = e2->refs[0]; - } - } - } -@@ -3141,14 +3147,14 @@ void cpool::initMemberIndexes() { - int fc = field_counts[i]; - int mc = method_counts[i]; - all_indexes[i*2+0].init(fc, field_ix+fbase, -- CONSTANT_Fieldref + SUBINDEX_BIT); -+ CONSTANT_Fieldref + SUBINDEX_BIT); - all_indexes[i*2+1].init(mc, method_ix+mbase, -- CONSTANT_Methodref + SUBINDEX_BIT); -+ CONSTANT_Methodref + SUBINDEX_BIT); - // reuse field_counts and member_counts as fill pointers: - field_counts[i] = fbase; - method_counts[i] = mbase; - printcr(3, "class %d fields @%d[%d] methods @%d[%d]", -- i, fbase, fc, mbase, mc); -+ i, fbase, fc, mbase, mc); - fbase += fc+1; - mbase += mc+1; - // (the +1 leaves a space between every subarray) -@@ -3178,7 +3184,7 @@ void cpool::initMemberIndexes() { - cpindex* fix = getFieldIndex(cls); - cpindex* mix = getMethodIndex(cls); - printcr(2, "field and method index for %s [%d] [%d]", -- cls->string(), mix->len, fix->len); -+ cls->string(), mix->len, fix->len); - prevord = -1; - for (j = 0, len = fix->len; j < len; j++) { - entry* f = fix->get(j); -@@ -3204,7 +3210,7 @@ void cpool::initMemberIndexes() { - } - assert(fvisited == nfields); - assert(mvisited == nmethods); --#endif -+#endif - - // Free intermediate buffers. - u->free_temps(); -@@ -3438,8 +3444,8 @@ bool unpacker::set_option(const char* pr - bool unpacker::set_option(const char* prop, const char* value) { - if (prop == NULL) return false; - if (strcmp(prop, UNPACK_DEFLATE_HINT) == 0) { -- deflate_hint_or_zero = ( (value == null || strcmp(value, "keep") == 0) -- ? 0: BOOL_TF(value) ? +1: -1); -+ deflate_hint_or_zero = ( (value == null || strcmp(value, "keep") == 0) -+ ? 0: BOOL_TF(value) ? +1: -1); - #ifdef HAVE_STRIP - } else if (strcmp(prop, UNPACK_STRIP_COMPILE) == 0) { - strip_compile = STR_TF(value); -@@ -3466,7 +3472,7 @@ bool unpacker::set_option(const char* pr - } else { - modification_time_or_zero = atoi(value); - if (modification_time_or_zero == 0) -- modification_time_or_zero = 1; // make non-zero -+ modification_time_or_zero = 1; // make non-zero - } - } else if (strcmp(prop, UNPACK_LOG_FILE) == 0) { - log_file = (value == null)? value: saveStr(value); -@@ -3597,14 +3603,16 @@ void unpacker::dump_options() { - - - // Usage: unpack a byte buffer --// packptr is a reference to byte buffer containing a -+// packptr is a reference to byte buffer containing a - // packed file and len is the length of the buffer. - // If null, the callback is used to fill an internal buffer. - void unpacker::start(void* packptr, size_t len) { -+ CHECK; - NOT_PRODUCT(debug_u = this); - if (packptr != null && len != 0) { - inbytes.set((byte*) packptr, len); - } -+ CHECK; - read_bands(); - } - -@@ -3735,6 +3743,7 @@ void unpacker::write_bc_ops() { - NOT_PRODUCT(bc_superfield.setIndex(null)); - NOT_PRODUCT(bc_supermethod.setIndex(null)); - } -+ CHECK; - - for (int curIP = 0; ; curIP++) { - int curPC = wpoffset() - codeBase; -@@ -3760,196 +3769,197 @@ void unpacker::write_bc_ops() { - case bc_tableswitch: // apc: (df, lo, hi, (hi-lo+1)*(label)) - case bc_lookupswitch: // apc: (df, nc, nc*(case, label)) - { -- int caseCount = bc_case_count.getInt(); -- while (((wpoffset() - codeBase) % 4) != 0) putu1_fast(0); -- ensure_put_space(30 + caseCount*8); -- put_label(curIP, 4); //int df = bc_label.getInt(); -- if (bc == bc_tableswitch) { -- int lo = bc_case_value.getInt(); -- int hi = lo + caseCount-1; -- putu4(lo); -- putu4(hi); -- for (int j = 0; j < caseCount; j++) { -- put_label(curIP, 4); //int lVal = bc_label.getInt(); -- //int cVal = lo + j; -- } -- } else { -- putu4(caseCount); -- for (int j = 0; j < caseCount; j++) { -- int cVal = bc_case_value.getInt(); -- putu4(cVal); -- put_label(curIP, 4); //int lVal = bc_label.getInt(); -- } -- } -- assert(to_bci(curIP) == curPC); -- continue; -+ int caseCount = bc_case_count.getInt(); -+ while (((wpoffset() - codeBase) % 4) != 0) putu1_fast(0); -+ ensure_put_space(30 + caseCount*8); -+ put_label(curIP, 4); //int df = bc_label.getInt(); -+ if (bc == bc_tableswitch) { -+ int lo = bc_case_value.getInt(); -+ int hi = lo + caseCount-1; -+ putu4(lo); -+ putu4(hi); -+ for (int j = 0; j < caseCount; j++) { -+ put_label(curIP, 4); //int lVal = bc_label.getInt(); -+ //int cVal = lo + j; -+ } -+ } else { -+ putu4(caseCount); -+ for (int j = 0; j < caseCount; j++) { -+ int cVal = bc_case_value.getInt(); -+ putu4(cVal); -+ put_label(curIP, 4); //int lVal = bc_label.getInt(); -+ } -+ } -+ assert(to_bci(curIP) == curPC); -+ continue; - } - case bc_iinc: - { -- int local = bc_local.getInt(); -- int delta = (isWide ? bc_short : bc_byte).getInt(); -- if (isWide) { -- putu2(local); -- putu2(delta); -- } else { -- putu1_fast(local); -- putu1_fast(delta); -- } -- continue; -+ int local = bc_local.getInt(); -+ int delta = (isWide ? bc_short : bc_byte).getInt(); -+ if (isWide) { -+ putu2(local); -+ putu2(delta); -+ } else { -+ putu1_fast(local); -+ putu1_fast(delta); -+ } -+ continue; - } - case bc_sipush: - { -- int val = bc_short.getInt(); -- putu2(val); -- continue; -+ int val = bc_short.getInt(); -+ putu2(val); -+ continue; - } - case bc_bipush: - case bc_newarray: - { -- int val = bc_byte.getByte(); -- putu1_fast(val); -- continue; -+ int val = bc_byte.getByte(); -+ putu1_fast(val); -+ continue; - } - case bc_ref_escape: - { -- // Note that insnMap has one entry for this. -+ // Note that insnMap has one entry for this. - --wp; // not really part of the code -- int size = bc_escrefsize.getInt(); -- entry* ref = bc_escref.getRefN(); -- CHECK; -- switch (size) { -- case 1: putu1ref(ref); break; -- case 2: putref(ref); break; -- default: assert(false); -- } -- continue; -+ int size = bc_escrefsize.getInt(); -+ entry* ref = bc_escref.getRefN(); -+ CHECK; -+ switch (size) { -+ case 1: putu1ref(ref); break; -+ case 2: putref(ref); break; -+ default: assert(false); -+ } -+ continue; - } - case bc_byte_escape: - { -- // Note that insnMap has one entry for all these bytes. -+ // Note that insnMap has one entry for all these bytes. - --wp; // not really part of the code -- int size = bc_escsize.getInt(); -- ensure_put_space(size); -- for (int j = 0; j < size; j++) -- putu1_fast(bc_escbyte.getByte()); -- continue; -+ int size = bc_escsize.getInt(); -+ ensure_put_space(size); -+ for (int j = 0; j < size; j++) -+ putu1_fast(bc_escbyte.getByte()); -+ continue; - } - default: - if (is_invoke_init_op(bc)) { -- origBC = bc_invokespecial; -- entry* classRef; -- switch (bc - _invokeinit_op) { -- case _invokeinit_self_option: classRef = thisClass; break; -- case _invokeinit_super_option: classRef = superClass; break; -- default: assert(bc == _invokeinit_op+_invokeinit_new_option); -- case _invokeinit_new_option: classRef = newClass; break; -- } -- wp[-1] = origBC; // overwrite with origBC -- int coding = bc_initref.getInt(); -- // Find the nth overloading of <init> in classRef. -- entry* ref = null; -- cpindex* ix = (classRef == null)? null: cp.getMethodIndex(classRef); -- for (int j = 0, which_init = 0; ; j++) { -- ref = (ix == null)? null: ix->get(j); -- if (ref == null) break; // oops, bad input -- assert(ref->tag == CONSTANT_Methodref); -- if (ref->memberDescr()->descrName() == cp.sym[cpool::s_lt_init_gt]) { -- if (which_init++ == coding) break; -- } -- } -- putref(ref); -- continue; -+ origBC = bc_invokespecial; -+ entry* classRef; -+ switch (bc - _invokeinit_op) { -+ case _invokeinit_self_option: classRef = thisClass; break; -+ case _invokeinit_super_option: classRef = superClass; break; -+ default: assert(bc == _invokeinit_op+_invokeinit_new_option); -+ case _invokeinit_new_option: classRef = newClass; break; -+ } -+ wp[-1] = origBC; // overwrite with origBC -+ int coding = bc_initref.getInt(); -+ // Find the nth overloading of <init> in classRef. -+ entry* ref = null; -+ cpindex* ix = cp.getMethodIndex(classRef); -+ CHECK; -+ for (int j = 0, which_init = 0; ; j++) { -+ ref = (ix == null)? null: ix->get(j); -+ if (ref == null) break; // oops, bad input -+ assert(ref->tag == CONSTANT_Methodref); -+ if (ref->memberDescr()->descrName() == cp.sym[cpool::s_lt_init_gt]) { -+ if (which_init++ == coding) break; -+ } -+ } -+ putref(ref); -+ continue; - } - bc_which = ref_band_for_self_op(bc, isAload, origBC); - if (bc_which != null) { -- if (!isAload) { -- wp[-1] = origBC; // overwrite with origBC -- } else { -- wp[-1] = bc_aload_0; // overwrite with _aload_0 -- // Note: insnMap keeps the _aload_0 separate. -- bcimap.add(++curPC); -- ++curIP; -- putu1_fast(origBC); -- } -- entry* ref = bc_which->getRef(); -- CHECK; -- putref(ref); -- continue; -+ if (!isAload) { -+ wp[-1] = origBC; // overwrite with origBC -+ } else { -+ wp[-1] = bc_aload_0; // overwrite with _aload_0 -+ // Note: insnMap keeps the _aload_0 separate. -+ bcimap.add(++curPC); -+ ++curIP; -+ putu1_fast(origBC); -+ } -+ entry* ref = bc_which->getRef(); -+ CHECK; -+ putref(ref); -+ continue; - } - if (is_branch_op(bc)) { -- //int lVal = bc_label.getInt(); -- if (bc < bc_goto_w) { -- put_label(curIP, 2); //putu2(lVal & 0xFFFF); -- } else { -- assert(bc <= bc_jsr_w); -- put_label(curIP, 4); //putu4(lVal); -- } -- assert(to_bci(curIP) == curPC); -- continue; -+ //int lVal = bc_label.getInt(); -+ if (bc < bc_goto_w) { -+ put_label(curIP, 2); //putu2(lVal & 0xFFFF); -+ } else { -+ assert(bc <= bc_jsr_w); -+ put_label(curIP, 4); //putu4(lVal); -+ } -+ assert(to_bci(curIP) == curPC); -+ continue; - } - bc_which = ref_band_for_op(bc); - if (bc_which != null) { -- entry* ref = bc_which->getRefCommon(bc_which->ix, bc_which->nullOK); -- CHECK; -- if (ref == null && bc_which == &bc_classref) { -- // Shorthand for class self-references. -- ref = thisClass; -- } -- origBC = bc; -- switch (bc) { -- case bc_ildc: -- case bc_cldc: -- case bc_fldc: -- case bc_aldc: -- origBC = bc_ldc; -- break; -- case bc_ildc_w: -- case bc_cldc_w: -- case bc_fldc_w: -- case bc_aldc_w: -- origBC = bc_ldc_w; -- break; -- case bc_lldc2_w: -- case bc_dldc2_w: -- origBC = bc_ldc2_w; -- break; -- case bc_new: -- newClass = ref; -- break; -- } -- wp[-1] = origBC; // overwrite with origBC -- if (origBC == bc_ldc) { -- putu1ref(ref); -- } else { -- putref(ref); -- } -- if (origBC == bc_multianewarray) { -- // Copy the trailing byte also. -- int val = bc_byte.getByte(); -- putu1_fast(val); -- } else if (origBC == bc_invokeinterface) { -- int argSize = ref->memberDescr()->descrType()->typeSize(); -- putu1_fast(1 + argSize); -- putu1_fast(0); -- } -- continue; -+ entry* ref = bc_which->getRefCommon(bc_which->ix, bc_which->nullOK); -+ CHECK; -+ if (ref == null && bc_which == &bc_classref) { -+ // Shorthand for class self-references. -+ ref = thisClass; -+ } -+ origBC = bc; -+ switch (bc) { -+ case bc_ildc: -+ case bc_cldc: -+ case bc_fldc: -+ case bc_aldc: -+ origBC = bc_ldc; -+ break; -+ case bc_ildc_w: -+ case bc_cldc_w: -+ case bc_fldc_w: -+ case bc_aldc_w: -+ origBC = bc_ldc_w; -+ break; -+ case bc_lldc2_w: -+ case bc_dldc2_w: -+ origBC = bc_ldc2_w; -+ break; -+ case bc_new: -+ newClass = ref; -+ break; -+ } -+ wp[-1] = origBC; // overwrite with origBC -+ if (origBC == bc_ldc) { -+ putu1ref(ref); -+ } else { -+ putref(ref); -+ } -+ if (origBC == bc_multianewarray) { -+ // Copy the trailing byte also. -+ int val = bc_byte.getByte(); -+ putu1_fast(val); -+ } else if (origBC == bc_invokeinterface) { -+ int argSize = ref->memberDescr()->descrType()->typeSize(); -+ putu1_fast(1 + argSize); -+ putu1_fast(0); -+ } -+ continue; - } - if (is_local_slot_op(bc)) { -- int local = bc_local.getInt(); -- if (isWide) { -- putu2(local); -- if (bc == bc_iinc) { -- int iVal = bc_short.getInt(); -- putu2(iVal); -- } -- } else { -- putu1_fast(local); -- if (bc == bc_iinc) { -- int iVal = bc_byte.getByte(); -- putu1_fast(iVal); -- } -- } -- continue; -+ int local = bc_local.getInt(); -+ if (isWide) { -+ putu2(local); -+ if (bc == bc_iinc) { -+ int iVal = bc_short.getInt(); -+ putu2(iVal); -+ } -+ } else { -+ putu1_fast(local); -+ if (bc == bc_iinc) { -+ int iVal = bc_byte.getByte(); -+ putu1_fast(iVal); -+ } -+ } -+ continue; - } - // Random bytecode. Just copy it. - assert(bc < bc_bytecode_limit); -@@ -4073,78 +4083,80 @@ int unpacker::write_attrs(int attrc, jul - case ADH_BYTE(ATTR_CONTEXT_FIELD, X_ATTR_OVERFLOW): - case ADH_BYTE(ATTR_CONTEXT_METHOD, X_ATTR_OVERFLOW): - case ADH_BYTE(ATTR_CONTEXT_CODE, X_ATTR_OVERFLOW): -- // no attribute at all, so back up on this one -- wp = wp_at(abase); -- continue; -+ // no attribute at all, so back up on this one -+ wp = wp_at(abase); -+ continue; - - case ADH_BYTE(ATTR_CONTEXT_CLASS, CLASS_ATTR_ClassFile_version): -- cur_class_minver = class_ClassFile_version_minor_H.getInt(); -- cur_class_majver = class_ClassFile_version_major_H.getInt(); -- // back up; not a real attribute -- wp = wp_at(abase); -- continue; -+ cur_class_minver = class_ClassFile_version_minor_H.getInt(); -+ cur_class_majver = class_ClassFile_version_major_H.getInt(); -+ // back up; not a real attribute -+ wp = wp_at(abase); -+ continue; - - case ADH_BYTE(ATTR_CONTEXT_CLASS, CLASS_ATTR_InnerClasses): -- // note the existence of this attr, but save for later -- if (cur_class_has_local_ics) -- abort("too many InnerClasses attrs"); -- cur_class_has_local_ics = true; -- wp = wp_at(abase); -- continue; -+ // note the existence of this attr, but save for later -+ if (cur_class_has_local_ics) -+ abort("too many InnerClasses attrs"); -+ cur_class_has_local_ics = true; -+ wp = wp_at(abase); -+ continue; - - case ADH_BYTE(ATTR_CONTEXT_CLASS, CLASS_ATTR_SourceFile): -- aname = cp.sym[cpool::s_SourceFile]; -- ref = class_SourceFile_RUN.getRefN(); -- CHECK_0; -- if (ref == null) { -- bytes& n = cur_class->ref(0)->value.b; -- // parse n = (<pkg>/)*<outer>?($<id>)* -- int pkglen = lastIndexOf(SLASH_MIN, SLASH_MAX, n, n.len)+1; -- bytes prefix = n.slice(pkglen, n.len); -- for (;;) { -- // Work backwards, finding all '$', '#', etc. -- int dollar = lastIndexOf(DOLLAR_MIN, DOLLAR_MAX, prefix, prefix.len); -- if (dollar < 0) break; -- prefix = prefix.slice(0, dollar); -- } -- const char* suffix = ".java"; -- int len = prefix.len + strlen(suffix); -- bytes name; name.set(T_NEW(byte, add_size(len, 1)), len); -- name.strcat(prefix).strcat(suffix); -- ref = cp.ensureUtf8(name); -- } -- putref(ref); -- break; -+ aname = cp.sym[cpool::s_SourceFile]; -+ ref = class_SourceFile_RUN.getRefN(); -+ CHECK_0; -+ if (ref == null) { -+ bytes& n = cur_class->ref(0)->value.b; -+ // parse n = (<pkg>/)*<outer>?($<id>)* -+ int pkglen = lastIndexOf(SLASH_MIN, SLASH_MAX, n, n.len)+1; -+ bytes prefix = n.slice(pkglen, n.len); -+ for (;;) { -+ // Work backwards, finding all '$', '#', etc. -+ int dollar = lastIndexOf(DOLLAR_MIN, DOLLAR_MAX, prefix, prefix.len); -+ if (dollar < 0) break; -+ prefix = prefix.slice(0, dollar); -+ } -+ const char* suffix = ".java"; -+ int len = prefix.len + strlen(suffix); -+ bytes name; name.set(T_NEW(byte, add_size(len, 1)), len); -+ name.strcat(prefix).strcat(suffix); -+ ref = cp.ensureUtf8(name); -+ } -+ putref(ref); -+ break; - - case ADH_BYTE(ATTR_CONTEXT_CLASS, CLASS_ATTR_EnclosingMethod): -- aname = cp.sym[cpool::s_EnclosingMethod]; -- putref(class_EnclosingMethod_RC.getRefN()); -- putref(class_EnclosingMethod_RDN.getRefN()); -- break; -+ aname = cp.sym[cpool::s_EnclosingMethod]; -+ putref(class_EnclosingMethod_RC.getRefN()); -+ CHECK_0; -+ putref(class_EnclosingMethod_RDN.getRefN()); -+ break; - - case ADH_BYTE(ATTR_CONTEXT_FIELD, FIELD_ATTR_ConstantValue): -- aname = cp.sym[cpool::s_ConstantValue]; -- putref(field_ConstantValue_KQ.getRefUsing(cp.getKQIndex())); -- break; -+ aname = cp.sym[cpool::s_ConstantValue]; -+ putref(field_ConstantValue_KQ.getRefUsing(cp.getKQIndex())); -+ break; - - case ADH_BYTE(ATTR_CONTEXT_METHOD, METHOD_ATTR_Code): -- aname = cp.sym[cpool::s_Code]; -- write_code(); -- break; -+ aname = cp.sym[cpool::s_Code]; -+ write_code(); -+ break; - - case ADH_BYTE(ATTR_CONTEXT_METHOD, METHOD_ATTR_Exceptions): -- aname = cp.sym[cpool::s_Exceptions]; -- putu2(count = method_Exceptions_N.getInt()); -- for (j = 0; j < count; j++) { -- putref(method_Exceptions_RC.getRefN()); -- } -- break; -+ aname = cp.sym[cpool::s_Exceptions]; -+ putu2(count = method_Exceptions_N.getInt()); -+ for (j = 0; j < count; j++) { -+ putref(method_Exceptions_RC.getRefN()); -+ CHECK_0; -+ } -+ break; - - case ADH_BYTE(ATTR_CONTEXT_CODE, CODE_ATTR_StackMapTable): -- aname = cp.sym[cpool::s_StackMapTable]; -+ aname = cp.sym[cpool::s_StackMapTable]; - // (keep this code aligned with its brother in unpacker::read_attrs) -- putu2(count = code_StackMapTable_N.getInt()); -- for (j = 0; j < count; j++) { -+ putu2(count = code_StackMapTable_N.getInt()); -+ for (j = 0; j < count; j++) { - int tag = code_StackMapTable_frame_T.getByte(); - putu1(tag); - if (tag <= 127) { -@@ -4160,109 +4172,115 @@ int unpacker::write_attrs(int attrc, jul - // (253) [(1)(2)(2)] - // (254) [(1)(2)(2)(2)] - putu2(code_StackMapTable_offset.getInt()); -+ CHECK_0; - for (int j2 = (tag - 251); j2 > 0; j2--) { - put_stackmap_type(); -+ CHECK_0; - } - } else { - // (255) [(1)NH[(2)]NH[(2)]] - putu2(code_StackMapTable_offset.getInt()); - putu2(j2 = code_StackMapTable_local_N.getInt()); -- while (j2-- > 0) put_stackmap_type(); -+ while (j2-- > 0) {put_stackmap_type(); CHECK_0;} - putu2(j2 = code_StackMapTable_stack_N.getInt()); -- while (j2-- > 0) put_stackmap_type(); -+ while (j2-- > 0) {put_stackmap_type(); CHECK_0;} - } -- } -- break; -+ } -+ break; - - case ADH_BYTE(ATTR_CONTEXT_CODE, CODE_ATTR_LineNumberTable): -- aname = cp.sym[cpool::s_LineNumberTable]; -- putu2(count = code_LineNumberTable_N.getInt()); -- for (j = 0; j < count; j++) { -- putu2(to_bci(code_LineNumberTable_bci_P.getInt())); -- putu2(code_LineNumberTable_line.getInt()); -- } -- break; -+ aname = cp.sym[cpool::s_LineNumberTable]; -+ putu2(count = code_LineNumberTable_N.getInt()); -+ for (j = 0; j < count; j++) { -+ putu2(to_bci(code_LineNumberTable_bci_P.getInt())); -+ putu2(code_LineNumberTable_line.getInt()); -+ } -+ break; - - case ADH_BYTE(ATTR_CONTEXT_CODE, CODE_ATTR_LocalVariableTable): -- aname = cp.sym[cpool::s_LocalVariableTable]; -- putu2(count = code_LocalVariableTable_N.getInt()); -- for (j = 0; j < count; j++) { -- int bii = code_LocalVariableTable_bci_P.getInt(); -- int bci = to_bci(bii); -- putu2(bci); -- bii += code_LocalVariableTable_span_O.getInt(); -- putu2(to_bci(bii) - bci); -- putref(code_LocalVariableTable_name_RU.getRefN()); -- putref(code_LocalVariableTable_type_RS.getRefN()); -- putu2(code_LocalVariableTable_slot.getInt()); -- } -- break; -+ aname = cp.sym[cpool::s_LocalVariableTable]; -+ putu2(count = code_LocalVariableTable_N.getInt()); -+ for (j = 0; j < count; j++) { -+ int bii = code_LocalVariableTable_bci_P.getInt(); -+ int bci = to_bci(bii); -+ putu2(bci); -+ bii += code_LocalVariableTable_span_O.getInt(); -+ putu2(to_bci(bii) - bci); -+ putref(code_LocalVariableTable_name_RU.getRefN()); -+ CHECK_0; -+ putref(code_LocalVariableTable_type_RS.getRefN()); -+ CHECK_0; -+ putu2(code_LocalVariableTable_slot.getInt()); -+ } -+ break; - - case ADH_BYTE(ATTR_CONTEXT_CODE, CODE_ATTR_LocalVariableTypeTable): -- aname = cp.sym[cpool::s_LocalVariableTypeTable]; -- putu2(count = code_LocalVariableTypeTable_N.getInt()); -- for (j = 0; j < count; j++) { -- int bii = code_LocalVariableTypeTable_bci_P.getInt(); -- int bci = to_bci(bii); -- putu2(bci); -- bii += code_LocalVariableTypeTable_span_O.getInt(); -- putu2(to_bci(bii) - bci); -- putref(code_LocalVariableTypeTable_name_RU.getRefN()); -- putref(code_LocalVariableTypeTable_type_RS.getRefN()); -- putu2(code_LocalVariableTypeTable_slot.getInt()); -- } -- break; -+ aname = cp.sym[cpool::s_LocalVariableTypeTable]; -+ putu2(count = code_LocalVariableTypeTable_N.getInt()); -+ for (j = 0; j < count; j++) { -+ int bii = code_LocalVariableTypeTable_bci_P.getInt(); -+ int bci = to_bci(bii); -+ putu2(bci); -+ bii += code_LocalVariableTypeTable_span_O.getInt(); -+ putu2(to_bci(bii) - bci); -+ putref(code_LocalVariableTypeTable_name_RU.getRefN()); -+ CHECK_0; -+ putref(code_LocalVariableTypeTable_type_RS.getRefN()); -+ CHECK_0; -+ putu2(code_LocalVariableTypeTable_slot.getInt()); -+ } -+ break; - - case ADH_BYTE(ATTR_CONTEXT_CLASS, X_ATTR_Signature): -- aname = cp.sym[cpool::s_Signature]; -- putref(class_Signature_RS.getRefN()); -- break; -+ aname = cp.sym[cpool::s_Signature]; -+ putref(class_Signature_RS.getRefN()); -+ break; - - case ADH_BYTE(ATTR_CONTEXT_FIELD, X_ATTR_Signature): -- aname = cp.sym[cpool::s_Signature]; -- putref(field_Signature_RS.getRefN()); -- break; -+ aname = cp.sym[cpool::s_Signature]; -+ putref(field_Signature_RS.getRefN()); -+ break; - - case ADH_BYTE(ATTR_CONTEXT_METHOD, X_ATTR_Signature): -- aname = cp.sym[cpool::s_Signature]; -- putref(method_Signature_RS.getRefN()); -- break; -+ aname = cp.sym[cpool::s_Signature]; -+ putref(method_Signature_RS.getRefN()); -+ break; - - case ADH_BYTE(ATTR_CONTEXT_CLASS, X_ATTR_Deprecated): - case ADH_BYTE(ATTR_CONTEXT_FIELD, X_ATTR_Deprecated): - case ADH_BYTE(ATTR_CONTEXT_METHOD, X_ATTR_Deprecated): -- aname = cp.sym[cpool::s_Deprecated]; -- // no data -- break; -- } -- } -- -+ aname = cp.sym[cpool::s_Deprecated]; -+ // no data -+ break; -+ } -+ } -+ CHECK_0; - if (aname == null) { - // Unparse a compressor-defined attribute. - layout_definition* lo = ad.getLayout(idx); - if (lo == null) { -- abort("bad layout index"); -- break; -+ abort("bad layout index"); -+ break; - } - assert(lo->idx == idx); - aname = lo->nameEntry; - if (aname == null) { -- bytes nameb; nameb.set(lo->name); -- aname = cp.ensureUtf8(nameb); -- // Cache the name entry for next time. -- lo->nameEntry = aname; -+ bytes nameb; nameb.set(lo->name); -+ aname = cp.ensureUtf8(nameb); -+ // Cache the name entry for next time. -+ lo->nameEntry = aname; - } - // Execute all the layout elements. - band** bands = lo->bands(); - if (lo->hasCallables()) { -- band& cble = *bands[0]; -- assert(cble.le_kind == EK_CBLE); -- bands = cble.le_body; -+ band& cble = *bands[0]; -+ assert(cble.le_kind == EK_CBLE); -+ bands = cble.le_body; - } - putlayout(bands); - } - -- if (aname == null) -+ if (aname == null) - abort("bad attribute index"); - CHECK_0; - -@@ -4335,8 +4353,8 @@ void unpacker::write_classfile_tail() { - julong indexMask = ad.flagIndexMask(); - - cur_class = class_this.getRef(); -+ CHECK; - cur_super = class_super.getRef(); -- - CHECK; - - if (cur_super == cur_class) cur_super = null; -@@ -4349,6 +4367,7 @@ void unpacker::write_classfile_tail() { - putu2(num = class_interface_count.getInt()); - for (i = 0; i < num; i++) { - putref(class_interface.getRef()); -+ CHECK; - } - - write_members(class_field_count.getInt(), ATTR_CONTEXT_FIELD); -@@ -4389,8 +4408,8 @@ void unpacker::write_classfile_tail() { - entry& e = *oes[i]; - if (e.tag != CONSTANT_Class) continue; // wrong sort - for (inner_class* ic = cp.getIC(&e); -- ic != null; -- ic = cp.getIC(ic->outer)) { -+ ic != null; -+ ic = cp.getIC(ic->outer)) { - if (ic->requested) break; // already processed - ic->requested = true; - requested_ics.add(ic); -@@ -4421,22 +4440,24 @@ void unpacker::write_classfile_tail() { - if (flags == 0) { - // The extra IC is simply a copy of a global IC. - if (global_ic == null) { -- abort("bad reference to inner class"); -- break; -+ abort("bad reference to inner class"); -+ break; - } - extra_ic = (*global_ic); // fill in rest of fields - } else { - flags &= ~ACC_IC_LONG_FORM; // clear high bit if set to get clean zero - extra_ic.flags = flags; - extra_ic.outer = class_InnerClasses_outer_RCN.getRefN(); -+ CHECK; - extra_ic.name = class_InnerClasses_name_RUN.getRefN(); -+ CHECK; - // Detect if this is an exact copy of the global tuple. - if (global_ic != null) { -- if (global_ic->flags != extra_ic.flags || -- global_ic->outer != extra_ic.outer || -- global_ic->name != extra_ic.name) { -- global_ic = null; // not really the same, so break the link -- } -+ if (global_ic->flags != extra_ic.flags || -+ global_ic->outer != extra_ic.outer || -+ global_ic->name != extra_ic.name) { -+ global_ic = null; // not really the same, so break the link -+ } - } - } - if (global_ic != null && global_ic->requested) { -@@ -4465,15 +4486,15 @@ void unpacker::write_classfile_tail() { - for (i = -num_global_ics; i < num_extra_ics; i++) { - inner_class* ic; - if (i < 0) -- ic = (inner_class*) requested_ics.get(num_global_ics+i); -+ ic = (inner_class*) requested_ics.get(num_global_ics+i); - else -- ic = &extra_ics[i]; -+ ic = &extra_ics[i]; - if (ic->requested) { -- putref(ic->inner); -- putref(ic->outer); -- putref(ic->name); -- putu2(ic->flags); -- NOT_PRODUCT(local_ics--); -+ putref(ic->inner); -+ putref(ic->outer); -+ putref(ic->name); -+ putu2(ic->flags); -+ NOT_PRODUCT(local_ics--); - } - } - assert(local_ics == 0); // must balance -@@ -4573,7 +4594,7 @@ unpacker::file* unpacker::get_next_file( - if (archive_size != 0) { - julong predicted_size = unsized_bytes_read + archive_size; - if (predicted_size != bytes_read) -- abort("archive header had incorrect size"); -+ abort("archive header had incorrect size"); - } - return null; - } -@@ -4637,7 +4658,7 @@ unpacker::file* unpacker::get_next_file( - size_t rpleft = input_remaining(); - if (rpleft > 0) { - if (rpleft > cur_file.size) -- rpleft = (size_t) cur_file.size; -+ rpleft = (size_t) cur_file.size; - cur_file.data[0].set(rp, rpleft); - rp += rpleft; - } -@@ -4655,7 +4676,7 @@ unpacker::file* unpacker::get_next_file( - - // Write a file to jarout. - void unpacker::write_file_to_jar(unpacker::file* f) { -- size_t htsize = f->data[0].len + f->data[1].len; -+ size_t htsize = f->data[0].len + f->data[1].len; - julong fsize = f->size; - #ifndef PRODUCT - if (nowrite NOT_PRODUCT(|| skipfiles-- > 0)) { -@@ -4665,7 +4686,7 @@ void unpacker::write_file_to_jar(unpacke - #endif - if (htsize == fsize) { - jarout->addJarEntry(f->name, f->deflate_hint(), f->modtime, -- f->data[0], f->data[1]); -+ f->data[0], f->data[1]); - } else { - assert(input_remaining() == 0); - bytes part1, part2; -@@ -4680,27 +4701,27 @@ void unpacker::write_file_to_jar(unpacke - if (fleft > 0) { - // Must read some more. - if (live_input) { -- // Stop using the input buffer. Make a new one: -- if (free_input) input.free(); -- input.init(fleft > (1<<12) ? fleft : (1<<12)); -- free_input = true; -- live_input = false; -+ // Stop using the input buffer. Make a new one: -+ if (free_input) input.free(); -+ input.init(fleft > (1<<12) ? fleft : (1<<12)); -+ free_input = true; -+ live_input = false; - } else { -- // Make it large enough. -- assert(free_input); // must be reallocable -- input.ensureSize(fleft); -+ // Make it large enough. -+ assert(free_input); // must be reallocable -+ input.ensureSize(fleft); - } - rplimit = rp = input.base(); - CHECK; - input.setLimit(rp + fleft); - if (!ensure_input(fleft)) -- abort("EOF reading resource file"); -+ abort("EOF reading resource file"); - part2.ptr = input_scan(); - part2.len = input_remaining(); - rplimit = rp = input.base(); - } - jarout->addJarEntry(f->name, f->deflate_hint(), f->modtime, -- part1, part2); -+ part1, part2); - } - if (verbose >= 3) { - fprintf(errstrm, "Wrote %lld bytes to: %s\n", fsize, f->name); -@@ -4722,7 +4743,7 @@ void unpacker::redirect_stdio() { - } else if (strcmp(log_file, LOGFILE_STDOUT) == 0) { - errstrm = stdout; - return; -- } else if (log_file[0] != '\0' && (errstrm = fopen(log_file,"a+")) != NULL) { -+ } else if (log_file[0] != '\0' && (errstrm = fopen(log_file,"a+")) != NULL) { - return; - } else { - char log_file_name[PATH_MAX+100]; -@@ -4732,7 +4753,7 @@ void unpacker::redirect_stdio() { - if (n < 1 || n > PATH_MAX) { - sprintf(tmpdir,"C:\\"); - } -- sprintf(log_file_name, "%sunpack.log", tmpdir); -+ sprintf(log_file_name, "%sunpack.log", tmpdir); - #else - sprintf(tmpdir,"/tmp"); - sprintf(log_file_name, "/tmp/unpack.log"); -@@ -4742,7 +4763,7 @@ void unpacker::redirect_stdio() { - return ; - } - -- char *tname = tempnam(tmpdir,"#upkg"); -+ char *tname = tempnam(tmpdir,"#upkg"); - sprintf(log_file_name, "%s", tname); - if ((errstrm = fopen(log_file_name, "a+")) != NULL) { - log_file = errstrm_name = saveStr(log_file_name); -@@ -4758,7 +4779,7 @@ void unpacker::redirect_stdio() { - #endif - // Last resort - // (Do not use stdout, since it might be jarout->jarfp.) -- errstrm = stderr; -+ errstrm = stderr; - log_file = errstrm_name = LOGFILE_STDERR; - } - } -@@ -4799,3 +4820,5 @@ void unpacker::abort(const char* message - #endif - #endif // JNI - } -+ -+
--- a/patches/security/20130201/7186948.patch Tue Mar 19 00:21:31 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,20 +0,0 @@ -# HG changeset patch -# User rupashka -# Date 1350390610 -14400 -# Node ID 6deb10c2d5d0c8925fd2012d9fc3b9325c997f21 -# Parent ce11c5c59cb8672eeddf9d5ce49563ccbc387854 -7186948: Improve Swing data validation -Reviewed-by: art, ahgross - -diff --git a/src/share/classes/javax/swing/UIDefaults.java b/src/share/classes/javax/swing/UIDefaults.java ---- openjdk/jdk/src/share/classes/javax/swing/UIDefaults.java -+++ openjdk/jdk/src/share/classes/javax/swing/UIDefaults.java -@@ -677,6 +677,8 @@ public class UIDefaults extends Hashtabl - try { - String className = (String)get(uiClassID); - if (className != null) { -+ ReflectUtil.checkPackageAccess(className); -+ - Class cls = (Class)get(className); - if (cls == null) { - if (uiClassLoader == null) {
--- a/patches/security/20130201/7186952.patch Tue Mar 19 00:21:31 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,127 +0,0 @@ -# HG changeset patch -# User denis -# Date 1353947054 -14400 -# Node ID 9bbc6817b00c3e9d4eba05d53a8a20b45947ea03 -# Parent c684d497e159d3eebded29e997d953019305ec45 -7186952: Improve clipboard access -Reviewed-by: serb, ahgross - -diff --git a/src/share/classes/java/awt/TextComponent.java b/src/share/classes/java/awt/TextComponent.java ---- openjdk/jdk/src/share/classes/java/awt/TextComponent.java -+++ openjdk/jdk/src/share/classes/java/awt/TextComponent.java -@@ -107,12 +107,6 @@ public class TextComponent extends Compo - // the background color of non-editable TextComponents. - boolean backgroundSetByClientCode = false; - -- /** -- * True if this <code>TextComponent</code> has access -- * to the System clipboard. -- */ -- transient private boolean canAccessClipboard; -- - transient protected TextListener textListener; - - /* -@@ -137,7 +131,6 @@ public class TextComponent extends Compo - GraphicsEnvironment.checkHeadless(); - this.text = (text != null) ? text : ""; - setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR)); -- checkSystemClipboardAccess(); - } - - private void enableInputMethodsIfNecessary() { -@@ -727,17 +720,14 @@ public class TextComponent extends Compo - /** - * Assigns a valid value to the canAccessClipboard instance variable. - */ -- private void checkSystemClipboardAccess() { -- canAccessClipboard = true; -+ private boolean canAccessClipboard() { - SecurityManager sm = System.getSecurityManager(); -- if (sm != null) { -- try { -- sm.checkSystemClipboardAccess(); -- } -- catch (SecurityException e) { -- canAccessClipboard = false; -- } -- } -+ if (sm == null) return true; -+ try { -+ sm.checkSystemClipboardAccess(); -+ return true; -+ } catch (SecurityException e) {} -+ return false; - } - - /* -@@ -820,7 +810,6 @@ public class TextComponent extends Compo - } - } - enableInputMethodsIfNecessary(); -- checkSystemClipboardAccess(); - } - - -diff --git a/src/windows/native/sun/windows/awt_TextComponent.cpp b/src/windows/native/sun/windows/awt_TextComponent.cpp ---- openjdk/jdk/src/windows/native/sun/windows/awt_TextComponent.cpp -+++ openjdk/jdk/src/windows/native/sun/windows/awt_TextComponent.cpp -@@ -52,13 +52,11 @@ struct EnableEditingStruct { - * AwtTextComponent fields - */ - --/* java.awt.TextComponent fields */ --jfieldID AwtTextComponent::canAccessClipboardID; -- -- - /************************************************************************ - * AwtTextComponent methods - */ -+ -+jmethodID AwtTextComponent::canAccessClipboardMID; - - AwtTextComponent::AwtTextComponent() { - m_synthetic = FALSE; -@@ -188,8 +186,7 @@ AwtTextComponent::WmPaste() - } - jobject target = GetTarget(env); - jboolean canAccessClipboard = -- env->GetBooleanField(target, -- AwtTextComponent::canAccessClipboardID); -+ env->CallBooleanMethod (target, AwtTextComponent::canAccessClipboardMID); - env->DeleteLocalRef(target); - return (canAccessClipboard) ? mrDoDefault : mrConsume; - } -@@ -622,12 +619,13 @@ Java_sun_awt_windows_WTextComponentPeer_ - { - TRY; - -- cls = env->FindClass("java/awt/TextComponent"); -- if (cls != NULL) { -- AwtTextComponent::canAccessClipboardID = -- env->GetFieldID(cls, "canAccessClipboard", "Z"); -- DASSERT(AwtTextComponent::canAccessClipboardID != NULL); -- } -+ jclass textComponentClassID = env->FindClass("java/awt/TextComponent"); -+ AwtTextComponent::canAccessClipboardMID = -+ env->GetMethodID(textComponentClassID, -+ "canAccessClipboard", "()Z"); -+ env->DeleteLocalRef(textComponentClassID); -+ -+ DASSERT(AwtTextComponent::canAccessClipboardMID != NULL) - - CATCH_BAD_ALLOC; - } -diff --git a/src/windows/native/sun/windows/awt_TextComponent.h b/src/windows/native/sun/windows/awt_TextComponent.h ---- openjdk/jdk/src/windows/native/sun/windows/awt_TextComponent.h -+++ openjdk/jdk/src/windows/native/sun/windows/awt_TextComponent.h -@@ -42,8 +42,7 @@ - - class AwtTextComponent : public AwtComponent { - public: -- /* java.awt.TextComponent canAccessClipboard field ID */ -- static jfieldID canAccessClipboardID; -+ static jmethodID canAccessClipboardMID; - - AwtTextComponent(); -
--- a/patches/security/20130201/7186954.patch Tue Mar 19 00:21:31 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,81 +0,0 @@ -# HG changeset patch -# User dmeetry -# Date 1352295947 -14400 -# Node ID ee4632a30696050ebd5c014fb3da64112ab48dd3 -# Parent 6e2d4ed84b41667df189abb7bd0915cda01a85a0 -7186954: Improve connection performance -Reviewed-by: khazra - -diff --git a/src/share/classes/sun/net/httpserver/ChunkedInputStream.java b/src/share/classes/sun/net/httpserver/ChunkedInputStream.java ---- openjdk/jdk/src/share/classes/sun/net/httpserver/ChunkedInputStream.java -+++ openjdk/jdk/src/share/classes/sun/net/httpserver/ChunkedInputStream.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -41,8 +41,12 @@ class ChunkedInputStream extends LeftOve - - private boolean needToReadHeader = true; - -- static char CR = '\r'; -- static char LF = '\n'; -+ final static char CR = '\r'; -+ final static char LF = '\n'; -+ /* -+ * Maximum chunk header size of 2KB + 2 bytes for CRLF -+ */ -+ private final static int MAX_CHUNK_HEADER_SIZE = 2050; - - private int numeric (char[] arr, int nchars) throws IOException { - assert arr.length >= nchars; -@@ -73,9 +77,13 @@ class ChunkedInputStream extends LeftOve - char[] len_arr = new char [16]; - int len_size = 0; - boolean end_of_len = false; -+ int read = 0; - - while ((c=(char)in.read())!= -1) { -- if (len_size == len_arr.length -1) { -+ read++; -+ if ((len_size == len_arr.length -1) || -+ (read > MAX_CHUNK_HEADER_SIZE)) -+ { - throw new IOException ("invalid chunk header"); - } - if (gotCR) { -diff --git a/src/share/classes/sun/net/www/http/ChunkedInputStream.java b/src/share/classes/sun/net/www/http/ChunkedInputStream.java ---- openjdk/jdk/src/share/classes/sun/net/www/http/ChunkedInputStream.java -+++ openjdk/jdk/src/share/classes/sun/net/www/http/ChunkedInputStream.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 1999, 2006, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -125,6 +125,11 @@ class ChunkedInputStream extends InputSt - */ - private boolean closed; - -+ /* -+ * Maximum chunk header size of 2KB + 2 bytes for CRLF -+ */ -+ private final static int MAX_CHUNK_HEADER_SIZE = 2050; -+ - /** - * State to indicate that next field should be :- - * chunk-size [ chunk-extension ] CRLF -@@ -290,6 +295,10 @@ class ChunkedInputStream extends InputSt - break; - } - pos++; -+ if ((pos - rawPos) >= MAX_CHUNK_HEADER_SIZE) { -+ error = true; -+ throw new IOException("Chunk header too long"); -+ } - } - if (pos >= rawCount) { - return;
--- a/patches/security/20130201/7192392.patch Tue Mar 19 00:21:31 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,695 +0,0 @@ -# HG changeset patch -# User mbankal -# Date 1355226562 28800 -# Node ID 726b9456757648efb7c68e41c6bcc08a401eef83 -# Parent aade089d4505d382f49306a90873c4217367e709 -7192392: Better validation of client keys -Reviewed-by: xuelei - -diff --git a/src/share/classes/com/sun/crypto/provider/DHKeyAgreement.java b/src/share/classes/com/sun/crypto/provider/DHKeyAgreement.java ---- openjdk/jdk/src/share/classes/com/sun/crypto/provider/DHKeyAgreement.java -+++ openjdk/jdk/src/share/classes/com/sun/crypto/provider/DHKeyAgreement.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -39,6 +39,7 @@ import javax.crypto.ShortBufferException - import javax.crypto.ShortBufferException; - import javax.crypto.SecretKey; - import javax.crypto.spec.*; -+import sun.security.util.KeyUtil; - - /** - * This class implements the Diffie-Hellman key agreement protocol between -@@ -205,6 +206,9 @@ extends KeyAgreementSpi { - if (pub_g != null && !(init_g.equals(pub_g))) { - throw new InvalidKeyException("Incompatible parameters"); - } -+ -+ // validate the Diffie-Hellman public key -+ KeyUtil.validate(dhPubKey); - - // store the y value - this.y = dhPubKey.getY(); -diff --git a/src/share/classes/sun/security/pkcs11/P11KeyAgreement.java b/src/share/classes/sun/security/pkcs11/P11KeyAgreement.java ---- openjdk/jdk/src/share/classes/sun/security/pkcs11/P11KeyAgreement.java -+++ openjdk/jdk/src/share/classes/sun/security/pkcs11/P11KeyAgreement.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -37,6 +37,7 @@ import static sun.security.pkcs11.Templa - import static sun.security.pkcs11.TemplateManager.*; - import sun.security.pkcs11.wrapper.*; - import static sun.security.pkcs11.wrapper.PKCS11Constants.*; -+import sun.security.util.KeyUtil; - - /** - * KeyAgreement implementation class. This class currently supports -@@ -134,6 +135,8 @@ final class P11KeyAgreement extends KeyA - BigInteger p, g, y; - if (key instanceof DHPublicKey) { - DHPublicKey dhKey = (DHPublicKey)key; -+ // validate the Diffie-Hellman public key -+ KeyUtil.validate(dhKey); - y = dhKey.getY(); - DHParameterSpec params = dhKey.getParams(); - p = params.getP(); -@@ -145,6 +148,8 @@ final class P11KeyAgreement extends KeyA - try { - DHPublicKeySpec spec = (DHPublicKeySpec)kf.engineGetKeySpec - (key, DHPublicKeySpec.class); -+ // validate the Diffie-Hellman public key -+ KeyUtil.validate(spec); - y = spec.getY(); - p = spec.getP(); - g = spec.getG(); -diff --git a/src/share/classes/sun/security/ssl/ClientHandshaker.java b/src/share/classes/sun/security/ssl/ClientHandshaker.java ---- openjdk/jdk/src/share/classes/sun/security/ssl/ClientHandshaker.java -+++ openjdk/jdk/src/share/classes/sun/security/ssl/ClientHandshaker.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -168,7 +168,11 @@ final class ClientHandshaker extends Han - } - break; - case K_DH_ANON: -- this.serverKeyExchange(new DH_ServerKeyExchange(input)); -+ try { -+ this.serverKeyExchange(new DH_ServerKeyExchange(input)); -+ } catch (GeneralSecurityException e) { -+ throwSSLException("Server key", e); -+ } - break; - case K_DHE_DSS: - case K_DHE_RSA: -@@ -811,7 +815,7 @@ final class ClientHandshaker extends Han - case K_DHE_RSA: - case K_DHE_DSS: - case K_DH_ANON: -- preMasterSecret = dh.getAgreedSecret(serverDH); -+ preMasterSecret = dh.getAgreedSecret(serverDH, true); - break; - case K_ECDHE_RSA: - case K_ECDHE_ECDSA: -diff --git a/src/share/classes/sun/security/ssl/DHClientKeyExchange.java b/src/share/classes/sun/security/ssl/DHClientKeyExchange.java ---- openjdk/jdk/src/share/classes/sun/security/ssl/DHClientKeyExchange.java -+++ openjdk/jdk/src/share/classes/sun/security/ssl/DHClientKeyExchange.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -29,7 +29,7 @@ import java.io.IOException; - import java.io.IOException; - import java.io.PrintStream; - import java.math.BigInteger; -- -+import javax.net.ssl.SSLHandshakeException; - - /* - * Message used by clients to send their Diffie-Hellman public -@@ -50,7 +50,7 @@ final class DHClientKeyExchange extends - private byte dh_Yc[]; // 1 to 2^16 -1 bytes - - BigInteger getClientPublicKey() { -- return new BigInteger(1, dh_Yc); -+ return dh_Yc == null ? null : new BigInteger(1, dh_Yc); - } - - /* -@@ -72,7 +72,14 @@ final class DHClientKeyExchange extends - * but that's what the protocol spec requires.) - */ - DHClientKeyExchange(HandshakeInStream input) throws IOException { -- dh_Yc = input.getBytes16(); -+ if (input.available() >= 2) { -+ dh_Yc = input.getBytes16(); -+ } else { -+ // currently, we don't support cipher suites that requires -+ // implicit public key of client. -+ throw new SSLHandshakeException( -+ "Unsupported implicit client DiffieHellman public key"); -+ } - } - - int messageLength() { -@@ -84,7 +91,9 @@ final class DHClientKeyExchange extends - } - - void send(HandshakeOutStream s) throws IOException { -- s.putBytes16(dh_Yc); -+ if (dh_Yc != null && dh_Yc.length != 0) { -+ s.putBytes16(dh_Yc); -+ } - } - - void print(PrintStream s) throws IOException { -diff --git a/src/share/classes/sun/security/ssl/DHCrypt.java b/src/share/classes/sun/security/ssl/DHCrypt.java ---- openjdk/jdk/src/share/classes/sun/security/ssl/DHCrypt.java -+++ openjdk/jdk/src/share/classes/sun/security/ssl/DHCrypt.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 1996, 2007, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -28,11 +28,14 @@ package sun.security.ssl; - - import java.math.BigInteger; - import java.security.*; -+import java.io.IOException; -+import javax.net.ssl.SSLHandshakeException; - - import javax.crypto.SecretKey; - import javax.crypto.KeyAgreement; - import javax.crypto.interfaces.DHPublicKey; - import javax.crypto.spec.*; -+import sun.security.util.KeyUtil; - - /** - * This class implements the Diffie-Hellman key exchange algorithm. -@@ -54,7 +57,8 @@ import javax.crypto.spec.*; - * . if we are server, call DHCrypt(keyLength,random). This generates - * an ephemeral keypair of the request length. - * . if we are client, call DHCrypt(modulus, base, random). This -- * generates an ephemeral keypair using the parameters specified by the server. -+ * generates an ephemeral keypair using the parameters specified by -+ * the server. - * . send parameters and public value to remote peer - * . receive peers ephemeral public key - * . call getAgreedSecret() to calculate the shared secret -@@ -83,6 +87,9 @@ final class DHCrypt { - // public component of our key, X = (g ^ x) mod p - private BigInteger publicValue; // X (aka y) - -+ // the times to recover from failure if public key validation -+ private static int MAX_FAILOVER_TIMES = 2; -+ - /** - * Generate a Diffie-Hellman keypair of the specified size. - */ -@@ -90,9 +97,10 @@ final class DHCrypt { - try { - KeyPairGenerator kpg = JsseJce.getKeyPairGenerator("DiffieHellman"); - kpg.initialize(keyLength, random); -- KeyPair kp = kpg.generateKeyPair(); -- privateKey = kp.getPrivate(); -- DHPublicKeySpec spec = getDHPublicKeySpec(kp.getPublic()); -+ DHPublicKeySpec spec = generateDHPublicKeySpec(kpg); -+ if (spec == null) { -+ throw new RuntimeException("Could not generate DH keypair"); -+ } - publicValue = spec.getY(); - modulus = spec.getP(); - base = spec.getG(); -@@ -115,9 +123,10 @@ final class DHCrypt { - KeyPairGenerator kpg = JsseJce.getKeyPairGenerator("DiffieHellman"); - DHParameterSpec params = new DHParameterSpec(modulus, base); - kpg.initialize(params, random); -- KeyPair kp = kpg.generateKeyPair(); -- privateKey = kp.getPrivate(); -- DHPublicKeySpec spec = getDHPublicKeySpec(kp.getPublic()); -+ DHPublicKeySpec spec = generateDHPublicKeySpec(kpg); -+ if (spec == null) { -+ throw new RuntimeException("Could not generate DH keypair"); -+ } - publicValue = spec.getY(); - } catch (GeneralSecurityException e) { - throw new RuntimeException("Could not generate DH keypair", e); -@@ -128,7 +137,8 @@ final class DHCrypt { - if (key instanceof DHPublicKey) { - DHPublicKey dhKey = (DHPublicKey)key; - DHParameterSpec params = dhKey.getParams(); -- return new DHPublicKeySpec(dhKey.getY(), params.getP(), params.getG()); -+ return new DHPublicKeySpec(dhKey.getY(), -+ params.getP(), params.getG()); - } - try { - KeyFactory factory = JsseJce.getKeyFactory("DH"); -@@ -168,16 +178,29 @@ final class DHCrypt { - * has not been set (or generated). - * - * @param peerPublicKey the peer's public key. -- * @returns the secret, which is an unsigned big-endian integer -+ * @param keyIsValidated whether the {@code peerPublicKey} has beed -+ * validated -+ * @return the secret, which is an unsigned big-endian integer - * the same size as the Diffie-Hellman modulus. - */ -- SecretKey getAgreedSecret(BigInteger peerPublicValue) { -+ SecretKey getAgreedSecret(BigInteger peerPublicValue, -+ boolean keyIsValidated) throws IOException { - try { - KeyFactory kf = JsseJce.getKeyFactory("DiffieHellman"); - DHPublicKeySpec spec = - new DHPublicKeySpec(peerPublicValue, modulus, base); - PublicKey publicKey = kf.generatePublic(spec); - KeyAgreement ka = JsseJce.getKeyAgreement("DiffieHellman"); -+ // validate the Diffie-Hellman public key -+ if (!keyIsValidated && -+ !KeyUtil.isOracleJCEProvider(ka.getProvider().getName())) { -+ try { -+ KeyUtil.validate(spec); -+ } catch (InvalidKeyException ike) { -+ // prefer handshake_failure alert to internal_error alert -+ throw new SSLHandshakeException(ike.getMessage()); -+ } -+ } - ka.init(privateKey); - ka.doPhase(publicKey, true); - return ka.generateSecret("TlsPremasterSecret"); -@@ -186,4 +209,33 @@ final class DHCrypt { - } - } - -+ // Generate and validate DHPublicKeySpec -+ private DHPublicKeySpec generateDHPublicKeySpec(KeyPairGenerator kpg) -+ throws GeneralSecurityException { -+ -+ boolean doExtraValiadtion = -+ (!KeyUtil.isOracleJCEProvider(kpg.getProvider().getName())); -+ for (int i = 0; i <= MAX_FAILOVER_TIMES; i++) { -+ KeyPair kp = kpg.generateKeyPair(); -+ privateKey = kp.getPrivate(); -+ DHPublicKeySpec spec = getDHPublicKeySpec(kp.getPublic()); -+ -+ // validate the Diffie-Hellman public key -+ if (doExtraValiadtion) { -+ try { -+ KeyUtil.validate(spec); -+ } catch (InvalidKeyException ivke) { -+ if (i == MAX_FAILOVER_TIMES) { -+ throw ivke; -+ } -+ // otherwise, ignore the exception and try the next one -+ continue; -+ } -+ } -+ -+ return spec; -+ } -+ -+ return null; -+ } - } -diff --git a/src/share/classes/sun/security/ssl/HandshakeMessage.java b/src/share/classes/sun/security/ssl/HandshakeMessage.java ---- openjdk/jdk/src/share/classes/sun/security/ssl/HandshakeMessage.java -+++ openjdk/jdk/src/share/classes/sun/security/ssl/HandshakeMessage.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -42,6 +42,7 @@ import javax.security.auth.x500.X500Prin - - import javax.crypto.KeyGenerator; - import javax.crypto.SecretKey; -+import javax.crypto.spec.DHPublicKeySpec; - import javax.crypto.spec.SecretKeySpec; - - import javax.net.ssl.*; -@@ -51,6 +52,7 @@ import sun.security.internal.spec.TlsPrf - import sun.security.internal.spec.TlsPrfParameterSpec; - - import sun.security.ssl.CipherSuite.*; -+import sun.security.util.KeyUtil; - - /** - * Many data structures are involved in the handshake messages. These -@@ -715,6 +717,7 @@ class DH_ServerKeyExchange extends Serve - * key exchange. - */ - DH_ServerKeyExchange(DHCrypt obj) { -+ // The DH key has been validated in the constructor of DHCrypt. - getValues(obj); - signature = null; - } -@@ -727,6 +730,7 @@ class DH_ServerKeyExchange extends Serve - DH_ServerKeyExchange(DHCrypt obj, PrivateKey key, byte clntNonce[], - byte svrNonce[], SecureRandom sr) throws GeneralSecurityException { - -+ // The DH key has been validated in the constructor of DHCrypt. - getValues(obj); - - Signature sig; -@@ -751,10 +755,14 @@ class DH_ServerKeyExchange extends Serve - * stream, as if sent from server to client for use with - * DH_anon key exchange - */ -- DH_ServerKeyExchange(HandshakeInStream input) throws IOException { -+ DH_ServerKeyExchange(HandshakeInStream input) -+ throws IOException, GeneralSecurityException { - dh_p = input.getBytes16(); - dh_g = input.getBytes16(); - dh_Ys = input.getBytes16(); -+ KeyUtil.validate(new DHPublicKeySpec(new BigInteger(1, dh_Ys), -+ new BigInteger(1, dh_p), -+ new BigInteger(1, dh_g))); - signature = null; - } - -@@ -770,7 +778,9 @@ class DH_ServerKeyExchange extends Serve - dh_p = input.getBytes16(); - dh_g = input.getBytes16(); - dh_Ys = input.getBytes16(); -- -+ KeyUtil.validate(new DHPublicKeySpec(new BigInteger(1, dh_Ys), -+ new BigInteger(1, dh_p), -+ new BigInteger(1, dh_g))); - byte signature[]; - if (dhKeyExchangeFix) { - signature = input.getBytes16(); -diff --git a/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java b/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java ---- openjdk/jdk/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java -+++ openjdk/jdk/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java -@@ -36,7 +36,7 @@ import javax.net.ssl.*; - import javax.net.ssl.*; - - import sun.security.internal.spec.TlsRsaPremasterSecretParameterSpec; --import sun.security.util.KeyLength; -+import sun.security.util.KeyUtil; - - /** - * This is the client key exchange message (CLIENT --> SERVER) used with -@@ -194,7 +194,7 @@ final class RSAClientKeyExchange extends - "unable to get the plaintext of the premaster secret"); - } - -- int keySize = KeyLength.getKeySize(secretKey); -+ int keySize = KeyUtil.getKeySize(secretKey); - if (keySize > 0 && keySize != 384) { // 384 = 48 * 8 - if (debug != null && Debug.isOn("handshake")) { - System.out.println( -diff --git a/src/share/classes/sun/security/ssl/ServerHandshaker.java b/src/share/classes/sun/security/ssl/ServerHandshaker.java ---- openjdk/jdk/src/share/classes/sun/security/ssl/ServerHandshaker.java -+++ openjdk/jdk/src/share/classes/sun/security/ssl/ServerHandshaker.java -@@ -1147,7 +1147,7 @@ final class ServerHandshaker extends Han - if (debug != null && Debug.isOn("handshake")) { - mesg.print(System.out); - } -- return dh.getAgreedSecret(mesg.getClientPublicKey()); -+ return dh.getAgreedSecret(mesg.getClientPublicKey(), false); - } - - private SecretKey clientKeyExchange(ECDHClientKeyExchange mesg) -diff --git a/src/share/classes/sun/security/util/KeyLength.java b/src/share/classes/sun/security/util/KeyLength.java -deleted file mode 100644 ---- openjdk/jdk/src/share/classes/sun/security/util/KeyLength.java -+++ /dev/null -@@ -1,91 +0,0 @@ --/* -- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. -- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -- * -- * This code is free software; you can redistribute it and/or modify it -- * under the terms of the GNU General Public License version 2 only, as -- * published by the Free Software Foundation. Oracle designates this -- * particular file as subject to the "Classpath" exception as provided -- * by Oracle in the LICENSE file that accompanied this code. -- * -- * This code is distributed in the hope that it will be useful, but WITHOUT -- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -- * version 2 for more details (a copy is included in the LICENSE file that -- * accompanied this code). -- * -- * You should have received a copy of the GNU General Public License version -- * 2 along with this work; if not, write to the Free Software Foundation, -- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -- * -- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -- * or visit www.oracle.com if you need additional information or have any -- * questions. -- */ -- --package sun.security.util; -- --import java.security.Key; --import java.security.PrivilegedAction; --import java.security.AccessController; --import java.security.interfaces.ECKey; --import java.security.interfaces.RSAKey; --import java.security.interfaces.DSAKey; --import javax.crypto.SecretKey; --import javax.crypto.interfaces.DHKey; -- --/** -- * A utility class to get key length -- */ --public final class KeyLength { -- -- /** -- * Returns the key size of the given key object in bits. -- * -- * @param key the key object, cannot be null -- * @return the key size of the given key object in bits, or -1 if the -- * key size is not accessible -- */ -- final public static int getKeySize(Key key) { -- int size = -1; -- -- if (key instanceof Length) { -- try { -- Length ruler = (Length)key; -- size = ruler.length(); -- } catch (UnsupportedOperationException usoe) { -- // ignore the exception -- } -- -- if (size >= 0) { -- return size; -- } -- } -- -- // try to parse the length from key specification -- if (key instanceof SecretKey) { -- SecretKey sk = (SecretKey)key; -- String format = sk.getFormat(); -- if ("RAW".equals(format) && sk.getEncoded() != null) { -- size = (sk.getEncoded().length * 8); -- } // Otherwise, it may be a unextractable key of PKCS#11, or -- // a key we are not able to handle. -- } else if (key instanceof RSAKey) { -- RSAKey pubk = (RSAKey)key; -- size = pubk.getModulus().bitLength(); -- } else if (key instanceof ECKey) { -- ECKey pubk = (ECKey)key; -- size = pubk.getParams().getOrder().bitLength(); -- } else if (key instanceof DSAKey) { -- DSAKey pubk = (DSAKey)key; -- size = pubk.getParams().getP().bitLength(); -- } else if (key instanceof DHKey) { -- DHKey pubk = (DHKey)key; -- size = pubk.getParams().getP().bitLength(); -- } // Otherwise, it may be a unextractable key of PKCS#11, or -- // a key we are not able to handle. -- -- return size; -- } --} -- -diff --git a/src/share/classes/sun/security/util/KeyUtil.java b/src/share/classes/sun/security/util/KeyUtil.java -new file mode 100644 ---- /dev/null -+++ openjdk/jdk/src/share/classes/sun/security/util/KeyUtil.java -@@ -0,0 +1,184 @@ -+/* -+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. -+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -+ * -+ */ -+ -+package sun.security.util; -+ -+import java.security.Key; -+import java.security.PrivilegedAction; -+import java.security.AccessController; -+import java.security.InvalidKeyException; -+import java.security.interfaces.ECKey; -+import java.security.interfaces.RSAKey; -+import java.security.interfaces.DSAKey; -+import java.security.spec.KeySpec; -+import javax.crypto.SecretKey; -+import javax.crypto.interfaces.DHKey; -+import javax.crypto.interfaces.DHPublicKey; -+import javax.crypto.spec.DHParameterSpec; -+import javax.crypto.spec.DHPublicKeySpec; -+import java.math.BigInteger; -+ -+/** -+ * A utility class to get key length, valiate keys, etc. -+ */ -+public final class KeyUtil { -+ -+ /** -+ * Returns the key size of the given key object in bits. -+ * -+ * @param key the key object, cannot be null -+ * @return the key size of the given key object in bits, or -1 if the -+ * key size is not accessible -+ */ -+ public static final int getKeySize(Key key) { -+ int size = -1; -+ -+ if (key instanceof Length) { -+ try { -+ Length ruler = (Length)key; -+ size = ruler.length(); -+ } catch (UnsupportedOperationException usoe) { -+ // ignore the exception -+ } -+ -+ if (size >= 0) { -+ return size; -+ } -+ } -+ -+ // try to parse the length from key specification -+ if (key instanceof SecretKey) { -+ SecretKey sk = (SecretKey)key; -+ String format = sk.getFormat(); -+ if ("RAW".equals(format) && sk.getEncoded() != null) { -+ size = (sk.getEncoded().length * 8); -+ } // Otherwise, it may be a unextractable key of PKCS#11, or -+ // a key we are not able to handle. -+ } else if (key instanceof RSAKey) { -+ RSAKey pubk = (RSAKey)key; -+ size = pubk.getModulus().bitLength(); -+ } else if (key instanceof ECKey) { -+ ECKey pubk = (ECKey)key; -+ size = pubk.getParams().getOrder().bitLength(); -+ } else if (key instanceof DSAKey) { -+ DSAKey pubk = (DSAKey)key; -+ size = pubk.getParams().getP().bitLength(); -+ } else if (key instanceof DHKey) { -+ DHKey pubk = (DHKey)key; -+ size = pubk.getParams().getP().bitLength(); -+ } // Otherwise, it may be a unextractable key of PKCS#11, or -+ // a key we are not able to handle. -+ -+ return size; -+ } -+ -+ /** -+ * Returns whether the key is valid or not. -+ * <P> -+ * Note that this method is only apply to DHPublicKey at present. -+ * -+ * @param publicKey -+ * the key object, cannot be null -+ * -+ * @throws NullPointerException if {@code publicKey} is null -+ * @throws InvalidKeyException if {@code publicKey} is invalid -+ */ -+ public static final void validate(Key key) -+ throws InvalidKeyException { -+ if (key == null) { -+ throw new NullPointerException( -+ "The key to be validated cannot be null"); -+ } -+ -+ if (key instanceof DHPublicKey) { -+ validateDHPublicKey((DHPublicKey)key); -+ } -+ } -+ -+ -+ /** -+ * Returns whether the key spec is valid or not. -+ * <P> -+ * Note that this method is only apply to DHPublicKeySpec at present. -+ * -+ * @param keySpec -+ * the key spec object, cannot be null -+ * -+ * @throws NullPointerException if {@code keySpec} is null -+ * @throws InvalidKeyException if {@code keySpec} is invalid -+ */ -+ public static final void validate(KeySpec keySpec) -+ throws InvalidKeyException { -+ if (keySpec == null) { -+ throw new NullPointerException( -+ "The key spec to be validated cannot be null"); -+ } -+ -+ if (keySpec instanceof DHPublicKeySpec) { -+ validateDHPublicKey((DHPublicKeySpec)keySpec); -+ } -+ } -+ -+ /** -+ * Returns whether the specified provider is Oracle provider or not. -+ * <P> -+ * Note that this method is only apply to SunJCE and SunPKCS11 at present. -+ * -+ * @param providerName -+ * the provider name -+ * @return true if, and only if, the provider of the specified -+ * {@code providerName} is Oracle provider -+ */ -+ public static final boolean isOracleJCEProvider(String providerName) { -+ return providerName != null && (providerName.equals("SunJCE") || -+ providerName.startsWith("SunPKCS11")); -+ } -+ -+ /** -+ * Returns whether the Diffie-Hellman public key is valid or not. -+ * -+ * Per RFC 2631 and NIST SP800-56A, the following algorithm is used to -+ * validate Diffie-Hellman public keys: -+ * 1. Verify that y lies within the interval [2,p-1]. If it does not, -+ * the key is invalid. -+ * 2. Compute y^q mod p. If the result == 1, the key is valid. -+ * Otherwise the key is invalid. -+ */ -+ private static void validateDHPublicKey(DHPublicKey publicKey) -+ throws InvalidKeyException { -+ DHParameterSpec paramSpec = publicKey.getParams(); -+ -+ BigInteger p = paramSpec.getP(); -+ BigInteger g = paramSpec.getG(); -+ BigInteger y = publicKey.getY(); -+ -+ validateDHPublicKey(p, g, y); -+ } -+ -+ private static void validateDHPublicKey(DHPublicKeySpec publicKeySpec) -+ throws InvalidKeyException { -+ validateDHPublicKey(publicKeySpec.getP(), -+ publicKeySpec.getG(), publicKeySpec.getY()); -+ } -+ -+ private static void validateDHPublicKey(BigInteger p, -+ BigInteger g, BigInteger y) throws InvalidKeyException { -+ -+ // For better interoperability, the interval is limited to [2, p-2]. -+ BigInteger leftOpen = BigInteger.ONE; -+ BigInteger rightOpen = p.subtract(BigInteger.ONE); -+ if (y.compareTo(leftOpen) <= 0) { -+ throw new InvalidKeyException( -+ "Diffie-Hellman public key is too small"); -+ } -+ if (y.compareTo(rightOpen) >= 0) { -+ throw new InvalidKeyException( -+ "Diffie-Hellman public key is too large"); -+ } -+ -+ // Don't bother to check against the y^q mod p if safe primes are used. -+ } -+}
--- a/patches/security/20130201/7192393.patch Tue Mar 19 00:21:31 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,60 +0,0 @@ -# HG changeset patch -# User mbankal -# Date 1355294606 28800 -# Node ID 708c134c36312faf8721c0c981be6553e4ebf49f -# Parent 175c95df5b8609142188946b59040de2e4cbe0af -7192393: Better Checking of order of TLS Messages -Reviewed-by: xuelei - -diff --git a/src/share/classes/sun/security/ssl/ClientHandshaker.java b/src/share/classes/sun/security/ssl/ClientHandshaker.java ---- openjdk/jdk/src/share/classes/sun/security/ssl/ClientHandshaker.java -+++ openjdk/jdk/src/share/classes/sun/security/ssl/ClientHandshaker.java -@@ -128,9 +128,8 @@ final class ClientHandshaker extends Han - * in the constructor. - */ - void processMessage(byte type, int messageLen) throws IOException { -- if (state > type -- && (type != HandshakeMessage.ht_hello_request -- && state != HandshakeMessage.ht_client_hello)) { -+ if (state >= type -+ && (type != HandshakeMessage.ht_hello_request)) { - throw new SSLProtocolException( - "Handshake message sequence violation, " + type); - } -diff --git a/src/share/classes/sun/security/ssl/ServerHandshaker.java b/src/share/classes/sun/security/ssl/ServerHandshaker.java ---- openjdk/jdk/src/share/classes/sun/security/ssl/ServerHandshaker.java -+++ openjdk/jdk/src/share/classes/sun/security/ssl/ServerHandshaker.java -@@ -153,7 +153,7 @@ final class ServerHandshaker extends Han - // In SSLv3 and TLS, messages follow strictly increasing - // numerical order _except_ for one annoying special case. - // -- if ((state > type) -+ if ((state >= type) - && (state != HandshakeMessage.ht_client_key_exchange - && type != HandshakeMessage.ht_certificate_verify)) { - throw new SSLProtocolException( -@@ -250,16 +250,17 @@ final class ServerHandshaker extends Han - } - - // -- // Move the state machine forward except for that annoying -- // special case. This means that clients could send extra -- // cert verify messages; not a problem so long as all of -- // them actually check out. -+ // Move state machine forward if the message handling -+ // code didn't already do so - // -- if (state < type && type != HandshakeMessage.ht_certificate_verify) { -- state = type; -+ if (state < type) { -+ if(type == HandshakeMessage.ht_certificate_verify) { -+ state = type + 2; // an annoying special case -+ } else { -+ state = type; -+ } - } - } -- - - /* - * ClientHello presents the server with a bunch of options, to which the
--- a/patches/security/20130201/7192977.patch Tue Mar 19 00:21:31 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,444 +0,0 @@ -# HG changeset patch -# User bagiras -# Date 1353597657 -10800 -# Node ID ead41322b23a97b1b5271e3c078d36696b8dfa50 -# Parent 787e9230b414f346f9c318918aaf58b872b9912e -7192977: Issue in toolkit thread -Reviewed-by: skoivu, art - -diff --git a/src/share/classes/java/awt/EventQueue.java b/src/share/classes/java/awt/EventQueue.java ---- openjdk/jdk/src/share/classes/java/awt/EventQueue.java -+++ openjdk/jdk/src/share/classes/java/awt/EventQueue.java -@@ -173,8 +173,14 @@ public class EventQueue { - } - public void removeSourceEvents(EventQueue eventQueue, - Object source, -- boolean removeAllEvents) { -+ boolean removeAllEvents) -+ { - eventQueue.removeSourceEvents(source, removeAllEvents); -+ } -+ public void invokeAndWait(Object source, Runnable r) -+ throws InterruptedException, InvocationTargetException -+ { -+ EventQueue.invokeAndWait(source, r); - } - }); - } -@@ -1042,8 +1048,14 @@ public class EventQueue { - * @since 1.2 - */ - public static void invokeAndWait(Runnable runnable) -- throws InterruptedException, InvocationTargetException { -+ throws InterruptedException, InvocationTargetException -+ { -+ invokeAndWait(Toolkit.getDefaultToolkit(), runnable); -+ } - -+ static void invokeAndWait(Object source, Runnable runnable) -+ throws InterruptedException, InvocationTargetException -+ { - if (EventQueue.isDispatchThread()) { - throw new Error("Cannot call invokeAndWait from the event dispatcher thread"); - } -@@ -1052,8 +1064,7 @@ public class EventQueue { - Object lock = new AWTInvocationLock(); - - InvocationEvent event = -- new InvocationEvent(Toolkit.getDefaultToolkit(), runnable, lock, -- true); -+ new InvocationEvent(source, runnable, lock, true); - - synchronized (lock) { - Toolkit.getEventQueue().postEvent(event); -diff --git a/src/share/classes/java/awt/Window.java b/src/share/classes/java/awt/Window.java ---- openjdk/jdk/src/share/classes/java/awt/Window.java -+++ openjdk/jdk/src/share/classes/java/awt/Window.java -@@ -1036,7 +1036,7 @@ public class Window extends Container im - } - else { - try { -- EventQueue.invokeAndWait(action); -+ EventQueue.invokeAndWait(this, action); - } - catch (InterruptedException e) { - System.err.println("Disposal was interrupted:"); -diff --git a/src/share/classes/javax/swing/RepaintManager.java b/src/share/classes/javax/swing/RepaintManager.java ---- openjdk/jdk/src/share/classes/javax/swing/RepaintManager.java -+++ openjdk/jdk/src/share/classes/javax/swing/RepaintManager.java -@@ -27,17 +27,21 @@ package javax.swing; - - import java.awt.*; - import java.awt.event.*; --import java.awt.peer.ComponentPeer; --import java.awt.peer.ContainerPeer; - import java.awt.image.VolatileImage; -+import java.security.AccessControlContext; - import java.security.AccessController; -+import java.security.PrivilegedAction; - import java.util.*; -+import java.util.concurrent.atomic.AtomicInteger; - import java.applet.*; - - import sun.awt.AppContext; -+import sun.awt.AWTAccessor; - import sun.awt.DisplayChangedListener; - import sun.awt.SunToolkit; - import sun.java2d.SunGraphicsEnvironment; -+import sun.misc.JavaSecurityAccess; -+import sun.misc.SharedSecrets; - import sun.security.action.GetPropertyAction; - - -@@ -168,6 +172,9 @@ public class RepaintManager - * Runnable used to process all repaint/revalidate requests. - */ - private final ProcessingRunnable processingRunnable; -+ -+ private final static JavaSecurityAccess javaSecurityAccess = -+ SharedSecrets.getJavaSecurityAccess(); - - - static { -@@ -553,13 +560,26 @@ public class RepaintManager - // This is called from the toolkit thread when awt needs to run a - // Runnable before we paint. - // -- void nativeQueueSurfaceDataRunnable(AppContext appContext, Component c, -- Runnable r) { -+ void nativeQueueSurfaceDataRunnable(AppContext appContext, -+ final Component c, final Runnable r) -+ { - synchronized(this) { - if (runnableList == null) { - runnableList = new LinkedList<Runnable>(); - } -- runnableList.add(r); -+ runnableList.add(new Runnable() { -+ public void run() { -+ AccessControlContext stack = AccessController.getContext(); -+ AccessControlContext acc = -+ AWTAccessor.getComponentAccessor().getAccessControlContext(c); -+ javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Void>() { -+ public Void run() { -+ r.run(); -+ return null; -+ } -+ }, stack, acc); -+ } -+ }); - } - scheduleProcessingRunnable(appContext); - } -@@ -639,9 +659,9 @@ public class RepaintManager - * @see #addInvalidComponent - */ - public void validateInvalidComponents() { -- java.util.List<Component> ic; -+ final java.util.List<Component> ic; - synchronized(this) { -- if(invalidComponents == null) { -+ if (invalidComponents == null) { - return; - } - ic = invalidComponents; -@@ -649,7 +669,17 @@ public class RepaintManager - } - int n = ic.size(); - for(int i = 0; i < n; i++) { -- ic.get(i).validate(); -+ final Component c = ic.get(i); -+ AccessControlContext stack = AccessController.getContext(); -+ AccessControlContext acc = -+ AWTAccessor.getComponentAccessor().getAccessControlContext(c); -+ javaSecurityAccess.doIntersectionPrivilege( -+ new PrivilegedAction<Void>() { -+ public Void run() { -+ c.validate(); -+ return null; -+ } -+ }, stack, acc); - } - } - -@@ -696,76 +726,75 @@ public class RepaintManager - paintDirtyRegions(tmpDirtyComponents); - } - -- private void paintDirtyRegions(Map<Component,Rectangle> -- tmpDirtyComponents){ -- int i, count; -- java.util.List<Component> roots; -- Component dirtyComponent; -- -- count = tmpDirtyComponents.size(); -- if (count == 0) { -+ private void paintDirtyRegions( -+ final Map<Component,Rectangle> tmpDirtyComponents) -+ { -+ if (tmpDirtyComponents.isEmpty()) { - return; - } - -- Rectangle rect; -- int localBoundsX = 0; -- int localBoundsY = 0; -- int localBoundsH = 0; -- int localBoundsW = 0; -- Enumeration keys; -- -- roots = new ArrayList<Component>(count); -+ final java.util.List<Component> roots = -+ new ArrayList<Component>(tmpDirtyComponents.size()); - - for (Component dirty : tmpDirtyComponents.keySet()) { - collectDirtyComponents(tmpDirtyComponents, dirty, roots); - } - -- count = roots.size(); -- // System.out.println("roots size is " + count); -+ final AtomicInteger count = new AtomicInteger(roots.size()); - painting = true; - try { -- for(i=0 ; i < count ; i++) { -- dirtyComponent = roots.get(i); -- rect = tmpDirtyComponents.get(dirtyComponent); -- // System.out.println("Should refresh :" + rect); -- localBoundsH = dirtyComponent.getHeight(); -- localBoundsW = dirtyComponent.getWidth(); -+ for(int j = 0; j < count.get(); j++) { -+ final int i = j; -+ final Component dirtyComponent = roots.get(j); - -- SwingUtilities.computeIntersection(localBoundsX, -- localBoundsY, -- localBoundsW, -- localBoundsH, -- rect); -- if (dirtyComponent instanceof JComponent) { -- ((JComponent)dirtyComponent).paintImmediately( -- rect.x,rect.y,rect.width, rect.height); -- } -- else if (dirtyComponent.isShowing()) { -- Graphics g = JComponent.safelyGetGraphics( -- dirtyComponent, dirtyComponent); -- // If the Graphics goes away, it means someone disposed of -- // the window, don't do anything. -- if (g != null) { -- g.setClip(rect.x, rect.y, rect.width, rect.height); -- try { -- dirtyComponent.paint(g); -- } finally { -- g.dispose(); -+ AccessControlContext stack = AccessController.getContext(); -+ AccessControlContext acc = -+ AWTAccessor.getComponentAccessor().getAccessControlContext(dirtyComponent); -+ javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Void>() { -+ public Void run() { -+ Rectangle rect = tmpDirtyComponents.get(dirtyComponent); -+ -+ int localBoundsH = dirtyComponent.getHeight(); -+ int localBoundsW = dirtyComponent.getWidth(); -+ SwingUtilities.computeIntersection(0, -+ 0, -+ localBoundsW, -+ localBoundsH, -+ rect); -+ if (dirtyComponent instanceof JComponent) { -+ ((JComponent)dirtyComponent).paintImmediately( -+ rect.x,rect.y,rect.width, rect.height); - } -+ else if (dirtyComponent.isShowing()) { -+ Graphics g = JComponent.safelyGetGraphics( -+ dirtyComponent, dirtyComponent); -+ // If the Graphics goes away, it means someone disposed of -+ // the window, don't do anything. -+ if (g != null) { -+ g.setClip(rect.x, rect.y, rect.width, rect.height); -+ try { -+ dirtyComponent.paint(g); -+ } finally { -+ g.dispose(); -+ } -+ } -+ } -+ // If the repaintRoot has been set, service it now and -+ // remove any components that are children of repaintRoot. -+ if (repaintRoot != null) { -+ adjustRoots(repaintRoot, roots, i + 1); -+ count.set(roots.size()); -+ paintManager.isRepaintingRoot = true; -+ repaintRoot.paintImmediately(0, 0, repaintRoot.getWidth(), -+ repaintRoot.getHeight()); -+ paintManager.isRepaintingRoot = false; -+ // Only service repaintRoot once. -+ repaintRoot = null; -+ } -+ -+ return null; - } -- } -- // If the repaintRoot has been set, service it now and -- // remove any components that are children of repaintRoot. -- if (repaintRoot != null) { -- adjustRoots(repaintRoot, roots, i + 1); -- count = roots.size(); -- paintManager.isRepaintingRoot = true; -- repaintRoot.paintImmediately(0, 0, repaintRoot.getWidth(), -- repaintRoot.getHeight()); -- paintManager.isRepaintingRoot = false; -- // Only service repaintRoot once. -- repaintRoot = null; -- } -+ }, stack, acc); - } - } finally { - painting = false; -diff --git a/src/share/classes/sun/applet/AppletPanel.java b/src/share/classes/sun/applet/AppletPanel.java ---- openjdk/jdk/src/share/classes/sun/applet/AppletPanel.java -+++ openjdk/jdk/src/share/classes/sun/applet/AppletPanel.java -@@ -47,6 +47,7 @@ import java.util.WeakHashMap; - import java.util.WeakHashMap; - import javax.swing.SwingUtilities; - import sun.awt.AppContext; -+import sun.awt.AWTAccessor; - import sun.awt.EmbeddedFrame; - import sun.awt.SunToolkit; - import sun.misc.MessageUtils; -@@ -449,12 +450,12 @@ abstract class AppletPanel extends Panel - // to avoid deadlock. - try { - final AppletPanel p = this; -- -- SwingUtilities.invokeAndWait(new Runnable() { -- public void run() { -- p.validate(); -- } -- }); -+ Runnable r = new Runnable() { -+ public void run() { -+ p.validate(); -+ } -+ }; -+ AWTAccessor.getEventQueueAccessor().invokeAndWait(applet, r); - } - catch(InterruptedException ie) { - } -@@ -479,18 +480,19 @@ abstract class AppletPanel extends Panel - try { - final AppletPanel p = this; - final Applet a = applet; -+ Runnable r = new Runnable() { -+ public void run() { -+ p.validate(); -+ a.setVisible(true); - -- SwingUtilities.invokeAndWait(new Runnable() { -- public void run() { -- p.validate(); -- a.setVisible(true); -- -- // Fix for BugTraq ID 4041703. -- // Set the default focus for an applet. -- if (hasInitialFocus()) -- setDefaultFocus(); -+ // Fix for BugTraq ID 4041703. -+ // Set the default focus for an applet. -+ if (hasInitialFocus()) { -+ setDefaultFocus(); - } -- }); -+ } -+ }; -+ AWTAccessor.getEventQueueAccessor().invokeAndWait(applet, r); - } - catch(InterruptedException ie) { - } -@@ -513,13 +515,12 @@ abstract class AppletPanel extends Panel - // to avoid deadlock. - try { - final Applet a = applet; -- -- SwingUtilities.invokeAndWait(new Runnable() { -- public void run() -- { -- a.setVisible(false); -- } -- }); -+ Runnable r = new Runnable() { -+ public void run() { -+ a.setVisible(false); -+ } -+ }; -+ AWTAccessor.getEventQueueAccessor().invokeAndWait(applet, r); - } - catch(InterruptedException ie) { - } -@@ -571,17 +572,14 @@ abstract class AppletPanel extends Panel - } - status = APPLET_DISPOSE; - -- try -- { -+ try { - final Applet a = applet; -- -- EventQueue.invokeAndWait(new Runnable() -- { -- public void run() -- { -+ Runnable r = new Runnable() { -+ public void run() { - remove(a); - } -- }); -+ }; -+ AWTAccessor.getEventQueueAccessor().invokeAndWait(applet, r); - } - catch(InterruptedException ie) - { -diff --git a/src/share/classes/sun/awt/AWTAccessor.java b/src/share/classes/sun/awt/AWTAccessor.java ---- openjdk/jdk/src/share/classes/sun/awt/AWTAccessor.java -+++ openjdk/jdk/src/share/classes/sun/awt/AWTAccessor.java -@@ -29,6 +29,7 @@ import java.awt.*; - - import sun.misc.Unsafe; - -+import java.lang.reflect.InvocationTargetException; - import java.security.AccessControlContext; - - import java.util.Vector; -@@ -198,6 +199,11 @@ public final class AWTAccessor { - */ - void removeSourceEvents(EventQueue eventQueue, Object source, - boolean removeAllEvents); -+ /** -+ * Static in EventQueue -+ */ -+ void invokeAndWait(Object source, Runnable r) -+ throws InterruptedException, InvocationTargetException; - } - - /** -diff --git a/src/windows/classes/sun/awt/windows/WComponentPeer.java b/src/windows/classes/sun/awt/windows/WComponentPeer.java ---- openjdk/jdk/src/windows/classes/sun/awt/windows/WComponentPeer.java -+++ openjdk/jdk/src/windows/classes/sun/awt/windows/WComponentPeer.java -@@ -427,14 +427,15 @@ public abstract class WComponentPeer ext - try { - replaceSurfaceData(); - } catch (InvalidPipeException e) { -- // REMIND : what do we do if our surface creation failed? -+ // REMIND : what do we do if our surface creation failed? - } - } - } - }; -+ Component c = (Component)target; - // Fix 6255371. -- if (!PaintEventDispatcher.getPaintEventDispatcher().queueSurfaceDataReplacing((Component)target, r)) { -- postEvent(new InvocationEvent(Toolkit.getDefaultToolkit(), r)); -+ if (!PaintEventDispatcher.getPaintEventDispatcher().queueSurfaceDataReplacing(c, r)) { -+ postEvent(new InvocationEvent(c, r)); - } - } -
--- a/patches/security/20130201/7197546.patch Tue Mar 19 00:21:31 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,479 +0,0 @@ -# HG changeset patch -# User mbankal -# Date 1355327990 28800 -# Node ID 41f8dd88c5e9aec4975c36414a865aed5643c880 -# Parent 708c134c36312faf8721c0c981be6553e4ebf49f -7197546: (proxy) Reflect about creating reflective proxies -Reviewed-by: mchung - -diff --git a/src/share/classes/java/lang/Class.java b/src/share/classes/java/lang/Class.java ---- openjdk/jdk/src/share/classes/java/lang/Class.java -+++ openjdk/jdk/src/share/classes/java/lang/Class.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 1994, 2006, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 1994, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -65,7 +65,9 @@ import sun.reflect.generics.scope.ClassS - import sun.reflect.generics.scope.ClassScope; - import sun.security.util.SecurityConstants; - import java.lang.annotation.Annotation; -+import java.lang.reflect.Proxy; - import sun.reflect.annotation.*; -+import sun.reflect.misc.ReflectUtil; - - /** - * Instances of the class {@code Class} represent classes and -@@ -320,7 +322,7 @@ public final - throws InstantiationException, IllegalAccessException - { - if (System.getSecurityManager() != null) { -- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader()); -+ checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), false); - } - return newInstance0(); - } -@@ -1294,7 +1296,7 @@ public final - // be very careful not to change the stack depth of this - // checkMemberAccess call for security reasons - // see java.lang.SecurityManager.checkMemberAccess -- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader()); -+ checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), false); - - // Privileged so this implementation can look at DECLARED classes, - // something the caller might not have privilege to do. The code here -@@ -1372,7 +1374,7 @@ public final - // be very careful not to change the stack depth of this - // checkMemberAccess call for security reasons - // see java.lang.SecurityManager.checkMemberAccess -- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader()); -+ checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true); - return copyFields(privateGetPublicFields(null)); - } - -@@ -1423,7 +1425,7 @@ public final - // be very careful not to change the stack depth of this - // checkMemberAccess call for security reasons - // see java.lang.SecurityManager.checkMemberAccess -- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader()); -+ checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true); - return copyMethods(privateGetPublicMethods()); - } - -@@ -1472,7 +1474,7 @@ public final - // be very careful not to change the stack depth of this - // checkMemberAccess call for security reasons - // see java.lang.SecurityManager.checkMemberAccess -- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader()); -+ checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true); - return copyConstructors(privateGetDeclaredConstructors(true)); - } - -@@ -1531,7 +1533,7 @@ public final - // be very careful not to change the stack depth of this - // checkMemberAccess call for security reasons - // see java.lang.SecurityManager.checkMemberAccess -- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader()); -+ checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true); - Field field = getField0(name); - if (field == null) { - throw new NoSuchFieldException(name); -@@ -1616,7 +1618,7 @@ public final - // be very careful not to change the stack depth of this - // checkMemberAccess call for security reasons - // see java.lang.SecurityManager.checkMemberAccess -- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader()); -+ checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true); - Method method = getMethod0(name, parameterTypes); - if (method == null) { - throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes)); -@@ -1670,7 +1672,7 @@ public final - // be very careful not to change the stack depth of this - // checkMemberAccess call for security reasons - // see java.lang.SecurityManager.checkMemberAccess -- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader()); -+ checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true); - return getConstructor0(parameterTypes, Member.PUBLIC); - } - -@@ -1712,7 +1714,7 @@ public final - // be very careful not to change the stack depth of this - // checkMemberAccess call for security reasons - // see java.lang.SecurityManager.checkMemberAccess -- checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader()); -+ checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), false); - return getDeclaredClasses0(); - } - -@@ -1756,7 +1758,7 @@ public final - // be very careful not to change the stack depth of this - // checkMemberAccess call for security reasons - // see java.lang.SecurityManager.checkMemberAccess -- checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader()); -+ checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true); - return copyFields(privateGetDeclaredFields(false)); - } - -@@ -1804,7 +1806,7 @@ public final - // be very careful not to change the stack depth of this - // checkMemberAccess call for security reasons - // see java.lang.SecurityManager.checkMemberAccess -- checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader()); -+ checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true); - return copyMethods(privateGetDeclaredMethods(false)); - } - -@@ -1849,7 +1851,7 @@ public final - // be very careful not to change the stack depth of this - // checkMemberAccess call for security reasons - // see java.lang.SecurityManager.checkMemberAccess -- checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader()); -+ checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true); - return copyConstructors(privateGetDeclaredConstructors(false)); - } - -@@ -1893,7 +1895,7 @@ public final - // be very careful not to change the stack depth of this - // checkMemberAccess call for security reasons - // see java.lang.SecurityManager.checkMemberAccess -- checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader()); -+ checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true); - Field field = searchFields(privateGetDeclaredFields(false), name); - if (field == null) { - throw new NoSuchFieldException(name); -@@ -1948,7 +1950,7 @@ public final - // be very careful not to change the stack depth of this - // checkMemberAccess call for security reasons - // see java.lang.SecurityManager.checkMemberAccess -- checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader()); -+ checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true); - Method method = searchMethods(privateGetDeclaredMethods(false), name, parameterTypes); - if (method == null) { - throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes)); -@@ -1998,7 +2000,7 @@ public final - // be very careful not to change the stack depth of this - // checkMemberAccess call for security reasons - // see java.lang.SecurityManager.checkMemberAccess -- checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader()); -+ checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true); - return getConstructor0(parameterTypes, Member.DECLARED); - } - -@@ -2168,18 +2170,26 @@ public final - * <p> Default policy: allow all clients access with normal Java access - * control. - */ -- private void checkMemberAccess(int which, ClassLoader ccl) { -+ private void checkMemberAccess(int which, ClassLoader ccl, boolean checkProxyInterfaces) { - SecurityManager s = System.getSecurityManager(); - if (s != null) { - s.checkMemberAccess(this, which); - ClassLoader cl = getClassLoader0(); -- if ((ccl != null) && (ccl != cl) && -- ((cl == null) || !cl.isAncestor(ccl))) { -+ if (ReflectUtil.needsPackageAccessCheck(ccl, cl)) { -+ - String name = this.getName(); - int i = name.lastIndexOf('.'); - if (i != -1) { -- s.checkPackageAccess(name.substring(0, i)); -+ // skip the package access check on a proxy class in default proxy package -+ String pkg = name.substring(0, i); -+ if (!Proxy.isProxyClass(this) || !pkg.equals(ReflectUtil.PROXY_PACKAGE)) { -+ s.checkPackageAccess(pkg); -+ } - } -+ } -+ // check package access on the proxy interfaces -+ if (checkProxyInterfaces && Proxy.isProxyClass(this)) { -+ ReflectUtil.checkProxyPackageAccess(ccl, this.getInterfaces()); - } - } - } -diff --git a/src/share/classes/java/lang/reflect/Proxy.java b/src/share/classes/java/lang/reflect/Proxy.java ---- openjdk/jdk/src/share/classes/java/lang/reflect/Proxy.java -+++ openjdk/jdk/src/share/classes/java/lang/reflect/Proxy.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 1999, 2006, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -27,6 +27,9 @@ package java.lang.reflect; - - import java.lang.ref.Reference; - import java.lang.ref.WeakReference; -+import java.security.AccessController; -+import java.security.Permission; -+import java.security.PrivilegedAction; - import java.util.Arrays; - import java.util.Collections; - import java.util.HashMap; -@@ -35,6 +38,9 @@ import java.util.Set; - import java.util.Set; - import java.util.WeakHashMap; - import sun.misc.ProxyGenerator; -+import sun.reflect.Reflection; -+import sun.reflect.misc.ReflectUtil; -+import sun.security.util.SecurityConstants; - - /** - * {@code Proxy} provides static methods for creating dynamic proxy -@@ -263,7 +269,67 @@ public class Proxy implements java.io.Se - * @param h the invocation handler for this proxy instance - */ - protected Proxy(InvocationHandler h) { -+ doNewInstanceCheck(); - this.h = h; -+ } -+ -+ private static class ProxyAccessHelper { -+ // The permission is implementation specific. -+ static final Permission PROXY_PERMISSION = -+ new ReflectPermission("proxyConstructorNewInstance"); -+ // These system properties are defined to provide a short-term -+ // workaround if customers need to disable the new security checks. -+ static final boolean allowNewInstance; -+ static final boolean allowNullLoader; -+ static { -+ allowNewInstance = getBooleanProperty("sun.reflect.proxy.allowsNewInstance"); -+ allowNullLoader = getBooleanProperty("sun.reflect.proxy.allowsNullLoader"); -+ } -+ -+ private static boolean getBooleanProperty(final String key) { -+ String s = AccessController.doPrivileged(new PrivilegedAction<String>() { -+ public String run() { -+ return System.getProperty(key); -+ } -+ }); -+ return Boolean.valueOf(s); -+ } -+ -+ static boolean needsNewInstanceCheck(Class<?> proxyClass) { -+ if (!Proxy.isProxyClass(proxyClass) || allowNewInstance) { -+ return false; -+ } -+ -+ if (proxyClass.getName().startsWith(ReflectUtil.PROXY_PACKAGE + ".")) { -+ // all proxy interfaces are public -+ return false; -+ } -+ for (Class<?> intf : proxyClass.getInterfaces()) { -+ if (!Modifier.isPublic(intf.getModifiers())) { -+ return true; -+ } -+ } -+ return false; -+ } -+ } -+ -+ /* -+ * Access check on a proxy class that implements any non-public interface. -+ * -+ * @throws SecurityException if a security manager exists, and -+ * the caller does not have the permission. -+ */ -+ private void doNewInstanceCheck() { -+ SecurityManager sm = System.getSecurityManager(); -+ Class<?> proxyClass = this.getClass(); -+ if (sm != null && ProxyAccessHelper.needsNewInstanceCheck(proxyClass)) { -+ try { -+ sm.checkPermission(ProxyAccessHelper.PROXY_PERMISSION); -+ } catch (SecurityException e) { -+ throw new SecurityException("Not allowed to construct a Proxy " -+ + "instance that implements a non-public interface", e); -+ } -+ } - } - - /** -@@ -344,6 +410,50 @@ public class Proxy implements java.io.Se - Class<?>... interfaces) - throws IllegalArgumentException - { -+ return getProxyClass0(loader, interfaces); // stack walk magic: do not refactor -+ } -+ -+ private static void checkProxyLoader(ClassLoader ccl, -+ ClassLoader loader) -+ { -+ SecurityManager sm = System.getSecurityManager(); -+ if (sm != null) { -+ if (loader == null && ccl != null) { -+ if (!ProxyAccessHelper.allowNullLoader) { -+ sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION); -+ } -+ } -+ } -+ } -+ -+ /* -+ * Generate a proxy class (caller-sensitive). -+ * -+ * To define a proxy class, it performs the access checks as in -+ * Class.forName (VM will invoke ClassLoader.checkPackageAccess): -+ * 1. "getClassLoader" permission check if loader == null -+ * 2. checkPackageAccess on the interfaces it implements -+ * -+ * To get a constructor and new instance of a proxy class, it performs -+ * the package access check on the interfaces it implements -+ * as in Class.getConstructor. -+ * -+ * If an interface is non-public, the proxy class must be defined by -+ * the defining loader of the interface. If the caller's class loader -+ * is not the same as the defining loader of the interface, the VM -+ * will throw IllegalAccessError when the generated proxy class is -+ * being defined via the defineClass0 method. -+ */ -+ private static Class<?> getProxyClass0(ClassLoader loader, -+ Class<?>... interfaces) { -+ SecurityManager sm = System.getSecurityManager(); -+ if (sm != null) { -+ final int CALLER_FRAME = 3; // 0: Reflection, 1: getProxyClass0 2: Proxy 3: caller -+ final Class<?> caller = Reflection.getCallerClass(CALLER_FRAME); -+ final ClassLoader ccl = caller.getClassLoader(); -+ checkProxyLoader(ccl, loader); -+ ReflectUtil.checkProxyPackageAccess(ccl, interfaces); -+ } - if (interfaces.length > 65535) { - throw new IllegalArgumentException("interface limit exceeded"); - } -@@ -494,8 +604,9 @@ public class Proxy implements java.io.Se - } - } - -- if (proxyPkg == null) { // if no non-public proxy interfaces, -- proxyPkg = ""; // use the unnamed package -+ if (proxyPkg == null) { -+ // if no non-public proxy interfaces, use sun.proxy package -+ proxyPkg = ReflectUtil.PROXY_PACKAGE + "."; - } - - { -@@ -595,22 +706,45 @@ public class Proxy implements java.io.Se - /* - * Look up or generate the designated proxy class. - */ -- Class cl = getProxyClass(loader, interfaces); -+ Class<?> cl = getProxyClass0(loader, interfaces); // stack walk magic: do not refactor - - /* - * Invoke its constructor with the designated invocation handler. - */ - try { -- Constructor cons = cl.getConstructor(constructorParams); -- return (Object) cons.newInstance(new Object[] { h }); -+ final Constructor<?> cons = cl.getConstructor(constructorParams); -+ final InvocationHandler ih = h; -+ SecurityManager sm = System.getSecurityManager(); -+ if (sm != null && ProxyAccessHelper.needsNewInstanceCheck(cl)) { -+ // create proxy instance with doPrivilege as the proxy class may -+ // implement non-public interfaces that requires a special permission -+ return AccessController.doPrivileged(new PrivilegedAction<Object>() { -+ public Object run() { -+ return newInstance(cons, ih); -+ } -+ }); -+ } else { -+ return newInstance(cons, ih); -+ } - } catch (NoSuchMethodException e) { - throw new InternalError(e.toString()); -+ } -+ } -+ -+ private static Object newInstance(Constructor<?> cons, InvocationHandler h) { -+ try { -+ return cons.newInstance(new Object[] {h} ); - } catch (IllegalAccessException e) { - throw new InternalError(e.toString()); - } catch (InstantiationException e) { - throw new InternalError(e.toString()); - } catch (InvocationTargetException e) { -- throw new InternalError(e.toString()); -+ Throwable t = e.getCause(); -+ if (t instanceof RuntimeException) { -+ throw (RuntimeException) t; -+ } else { -+ throw new InternalError(t.toString()); -+ } - } - } - -diff --git a/src/share/classes/sun/reflect/misc/ReflectUtil.java b/src/share/classes/sun/reflect/misc/ReflectUtil.java ---- openjdk/jdk/src/share/classes/sun/reflect/misc/ReflectUtil.java -+++ openjdk/jdk/src/share/classes/sun/reflect/misc/ReflectUtil.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -144,4 +144,63 @@ public final class ReflectUtil { - } - return true; - } -+ -+ // Returns true if p is an ancestor of cl i.e. class loader 'p' can -+ // be found in the cl's delegation chain -+ private static boolean isAncestor(ClassLoader p, ClassLoader cl) { -+ ClassLoader acl = cl; -+ do { -+ acl = acl.getParent(); -+ if (p == acl) { -+ return true; -+ } -+ } while (acl != null); -+ return false; -+ } -+ -+ /** -+ * Returns true if package access check is needed for reflective -+ * access from a class loader 'from' to classes or members in -+ * a class defined by class loader 'to'. This method returns true -+ * if 'from' is not the same as or an ancestor of 'to'. All code -+ * in a system domain are granted with all permission and so this -+ * method returns false if 'from' class loader is a class loader -+ * loading system classes. On the other hand, if a class loader -+ * attempts to access system domain classes, it requires package -+ * access check and this method will return true. -+ */ -+ public static boolean needsPackageAccessCheck(ClassLoader from, ClassLoader to) { -+ if (from == null || from == to) -+ return false; -+ -+ if (to == null) -+ return true; -+ -+ return !isAncestor(from, to); -+ } -+ -+ /** -+ * Access check on the interfaces that a proxy class implements and throw -+ * {@code SecurityException} if it accesses a restricted package. -+ * -+ * @param ccl the caller's class loader -+ * @param interfaces the list of interfaces that a proxy class implements -+ * -+ * @see Proxy#checkProxyAccess -+ */ -+ public static void checkProxyPackageAccess(ClassLoader ccl, -+ Class<?>... interfaces) -+ { -+ SecurityManager sm = System.getSecurityManager(); -+ if (sm != null) { -+ for (Class<?> intf : interfaces) { -+ ClassLoader cl = intf.getClassLoader(); -+ if (needsPackageAccessCheck(ccl, cl)) { -+ checkPackageAccess(intf); -+ } -+ } -+ } -+ } -+ -+ public static final String PROXY_PACKAGE = "sun.proxy"; - }
--- a/patches/security/20130201/7200491.patch Tue Mar 19 00:21:31 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,49 +0,0 @@ -# HG changeset patch -# User rupashka -# Date 1352203457 -14400 -# Node ID ac55f56db9ab0280853c4a6bfbdc2c578027f9f2 -# Parent 6deb10c2d5d0c8925fd2012d9fc3b9325c997f21 -7200491: Tighten up JTable layout code -Reviewed-by: art, skoivu - -diff --git a/src/share/classes/com/sun/java/swing/plaf/nimbus/NimbusLookAndFeel.java b/src/share/classes/com/sun/java/swing/plaf/nimbus/NimbusLookAndFeel.java ---- openjdk/jdk/src/share/classes/com/sun/java/swing/plaf/nimbus/NimbusLookAndFeel.java -+++ openjdk/jdk/src/share/classes/com/sun/java/swing/plaf/nimbus/NimbusLookAndFeel.java -@@ -159,7 +159,12 @@ public class NimbusLookAndFeel extends S - - // Store Table ScrollPane Corner Component - uiDefaults.put("Table.scrollPaneCornerComponent", -- TableScrollPaneCorner.class); -+ new UIDefaults.ActiveValue() { -+ @Override -+ public Object createValue(UIDefaults table) { -+ return new TableScrollPaneCorner(); -+ } -+ }); - - // Setup the settings for ToolBarSeparator which is custom - // installed for Nimbus -diff --git a/src/share/classes/javax/swing/JTable.java b/src/share/classes/javax/swing/JTable.java ---- openjdk/jdk/src/share/classes/javax/swing/JTable.java -+++ openjdk/jdk/src/share/classes/javax/swing/JTable.java -@@ -777,15 +777,11 @@ public class JTable extends JComponent i - scrollPane.getCorner(JScrollPane.UPPER_TRAILING_CORNER); - if (corner == null || corner instanceof UIResource){ - corner = null; -- Object componentClass = UIManager.get( -- "Table.scrollPaneCornerComponent"); -- if (componentClass instanceof Class){ -- try { -- corner = (Component) -- ((Class)componentClass).newInstance(); -- } catch (Exception e) { -- // just ignore and don't set corner -- } -+ try { -+ corner = (Component) UIManager.get( -+ "Table.scrollPaneCornerComponent"); -+ } catch (Exception e) { -+ // just ignore and don't set corner - } - scrollPane.setCorner(JScrollPane.UPPER_TRAILING_CORNER, - corner);
--- a/patches/security/20130201/7200500.patch Tue Mar 19 00:21:31 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,60 +0,0 @@ -# HG changeset patch -# User coffeys -# Date 1353019348 0 -# Node ID 27bb245457d801fab2a5a835e42a4adefdf7ce85 -# Parent 46582c3c96b3fdd43b58761c3869ce55fad1c755 -7200500: Launcher better input validation -Reviewed-by: ksrini - -diff --git a/src/share/bin/parse_manifest.c b/src/share/bin/parse_manifest.c ---- openjdk/jdk/src/share/bin/parse_manifest.c -+++ openjdk/jdk/src/share/bin/parse_manifest.c -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -487,9 +487,9 @@ JLI_ParseManifest(char *jarfile, manifes - #ifdef O_BINARY - | O_BINARY /* use binary mode on windows */ - #endif -- )) == -1) -+ )) == -1) { - return (-1); -- -+ } - info->manifest_version = NULL; - info->main_class = NULL; - info->jre_version = NULL; -@@ -536,12 +536,14 @@ JLI_JarUnpackFile(const char *jarfile, c - zentry entry; - void *data = NULL; - -- fd = open(jarfile, O_RDONLY -+ if ((fd = open(jarfile, O_RDONLY - #ifdef O_BINARY - | O_BINARY /* use binary mode on windows */ - #endif -- ); -- if (fd != -1 && find_file(fd, &entry, filename) == 0) { -+ )) == -1) { -+ return NULL; -+ } -+ if (find_file(fd, &entry, filename) == 0) { - data = inflate_file(fd, &entry, size); - } - close(fd); -@@ -583,9 +585,9 @@ JLI_ManifestIterate(const char *jarfile, - #ifdef O_BINARY - | O_BINARY /* use binary mode on windows */ - #endif -- )) == -1) -+ )) == -1) { - return (-1); -- -+ } - if (rc = find_file(fd, &entry, manifest_name) != 0) { - close(fd); - return (-2);
--- a/patches/security/20130201/7201064.patch Tue Mar 19 00:21:31 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,125 +0,0 @@ -# HG changeset patch -# User denis -# Date 1354529203 -14400 -# Node ID dd878232965aaa7d16fe7109fab69f7f1219f97a -# Parent 9bbc6817b00c3e9d4eba05d53a8a20b45947ea03 -7201064: Better dialogue checking -Reviewed-by: serb, skoivu - -diff --git a/src/share/classes/java/awt/Dialog.java b/src/share/classes/java/awt/Dialog.java ---- openjdk/jdk/src/share/classes/java/awt/Dialog.java -+++ openjdk/jdk/src/share/classes/java/awt/Dialog.java -@@ -34,6 +34,7 @@ import java.security.PrivilegedAction; - import java.security.PrivilegedAction; - import javax.accessibility.*; - import sun.awt.AppContext; -+import java.security.AccessControlException; - import sun.awt.SunToolkit; - import sun.awt.PeerEvent; - import sun.awt.util.IdentityArrayList; -@@ -127,6 +128,8 @@ public class Dialog extends Window { - * @since 1.4 - */ - boolean undecorated = false; -+ -+ private transient boolean initialized = false; - - /** - * Modal dialogs block all input to some top-level windows. -@@ -679,6 +682,7 @@ public class Dialog extends Window { - this.title = title; - setModalityType(modalityType); - SunToolkit.checkAndSetPolicy(this, false); -+ initialized = true; - } - - /** -@@ -730,6 +734,7 @@ public class Dialog extends Window { - this.title = title; - setModalityType(modalityType); - SunToolkit.checkAndSetPolicy(this, false); -+ initialized = true; - } - - /** -@@ -859,12 +864,9 @@ public class Dialog extends Window { - if (modalityType == type) { - return; - } -- if (type == ModalityType.TOOLKIT_MODAL) { -- SecurityManager sm = System.getSecurityManager(); -- if (sm != null) { -- sm.checkPermission(SecurityConstants.TOOLKIT_MODALITY_PERMISSION); -- } -- } -+ -+ checkModalityPermission(type); -+ - modalityType = type; - modal = (modalityType != ModalityType.MODELESS); - } -@@ -1039,6 +1041,11 @@ public class Dialog extends Window { - */ - @Deprecated - public void show() { -+ if (!initialized) { -+ throw new IllegalStateException("The dialog component " + -+ "has not been initialized properly"); -+ } -+ - beforeFirstShow = false; - if (!isModal()) { - conditionalShow(null, null); -@@ -1614,18 +1621,50 @@ public class Dialog extends Window { - } - } - -+ private void checkModalityPermission(ModalityType mt) { -+ if (mt == ModalityType.TOOLKIT_MODAL) { -+ SecurityManager sm = System.getSecurityManager(); -+ if (sm != null) { -+ sm.checkPermission( -+ SecurityConstants.TOOLKIT_MODALITY_PERMISSION -+ ); -+ } -+ } -+ } -+ - private void readObject(ObjectInputStream s) - throws ClassNotFoundException, IOException, HeadlessException - { - GraphicsEnvironment.checkHeadless(); -- s.defaultReadObject(); -+ -+ java.io.ObjectInputStream.GetField fields = -+ s.readFields(); -+ -+ ModalityType localModalityType = (ModalityType)fields.get("modalityType", null); -+ -+ try { -+ checkModalityPermission(localModalityType); -+ } catch (AccessControlException ace) { -+ localModalityType = DEFAULT_MODALITY_TYPE; -+ } - - // in 1.5 or earlier modalityType was absent, so use "modal" instead -- if (modalityType == null) { -+ if (localModalityType == null) { -+ this.modal = fields.get("modal", false); - setModal(modal); - } - -+ this.resizable = fields.get("resizable", true); -+ this.undecorated = fields.get("undecorated", false); -+ this.title = (String)fields.get("title", ""); -+ this.modalityType = localModalityType; -+ - blockedWindows = new IdentityArrayList(); -+ -+ SunToolkit.checkAndSetPolicy(this, false); -+ -+ initialized = true; -+ - } - - /*
--- a/patches/security/20130201/7201066.patch Tue Mar 19 00:21:31 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,66 +0,0 @@ -# HG changeset patch -# User coffeys -# Date 1352217014 0 -# Node ID 58fdb67fcacc67693fc43b5601e88bd7c216f850 -# Parent 42b1142b39b5a511e1e07b5877cc55e93767064e -7201066: Change modifiers on unused fields -Reviewed-by: alanb, skoivu - -diff --git a/src/share/classes/com/sun/corba/se/impl/activation/ServerMain.java b/src/share/classes/com/sun/corba/se/impl/activation/ServerMain.java ---- openjdk/corba/src/share/classes/com/sun/corba/se/impl/activation/ServerMain.java -+++ openjdk/corba/src/share/classes/com/sun/corba/se/impl/activation/ServerMain.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 1997, 2002, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -322,9 +322,9 @@ class ServerCallback extends - com.sun.corba.se.spi.activation._ServerImplBase - { - private ORB orb; -- private Method installMethod ; -- private Method uninstallMethod ; -- private Method shutdownMethod ; -+ private transient Method installMethod ; -+ private transient Method uninstallMethod ; -+ private transient Method shutdownMethod ; - private Object methodArgs[] ; - - ServerCallback(ORB orb, Method installMethod, Method uninstallMethod, -diff --git a/src/share/classes/com/sun/corba/se/impl/io/ObjectStreamClass.java b/src/share/classes/com/sun/corba/se/impl/io/ObjectStreamClass.java ---- openjdk/corba/src/share/classes/com/sun/corba/se/impl/io/ObjectStreamClass.java -+++ openjdk/corba/src/share/classes/com/sun/corba/se/impl/io/ObjectStreamClass.java -@@ -1536,8 +1536,8 @@ public class ObjectStreamClass implement - private boolean hasExternalizableBlockData; - Method writeObjectMethod; - Method readObjectMethod; -- private Method writeReplaceObjectMethod; -- private Method readResolveObjectMethod; -+ private transient Method writeReplaceObjectMethod; -+ private transient Method readResolveObjectMethod; - private Constructor cons ; - - /** -diff --git a/src/share/classes/com/sun/corba/se/impl/orbutil/ObjectStreamClass_1_3_1.java b/src/share/classes/com/sun/corba/se/impl/orbutil/ObjectStreamClass_1_3_1.java ---- openjdk/corba/src/share/classes/com/sun/corba/se/impl/orbutil/ObjectStreamClass_1_3_1.java -+++ openjdk/corba/src/share/classes/com/sun/corba/se/impl/orbutil/ObjectStreamClass_1_3_1.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2001, 2003, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -1119,8 +1119,8 @@ public class ObjectStreamClass_1_3_1 imp - private boolean hasExternalizableBlockData; - Method writeObjectMethod; - Method readObjectMethod; -- private Method writeReplaceObjectMethod; -- private Method readResolveObjectMethod; -+ private transient Method writeReplaceObjectMethod; -+ private transient Method readResolveObjectMethod; - - /* - * ObjectStreamClass_1_3_1 that this one was built from.
--- a/patches/security/20130201/7201068.patch Tue Mar 19 00:21:31 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,83 +0,0 @@ -# HG changeset patch -# User coffeys -# Date 1352286387 0 -# Node ID 6e2d4ed84b41667df189abb7bd0915cda01a85a0 -# Parent ac55f56db9ab0280853c4a6bfbdc2c578027f9f2 -7201068: Better handling of UI elements -Reviewed-by: mullan, skoivu - -diff --git a/src/share/lib/security/java.security b/src/share/lib/security/java.security ---- openjdk/jdk/src/share/lib/security/java.security -+++ openjdk/jdk/src/share/lib/security/java.security -@@ -127,7 +127,9 @@ system.scope=sun.security.provider.Ident - # passed to checkPackageAccess unless the - # corresponding RuntimePermission ("accessClassInPackage."+package) has - # been granted. --package.access=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio. -+package.access=sun.,\ -+ com.sun.xml.internal.,\ -+ com.sun.imageio. - - # - # List of comma-separated packages that start with or equal this string -@@ -139,7 +141,9 @@ package.access=sun.,com.sun.xml.internal - # by default, none of the class loaders supplied with the JDK call - # checkPackageDefinition. - # --package.definition=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio. -+package.definition=sun.,\ -+ com.sun.xml.internal.,\ -+ com.sun.imageio. - - # - # Determines whether this properties file can be appended to -diff --git a/src/share/lib/security/java.security-solaris b/src/share/lib/security/java.security-solaris ---- openjdk/jdk/src/share/lib/security/java.security-solaris -+++ openjdk/jdk/src/share/lib/security/java.security-solaris -@@ -128,7 +128,9 @@ system.scope=sun.security.provider.Ident - # passed to checkPackageAccess unless the - # corresponding RuntimePermission ("accessClassInPackage."+package) has - # been granted. --package.access=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio. -+package.access=sun.,\ -+ com.sun.xml.internal.,\ -+ com.sun.imageio. - - # - # List of comma-separated packages that start with or equal this string -@@ -140,7 +142,9 @@ package.access=sun.,com.sun.xml.internal - # by default, none of the class loaders supplied with the JDK call - # checkPackageDefinition. - # --package.definition=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio. -+package.definition=sun.,\ -+ com.sun.xml.internal.,\ -+ com.sun.imageio. - - # - # Determines whether this properties file can be appended to -diff --git a/src/share/lib/security/java.security-windows b/src/share/lib/security/java.security-windows ---- openjdk/jdk/src/share/lib/security/java.security-windows -+++ openjdk/jdk/src/share/lib/security/java.security-windows -@@ -128,7 +128,9 @@ system.scope=sun.security.provider.Ident - # passed to checkPackageAccess unless the - # corresponding RuntimePermission ("accessClassInPackage."+package) has - # been granted. --package.access=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio. -+package.access=sun.,\ -+ com.sun.xml.internal.,\ -+ com.sun.imageio. - - # - # List of comma-separated packages that start with or equal this string -@@ -140,7 +142,9 @@ package.access=sun.,com.sun.xml.internal - # by default, none of the class loaders supplied with the JDK call - # checkPackageDefinition. - # --package.definition=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio. -+package.definition=sun.,\ -+ com.sun.xml.internal.,\ -+ com.sun.imageio. - - # - # Determines whether this properties file can be appended to
--- a/patches/security/20130201/7201070.patch Tue Mar 19 00:21:31 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +0,0 @@ -# HG changeset patch -# User coffeys -# Date 1355322673 0 -# Node ID 042882b32f75d0e736c19f93688d37fb98d7d26d -# Parent 708c134c36312faf8721c0c981be6553e4ebf49f -7201070: Serialization to conform to protocol -Reviewed-by: smarks, skoivu - -diff --git a/src/share/classes/java/io/ObjectInputStream.java b/src/share/classes/java/io/ObjectInputStream.java ---- openjdk/jdk/src/share/classes/java/io/ObjectInputStream.java -+++ openjdk/jdk/src/share/classes/java/io/ObjectInputStream.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -1749,6 +1749,12 @@ public class ObjectInputStream - ObjectStreamClass desc = readClassDesc(false); - desc.checkDeserialize(); - -+ Class<?> cl = desc.forClass(); -+ if (cl == String.class || cl == Class.class -+ || cl == ObjectStreamClass.class) { -+ throw new InvalidClassException("invalid class descriptor"); -+ } -+ - Object obj; - try { - obj = desc.isInstantiable() ? desc.newInstance() : null;
--- a/patches/security/20130201/7201071.patch Tue Mar 19 00:21:31 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,553 +0,0 @@ -# HG changeset patch -# User robm -# Date 1352819613 0 -# Node ID 46582c3c96b3fdd43b58761c3869ce55fad1c755 -# Parent ee4632a30696050ebd5c014fb3da64112ab48dd3 -7201071: InetSocketAddress serialization issue -Reviewed-by: chegar - -diff --git a/src/share/classes/java/net/InetSocketAddress.java b/src/share/classes/java/net/InetSocketAddress.java ---- openjdk/jdk/src/share/classes/java/net/InetSocketAddress.java -+++ openjdk/jdk/src/share/classes/java/net/InetSocketAddress.java -@@ -24,9 +24,12 @@ - */ - package java.net; - --import java.io.ObjectInputStream; - import java.io.IOException; - import java.io.InvalidObjectException; -+import java.io.ObjectInputStream; -+import java.io.ObjectOutputStream; -+import java.io.ObjectStreamException; -+import java.io.ObjectStreamField; - - /** - * -@@ -46,24 +49,106 @@ import java.io.InvalidObjectException; - * @see java.net.ServerSocket - * @since 1.4 - */ --public class InetSocketAddress extends SocketAddress { -- /* The hostname of the Socket Address -- * @serial -- */ -- private String hostname = null; -- /* The IP address of the Socket Address -- * @serial -- */ -- private InetAddress addr = null; -- /* The port number of the Socket Address -- * @serial -- */ -- private int port; -+public class InetSocketAddress -+ extends SocketAddress -+{ -+ // Private implementation class pointed to by all public methods. -+ private static class InetSocketAddressHolder { -+ // The hostname of the Socket Address -+ private String hostname; -+ // The IP address of the Socket Address -+ private InetAddress addr; -+ // The port number of the Socket Address -+ private int port; -+ -+ private InetSocketAddressHolder(String hostname, InetAddress addr, int port) { -+ this.hostname = hostname; -+ this.addr = addr; -+ this.port = port; -+ } -+ -+ private int getPort() { -+ return port; -+ } -+ -+ private InetAddress getAddress() { -+ return addr; -+ } -+ -+ private String getHostName() { -+ if (hostname != null) -+ return hostname; -+ if (addr != null) -+ return addr.getHostName(); -+ return null; -+ } -+ -+ private String getHostString() { -+ if (hostname != null) -+ return hostname; -+ if (addr != null) { -+ if (addr.hostName != null) -+ return addr.hostName; -+ else -+ return addr.getHostAddress(); -+ } -+ return null; -+ } -+ -+ private boolean isUnresolved() { -+ return addr == null; -+ } -+ -+ @Override -+ public String toString() { -+ if (isUnresolved()) { -+ return hostname + ":" + port; -+ } else { -+ return addr.toString() + ":" + port; -+ } -+ } -+ -+ @Override -+ public final boolean equals(Object obj) { -+ if (obj == null || !(obj instanceof InetSocketAddressHolder)) -+ return false; -+ InetSocketAddressHolder that = (InetSocketAddressHolder)obj; -+ boolean sameIP; -+ if (addr != null) -+ sameIP = addr.equals(that.addr); -+ else if (hostname != null) -+ sameIP = (that.addr == null) && -+ hostname.equalsIgnoreCase(that.hostname); -+ else -+ sameIP = (that.addr == null) && (that.hostname == null); -+ return sameIP && (port == that.port); -+ } -+ -+ @Override -+ public final int hashCode() { -+ if (addr != null) -+ return addr.hashCode() + port; -+ if (hostname != null) -+ return hostname.toLowerCase().hashCode() + port; -+ return port; -+ } -+ } -+ -+ private final transient InetSocketAddressHolder holder; - - private static final long serialVersionUID = 5076001401234631237L; - -- private InetSocketAddress() { -+ private static int checkPort(int port) { -+ if (port < 0 || port > 0xFFFF) -+ throw new IllegalArgumentException("port out of range:" + port); -+ return port; - } -+ -+ private static String checkHost(String hostname) { -+ if (hostname == null) -+ throw new IllegalArgumentException("hostname can't be null"); -+ return hostname; -+ } - - /** - * Creates a socket address where the IP address is the wildcard address -@@ -97,14 +182,10 @@ public class InetSocketAddress extends S - * range of valid port values. - */ - public InetSocketAddress(InetAddress addr, int port) { -- if (port < 0 || port > 0xFFFF) { -- throw new IllegalArgumentException("port out of range:" + port); -- } -- this.port = port; -- if (addr == null) -- this.addr = InetAddress.anyLocalAddress(); -- else -- this.addr = addr; -+ holder = new InetSocketAddressHolder( -+ null, -+ addr == null ? InetAddress.anyLocalAddress() : addr, -+ checkPort(port)); - } - - /** -@@ -132,19 +213,20 @@ public class InetSocketAddress extends S - * @see #isUnresolved() - */ - public InetSocketAddress(String hostname, int port) { -- if (port < 0 || port > 0xFFFF) { -- throw new IllegalArgumentException("port out of range:" + port); -- } -- if (hostname == null) { -- throw new IllegalArgumentException("hostname can't be null"); -- } -+ checkHost(hostname); -+ InetAddress addr = null; -+ String host = null; - try { - addr = InetAddress.getByName(hostname); - } catch(UnknownHostException e) { -- this.hostname = hostname; -- addr = null; -+ host = hostname; - } -- this.port = port; -+ holder = new InetSocketAddressHolder(host, addr, checkPort(port)); -+ } -+ -+ // private constructor for creating unresolved instances -+ private InetSocketAddress(int port, String hostname) { -+ holder = new InetSocketAddressHolder(hostname, null, port); - } - - /** -@@ -169,31 +251,67 @@ public class InetSocketAddress extends S - * @since 1.5 - */ - public static InetSocketAddress createUnresolved(String host, int port) { -- if (port < 0 || port > 0xFFFF) { -- throw new IllegalArgumentException("port out of range:" + port); -- } -- if (host == null) { -- throw new IllegalArgumentException("hostname can't be null"); -- } -- InetSocketAddress s = new InetSocketAddress(); -- s.port = port; -- s.hostname = host; -- s.addr = null; -- return s; -+ return new InetSocketAddress(checkPort(port), checkHost(host)); -+ } -+ -+ /** -+ * @serialField hostname String -+ * @serialField addr InetAddress -+ * @serialField port int -+ */ -+ private static final ObjectStreamField[] serialPersistentFields = { -+ new ObjectStreamField("hostname", String.class), -+ new ObjectStreamField("addr", InetAddress.class), -+ new ObjectStreamField("port", int.class)}; -+ -+ private void writeObject(ObjectOutputStream out) -+ throws IOException -+ { -+ // Don't call defaultWriteObject() -+ ObjectOutputStream.PutField pfields = out.putFields(); -+ pfields.put("hostname", holder.hostname); -+ pfields.put("addr", holder.addr); -+ pfields.put("port", holder.port); -+ out.writeFields(); - } - -- private void readObject(ObjectInputStream s) -- throws IOException, ClassNotFoundException { -- s.defaultReadObject(); -+ private void readObject(ObjectInputStream in) -+ throws IOException, ClassNotFoundException -+ { -+ // Don't call defaultReadObject() -+ ObjectInputStream.GetField oisFields = in.readFields(); -+ final String oisHostname = (String)oisFields.get("hostname", null); -+ final InetAddress oisAddr = (InetAddress)oisFields.get("addr", null); -+ final int oisPort = oisFields.get("port", -1); - - // Check that our invariants are satisfied -- if (port < 0 || port > 0xFFFF) { -- throw new InvalidObjectException("port out of range:" + port); -- } -- -- if (hostname == null && addr == null) { -+ checkPort(oisPort); -+ if (oisHostname == null && oisAddr == null) - throw new InvalidObjectException("hostname and addr " + - "can't both be null"); -+ -+ InetSocketAddressHolder h = new InetSocketAddressHolder(oisHostname, -+ oisAddr, -+ oisPort); -+ UNSAFE.putObject(this, FIELDS_OFFSET, h); -+ } -+ -+ private void readObjectNoData() -+ throws ObjectStreamException -+ { -+ throw new InvalidObjectException("Stream data required"); -+ } -+ -+ private static final long FIELDS_OFFSET; -+ private static final sun.misc.Unsafe UNSAFE; -+ static { -+ try { -+ sun.misc.Unsafe unsafe = sun.misc.Unsafe.getUnsafe(); -+ FIELDS_OFFSET = unsafe.objectFieldOffset( -+ InetSocketAddress.class.getDeclaredField("holder")); -+ UNSAFE = unsafe; -+ } catch (NoSuchFieldException e) { -+ throw new Error(e); - } - } - -@@ -203,7 +321,7 @@ public class InetSocketAddress extends S - * @return the port number. - */ - public final int getPort() { -- return port; -+ return holder.getPort(); - } - - /** -@@ -213,7 +331,7 @@ public class InetSocketAddress extends S - * @return the InetAdress or <code>null</code> if it is unresolved. - */ - public final InetAddress getAddress() { -- return addr; -+ return holder.getAddress(); - } - - /** -@@ -222,11 +340,7 @@ public class InetSocketAddress extends S - * @return the hostname part of the address. - */ - public final String getHostName() { -- if (hostname != null) -- return hostname; -- if (addr != null) -- return addr.getHostName(); -- return null; -+ return holder.getHostName(); - } - - /** -@@ -238,15 +352,7 @@ public class InetSocketAddress extends S - * @since 1.6 - */ - final String getHostString() { -- if (hostname != null) -- return hostname; -- if (addr != null) { -- if (addr.hostName != null) -- return addr.hostName; -- else -- return addr.getHostAddress(); -- } -- return null; -+ return holder.getHostString(); - } - - /** -@@ -256,7 +362,7 @@ public class InetSocketAddress extends S - * an <code>InetAddress</code>. - */ - public final boolean isUnresolved() { -- return addr == null; -+ return holder.isUnresolved(); - } - - /** -@@ -267,12 +373,9 @@ public class InetSocketAddress extends S - * - * @return a string representation of this object. - */ -+ @Override - public String toString() { -- if (isUnresolved()) { -- return hostname + ":" + port; -- } else { -- return addr.toString() + ":" + port; -- } -+ return holder.toString(); - } - - /** -@@ -295,16 +398,7 @@ public class InetSocketAddress extends S - public final boolean equals(Object obj) { - if (obj == null || !(obj instanceof InetSocketAddress)) - return false; -- InetSocketAddress sockAddr = (InetSocketAddress) obj; -- boolean sameIP = false; -- if (this.addr != null) -- sameIP = this.addr.equals(sockAddr.addr); -- else if (this.hostname != null) -- sameIP = (sockAddr.addr == null) && -- this.hostname.equals(sockAddr.hostname); -- else -- sameIP = (sockAddr.addr == null) && (sockAddr.hostname == null); -- return sameIP && (this.port == sockAddr.port); -+ return holder.equals(((InetSocketAddress) obj).holder); - } - - /** -@@ -312,11 +406,8 @@ public class InetSocketAddress extends S - * - * @return a hash code value for this socket address. - */ -+ @Override - public final int hashCode() { -- if (addr != null) -- return addr.hashCode() + port; -- if (hostname != null) -- return hostname.hashCode() + port; -- return port; -+ return holder.hashCode(); - } - } -diff --git a/src/share/classes/sun/nio/ch/DatagramChannelImpl.java b/src/share/classes/sun/nio/ch/DatagramChannelImpl.java ---- openjdk/jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java -+++ openjdk/jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java -@@ -239,7 +239,7 @@ class DatagramChannelImpl - - synchronized (writeLock) { - ensureOpen(); -- InetSocketAddress isa = (InetSocketAddress)target; -+ InetSocketAddress isa = Net.checkAddress(target); - InetAddress ia = isa.getAddress(); - if (ia == null) - throw new IOException("Target address not resolved"); -@@ -250,9 +250,9 @@ class DatagramChannelImpl - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - if (ia.isMulticastAddress()) { -- sm.checkMulticast(isa.getAddress()); -+ sm.checkMulticast(ia); - } else { -- sm.checkConnect(isa.getAddress().getHostAddress(), -+ sm.checkConnect(ia.getHostAddress(), - isa.getPort()); - } - } -@@ -272,7 +272,7 @@ class DatagramChannelImpl - return 0; - writerThread = NativeThread.current(); - do { -- n = send(fd, src, target); -+ n = send(fd, src, isa); - } while ((n == IOStatus.INTERRUPTED) && isOpen()); - return IOStatus.normalize(n); - } finally { -@@ -283,7 +283,7 @@ class DatagramChannelImpl - } - } - -- private int send(FileDescriptor fd, ByteBuffer src, SocketAddress target) -+ private int send(FileDescriptor fd, ByteBuffer src, InetSocketAddress target) - throws IOException - { - if (src instanceof DirectBuffer) -@@ -315,7 +315,7 @@ class DatagramChannelImpl - } - - private int sendFromNativeBuffer(FileDescriptor fd, ByteBuffer bb, -- SocketAddress target) -+ InetSocketAddress target) - throws IOException - { - int pos = bb.position(); -@@ -324,7 +324,7 @@ class DatagramChannelImpl - int rem = (pos <= lim ? lim - pos : 0); - - int written = send0(fd, ((DirectBuffer)bb).address() + pos, -- rem, target); -+ rem, target.getAddress(), target.getPort()); - if (written > 0) - bb.position(pos + written); - return written; -@@ -703,8 +703,8 @@ class DatagramChannelImpl - boolean connected) - throws IOException; - -- private native int send0(FileDescriptor fd, long address, int len, -- SocketAddress sa) -+ private native int send0(FileDescriptor fd, long address, -+ int len, InetAddress addr, int port) - throws IOException; - - static { -diff --git a/src/solaris/native/sun/nio/ch/DatagramChannelImpl.c b/src/solaris/native/sun/nio/ch/DatagramChannelImpl.c ---- openjdk/jdk/src/solaris/native/sun/nio/ch/DatagramChannelImpl.c -+++ openjdk/jdk/src/solaris/native/sun/nio/ch/DatagramChannelImpl.c -@@ -46,8 +46,6 @@ - - #include "sun_nio_ch_DatagramChannelImpl.h" - --static jfieldID isa_addrID; /* address in java.net.InetSocketAddress */ --static jfieldID isa_portID; /* port in java.net.InetSocketAddress */ - static jfieldID dci_senderID; /* sender in sun.nio.ch.DatagramChannelImpl */ - static jfieldID dci_senderAddrID; /* sender InetAddress in sun.nio.ch.DatagramChannelImpl */ - static jfieldID dci_senderPortID; /* sender port in sun.nio.ch.DatagramChannelImpl */ -@@ -61,9 +59,6 @@ Java_sun_nio_ch_DatagramChannelImpl_init - isa_class = (*env)->NewGlobalRef(env, clazz); - isa_ctorID = (*env)->GetMethodID(env, clazz, "<init>", - "(Ljava/net/InetAddress;I)V"); -- isa_addrID = (*env)->GetFieldID(env, clazz, "addr", -- "Ljava/net/InetAddress;"); -- isa_portID = (*env)->GetFieldID(env, clazz, "port", "I"); - - clazz = (*env)->FindClass(env, "sun/nio/ch/DatagramChannelImpl"); - dci_senderID = (*env)->GetFieldID(env, clazz, "sender", -@@ -198,16 +193,15 @@ Java_sun_nio_ch_DatagramChannelImpl_rece - - JNIEXPORT jint JNICALL - Java_sun_nio_ch_DatagramChannelImpl_send0(JNIEnv *env, jobject this, -- jobject fdo, jlong address, -- jint len, jobject dest) -+ jobject fdo, jlong address, -+ jint len, jobject destAddress, -+ jint destPort) - { - jint fd = fdval(env, fdo); - void *buf = (void *)jlong_to_ptr(address); - SOCKADDR sa; - int sa_len = SOCKADDR_LEN; - jint n = 0; -- jobject destAddress = (*env)->GetObjectField(env, dest, isa_addrID); -- jint destPort = (*env)->GetIntField(env, dest, isa_portID); - - if (len > MAX_PACKET_LEN) { - len = MAX_PACKET_LEN; -diff --git a/src/windows/native/sun/nio/ch/DatagramChannelImpl.c b/src/windows/native/sun/nio/ch/DatagramChannelImpl.c ---- openjdk/jdk/src/windows/native/sun/nio/ch/DatagramChannelImpl.c -+++ openjdk/jdk/src/windows/native/sun/nio/ch/DatagramChannelImpl.c -@@ -34,8 +34,6 @@ - #include "net_util.h" - #include <winsock2.h> - --static jfieldID isa_addrID; /* address in java.net.InetSocketAddress */ --static jfieldID isa_portID; /* port in java.net.InetSocketAddress */ - static jfieldID dci_senderID; /* sender in sun.nio.ch.DatagramChannelImpl */ - static jfieldID dci_senderAddrID; /* sender InetAddress in sun.nio.ch.DatagramChannelImpl */ - static jfieldID dci_senderPortID; /* sender port in sun.nio.ch.DatagramChannelImpl */ -@@ -87,9 +85,6 @@ Java_sun_nio_ch_DatagramChannelImpl_init - isa_class = (*env)->NewGlobalRef(env, clazz); - isa_ctorID = (*env)->GetMethodID(env, clazz, "<init>", - "(Ljava/net/InetAddress;I)V"); -- isa_addrID = (*env)->GetFieldID(env, clazz, "addr", -- "Ljava/net/InetAddress;"); -- isa_portID = (*env)->GetFieldID(env, clazz, "port", "I"); - - clazz = (*env)->FindClass(env, "sun/nio/ch/DatagramChannelImpl"); - dci_senderID = (*env)->GetFieldID(env, clazz, "sender", -@@ -268,17 +263,14 @@ Java_sun_nio_ch_DatagramChannelImpl_rece - - JNIEXPORT jint JNICALL - Java_sun_nio_ch_DatagramChannelImpl_send0(JNIEnv *env, jobject this, -- jobject fdo, jlong address, -- jint len, jobject dest) -+ jobject fdo, jlong address, jint len, -+ jobject destAddress, jint destPort) - { - jint fd = fdval(env, fdo); - void *buf = (void *)jlong_to_ptr(address); - SOCKETADDRESS psa; - int sa_len = sizeof(psa); - jint rv = 0; -- jobject destAddress = (*env)->GetObjectField(env, dest, isa_addrID); -- jint destPort = (*env)->GetIntField(env, dest, isa_portID); -- - - if (NET_InetAddressToSockaddr(env, destAddress, destPort, - (struct sockaddr *)&psa, -diff --git a/test/java/nio/channels/DatagramChannel/SendToUnresolved.java b/test/java/nio/channels/DatagramChannel/SendToUnresolved.java ---- openjdk/jdk/test/java/nio/channels/DatagramChannel/SendToUnresolved.java -+++ openjdk/jdk/test/java/nio/channels/DatagramChannel/SendToUnresolved.java -@@ -44,6 +44,8 @@ public class SendToUnresolved { - throw new RuntimeException("Expected exception not thrown"); - } catch (IOException e) { - // Correct result -+ } catch (UnresolvedAddressException e) { -+ // Correct result - } - dc.close(); - }
--- a/patches/security/20130201/8000210.patch Tue Mar 19 00:21:31 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,104 +0,0 @@ -# HG changeset patch -# User weijun -# Date 1350962115 -28800 -# Node ID 9c2a2aae44a46e0b63b913987672d1488fa4e7a5 -# Parent 6088f35106866940de257456c8eee21b130d5ff5 -8000210: Improve JarFile code quality -Reviewed-by: ahgross, xuelei, mschoene - -diff --git a/src/share/classes/java/util/jar/JarFile.java b/src/share/classes/java/util/jar/JarFile.java ---- openjdk/jdk/src/share/classes/java/util/jar/JarFile.java -+++ openjdk/jdk/src/share/classes/java/util/jar/JarFile.java -@@ -32,6 +32,7 @@ import java.security.CodeSigner; - import java.security.CodeSigner; - import java.security.cert.Certificate; - import java.security.AccessController; -+import sun.misc.IOUtils; - import sun.security.action.GetPropertyAction; - import sun.security.util.ManifestEntryVerifier; - import sun.misc.SharedSecrets; -@@ -326,6 +327,9 @@ class JarFile extends ZipFile { - if (names != null) { - for (int i = 0; i < names.length; i++) { - JarEntry e = getJarEntry(names[i]); -+ if (e == null) { -+ throw new JarException("corrupted jar file"); -+ } - if (!e.isDirectory()) { - if (mev == null) { - mev = new ManifestEntryVerifier -@@ -345,6 +349,10 @@ class JarFile extends ZipFile { - // treat the jar file as being unsigned - jv = null; - verify = false; -+ if (JarVerifier.debug != null) { -+ JarVerifier.debug.println("jarfile parsing error!"); -+ ex.printStackTrace(); -+ } - } - - // if after initializing the verifier we have nothing -@@ -372,9 +380,8 @@ class JarFile extends ZipFile { - * META-INF files. - */ - private byte[] getBytes(ZipEntry ze) throws IOException { -- byte[] b = new byte[(int)ze.getSize()]; -- DataInputStream is = new DataInputStream(super.getInputStream(ze)); -- is.readFully(b, 0, b.length); -+ InputStream is = super.getInputStream(ze); -+ byte[] b = IOUtils.readFully(is, (int)ze.getSize(), true); - is.close(); - return b; - } -@@ -476,12 +483,7 @@ class JarFile extends ZipFile { - if (!isKnownToNotHaveClassPathAttribute()) { - JarEntry manEntry = getManEntry(); - if (manEntry != null) { -- byte[] b = new byte[(int)manEntry.getSize()]; -- DataInputStream dis = new DataInputStream( -- super.getInputStream(manEntry)); -- dis.readFully(b, 0, b.length); -- dis.close(); -- -+ byte[] b = getBytes(manEntry); - int last = b.length - src.length; - int i = 0; - next: -diff --git a/src/share/classes/sun/security/util/DerIndefLenConverter.java b/src/share/classes/sun/security/util/DerIndefLenConverter.java ---- openjdk/jdk/src/share/classes/sun/security/util/DerIndefLenConverter.java -+++ openjdk/jdk/src/share/classes/sun/security/util/DerIndefLenConverter.java -@@ -50,6 +50,7 @@ class DerIndefLenConverter { - - private byte[] data, newData; - private int newDataPos, dataPos, dataSize, index; -+ private int unresolved = 0; - - private ArrayList<Object> ndefsList = new ArrayList<Object>(); - -@@ -113,6 +114,7 @@ class DerIndefLenConverter { - numOfEncapsulatedLenBytes; - byte[] sectionLenBytes = getLengthBytes(sectionLen); - ndefsList.set(index, sectionLenBytes); -+ unresolved--; - - // Add the number of bytes required to represent this section - // to the total number of length bytes, -@@ -149,6 +151,7 @@ class DerIndefLenConverter { - int lenByte = data[dataPos++] & 0xff; - if (isIndefinite(lenByte)) { - ndefsList.add(new Integer(dataPos)); -+ unresolved++; - return curLen; - } - if (isLongForm(lenByte)) { -@@ -316,6 +319,10 @@ class DerIndefLenConverter { - parseValue(len); - } - -+ if (unresolved != 0) { -+ throw new IOException("not all indef len BER resolved"); -+ } -+ - newData = new byte[dataSize + numOfTotalLenBytes]; - dataPos=0; newDataPos=0; index=0; -
--- a/patches/security/20130201/8000537.patch Tue Mar 19 00:21:31 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,334 +0,0 @@ -# HG changeset patch -# User ewendeli -# Date 1353844618 -3600 -# Node ID 21415f01c66add2891500f10e41c7e99b2b10447 -# Parent 787e9230b414f346f9c318918aaf58b872b9912e -8000537: Contextualize RequiredModelMBean class -Reviewed-by: jbachorik -Contributed-by: Andreas Eriksson <andreas.eriksson@oracle.com> - -diff --git a/src/share/classes/javax/management/modelmbean/RequiredModelMBean.java b/src/share/classes/javax/management/modelmbean/RequiredModelMBean.java ---- openjdk/jdk/src/share/classes/javax/management/modelmbean/RequiredModelMBean.java -+++ openjdk/jdk/src/share/classes/javax/management/modelmbean/RequiredModelMBean.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -39,6 +39,9 @@ import java.lang.reflect.InvocationTarge - import java.lang.reflect.InvocationTargetException; - - import java.lang.reflect.Method; -+import java.security.AccessControlContext; -+import java.security.AccessController; -+import java.security.PrivilegedAction; - - import java.util.Date; - import java.util.HashMap; -@@ -77,6 +80,8 @@ import javax.management.RuntimeOperation - import javax.management.RuntimeOperationsException; - import javax.management.ServiceNotFoundException; - import javax.management.loading.ClassLoaderRepository; -+import sun.misc.JavaSecurityAccess; -+import sun.misc.SharedSecrets; - - import sun.reflect.misc.MethodUtil; - import sun.reflect.misc.ReflectUtil; -@@ -138,6 +143,9 @@ public class RequiredModelMBean - private boolean registered = false; - private transient MBeanServer server = null; - -+ private final static JavaSecurityAccess javaSecurityAccess = SharedSecrets.getJavaSecurityAccess(); -+ final private AccessControlContext acc = AccessController.getContext(); -+ - /*************************************/ - /* constructors */ - /*************************************/ -@@ -1025,10 +1033,30 @@ public class RequiredModelMBean - - if (opClassName != null) { - try { -- final ClassLoader targetClassLoader = -- targetObject.getClass().getClassLoader(); -- targetClass = Class.forName(opClassName, false, -- targetClassLoader); -+ AccessControlContext stack = AccessController.getContext(); -+ final Object obj = targetObject; -+ final String className = opClassName; -+ final ClassNotFoundException[] caughtException = new ClassNotFoundException[1]; -+ -+ targetClass = javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Class<?>>() { -+ -+ public Class<?> run() { -+ try { -+ ReflectUtil.checkPackageAccess(className); -+ final ClassLoader targetClassLoader = -+ obj.getClass().getClassLoader(); -+ return Class.forName(className, false, -+ targetClassLoader); -+ } catch (ClassNotFoundException e) { -+ caughtException[0] = e; -+ } -+ return null; -+ } -+ }, stack, acc); -+ -+ if (caughtException[0] != null) { -+ throw caughtException[0]; -+ } - } catch (ClassNotFoundException e) { - final String msg = - "class for invoke " + opName + " not found"; -@@ -1061,9 +1090,9 @@ public class RequiredModelMBean - return result; - } - -- private static Method resolveMethod(Class<?> targetClass, -+ private Method resolveMethod(Class<?> targetClass, - String opMethodName, -- String[] sig) -+ final String[] sig) - throws ReflectionException { - final boolean tracing = MODELMBEAN_LOGGER.isLoggable(Level.FINER); - -@@ -1078,30 +1107,44 @@ public class RequiredModelMBean - if (sig == null) - argClasses = null; - else { -+ final AccessControlContext stack = AccessController.getContext(); -+ final ReflectionException[] caughtException = new ReflectionException[1]; - final ClassLoader targetClassLoader = targetClass.getClassLoader(); -- argClasses = new Class[sig.length]; -- for (int i = 0; i < sig.length; i++) { -- if (tracing) { -- MODELMBEAN_LOGGER.logp(Level.FINER, -- RequiredModelMBean.class.getName(),"resolveMethod", -- "resolve type " + sig[i]); -- } -- argClasses[i] = (Class) primitiveClassMap.get(sig[i]); -- if (argClasses[i] == null) { -- try { -- argClasses[i] = -- Class.forName(sig[i], false, targetClassLoader); -- } catch (ClassNotFoundException e) { -+ argClasses = new Class<?>[sig.length]; -+ -+ javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Void>() { -+ -+ public Void run() { -+ for (int i = 0; i < sig.length; i++) { - if (tracing) { - MODELMBEAN_LOGGER.logp(Level.FINER, -- RequiredModelMBean.class.getName(), -- "resolveMethod", -- "class not found"); -+ RequiredModelMBean.class.getName(),"resolveMethod", -+ "resolve type " + sig[i]); - } -- final String msg = "Parameter class not found"; -- throw new ReflectionException(e, msg); -+ argClasses[i] = (Class<?>) primitiveClassMap.get(sig[i]); -+ if (argClasses[i] == null) { -+ try { -+ ReflectUtil.checkPackageAccess(sig[i]); -+ argClasses[i] = -+ Class.forName(sig[i], false, targetClassLoader); -+ } catch (ClassNotFoundException e) { -+ if (tracing) { -+ MODELMBEAN_LOGGER.logp(Level.FINER, -+ RequiredModelMBean.class.getName(), -+ "resolveMethod", -+ "class not found"); -+ } -+ final String msg = "Parameter class not found"; -+ caughtException[0] = new ReflectionException(e, msg); -+ } -+ } - } -+ return null; - } -+ }, stack, acc); -+ -+ if (caughtException[0] != null) { -+ throw caughtException[0]; - } - } - -@@ -1133,7 +1177,7 @@ public class RequiredModelMBean - /* Find a method in RequiredModelMBean as determined by the given - parameters. Return null if there is none, or if the parameters - exclude using it. Called from invoke. */ -- private static Method findRMMBMethod(String opMethodName, -+ private Method findRMMBMethod(String opMethodName, - Object targetObjectField, - String opClassName, - String[] sig) { -@@ -1155,19 +1199,28 @@ public class RequiredModelMBean - if (opClassName == null) - targetClass = rmmbClass; - else { -- try { -- final ClassLoader targetClassLoader = -- rmmbClass.getClassLoader(); -- targetClass = Class.forName(opClassName, false, -- targetClassLoader); -- if (!rmmbClass.isAssignableFrom(targetClass)) -- return null; -- } catch (ClassNotFoundException e) { -- return null; -- } -+ AccessControlContext stack = AccessController.getContext(); -+ final String className = opClassName; -+ targetClass = javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Class<?>>() { -+ -+ public Class<?> run() { -+ try { -+ ReflectUtil.checkPackageAccess(className); -+ final ClassLoader targetClassLoader = -+ rmmbClass.getClassLoader(); -+ Class clz = Class.forName(className, false, -+ targetClassLoader); -+ if (!rmmbClass.isAssignableFrom(clz)) -+ return null; -+ return clz; -+ } catch (ClassNotFoundException e) { -+ return null; -+ } -+ } -+ }, stack, acc); - } - try { -- return resolveMethod(targetClass, opMethodName, sig); -+ return targetClass != null ? resolveMethod(targetClass, opMethodName, sig) : null; - } catch (ReflectionException e) { - return null; - } -@@ -1177,12 +1231,34 @@ public class RequiredModelMBean - * Invoke the given method, and throw the somewhat unpredictable - * appropriate exception if the method itself gets an exception. - */ -- private Object invokeMethod(String opName, Method method, -- Object targetObject, Object[] opArgs) -+ private Object invokeMethod(String opName, final Method method, -+ final Object targetObject, final Object[] opArgs) - throws MBeanException, ReflectionException { - try { -- ReflectUtil.checkPackageAccess(method.getDeclaringClass()); -- return MethodUtil.invoke(method, targetObject, opArgs); -+ final Throwable[] caughtException = new Throwable[1]; -+ AccessControlContext stack = AccessController.getContext(); -+ Object rslt = javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Object>() { -+ -+ public Object run() { -+ try { -+ ReflectUtil.checkPackageAccess(method.getDeclaringClass()); -+ return MethodUtil.invoke(method, targetObject, opArgs); -+ } catch (InvocationTargetException e) { -+ caughtException[0] = e; -+ } catch (IllegalAccessException e) { -+ caughtException[0] = e; -+ } -+ return null; -+ } -+ }, stack, acc); -+ if (caughtException[0] != null) { -+ if (caughtException[0] instanceof Exception) { -+ throw (Exception)caughtException[0]; -+ } else if(caughtException[0] instanceof Error) { -+ throw (Error)caughtException[0]; -+ } -+ } -+ return rslt; - } catch (RuntimeErrorException ree) { - throw new RuntimeOperationsException(ree, - "RuntimeException occurred in RequiredModelMBean "+ -@@ -1569,7 +1646,7 @@ public class RequiredModelMBean - } - - // make sure response class matches type field -- String respType = attrInfo.getType(); -+ final String respType = attrInfo.getType(); - if (response != null) { - String responseClass = response.getClass().getName(); - if (!respType.equals(responseClass)) { -@@ -1592,9 +1669,30 @@ public class RequiredModelMBean - // inequality may come from type subclassing - boolean subtype; - try { -- ClassLoader cl = -- response.getClass().getClassLoader(); -- Class c = Class.forName(respType, true, cl); -+ final Class respClass = response.getClass(); -+ final Exception[] caughException = new Exception[1]; -+ -+ AccessControlContext stack = AccessController.getContext(); -+ -+ Class c = javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Class<?>>() { -+ -+ public Class<?> run() { -+ try { -+ ReflectUtil.checkPackageAccess(respType); -+ ClassLoader cl = -+ respClass.getClassLoader(); -+ return Class.forName(respType, true, cl); -+ } catch (Exception e) { -+ caughException[0] = e; -+ } -+ return null; -+ } -+ }, stack, acc); -+ -+ if (caughException[0] != null) { -+ throw caughException[0]; -+ } -+ - subtype = c.isInstance(response); - } catch (Exception e) { - subtype = false; -@@ -2748,16 +2847,36 @@ public class RequiredModelMBean - return MBeanServerFactory.getClassLoaderRepository(server); - } - -- private Class loadClass(String className) -+ private Class<?> loadClass(final String className) - throws ClassNotFoundException { -- try { -- return Class.forName(className); -- } catch (ClassNotFoundException e) { -- final ClassLoaderRepository clr = -- getClassLoaderRepository(); -- if (clr == null) throw new ClassNotFoundException(className); -- return clr.loadClass(className); -+ AccessControlContext stack = AccessController.getContext(); -+ final ClassNotFoundException[] caughtException = new ClassNotFoundException[1]; -+ -+ Class c = javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Class<?>>() { -+ -+ public Class<?> run() { -+ try { -+ ReflectUtil.checkPackageAccess(className); -+ return Class.forName(className); -+ } catch (ClassNotFoundException e) { -+ final ClassLoaderRepository clr = -+ getClassLoaderRepository(); -+ try { -+ if (clr == null) throw new ClassNotFoundException(className); -+ return clr.loadClass(className); -+ } catch (ClassNotFoundException ex) { -+ caughtException[0] = ex; -+ } -+ } -+ return null; -+ } -+ }, stack, acc); -+ -+ if (caughtException[0] != null) { -+ throw caughtException[0]; - } -+ -+ return c; - } - -
--- a/patches/security/20130201/8000540.patch Tue Mar 19 00:21:31 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,187 +0,0 @@ -# HG changeset patch -# User ngmr -# Date 1354993606 0 -# Node ID 42b1142b39b5a511e1e07b5877cc55e93767064e -# Parent c5203e9e0e07559914a9c46dbba4fe85df945624 -8000540: Improve IIOP type reuse management -Reviewed-by: alanb, ahgross, coffeys - -diff --git a/src/share/classes/com/sun/corba/se/impl/io/ObjectStreamClass.java b/src/share/classes/com/sun/corba/se/impl/io/ObjectStreamClass.java ---- openjdk/corba/src/share/classes/com/sun/corba/se/impl/io/ObjectStreamClass.java -+++ openjdk/corba/src/share/classes/com/sun/corba/se/impl/io/ObjectStreamClass.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -25,7 +25,7 @@ - /* - * Licensed Materials - Property of IBM - * RMI-IIOP v1.0 -- * Copyright IBM Corp. 1998 1999 All Rights Reserved -+ * Copyright IBM Corp. 1998 2012 All Rights Reserved - * - */ - -@@ -56,7 +56,8 @@ import java.io.Serializable; - - import java.util.Arrays; - import java.util.Comparator; --import java.util.Hashtable; -+import java.util.concurrent.ConcurrentHashMap; -+import java.util.concurrent.ConcurrentMap; - - import com.sun.corba.se.impl.util.RepositoryId; - -@@ -82,8 +83,6 @@ public class ObjectStreamClass implement - - private static Object noArgsList[] = {}; - private static Class noTypesList[] = {}; -- -- private static Hashtable translatedFields; - - private static final Bridge bridge = - (Bridge)AccessController.doPrivileged( -@@ -380,6 +379,58 @@ public class ObjectStreamClass implement - */ - } - -+ private static final class PersistentFieldsValue { -+ private final ConcurrentMap map = new ConcurrentHashMap(); -+ private static final Object NULL_VALUE = -+ (PersistentFieldsValue.class.getName() + ".NULL_VALUE"); -+ -+ PersistentFieldsValue() { } -+ -+ ObjectStreamField[] get(Class type) { -+ Object value = map.get(type); -+ if (value == null) { -+ value = computeValue(type); -+ Object oldValue = map.putIfAbsent(type, value); -+ if (oldValue != null) { -+ value = oldValue; -+ } -+ } -+ return ((value == NULL_VALUE) ? null : (ObjectStreamField[])value); -+ } -+ -+ private static Object computeValue(Class<?> type) { -+ try { -+ Field pf = type.getDeclaredField("serialPersistentFields"); -+ int mods = pf.getModifiers(); -+ if (Modifier.isPrivate(mods) && Modifier.isStatic(mods) && -+ Modifier.isFinal(mods)) { -+ pf.setAccessible(true); -+ java.io.ObjectStreamField[] fields = -+ (java.io.ObjectStreamField[])pf.get(type); -+ return translateFields(fields); -+ } -+ } catch (NoSuchFieldException e1) { -+ } catch (IllegalAccessException e2) { -+ } catch (IllegalArgumentException e3) { -+ } catch (ClassCastException e4) { } -+ return NULL_VALUE; -+ } -+ -+ private static ObjectStreamField[] translateFields( -+ java.io.ObjectStreamField[] fields) { -+ ObjectStreamField[] translation = -+ new ObjectStreamField[fields.length]; -+ for (int i = 0; i < fields.length; i++) { -+ translation[i] = new ObjectStreamField(fields[i].getName(), -+ fields[i].getType()); -+ } -+ return translation; -+ } -+ } -+ -+ private static final PersistentFieldsValue persistentFieldsValue = -+ new PersistentFieldsValue(); -+ - /* - * Initialize class descriptor. This method is only invoked on class - * descriptors created via calls to lookupInternal(). This method is kept -@@ -412,35 +463,7 @@ public class ObjectStreamClass implement - * If it is declared, use the declared serialPersistentFields. - * Otherwise, extract the fields from the class itself. - */ -- try { -- Field pf = cl.getDeclaredField("serialPersistentFields"); -- // serial bug 7; the serialPersistentFields were not -- // being read and stored as Accessible bit was not set -- pf.setAccessible(true); -- // serial bug 7; need to find if the field is of type -- // java.io.ObjectStreamField -- java.io.ObjectStreamField[] f = -- (java.io.ObjectStreamField[])pf.get(cl); -- int mods = pf.getModifiers(); -- if ((Modifier.isPrivate(mods)) && -- (Modifier.isStatic(mods)) && -- (Modifier.isFinal(mods))) -- { -- fields = (ObjectStreamField[])translateFields((Object[])pf.get(cl)); -- } -- } catch (NoSuchFieldException e) { -- fields = null; -- } catch (IllegalAccessException e) { -- fields = null; -- } catch (IllegalArgumentException e) { -- fields = null; -- } catch (ClassCastException e) { -- /* Thrown if a field serialPersistentField exists -- * but it is not of type ObjectStreamField. -- */ -- fields = null; -- } -- -+ fields = persistentFieldsValue.get(cl); - - if (fields == null) { - /* Get all of the declared fields for this -@@ -635,44 +658,6 @@ public class ObjectStreamClass implement - name = n; - suid = s; - superclass = null; -- } -- -- private static Object[] translateFields(Object objs[]) -- throws NoSuchFieldException { -- try{ -- java.io.ObjectStreamField fields[] = (java.io.ObjectStreamField[])objs; -- Object translation[] = null; -- -- if (translatedFields == null) -- translatedFields = new Hashtable(); -- -- translation = (Object[])translatedFields.get(fields); -- -- if (translation != null) -- return translation; -- else { -- Class osfClass = Class.forName("com.sun.corba.se.impl.io.ObjectStreamField"); -- translation = (Object[])java.lang.reflect.Array.newInstance(osfClass, objs.length); -- Object arg[] = new Object[2]; -- Class types[] = {String.class, Class.class}; -- Constructor constructor = osfClass.getDeclaredConstructor(types); -- for (int i = fields.length -1; i >= 0; i--){ -- arg[0] = fields[i].getName(); -- arg[1] = fields[i].getType(); -- -- translation[i] = constructor.newInstance(arg); -- } -- translatedFields.put(fields, translation); -- -- } -- -- return (Object[])translation; -- } -- catch(Throwable t){ -- NoSuchFieldException nsfe = new NoSuchFieldException(); -- nsfe.initCause( t ) ; -- throw nsfe ; -- } - } - - /*
--- a/patches/security/20130201/8000631.patch Tue Mar 19 00:21:31 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,3964 +0,0 @@ -# HG changeset patch -# User coffeys -# Date 1354992561 0 -# Node ID c5203e9e0e07559914a9c46dbba4fe85df945624 -# Parent 7f904eacf818c104549b94b957f34896a8548d9b -8000631: Restrict access to class constructor -Reviewed-by: alanb, ahgross - -diff --git a/make/com/sun/corba/minclude/com_sun_corba_se_impl_orbutil.jmk b/make/com/sun/corba/minclude/com_sun_corba_se_impl_orbutil.jmk ---- openjdk/corba/make/com/sun/corba/minclude/com_sun_corba_se_impl_orbutil.jmk -+++ openjdk/corba/make/com/sun/corba/minclude/com_sun_corba_se_impl_orbutil.jmk -@@ -1,5 +1,5 @@ - # --# Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved. -+# Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. - # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - # - # This code is free software; you can redistribute it and/or modify it -@@ -29,10 +29,6 @@ com_sun_corba_se_impl_orbutil_java = \ - com/sun/corba/se/impl/orbutil/DenseIntMapImpl.java \ - com/sun/corba/se/impl/orbutil/GetPropertyAction.java \ - com/sun/corba/se/impl/orbutil/HexOutputStream.java \ -- com/sun/corba/se/impl/orbutil/IIOPInputStream_1_3.java \ -- com/sun/corba/se/impl/orbutil/IIOPInputStream_1_3_1.java \ -- com/sun/corba/se/impl/orbutil/IIOPOutputStream_1_3.java \ -- com/sun/corba/se/impl/orbutil/IIOPOutputStream_1_3_1.java \ - com/sun/corba/se/impl/orbutil/LegacyHookGetFields.java \ - com/sun/corba/se/impl/orbutil/LegacyHookPutFields.java \ - com/sun/corba/se/impl/orbutil/LogKeywords.java \ -@@ -45,19 +41,11 @@ com_sun_corba_se_impl_orbutil_java = \ - com/sun/corba/se/impl/orbutil/ORBUtility.java \ - com/sun/corba/se/impl/orbutil/ORBClassLoader.java \ - com/sun/corba/se/impl/orbutil/RepIdDelegator.java \ -- com/sun/corba/se/impl/orbutil/RepIdDelegator_1_3.java \ -- com/sun/corba/se/impl/orbutil/RepIdDelegator_1_3_1.java \ -- com/sun/corba/se/impl/orbutil/RepositoryIdCache_1_3.java \ -- com/sun/corba/se/impl/orbutil/RepositoryId_1_3.java \ - com/sun/corba/se/impl/orbutil/RepositoryIdFactory.java \ - com/sun/corba/se/impl/orbutil/RepositoryIdStrings.java \ - com/sun/corba/se/impl/orbutil/RepositoryIdUtility.java \ - com/sun/corba/se/impl/orbutil/RepositoryIdInterface.java \ -- com/sun/corba/se/impl/orbutil/RepositoryIdCache_1_3_1.java \ -- com/sun/corba/se/impl/orbutil/RepositoryId_1_3_1.java \ - com/sun/corba/se/impl/orbutil/StackImpl.java \ -- com/sun/corba/se/impl/orbutil/ValueHandlerImpl_1_3_1.java \ -- com/sun/corba/se/impl/orbutil/ValueHandlerImpl_1_3.java \ - com/sun/corba/se/impl/orbutil/closure/Future.java \ - com/sun/corba/se/impl/orbutil/closure/Constant.java \ - com/sun/corba/se/impl/orbutil/concurrent/Sync.java \ -diff --git a/src/share/classes/com/sun/corba/se/impl/corba/AnyImpl.java b/src/share/classes/com/sun/corba/se/impl/corba/AnyImpl.java ---- openjdk/corba/src/share/classes/com/sun/corba/se/impl/corba/AnyImpl.java -+++ openjdk/corba/src/share/classes/com/sun/corba/se/impl/corba/AnyImpl.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 1997, 2004, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -1218,7 +1218,7 @@ public class AnyImpl extends Any - // See bug 4391648 for more info about the tcORB in this - // case. - RepositoryIdStrings repStrs -- = RepositoryIdFactory.getRepIdStringsFactory(tcORB); -+ = RepositoryIdFactory.getRepIdStringsFactory(); - - - // Assertion: c instanceof Serializable? -@@ -1251,7 +1251,7 @@ public class AnyImpl extends Any - // Anything else - // We know that this is a TypeCodeImpl since it is our ORB - classTC = (TypeCodeImpl)ValueUtility.createTypeCodeForClass( -- tcORB, c, ORBUtility.createValueHandler(tcORB)); -+ tcORB, c, ORBUtility.createValueHandler()); - // Intruct classTC to store its buffer - classTC.setCaching(true); - // Update the cache -diff --git a/src/share/classes/com/sun/corba/se/impl/encoding/CDRInputStream_1_0.java b/src/share/classes/com/sun/corba/se/impl/encoding/CDRInputStream_1_0.java ---- openjdk/corba/src/share/classes/com/sun/corba/se/impl/encoding/CDRInputStream_1_0.java -+++ openjdk/corba/src/share/classes/com/sun/corba/se/impl/encoding/CDRInputStream_1_0.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 1997, 2004, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -269,8 +269,8 @@ public class CDRInputStream_1_0 extends - - private final void createRepositoryIdHandlers() - { -- repIdUtil = RepositoryIdFactory.getRepIdUtility(orb); -- repIdStrs = RepositoryIdFactory.getRepIdStringsFactory(orb); -+ repIdUtil = RepositoryIdFactory.getRepIdUtility(); -+ repIdStrs = RepositoryIdFactory.getRepIdStringsFactory(); - } - - public GIOPVersion getGIOPVersion() { -@@ -564,10 +564,7 @@ public class CDRInputStream_1_0 extends - - checkForNegativeLength(len); - -- if (orb != null && ORBUtility.isLegacyORB((ORB)orb)) -- return legacyReadString(len); -- else -- return internalReadString(len); -+ return internalReadString(len); - } - - private final String internalReadString(int len) { -@@ -586,54 +583,6 @@ public class CDRInputStream_1_0 extends - read_octet(); - - return new String(result, 0, getCharConverter().getNumChars()); -- } -- -- private final String legacyReadString(int len) { -- -- // -- // Workaround for ORBs which send string lengths of -- // zero to mean empty string. -- // -- // -- // IMPORTANT: Do not replace 'new String("")' with "", it may result -- // in a Serialization bug (See serialization.zerolengthstring) and -- // bug id: 4728756 for details -- if (len == 0) -- return new String(""); -- -- len--; -- char[] c = new char[len]; -- -- int n = 0; -- while (n < len) { -- int avail; -- int bytes; -- int wanted; -- -- avail = bbwi.buflen - bbwi.position(); -- if (avail <= 0) { -- grow(1, 1); -- avail = bbwi.buflen - bbwi.position(); -- } -- wanted = len - n; -- bytes = (wanted < avail) ? wanted : avail; -- // Microbenchmarks are showing a loop of ByteBuffer.get(int) being -- // faster than ByteBuffer.get(byte[], int, int). -- for (int i=0; i<bytes; i++) { -- c[n+i] = (char) (bbwi.byteBuffer.get(bbwi.position()+i) & 0xFF); -- } -- bbwi.position(bbwi.position() + bytes); -- n += bytes; -- } -- -- // -- // Skip past terminating null byte -- // -- if (bbwi.position() + 1 > bbwi.buflen) -- alignAndCheck(1, 1); -- bbwi.position(bbwi.position() + 1); -- -- return new String(c); - } - - public final String read_string() { -@@ -1045,7 +994,7 @@ public class CDRInputStream_1_0 extends - - try { - if (valueHandler == null) -- valueHandler = ORBUtility.createValueHandler(orb); -+ valueHandler = ORBUtility.createValueHandler(); - - value = valueHandler.readValue(parent, - indirection, -diff --git a/src/share/classes/com/sun/corba/se/impl/encoding/CDROutputStream_1_0.java b/src/share/classes/com/sun/corba/se/impl/encoding/CDROutputStream_1_0.java ---- openjdk/corba/src/share/classes/com/sun/corba/se/impl/encoding/CDROutputStream_1_0.java -+++ openjdk/corba/src/share/classes/com/sun/corba/se/impl/encoding/CDROutputStream_1_0.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 1997, 2004, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -189,18 +189,8 @@ public class CDROutputStream_1_0 extends - - private final void createRepositoryIdHandlers() - { -- if (orb != null) { -- // Get the appropriate versions based on the ORB version. The -- // ORB versioning info is only in the core ORB. -- repIdUtil -- = RepositoryIdFactory.getRepIdUtility(orb); -- repIdStrs -- = RepositoryIdFactory.getRepIdStringsFactory(orb); -- } else { -- // Get the latest versions -- repIdUtil = RepositoryIdFactory.getRepIdUtility(); -- repIdStrs = RepositoryIdFactory.getRepIdStringsFactory(); -- } -+ repIdUtil = RepositoryIdFactory.getRepIdUtility(); -+ repIdStrs = RepositoryIdFactory.getRepIdStringsFactory(); - } - - public BufferManagerWrite getBufferManager() -@@ -705,7 +695,7 @@ public class CDROutputStream_1_0 extends - private void writeArray(Serializable array, Class clazz) { - - if (valueHandler == null) -- valueHandler = ORBUtility.createValueHandler(orb); //d11638 -+ valueHandler = ORBUtility.createValueHandler(); //d11638 - - // Write value_tag - int indirection = writeValueTag(mustChunk, true, -@@ -768,7 +758,7 @@ public class CDROutputStream_1_0 extends - - private void writeRMIIIOPValueType(Serializable object, Class clazz) { - if (valueHandler == null) -- valueHandler = ORBUtility.createValueHandler(orb); //d11638 -+ valueHandler = ORBUtility.createValueHandler(); //d11638 - - Serializable key = object; - -diff --git a/src/share/classes/com/sun/corba/se/impl/io/FVDCodeBaseImpl.java b/src/share/classes/com/sun/corba/se/impl/io/FVDCodeBaseImpl.java ---- openjdk/corba/src/share/classes/com/sun/corba/se/impl/io/FVDCodeBaseImpl.java -+++ openjdk/corba/src/share/classes/com/sun/corba/se/impl/io/FVDCodeBaseImpl.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 1999, 2003, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -86,7 +86,7 @@ public class FVDCodeBaseImpl extends _Co - // default to using the current ORB version in case the - // vhandler is not set - if (vhandler == null) { -- vhandler = new ValueHandlerImpl(false); -+ vhandler = ValueHandlerImpl.getInstance(false); - } - - // Util.getCodebase may return null which would -@@ -120,7 +120,7 @@ public class FVDCodeBaseImpl extends _Co - // default to using the current ORB version in case the - // vhandler is not set - if (vhandler == null) { -- vhandler = new ValueHandlerImpl(false); -+ vhandler = ValueHandlerImpl.getInstance(false); - } - - try{ -@@ -161,7 +161,7 @@ public class FVDCodeBaseImpl extends _Co - // default to using the current ORB version in case the - // vhandler is not set - if (vhandler == null) { -- vhandler = new ValueHandlerImpl(false); -+ vhandler = ValueHandlerImpl.getInstance(false); - } - - Stack repIds = new Stack(); -diff --git a/src/share/classes/com/sun/corba/se/impl/io/ValueHandlerImpl.java b/src/share/classes/com/sun/corba/se/impl/io/ValueHandlerImpl.java ---- openjdk/corba/src/share/classes/com/sun/corba/se/impl/io/ValueHandlerImpl.java -+++ openjdk/corba/src/share/classes/com/sun/corba/se/impl/io/ValueHandlerImpl.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -53,7 +53,7 @@ import com.sun.corba.se.impl.logging.OMG - import com.sun.corba.se.impl.logging.OMGSystemException; - import com.sun.corba.se.impl.logging.UtilSystemException; - --public class ValueHandlerImpl implements javax.rmi.CORBA.ValueHandlerMultiFormat { -+public final class ValueHandlerImpl implements javax.rmi.CORBA.ValueHandlerMultiFormat { - - // Property to override our maximum stream format version - public static final String FORMAT_VERSION_PROPERTY -@@ -150,12 +150,20 @@ public class ValueHandlerImpl implements - writeValueWithVersion(out, value, streamFormatVersion); - } - -- public ValueHandlerImpl(){} -+ private ValueHandlerImpl(){} - -- public ValueHandlerImpl(boolean isInputStream) { -+ private ValueHandlerImpl(boolean isInputStream) { - this(); - useHashtables = false; - this.isInputStream = isInputStream; -+ } -+ -+ static ValueHandlerImpl getInstance() { -+ return new ValueHandlerImpl(); -+ } -+ -+ static ValueHandlerImpl getInstance(boolean isInputStream) { -+ return new ValueHandlerImpl(isInputStream); - } - - /** -@@ -458,12 +466,7 @@ public class ValueHandlerImpl implements - return ObjectStreamClass.lookup(value.getClass()).writeReplace(value); - } - -- /** -- * Encapsulates writing of Java char arrays so that the 1.3 subclass -- * can override it without exposing internals across packages. This -- * is a fix for bug 4367783. -- */ -- protected void writeCharArray(org.omg.CORBA_2_3.portable.OutputStream out, -+ private void writeCharArray(org.omg.CORBA_2_3.portable.OutputStream out, - char[] array, - int offset, - int length) -@@ -576,12 +579,7 @@ public class ValueHandlerImpl implements - } - } - -- /** -- * Encapsulates reading of Java char arrays so that the 1.3 subclass -- * can override it without exposing internals across packages. This -- * is a fix for bug 4367783. -- */ -- protected void readCharArray(org.omg.CORBA_2_3.portable.InputStream in, -+ private void readCharArray(org.omg.CORBA_2_3.portable.InputStream in, - char[] array, - int offset, - int length) -@@ -795,7 +793,7 @@ public class ValueHandlerImpl implements - return RepositoryId.cache.getId(repId).isSequence(); - } - -- protected String getOutputStreamClassName() { -+ private String getOutputStreamClassName() { - return "com.sun.corba.se.impl.io.IIOPOutputStream"; - } - -@@ -843,29 +841,11 @@ public class ValueHandlerImpl implements - private IIOPOutputStream createOutputStreamBuiltInNoPriv( - final String name - ) throws IOException { -- return -- name.equals( -- IIOPOutputStream -- .class.getName() -- ) ? -- new IIOPOutputStream() : -- -- name.equals( -- com.sun.corba.se.impl.orbutil.IIOPOutputStream_1_3 -- .class.getName() -- ) ? -- new com.sun.corba.se.impl.orbutil.IIOPOutputStream_1_3() : -- -- name.equals( -- com.sun.corba.se.impl.orbutil.IIOPOutputStream_1_3_1 -- .class.getName() -- ) ? -- new com.sun.corba.se.impl.orbutil.IIOPOutputStream_1_3_1() : -- -- null; -+ return name.equals(IIOPOutputStream.class.getName()) ? -+ new IIOPOutputStream() : null; - } - -- protected String getInputStreamClassName() { -+ private String getInputStreamClassName() { - return "com.sun.corba.se.impl.io.IIOPInputStream"; - } - -@@ -913,26 +893,8 @@ public class ValueHandlerImpl implements - private IIOPInputStream createInputStreamBuiltInNoPriv( - final String name - ) throws IOException { -- return -- name.equals( -- IIOPInputStream -- .class.getName() -- ) ? -- new IIOPInputStream() : -- -- name.equals( -- com.sun.corba.se.impl.orbutil.IIOPInputStream_1_3 -- .class.getName() -- ) ? -- new com.sun.corba.se.impl.orbutil.IIOPInputStream_1_3() : -- -- name.equals( -- com.sun.corba.se.impl.orbutil.IIOPInputStream_1_3_1 -- .class.getName() -- ) ? -- new com.sun.corba.se.impl.orbutil.IIOPInputStream_1_3_1() : -- -- null; -+ return name.equals(IIOPInputStream.class.getName()) ? -+ new IIOPInputStream() : null; - } - - /** -@@ -958,12 +920,7 @@ public class ValueHandlerImpl implements - - } - -- /** -- * Our JDK 1.3 and JDK 1.3.1 behavior subclasses override this. -- * The correct behavior is for a Java char to map to a CORBA wchar, -- * but our older code mapped it to a CORBA char. -- */ -- protected TCKind getJavaCharTCKind() { -+ TCKind getJavaCharTCKind() { - return TCKind.tk_wchar; - } - } -diff --git a/src/share/classes/com/sun/corba/se/impl/io/ValueUtility.java b/src/share/classes/com/sun/corba/se/impl/io/ValueUtility.java ---- openjdk/corba/src/share/classes/com/sun/corba/se/impl/io/ValueUtility.java -+++ openjdk/corba/src/share/classes/com/sun/corba/se/impl/io/ValueUtility.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 1999, 2002, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -92,6 +92,14 @@ public class ValueUtility { - null, // tk_native 31 - null, // tk_abstract_interface 32 - }; -+ -+ static { -+ sun.corba.SharedSecrets.setJavaCorbaAccess(new sun.corba.JavaCorbaAccess() { -+ public ValueHandlerImpl newValueHandlerImpl() { -+ return ValueHandlerImpl.getInstance(); -+ } -+ }); -+ } - - public static String getSignature(ValueMember member) - throws ClassNotFoundException { -diff --git a/src/share/classes/com/sun/corba/se/impl/javax/rmi/CORBA/Util.java b/src/share/classes/com/sun/corba/se/impl/javax/rmi/CORBA/Util.java ---- openjdk/corba/src/share/classes/com/sun/corba/se/impl/javax/rmi/CORBA/Util.java -+++ openjdk/corba/src/share/classes/com/sun/corba/se/impl/javax/rmi/CORBA/Util.java -@@ -112,6 +112,9 @@ import com.sun.corba.se.impl.orbutil.ORB - import com.sun.corba.se.impl.orbutil.ORBClassLoader; - import com.sun.corba.se.impl.logging.UtilSystemException; - import com.sun.corba.se.spi.logging.CORBALogDomains; -+import sun.corba.SharedSecrets; -+import sun.corba.JavaCorbaAccess; -+ - - /** - * Provides utility methods that can be used by stubs and ties to -@@ -125,7 +128,8 @@ public class Util implements javax.rmi.C - // Maps targets to ties. - private static IdentityHashtable exportedServants = new IdentityHashtable(); - -- private static ValueHandlerImpl valueHandlerSingleton = new ValueHandlerImpl(); -+ private static final ValueHandlerImpl valueHandlerSingleton = -+ SharedSecrets.getJavaCorbaAccess().newValueHandlerImpl(); - - private UtilSystemException utilWrapper = UtilSystemException.get( - CORBALogDomains.RPC_ENCODING); -diff --git a/src/share/classes/com/sun/corba/se/impl/orb/ORBImpl.java b/src/share/classes/com/sun/corba/se/impl/orb/ORBImpl.java ---- openjdk/corba/src/share/classes/com/sun/corba/se/impl/orb/ORBImpl.java -+++ openjdk/corba/src/share/classes/com/sun/corba/se/impl/orb/ORBImpl.java -@@ -848,7 +848,7 @@ public class ORBImpl extends com.sun.cor - // backward compatability 4365188 - CodeBase cb; - -- ValueHandler vh = ORBUtility.createValueHandler(this); -+ ValueHandler vh = ORBUtility.createValueHandler(); - - cb = (CodeBase)vh.getRunTimeCodeBase(); - return ORBUtility.connectAndGetIOR( this, cb ) ; -diff --git a/src/share/classes/com/sun/corba/se/impl/orbutil/IIOPInputStream_1_3.java b/src/share/classes/com/sun/corba/se/impl/orbutil/IIOPInputStream_1_3.java -deleted file mode 100644 ---- openjdk/corba/src/share/classes/com/sun/corba/se/impl/orbutil/IIOPInputStream_1_3.java -+++ /dev/null -@@ -1,57 +0,0 @@ --/* -- * Copyright (c) 2000, 2002, Oracle and/or its affiliates. All rights reserved. -- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -- * -- * This code is free software; you can redistribute it and/or modify it -- * under the terms of the GNU General Public License version 2 only, as -- * published by the Free Software Foundation. Oracle designates this -- * particular file as subject to the "Classpath" exception as provided -- * by Oracle in the LICENSE file that accompanied this code. -- * -- * This code is distributed in the hope that it will be useful, but WITHOUT -- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -- * version 2 for more details (a copy is included in the LICENSE file that -- * accompanied this code). -- * -- * You should have received a copy of the GNU General Public License version -- * 2 along with this work; if not, write to the Free Software Foundation, -- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -- * -- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -- * or visit www.oracle.com if you need additional information or have any -- * questions. -- */ --package com.sun.corba.se.impl.orbutil; -- --import java.io.*; --import java.util.Hashtable; -- --/** -- * Implements legacy behavior from before Ladybird to maintain -- * backwards compatibility. -- */ --public class IIOPInputStream_1_3 extends com.sun.corba.se.impl.io.IIOPInputStream --{ -- // The newer version in the io package correctly reads a wstring instead. -- // This concerns bug 4379597. -- protected String internalReadUTF(org.omg.CORBA.portable.InputStream stream) -- { -- return stream.read_string(); -- } -- -- /** -- * Before JDK 1.3.1_01, the PutField/GetField implementation -- * actually sent a Hashtable. -- */ -- public ObjectInputStream.GetField readFields() -- throws IOException, ClassNotFoundException, NotActiveException { -- Hashtable fields = (Hashtable)readObject(); -- return new LegacyHookGetFields(fields); -- } -- -- public IIOPInputStream_1_3() -- throws java.io.IOException { -- super(); -- } --} -diff --git a/src/share/classes/com/sun/corba/se/impl/orbutil/IIOPInputStream_1_3_1.java b/src/share/classes/com/sun/corba/se/impl/orbutil/IIOPInputStream_1_3_1.java -deleted file mode 100644 ---- openjdk/corba/src/share/classes/com/sun/corba/se/impl/orbutil/IIOPInputStream_1_3_1.java -+++ /dev/null -@@ -1,54 +0,0 @@ --/* -- * Copyright (c) 2001, 2002, Oracle and/or its affiliates. All rights reserved. -- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -- * -- * This code is free software; you can redistribute it and/or modify it -- * under the terms of the GNU General Public License version 2 only, as -- * published by the Free Software Foundation. Oracle designates this -- * particular file as subject to the "Classpath" exception as provided -- * by Oracle in the LICENSE file that accompanied this code. -- * -- * This code is distributed in the hope that it will be useful, but WITHOUT -- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -- * version 2 for more details (a copy is included in the LICENSE file that -- * accompanied this code). -- * -- * You should have received a copy of the GNU General Public License version -- * 2 along with this work; if not, write to the Free Software Foundation, -- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -- * -- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -- * or visit www.oracle.com if you need additional information or have any -- * questions. -- */ -- --/* -- */ --package com.sun.corba.se.impl.orbutil; -- --import java.io.*; --import java.util.Hashtable; -- --/** -- * Implements legacy behavior from Ladybird to maintain -- * backwards compatibility. -- */ --public class IIOPInputStream_1_3_1 extends com.sun.corba.se.impl.io.IIOPInputStream --{ -- public IIOPInputStream_1_3_1() -- throws java.io.IOException { -- super(); -- } -- -- /** -- * Before JDK 1.3.1_01, the PutField/GetField implementation -- * actually sent a Hashtable. -- */ -- public ObjectInputStream.GetField readFields() -- throws IOException, ClassNotFoundException, NotActiveException { -- -- Hashtable fields = (Hashtable)readObject(); -- return new LegacyHookGetFields(fields); -- } --} -diff --git a/src/share/classes/com/sun/corba/se/impl/orbutil/IIOPOutputStream_1_3.java b/src/share/classes/com/sun/corba/se/impl/orbutil/IIOPOutputStream_1_3.java -deleted file mode 100644 ---- openjdk/corba/src/share/classes/com/sun/corba/se/impl/orbutil/IIOPOutputStream_1_3.java -+++ /dev/null -@@ -1,68 +0,0 @@ --/* -- * Copyright (c) 2000, 2002, Oracle and/or its affiliates. All rights reserved. -- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -- * -- * This code is free software; you can redistribute it and/or modify it -- * under the terms of the GNU General Public License version 2 only, as -- * published by the Free Software Foundation. Oracle designates this -- * particular file as subject to the "Classpath" exception as provided -- * by Oracle in the LICENSE file that accompanied this code. -- * -- * This code is distributed in the hope that it will be useful, but WITHOUT -- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -- * version 2 for more details (a copy is included in the LICENSE file that -- * accompanied this code). -- * -- * You should have received a copy of the GNU General Public License version -- * 2 along with this work; if not, write to the Free Software Foundation, -- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -- * -- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -- * or visit www.oracle.com if you need additional information or have any -- * questions. -- */ --package com.sun.corba.se.impl.orbutil; -- --import java.io.*; -- --/** -- * Implements legacy behavior from before Ladybird to maintain -- * backwards compatibility. -- */ --public class IIOPOutputStream_1_3 extends com.sun.corba.se.impl.io.IIOPOutputStream --{ -- // We can't assume that the superclass's putFields -- // member will be non-private. We must allow -- // the RI to run on JDK 1.3.1 FCS as well as -- // the JDK 1.3.1_01 patch. -- private ObjectOutputStream.PutField putFields_1_3; -- -- // The newer version in the io package correctly writes a wstring instead. -- // This concerns bug 4379597. -- protected void internalWriteUTF(org.omg.CORBA.portable.OutputStream stream, -- String data) -- { -- stream.write_string(data); -- } -- -- public IIOPOutputStream_1_3() -- throws java.io.IOException { -- super(); -- } -- -- /** -- * Before JDK 1.3.1_01, the PutField/GetField implementation -- * actually sent a Hashtable. -- */ -- public ObjectOutputStream.PutField putFields() -- throws IOException { -- putFields_1_3 = new LegacyHookPutFields(); -- return putFields_1_3; -- } -- -- public void writeFields() -- throws IOException { -- putFields_1_3.write(this); -- } --} -diff --git a/src/share/classes/com/sun/corba/se/impl/orbutil/IIOPOutputStream_1_3_1.java b/src/share/classes/com/sun/corba/se/impl/orbutil/IIOPOutputStream_1_3_1.java -deleted file mode 100644 ---- openjdk/corba/src/share/classes/com/sun/corba/se/impl/orbutil/IIOPOutputStream_1_3_1.java -+++ /dev/null -@@ -1,66 +0,0 @@ --/* -- * Copyright (c) 2001, 2002, Oracle and/or its affiliates. All rights reserved. -- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -- * -- * This code is free software; you can redistribute it and/or modify it -- * under the terms of the GNU General Public License version 2 only, as -- * published by the Free Software Foundation. Oracle designates this -- * particular file as subject to the "Classpath" exception as provided -- * by Oracle in the LICENSE file that accompanied this code. -- * -- * This code is distributed in the hope that it will be useful, but WITHOUT -- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -- * version 2 for more details (a copy is included in the LICENSE file that -- * accompanied this code). -- * -- * You should have received a copy of the GNU General Public License version -- * 2 along with this work; if not, write to the Free Software Foundation, -- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -- * -- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -- * or visit www.oracle.com if you need additional information or have any -- * questions. -- */ -- --/* -- */ --package com.sun.corba.se.impl.orbutil; -- --import java.io.*; --import java.util.Hashtable; -- --/** -- * Implements legacy behavior from Ladybird to maintain -- * backwards compatibility. -- */ --public class IIOPOutputStream_1_3_1 extends com.sun.corba.se.impl.io.IIOPOutputStream --{ -- // We can't assume that the superclass's putFields -- // member will be non-private. We must allow -- // the RI to run on JDK 1.3.1 FCS as well as -- // the JDK 1.3.1_01 patch. -- private ObjectOutputStream.PutField putFields_1_3_1; -- -- public IIOPOutputStream_1_3_1() -- throws java.io.IOException { -- super(); -- } -- -- /** -- * Before JDK 1.3.1_01, the PutField/GetField implementation -- * actually sent a Hashtable. -- */ -- public ObjectOutputStream.PutField putFields() -- throws IOException { -- -- putFields_1_3_1 = new LegacyHookPutFields(); -- return putFields_1_3_1; -- } -- -- public void writeFields() -- throws IOException { -- -- putFields_1_3_1.write(this); -- } --} -diff --git a/src/share/classes/com/sun/corba/se/impl/orbutil/ORBUtility.java b/src/share/classes/com/sun/corba/se/impl/orbutil/ORBUtility.java ---- openjdk/corba/src/share/classes/com/sun/corba/se/impl/orbutil/ORBUtility.java -+++ openjdk/corba/src/share/classes/com/sun/corba/se/impl/orbutil/ORBUtility.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -160,42 +160,10 @@ public final class ORBUtility { - } - - /** -- * Creates the correct ValueHandler for the given ORB, -- * querying ORBVersion information. If the ORB or -- * ORBVersion is null, gets the ValueHandler from -- * Util.createValueHandler. -+ * Return default ValueHandler - */ -- public static ValueHandler createValueHandler(ORB orb) { -- -- if (orb == null) -- return Util.createValueHandler(); -- -- ORBVersion version = orb.getORBVersion(); -- -- if (version == null) -- return Util.createValueHandler(); -- -- if (version.equals(ORBVersionFactory.getOLD())) -- return new ValueHandlerImpl_1_3(); -- if (version.equals(ORBVersionFactory.getNEW())) -- return new ValueHandlerImpl_1_3_1(); -- -+ public static ValueHandler createValueHandler() { - return Util.createValueHandler(); -- } -- -- /** -- * Returns true if the given ORB could accurately be determined to be a -- * Kestrel or earlier ORB. Note: If passed the ORBSingleton, this will return -- * false. -- */ -- public static boolean isLegacyORB(ORB orb) -- { -- try { -- ORBVersion currentORB = orb.getORBVersion(); -- return currentORB.equals( ORBVersionFactory.getOLD() ) ; -- } catch (SecurityException se) { -- return false; -- } - } - - /** -diff --git a/src/share/classes/com/sun/corba/se/impl/orbutil/RepIdDelegator_1_3.java b/src/share/classes/com/sun/corba/se/impl/orbutil/RepIdDelegator_1_3.java -deleted file mode 100644 ---- openjdk/corba/src/share/classes/com/sun/corba/se/impl/orbutil/RepIdDelegator_1_3.java -+++ /dev/null -@@ -1,177 +0,0 @@ --/* -- * Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved. -- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -- * -- * This code is free software; you can redistribute it and/or modify it -- * under the terms of the GNU General Public License version 2 only, as -- * published by the Free Software Foundation. Oracle designates this -- * particular file as subject to the "Classpath" exception as provided -- * by Oracle in the LICENSE file that accompanied this code. -- * -- * This code is distributed in the hope that it will be useful, but WITHOUT -- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -- * version 2 for more details (a copy is included in the LICENSE file that -- * accompanied this code). -- * -- * You should have received a copy of the GNU General Public License version -- * 2 along with this work; if not, write to the Free Software Foundation, -- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -- * -- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -- * or visit www.oracle.com if you need additional information or have any -- * questions. -- */ -- --package com.sun.corba.se.impl.orbutil; -- --import org.omg.CORBA.ORB; --import java.io.Serializable; --import java.util.Hashtable; --import java.net.MalformedURLException; --import com.sun.corba.se.impl.io.TypeMismatchException; --import com.sun.corba.se.impl.util.RepositoryId; -- --/** -- * Delegates to the RepositoryId_1_3 implementation in -- * com.sun.corba.se.impl.orbutil. This is necessary to -- * overcome the fact that many of RepositoryId's methods -- * are static. -- */ --public final class RepIdDelegator_1_3 -- implements RepositoryIdStrings, -- RepositoryIdUtility, -- RepositoryIdInterface --{ -- // RepositoryIdFactory methods -- -- public String createForAnyType(Class type) { -- return RepositoryId_1_3.createForAnyType(type); -- } -- -- public String createForJavaType(Serializable ser) -- throws TypeMismatchException -- { -- return RepositoryId_1_3.createForJavaType(ser); -- } -- -- public String createForJavaType(Class clz) -- throws TypeMismatchException -- { -- return RepositoryId_1_3.createForJavaType(clz); -- } -- -- public String createSequenceRepID(java.lang.Object ser) { -- return RepositoryId_1_3.createSequenceRepID(ser); -- } -- -- public String createSequenceRepID(Class clazz) { -- return RepositoryId_1_3.createSequenceRepID(clazz); -- } -- -- public RepositoryIdInterface getFromString(String repIdString) { -- return new RepIdDelegator_1_3(RepositoryId_1_3.cache.getId(repIdString)); -- } -- -- // RepositoryIdUtility methods -- -- public boolean isChunkedEncoding(int valueTag) { -- return RepositoryId.isChunkedEncoding(valueTag); -- } -- -- public boolean isCodeBasePresent(int valueTag) { -- return RepositoryId.isCodeBasePresent(valueTag); -- } -- -- public String getClassDescValueRepId() { -- return RepositoryId_1_3.kClassDescValueRepID; -- } -- -- public String getWStringValueRepId() { -- return RepositoryId_1_3.kWStringValueRepID; -- } -- -- public int getTypeInfo(int valueTag) { -- return RepositoryId.getTypeInfo(valueTag); -- } -- -- public int getStandardRMIChunkedNoRepStrId() { -- return RepositoryId.kPreComputed_StandardRMIChunked_NoRep; -- } -- -- public int getCodeBaseRMIChunkedNoRepStrId() { -- return RepositoryId.kPreComputed_CodeBaseRMIChunked_NoRep; -- } -- -- public int getStandardRMIChunkedId() { -- return RepositoryId.kPreComputed_StandardRMIChunked; -- } -- -- public int getCodeBaseRMIChunkedId() { -- return RepositoryId.kPreComputed_CodeBaseRMIChunked; -- } -- -- public int getStandardRMIUnchunkedId() { -- return RepositoryId.kPreComputed_StandardRMIUnchunked; -- } -- -- public int getCodeBaseRMIUnchunkedId() { -- return RepositoryId.kPreComputed_CodeBaseRMIUnchunked; -- } -- -- public int getStandardRMIUnchunkedNoRepStrId() { -- return RepositoryId.kPreComputed_StandardRMIUnchunked_NoRep; -- } -- -- public int getCodeBaseRMIUnchunkedNoRepStrId() { -- return RepositoryId.kPreComputed_CodeBaseRMIUnchunked_NoRep; -- } -- -- // RepositoryIdInterface methods -- -- public Class getClassFromType() throws ClassNotFoundException { -- return delegate.getClassFromType(); -- } -- -- public Class getClassFromType(String codebaseURL) -- throws ClassNotFoundException, MalformedURLException -- { -- return delegate.getClassFromType(codebaseURL); -- } -- -- public Class getClassFromType(Class expectedType, -- String codebaseURL) -- throws ClassNotFoundException, MalformedURLException -- { -- return delegate.getClassFromType(expectedType, codebaseURL); -- } -- -- public String getClassName() { -- return delegate.getClassName(); -- } -- -- // Constructor used for factory/utility cases -- public RepIdDelegator_1_3() {} -- -- // Constructor used by getIdFromString. All non-static -- // RepositoryId methods will use the provided delegate. -- private RepIdDelegator_1_3(RepositoryId_1_3 _delegate) { -- this.delegate = _delegate; -- } -- -- private RepositoryId_1_3 delegate = null; -- -- public String toString() { -- if (delegate != null) -- return delegate.toString(); -- else -- return this.getClass().getName(); -- } -- -- public boolean equals(Object obj) { -- if (delegate != null) -- return delegate.equals(obj); -- else -- return super.equals(obj); -- } --} -diff --git a/src/share/classes/com/sun/corba/se/impl/orbutil/RepIdDelegator_1_3_1.java b/src/share/classes/com/sun/corba/se/impl/orbutil/RepIdDelegator_1_3_1.java -deleted file mode 100644 ---- openjdk/corba/src/share/classes/com/sun/corba/se/impl/orbutil/RepIdDelegator_1_3_1.java -+++ /dev/null -@@ -1,177 +0,0 @@ --/* -- * Copyright (c) 2001, 2004, Oracle and/or its affiliates. All rights reserved. -- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -- * -- * This code is free software; you can redistribute it and/or modify it -- * under the terms of the GNU General Public License version 2 only, as -- * published by the Free Software Foundation. Oracle designates this -- * particular file as subject to the "Classpath" exception as provided -- * by Oracle in the LICENSE file that accompanied this code. -- * -- * This code is distributed in the hope that it will be useful, but WITHOUT -- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -- * version 2 for more details (a copy is included in the LICENSE file that -- * accompanied this code). -- * -- * You should have received a copy of the GNU General Public License version -- * 2 along with this work; if not, write to the Free Software Foundation, -- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -- * -- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -- * or visit www.oracle.com if you need additional information or have any -- * questions. -- */ -- --package com.sun.corba.se.impl.orbutil; -- --import org.omg.CORBA.ORB; --import java.io.Serializable; --import java.util.Hashtable; --import java.net.MalformedURLException; --import com.sun.corba.se.impl.io.TypeMismatchException; --import com.sun.corba.se.impl.util.RepositoryId; -- --/** -- * Delegates to the RepositoryId_1_3_1 implementation in -- * com.sun.corba.se.impl.orbutil. This is necessary to -- * overcome the fact that many of RepositoryId's methods -- * are static. -- */ --public final class RepIdDelegator_1_3_1 -- implements RepositoryIdStrings, -- RepositoryIdUtility, -- RepositoryIdInterface --{ -- // RepositoryIdFactory methods -- -- public String createForAnyType(Class type) { -- return RepositoryId_1_3_1.createForAnyType(type); -- } -- -- public String createForJavaType(Serializable ser) -- throws TypeMismatchException -- { -- return RepositoryId_1_3_1.createForJavaType(ser); -- } -- -- public String createForJavaType(Class clz) -- throws TypeMismatchException -- { -- return RepositoryId_1_3_1.createForJavaType(clz); -- } -- -- public String createSequenceRepID(java.lang.Object ser) { -- return RepositoryId_1_3_1.createSequenceRepID(ser); -- } -- -- public String createSequenceRepID(Class clazz) { -- return RepositoryId_1_3_1.createSequenceRepID(clazz); -- } -- -- public RepositoryIdInterface getFromString(String repIdString) { -- return new RepIdDelegator_1_3_1(RepositoryId_1_3_1.cache.getId(repIdString)); -- } -- -- // RepositoryIdUtility methods -- -- public boolean isChunkedEncoding(int valueTag) { -- return RepositoryId.isChunkedEncoding(valueTag); -- } -- -- public boolean isCodeBasePresent(int valueTag) { -- return RepositoryId.isCodeBasePresent(valueTag); -- } -- -- public String getClassDescValueRepId() { -- return RepositoryId_1_3_1.kClassDescValueRepID; -- } -- -- public String getWStringValueRepId() { -- return RepositoryId_1_3_1.kWStringValueRepID; -- } -- -- public int getTypeInfo(int valueTag) { -- return RepositoryId.getTypeInfo(valueTag); -- } -- -- public int getStandardRMIChunkedNoRepStrId() { -- return RepositoryId.kPreComputed_StandardRMIChunked_NoRep; -- } -- -- public int getCodeBaseRMIChunkedNoRepStrId() { -- return RepositoryId.kPreComputed_CodeBaseRMIChunked_NoRep; -- } -- -- public int getStandardRMIChunkedId() { -- return RepositoryId.kPreComputed_StandardRMIChunked; -- } -- -- public int getCodeBaseRMIChunkedId() { -- return RepositoryId.kPreComputed_CodeBaseRMIChunked; -- } -- -- public int getStandardRMIUnchunkedId() { -- return RepositoryId.kPreComputed_StandardRMIUnchunked; -- } -- -- public int getCodeBaseRMIUnchunkedId() { -- return RepositoryId.kPreComputed_CodeBaseRMIUnchunked; -- } -- -- public int getStandardRMIUnchunkedNoRepStrId() { -- return RepositoryId.kPreComputed_StandardRMIUnchunked_NoRep; -- } -- -- public int getCodeBaseRMIUnchunkedNoRepStrId() { -- return RepositoryId.kPreComputed_CodeBaseRMIUnchunked_NoRep; -- } -- -- // RepositoryIdInterface methods -- -- public Class getClassFromType() throws ClassNotFoundException { -- return delegate.getClassFromType(); -- } -- -- public Class getClassFromType(String codebaseURL) -- throws ClassNotFoundException, MalformedURLException -- { -- return delegate.getClassFromType(codebaseURL); -- } -- -- public Class getClassFromType(Class expectedType, -- String codebaseURL) -- throws ClassNotFoundException, MalformedURLException -- { -- return delegate.getClassFromType(expectedType, codebaseURL); -- } -- -- public String getClassName() { -- return delegate.getClassName(); -- } -- -- // Constructor used for factory/utility cases -- public RepIdDelegator_1_3_1() {} -- -- // Constructor used by getIdFromString. All non-static -- // RepositoryId methods will use the provided delegate. -- private RepIdDelegator_1_3_1(RepositoryId_1_3_1 _delegate) { -- this.delegate = _delegate; -- } -- -- private RepositoryId_1_3_1 delegate = null; -- -- public String toString() { -- if (delegate != null) -- return delegate.toString(); -- else -- return this.getClass().getName(); -- } -- -- public boolean equals(Object obj) { -- if (delegate != null) -- return delegate.equals(obj); -- else -- return super.equals(obj); -- } --} -diff --git a/src/share/classes/com/sun/corba/se/impl/orbutil/RepositoryIdCache_1_3.java b/src/share/classes/com/sun/corba/se/impl/orbutil/RepositoryIdCache_1_3.java -deleted file mode 100644 ---- openjdk/corba/src/share/classes/com/sun/corba/se/impl/orbutil/RepositoryIdCache_1_3.java -+++ /dev/null -@@ -1,108 +0,0 @@ --/* -- * Copyright (c) 2000, 2002, Oracle and/or its affiliates. All rights reserved. -- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -- * -- * This code is free software; you can redistribute it and/or modify it -- * under the terms of the GNU General Public License version 2 only, as -- * published by the Free Software Foundation. Oracle designates this -- * particular file as subject to the "Classpath" exception as provided -- * by Oracle in the LICENSE file that accompanied this code. -- * -- * This code is distributed in the hope that it will be useful, but WITHOUT -- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -- * version 2 for more details (a copy is included in the LICENSE file that -- * accompanied this code). -- * -- * You should have received a copy of the GNU General Public License version -- * 2 along with this work; if not, write to the Free Software Foundation, -- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -- * -- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -- * or visit www.oracle.com if you need additional information or have any -- * questions. -- */ --/* -- * Licensed Materials - Property of IBM -- * RMI-IIOP v1.0 -- * Copyright IBM Corp. 1998 1999 All Rights Reserved -- * -- */ -- --package com.sun.corba.se.impl.orbutil; -- --import java.util.Stack; --import java.util.Hashtable; --import java.util.EmptyStackException; --import java.util.Enumeration; -- --// Really limited pool - in this case just creating several at a time... --class RepositoryIdPool_1_3 extends Stack { -- -- private static int MAX_CACHE_SIZE = 4; -- private RepositoryIdCache_1_3 cache; -- -- public final synchronized RepositoryId_1_3 popId() { -- -- try { -- return (RepositoryId_1_3)super.pop(); -- } -- catch(EmptyStackException e) { -- increasePool(5); -- return (RepositoryId_1_3)super.pop(); -- } -- -- } -- -- // Pool management -- final void increasePool(int size) { -- //if (cache.size() <= MAX_CACHE_SIZE) -- for (int i = size; i > 0; i--) -- push(new RepositoryId_1_3()); -- /* -- // _REVISIT_ This will not work w/out either thread tracing or weak references. I am -- // betting that thread tracing almost completely negates benefit of reuse. Until either -- // 1.2 only inclusion or proof to the contrary, I'll leave it this way... -- else { -- int numToReclaim = cache.size() / 2; -- Enumeration keys = cache.keys(); -- Enumeration elements = cache.elements(); -- for (int i = numToReclaim; i > 0; i--) { -- Object key = keys.nextElement(); -- Object element = elements.nextElement(); -- -- push(element); -- cache.remove(key); -- } -- } -- */ -- } -- -- final void setCaches(RepositoryIdCache_1_3 cache) { -- this.cache = cache; -- } -- --} -- --public class RepositoryIdCache_1_3 extends Hashtable { -- -- private RepositoryIdPool_1_3 pool = new RepositoryIdPool_1_3(); -- -- public RepositoryIdCache_1_3() { -- pool.setCaches(this); -- } -- -- public final synchronized RepositoryId_1_3 getId(String key) { -- RepositoryId_1_3 repId = (RepositoryId_1_3)super.get(key); -- -- if (repId != null) -- return repId; -- else { -- //repId = pool.popId().init(key); -- repId = new RepositoryId_1_3(key); -- put(key, repId); -- return repId; -- } -- -- } --} -diff --git a/src/share/classes/com/sun/corba/se/impl/orbutil/RepositoryIdCache_1_3_1.java b/src/share/classes/com/sun/corba/se/impl/orbutil/RepositoryIdCache_1_3_1.java -deleted file mode 100644 ---- openjdk/corba/src/share/classes/com/sun/corba/se/impl/orbutil/RepositoryIdCache_1_3_1.java -+++ /dev/null -@@ -1,102 +0,0 @@ --/* -- * Copyright (c) 2001, 2002, Oracle and/or its affiliates. All rights reserved. -- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -- * -- * This code is free software; you can redistribute it and/or modify it -- * under the terms of the GNU General Public License version 2 only, as -- * published by the Free Software Foundation. Oracle designates this -- * particular file as subject to the "Classpath" exception as provided -- * by Oracle in the LICENSE file that accompanied this code. -- * -- * This code is distributed in the hope that it will be useful, but WITHOUT -- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -- * version 2 for more details (a copy is included in the LICENSE file that -- * accompanied this code). -- * -- * You should have received a copy of the GNU General Public License version -- * 2 along with this work; if not, write to the Free Software Foundation, -- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -- * -- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -- * or visit www.oracle.com if you need additional information or have any -- * questions. -- */ -- --package com.sun.corba.se.impl.orbutil; -- --import java.util.Stack; --import java.util.Hashtable; --import java.util.EmptyStackException; --import java.util.Enumeration; -- --// Really limited pool - in this case just creating several at a time... --class RepositoryIdPool_1_3_1 extends Stack { -- -- private static int MAX_CACHE_SIZE = 4; -- private RepositoryIdCache_1_3_1 cache; -- -- public final synchronized RepositoryId_1_3_1 popId() { -- -- try { -- return (RepositoryId_1_3_1)super.pop(); -- } -- catch(EmptyStackException e) { -- increasePool(5); -- return (RepositoryId_1_3_1)super.pop(); -- } -- -- } -- -- // Pool management -- final void increasePool(int size) { -- //if (cache.size() <= MAX_CACHE_SIZE) -- for (int i = size; i > 0; i--) -- push(new RepositoryId_1_3_1()); -- /* -- // _REVISIT_ This will not work w/out either thread tracing or weak references. I am -- // betting that thread tracing almost completely negates benefit of reuse. Until either -- // 1.2 only inclusion or proof to the contrary, I'll leave it this way... -- else { -- int numToReclaim = cache.size() / 2; -- Enumeration keys = cache.keys(); -- Enumeration elements = cache.elements(); -- for (int i = numToReclaim; i > 0; i--) { -- Object key = keys.nextElement(); -- Object element = elements.nextElement(); -- -- push(element); -- cache.remove(key); -- } -- } -- */ -- } -- -- final void setCaches(RepositoryIdCache_1_3_1 cache) { -- this.cache = cache; -- } -- --} -- --public class RepositoryIdCache_1_3_1 extends Hashtable { -- -- private RepositoryIdPool_1_3_1 pool = new RepositoryIdPool_1_3_1(); -- -- public RepositoryIdCache_1_3_1() { -- pool.setCaches(this); -- } -- -- public final synchronized RepositoryId_1_3_1 getId(String key) { -- RepositoryId_1_3_1 repId = (RepositoryId_1_3_1)super.get(key); -- -- if (repId != null) -- return repId; -- else { -- //repId = pool.popId().init(key); -- repId = new RepositoryId_1_3_1(key); -- put(key, repId); -- return repId; -- } -- -- } --} -diff --git a/src/share/classes/com/sun/corba/se/impl/orbutil/RepositoryIdFactory.java b/src/share/classes/com/sun/corba/se/impl/orbutil/RepositoryIdFactory.java ---- openjdk/corba/src/share/classes/com/sun/corba/se/impl/orbutil/RepositoryIdFactory.java -+++ openjdk/corba/src/share/classes/com/sun/corba/se/impl/orbutil/RepositoryIdFactory.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -30,12 +30,6 @@ import com.sun.corba.se.spi.orb.ORB; - - public abstract class RepositoryIdFactory - { -- private static final RepIdDelegator_1_3 legacyDelegator -- = new RepIdDelegator_1_3(); -- -- private static final RepIdDelegator_1_3_1 ladybirdDelegator -- = new RepIdDelegator_1_3_1(); -- - private static final RepIdDelegator currentDelegator - = new RepIdDelegator(); - -@@ -48,29 +42,6 @@ public abstract class RepositoryIdFactor - } - - /** -- * Checks the version of the ORB and returns the appropriate -- * RepositoryIdStrings instance. -- */ -- public static RepositoryIdStrings getRepIdStringsFactory(ORB orb) -- { -- if (orb != null) { -- switch (orb.getORBVersion().getORBType()) { -- case ORBVersion.NEWER: -- case ORBVersion.FOREIGN: -- case ORBVersion.JDK1_3_1_01: -- return currentDelegator; -- case ORBVersion.OLD: -- return legacyDelegator; -- case ORBVersion.NEW: -- return ladybirdDelegator; -- default: -- return currentDelegator; -- } -- } else -- return currentDelegator; -- } -- -- /** - * Returns the latest version RepositoryIdUtility instance - */ - public static RepositoryIdUtility getRepIdUtility() -@@ -78,26 +49,4 @@ public abstract class RepositoryIdFactor - return currentDelegator; - } - -- /** -- * Checks the version of the ORB and returns the appropriate -- * RepositoryIdUtility instance. -- */ -- public static RepositoryIdUtility getRepIdUtility(ORB orb) -- { -- if (orb != null) { -- switch (orb.getORBVersion().getORBType()) { -- case ORBVersion.NEWER: -- case ORBVersion.FOREIGN: -- case ORBVersion.JDK1_3_1_01: -- return currentDelegator; -- case ORBVersion.OLD: -- return legacyDelegator; -- case ORBVersion.NEW: -- return ladybirdDelegator; -- default: -- return currentDelegator; -- } -- } else -- return currentDelegator; -- } - } -diff --git a/src/share/classes/com/sun/corba/se/impl/orbutil/RepositoryId_1_3.java b/src/share/classes/com/sun/corba/se/impl/orbutil/RepositoryId_1_3.java -deleted file mode 100644 ---- openjdk/corba/src/share/classes/com/sun/corba/se/impl/orbutil/RepositoryId_1_3.java -+++ /dev/null -@@ -1,990 +0,0 @@ --/* -- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. -- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -- * -- * This code is free software; you can redistribute it and/or modify it -- * under the terms of the GNU General Public License version 2 only, as -- * published by the Free Software Foundation. Oracle designates this -- * particular file as subject to the "Classpath" exception as provided -- * by Oracle in the LICENSE file that accompanied this code. -- * -- * This code is distributed in the hope that it will be useful, but WITHOUT -- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -- * version 2 for more details (a copy is included in the LICENSE file that -- * accompanied this code). -- * -- * You should have received a copy of the GNU General Public License version -- * 2 along with this work; if not, write to the Free Software Foundation, -- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -- * -- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -- * or visit www.oracle.com if you need additional information or have any -- * questions. -- */ --/* -- * Licensed Materials - Property of IBM -- * RMI-IIOP v1.0 -- * Copyright IBM Corp. 1998 1999 All Rights Reserved -- * -- */ -- --package com.sun.corba.se.impl.orbutil; -- --import java.util.StringTokenizer; --import java.util.Hashtable; --import java.io.IOException; --import java.lang.reflect.Method; -- --// Imports for using codebase URL to load class --import java.net.MalformedURLException; --import org.omg.CORBA.portable.ValueBase; --import org.omg.CORBA.portable.IDLEntity; -- --import com.sun.corba.se.impl.util.JDKBridge; --import com.sun.corba.se.impl.util.Utility; --import com.sun.corba.se.impl.util.PackagePrefixChecker; --import com.sun.corba.se.impl.util.IdentityHashtable; --import com.sun.corba.se.impl.io.ObjectStreamClass; -- --import javax.rmi.CORBA.Util; -- --// keeping the original RepositoryId class that was shipped in --// JDK 1.3. It has interoperability bugs -- --public class RepositoryId_1_3 { -- -- // Legal IDL Identifier characters (1 = legal). Note -- // that '.' (2E) is marked as legal even though it is -- // not legal in IDL. This allows us to treat a fully -- // qualified Java name with '.' package separators -- // uniformly, and is safe because that is the only -- // legal use of '.' in a Java name. -- -- public static final RepositoryIdCache_1_3 cache = new RepositoryIdCache_1_3(); -- private static final byte[] IDL_IDENTIFIER_CHARS = { -- -- // 0 1 2 3 4 5 6 7 8 9 a b c d e f -- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 00-0f -- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 10-1f -- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,1,0, // 20-2f -- 1,1,1,1, 1,1,1,1, 1,1,0,0, 0,0,0,0, // 30-3f -- 0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, // 40-4f -- 1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,1, // 50-5f -- 0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, // 60-6f -- 1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,0, // 70-7f -- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 80-8f -- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 90-9f -- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // a0-af -- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // b0-bf -- 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, // c0-cf -- 0,1,1,1, 1,1,1,0, 1,1,1,1, 1,0,0,1, // d0-df -- 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, // e0-ef -- 0,1,1,1, 1,1,1,0, 1,1,1,1, 1,0,0,1, // f0-ff -- }; -- -- private static String defaultServerURL = null; -- private static boolean useCodebaseOnly = false; -- -- static { -- if (defaultServerURL == null) -- defaultServerURL = (String)JDKBridge.getLocalCodebase(); -- useCodebaseOnly = JDKBridge.useCodebaseOnly(); -- -- } -- -- private static IdentityHashtable classToRepStr = new IdentityHashtable(); -- private static IdentityHashtable classIDLToRepStr = new IdentityHashtable(); -- private static IdentityHashtable classSeqToRepStr = new IdentityHashtable(); -- -- private static IdentityHashtable repStrToByteArray = new IdentityHashtable(); -- private static Hashtable repStrToClass = new Hashtable(); -- -- private String repId = null; -- private boolean isSupportedFormat = true; -- private String typeString = null; -- private String versionString = null; -- private boolean isSequence = false; -- private boolean isRMIValueType = false; -- private boolean isIDLType = false; -- private String completeClassName = null; -- private String unqualifiedName = null; -- private String definedInId = null; -- private Class clazz = null; -- private String suid = null, actualSuid = null; -- private long suidLong = ObjectStreamClass.kDefaultUID, actualSuidLong = ObjectStreamClass.kDefaultUID; -- -- // Repository ID fragments -- private static final String kValuePrefix = "RMI:"; -- private static final String kIDLPrefix = "IDL:"; -- private static final String kIDLNamePrefix = "omg.org/"; -- private static final String kIDLClassnamePrefix = "org.omg."; -- private static final String kSequencePrefix = "["; -- private static final String kCORBAPrefix = "CORBA/"; -- private static final String kArrayPrefix = kValuePrefix + kSequencePrefix + kCORBAPrefix; -- private static final int kValuePrefixLength = kValuePrefix.length(); -- private static final int kIDLPrefixLength = kIDLPrefix.length(); -- private static final int kSequencePrefixLength = kSequencePrefix.length(); -- private static final String kInterfaceHashCode = ":0000000000000000"; -- private static final String kInterfaceOnlyHashStr = "0000000000000000"; -- private static final String kExternalizableHashStr = "0000000000000001"; -- -- // Value tag utility methods and constants -- public static final int kInitialValueTag= 0x7fffff00; -- public static final int kNoTypeInfo = 0; -- public static final int kSingleRepTypeInfo = 0x02; -- public static final int kPartialListTypeInfo = 0x06; -- public static final int kChunkedMask = 0x08; -- -- // Public, well known repository IDs -- -- // _REVISIT_ : A table structure with a good search routine for all of this -- // would be more efficient and easier to maintain... -- -- // String -- public static final String kWStringValueVersion = "1.0"; -- public static final String kWStringValueHash = ":"+kWStringValueVersion; -- public static final String kWStringStubValue = "WStringValue"; -- public static final String kWStringTypeStr = "omg.org/CORBA/"+kWStringStubValue; -- public static final String kWStringValueRepID = kIDLPrefix + kWStringTypeStr + kWStringValueHash; -- -- // Any -- public static final String kAnyRepID = kIDLPrefix + "omg.org/CORBA/Any"; -- -- // Class -- public static final String kClassDescValueHash = ":" + Long.toHexString( -- ObjectStreamClass.getSerialVersionUID(javax.rmi.CORBA.ClassDesc.class)); -- public static final String kClassDescStubValue = "ClassDesc"; -- public static final String kClassDescTypeStr = "javax.rmi.CORBA."+kClassDescStubValue; -- public static final String kClassDescValueRepID = kValuePrefix + kClassDescTypeStr + kClassDescValueHash; -- -- // Object -- public static final String kObjectValueHash = ":1.0"; -- public static final String kObjectStubValue = "Object"; -- -- // Sequence -- public static final String kSequenceValueHash = ":1.0"; -- public static final String kPrimitiveSequenceValueHash = ":0000000000000000"; -- -- // Serializable -- public static final String kSerializableValueHash = ":1.0"; -- public static final String kSerializableStubValue = "Serializable"; -- -- // Externalizable -- public static final String kExternalizableValueHash = ":1.0"; -- public static final String kExternalizableStubValue = "Externalizable"; -- -- // Remote (The empty string is used for java.rmi.Remote) -- public static final String kRemoteValueHash = ""; -- public static final String kRemoteStubValue = ""; -- public static final String kRemoteTypeStr = ""; -- public static final String kRemoteValueRepID = ""; -- -- private static final Hashtable kSpecialArrayTypeStrings = new Hashtable(); -- -- static { -- kSpecialArrayTypeStrings.put("CORBA.WStringValue", new StringBuffer(java.lang.String.class.getName())); -- kSpecialArrayTypeStrings.put("javax.rmi.CORBA.ClassDesc", new StringBuffer(java.lang.Class.class.getName())); -- kSpecialArrayTypeStrings.put("CORBA.Object", new StringBuffer(java.rmi.Remote.class.getName())); -- -- } -- -- private static final Hashtable kSpecialCasesRepIDs = new Hashtable(); -- -- static { -- kSpecialCasesRepIDs.put(java.lang.String.class, kWStringValueRepID); -- kSpecialCasesRepIDs.put(java.lang.Class.class, kClassDescValueRepID); -- kSpecialCasesRepIDs.put(java.rmi.Remote.class, kRemoteValueRepID); -- } -- -- private static final Hashtable kSpecialCasesStubValues = new Hashtable(); -- -- static { -- kSpecialCasesStubValues.put(java.lang.String.class, kWStringStubValue); -- kSpecialCasesStubValues.put(java.lang.Class.class, kClassDescStubValue); -- kSpecialCasesStubValues.put(java.lang.Object.class, kObjectStubValue); -- kSpecialCasesStubValues.put(java.io.Serializable.class, kSerializableStubValue); -- kSpecialCasesStubValues.put(java.io.Externalizable.class, kExternalizableStubValue); -- kSpecialCasesStubValues.put(java.rmi.Remote.class, kRemoteStubValue); -- } -- -- -- private static final Hashtable kSpecialCasesVersions = new Hashtable(); -- -- static { -- kSpecialCasesVersions.put(java.lang.String.class, kWStringValueHash); -- kSpecialCasesVersions.put(java.lang.Class.class, kClassDescValueHash); -- kSpecialCasesVersions.put(java.lang.Object.class, kObjectValueHash); -- kSpecialCasesVersions.put(java.io.Serializable.class, kSerializableValueHash); -- kSpecialCasesVersions.put(java.io.Externalizable.class, kExternalizableValueHash); -- kSpecialCasesVersions.put(java.rmi.Remote.class, kRemoteValueHash); -- } -- -- private static final Hashtable kSpecialCasesClasses = new Hashtable(); -- -- static { -- kSpecialCasesClasses.put(kWStringTypeStr, java.lang.String.class); -- kSpecialCasesClasses.put(kClassDescTypeStr, java.lang.Class.class); -- kSpecialCasesClasses.put(kRemoteTypeStr, java.rmi.Remote.class); -- -- kSpecialCasesClasses.put("org.omg.CORBA.WStringValue", java.lang.String.class); -- kSpecialCasesClasses.put("javax.rmi.CORBA.ClassDesc", java.lang.Class.class); -- //kSpecialCasesClasses.put(kRemoteTypeStr, java.rmi.Remote.class); -- } -- -- private static final Hashtable kSpecialCasesArrayPrefix = new Hashtable(); -- -- static { -- kSpecialCasesArrayPrefix.put(java.lang.String.class, kValuePrefix + kSequencePrefix + kCORBAPrefix); -- kSpecialCasesArrayPrefix.put(java.lang.Class.class, kValuePrefix + kSequencePrefix + "javax/rmi/CORBA/"); -- kSpecialCasesArrayPrefix.put(java.lang.Object.class, kValuePrefix + kSequencePrefix + "java/lang/"); -- kSpecialCasesArrayPrefix.put(java.io.Serializable.class, kValuePrefix + kSequencePrefix + "java/io/"); -- kSpecialCasesArrayPrefix.put(java.io.Externalizable.class, kValuePrefix + kSequencePrefix + "java/io/"); -- kSpecialCasesArrayPrefix.put(java.rmi.Remote.class, kValuePrefix + kSequencePrefix + kCORBAPrefix); -- } -- -- private static final Hashtable kSpecialPrimitives = new Hashtable(); -- -- static { -- kSpecialPrimitives.put("int","long"); -- kSpecialPrimitives.put("long","longlong"); -- kSpecialPrimitives.put("byte","octet"); -- } -- -- /** -- * Used to convert ascii to hex. -- */ -- private static final byte ASCII_HEX[] = { -- (byte)'0', -- (byte)'1', -- (byte)'2', -- (byte)'3', -- (byte)'4', -- (byte)'5', -- (byte)'6', -- (byte)'7', -- (byte)'8', -- (byte)'9', -- (byte)'A', -- (byte)'B', -- (byte)'C', -- (byte)'D', -- (byte)'E', -- (byte)'F', -- }; -- -- -- // Interface Rep ID Strings -- public static final String kjava_rmi_Remote = createForAnyType(java.rmi.Remote.class); -- public static final String korg_omg_CORBA_Object = createForAnyType(org.omg.CORBA.Object.class); -- -- // Dummy arguments for getIdFromHelper method -- public static final Class kNoParamTypes[] ={}; -- public static final Object kNoArgs[] = {}; -- -- -- RepositoryId_1_3(){} -- -- RepositoryId_1_3(String aRepId){ -- init(aRepId); -- } -- -- RepositoryId_1_3 init(String aRepId){ -- -- this.repId = aRepId; -- -- // Special case for remote -- if (aRepId.length() == 0) { -- clazz = java.rmi.Remote.class; -- typeString = ""; -- isRMIValueType = true; -- suid = kInterfaceOnlyHashStr; -- return this; -- } -- else if (aRepId.equals(kWStringValueRepID)) { -- clazz = java.lang.String.class; -- typeString = kWStringTypeStr; -- isIDLType = true; -- versionString = kWStringValueVersion; -- return this; -- } -- else { -- -- String repId = convertFromISOLatin1(aRepId); -- -- versionString = repId.substring(repId.indexOf(':', repId.indexOf(':')+1)); -- if (repId.startsWith(kIDLPrefix)) { -- typeString = -- repId.substring(kIDLPrefixLength, repId.indexOf(':', kIDLPrefixLength)); -- isIDLType = true; -- if (typeString.startsWith(kIDLNamePrefix)) -- completeClassName = kIDLClassnamePrefix + -- typeString.substring(kIDLNamePrefix.length()).replace('/','.'); -- else completeClassName = typeString.replace('/','.'); -- -- } -- else if (repId.startsWith(kValuePrefix)) { -- typeString = -- repId.substring(kValuePrefixLength, repId.indexOf(':', kValuePrefixLength)); -- isRMIValueType = true; -- -- if (versionString.indexOf('.') == -1) { -- actualSuid = versionString.substring(1); -- suid = actualSuid; // default if not explicitly specified -- -- if (actualSuid.indexOf(':') != -1){ -- // we have a declared hash also -- int pos = actualSuid.indexOf(':')+1; -- // actualSuid = suid.substring(pos); -- // suid = suid.substring(0, pos-1); -- suid = actualSuid.substring(pos); -- actualSuid = actualSuid.substring(0, pos-1); -- } -- -- } -- else { -- // _REVISIT_ : Special case version failure ? -- } -- } -- else isSupportedFormat = false; -- -- if (typeString.startsWith(kSequencePrefix)) { -- isSequence = true; -- } -- -- -- return this; -- } -- } -- -- public final String getUnqualifiedName() { -- if (unqualifiedName == null){ -- String className = getClassName(); -- int index = (className != null) ? className.lastIndexOf('.') : -1; -- if (index == -1){ -- unqualifiedName = className; -- definedInId = "IDL::1.0"; -- } -- else { -- unqualifiedName = className.substring(index); -- definedInId = "IDL:" + className.substring(0, index).replace('.','/') + ":1.0"; -- } -- } -- -- return unqualifiedName; -- } -- -- public final String getDefinedInId() { -- if (definedInId == null){ -- getUnqualifiedName(); -- } -- -- return definedInId; -- } -- -- public final String getTypeString() { -- return typeString; -- } -- -- public final String getVersionString() { -- return versionString; -- } -- -- public final String getSerialVersionUID() { -- return suid; -- } -- -- public final String getActualSerialVersionUID() { -- return actualSuid; -- } -- public final long getSerialVersionUIDAsLong() { -- return suidLong; -- } -- -- public final long getActualSerialVersionUIDAsLong() { -- return actualSuidLong; -- } -- -- public final boolean isRMIValueType() { -- return isRMIValueType; -- } -- -- public final boolean isIDLType() { -- return isIDLType; -- } -- -- public final String getRepositoryId() { -- return repId; -- } -- -- public static byte[] getByteArray(String repStr) { -- synchronized (repStrToByteArray){ -- return (byte[]) repStrToByteArray.get(repStr); -- } -- } -- -- public static void setByteArray(String repStr, byte[] repStrBytes) { -- synchronized (repStrToByteArray){ -- repStrToByteArray.put(repStr, repStrBytes); -- } -- } -- -- public final boolean isSequence() { -- return isSequence; -- } -- -- public final boolean isSupportedFormat() { -- return isSupportedFormat; -- } -- -- -- // This method will return the classname from the typestring OR if the classname turns out to be -- // a special class "pseudo" name, then the matching real classname is returned. -- public final String getClassName() { -- -- if (isRMIValueType) -- return typeString; -- else if (isIDLType) -- return completeClassName; -- else return null; -- -- } -- -- // This method calls getClazzFromType() and falls back to the repStrToClass -- // cache if no class was found. It's used where any class matching the -- // given repid is an acceptable result. -- public final Class getAnyClassFromType() throws ClassNotFoundException { -- try { -- return getClassFromType(); -- } catch (ClassNotFoundException cnfe) { -- Class clz = (Class)repStrToClass.get(repId); -- if (clz != null) -- return clz; -- else -- throw cnfe; -- } -- } -- -- public final Class getClassFromType() -- throws ClassNotFoundException { -- if (clazz != null) -- return clazz; -- -- Class specialCase = (Class)kSpecialCasesClasses.get(getClassName()); -- -- if (specialCase != null){ -- clazz = specialCase; -- return specialCase; -- } -- else -- { -- try{ -- return Util.loadClass(getClassName(), null, null); -- } -- catch(ClassNotFoundException cnfe){ -- if (defaultServerURL != null) { -- try{ -- return getClassFromType(defaultServerURL); -- } -- catch(MalformedURLException mue){ -- throw cnfe; -- } -- } -- else throw cnfe; -- } -- } -- -- } -- -- public final Class getClassFromType(Class expectedType, String codebase) -- throws ClassNotFoundException { -- if (clazz != null) -- return clazz; -- -- Class specialCase = (Class)kSpecialCasesClasses.get(getClassName()); -- -- if (specialCase != null){ -- clazz = specialCase; -- return specialCase; -- } else { -- ClassLoader expectedTypeClassLoader = (expectedType == null ? null : expectedType.getClassLoader()); -- return loadClassOfType(getClassName(), -- codebase, -- expectedTypeClassLoader, -- expectedType, -- expectedTypeClassLoader); -- } -- -- } -- -- public final Class getClassFromType(String url) -- throws ClassNotFoundException, MalformedURLException { -- return Util.loadClass(getClassName(), url, null); -- } -- -- public final String toString() { -- return repId; -- } -- -- private static String createHashString(java.io.Serializable ser) { -- -- return createHashString(ser.getClass()); -- } -- -- private static String createHashString(java.lang.Class clazz) { -- -- if (clazz.isInterface() || !java.io.Serializable.class.isAssignableFrom(clazz)) -- return kInterfaceHashCode; -- -- -- long actualLong = ObjectStreamClassUtil_1_3.computeStructuralUID(false, clazz); -- String hash = null; -- if (actualLong == 0) -- hash = kInterfaceOnlyHashStr; -- else if (actualLong == 1) -- hash = kExternalizableHashStr; -- else -- hash = Long.toHexString(actualLong).toUpperCase(); -- while(hash.length() < 16){ -- hash = "0" + hash; -- } -- -- long declaredLong = ObjectStreamClassUtil_1_3.computeSerialVersionUID(clazz); -- String declared = null; -- if (declaredLong == 0) -- declared = kInterfaceOnlyHashStr; -- else if (declaredLong == 1) -- declared = kExternalizableHashStr; -- else -- declared = Long.toHexString(declaredLong).toUpperCase(); -- while (declared.length() < 16){ -- declared = "0" + declared; -- } -- hash = hash + ":" + declared; -- -- return ":" + hash; -- } -- -- /** -- * Creates a repository ID for a sequence. This is for expert users only as -- * this method assumes the object passed is an array. If passed an object -- * that is not an array, it will produce a rep id for a sequence of zero -- * length. This would be an error. -- * @param ser The Java object to create a repository ID for -- **/ -- public static String createSequenceRepID(java.lang.Object ser){ -- return createSequenceRepID(ser.getClass()); -- } -- -- /** -- * Creates a repository ID for a sequence. This is for expert users only as -- * this method assumes the object passed is an array. If passed an object -- * that is not an array, it will produce a malformed rep id. -- * @param clazz The Java class to create a repository ID for -- **/ -- public static String createSequenceRepID(java.lang.Class clazz){ -- synchronized (classSeqToRepStr){ -- -- String repid = (String)classSeqToRepStr.get(clazz); -- if (repid != null) -- return repid; -- -- Class originalClazz = clazz; -- -- Class type = null; -- int numOfDims = 0; -- -- while ((type = clazz.getComponentType()) != null) { -- numOfDims++; -- clazz = type; -- } -- -- if (clazz.isPrimitive()) -- repid = kValuePrefix + originalClazz.getName() + kPrimitiveSequenceValueHash; -- else { -- StringBuffer buf = new StringBuffer(); -- buf.append(kValuePrefix); -- while(numOfDims-- > 0) { -- buf.append("["); -- } -- buf.append("L"); -- buf.append(convertToISOLatin1(clazz.getName())); -- buf.append(";"); -- buf.append(createHashString(clazz)); -- repid = buf.toString(); -- } -- classSeqToRepStr.put(originalClazz,repid); -- return repid; -- } -- -- } -- -- -- public static String createForSpecialCase(java.lang.Class clazz){ -- if (clazz.isArray()){ -- return createSequenceRepID(clazz); -- } -- else { -- return (String)kSpecialCasesRepIDs.get(clazz); -- } -- } -- -- public static String createForSpecialCase(java.io.Serializable ser){ -- Class clazz = ser.getClass(); -- if (clazz.isArray()){ -- return createSequenceRepID(ser); -- } -- else -- return createForSpecialCase(clazz); -- } -- -- /** -- * Creates a repository ID for a normal Java Type. -- * @param ser The Java object to create a repository ID for -- * @exception com.sun.corba.se.impl.io.TypeMismatchException if ser implements the -- * org.omg.CORBA.portable.IDLEntity interface which indicates it is an IDL Value type. -- **/ -- public static String createForJavaType(java.io.Serializable ser) -- throws com.sun.corba.se.impl.io.TypeMismatchException -- { -- synchronized (classToRepStr) { -- String repid = createForSpecialCase(ser); -- if (repid != null) -- return repid; -- Class clazz = ser.getClass(); -- repid = (String)classToRepStr.get(clazz); -- -- if (repid != null) -- return repid; -- -- repid = kValuePrefix + convertToISOLatin1(clazz.getName()) + -- createHashString(clazz); -- -- classToRepStr.put(clazz, repid); -- repStrToClass.put(repid, clazz); -- return repid; -- } -- } -- -- /** -- * Creates a repository ID for a normal Java Type. -- * @param clz The Java class to create a repository ID for -- * @exception com.sun.corba.se.impl.io.TypeMismatchException if ser implements the -- * org.omg.CORBA.portable.IDLEntity interface which indicates it is an IDL Value type. -- **/ -- public static String createForJavaType(Class clz) -- throws com.sun.corba.se.impl.io.TypeMismatchException -- { -- synchronized (classToRepStr){ -- String repid = createForSpecialCase(clz); -- if (repid != null) -- return repid; -- -- repid = (String)classToRepStr.get(clz); -- if (repid != null) -- return repid; -- -- repid = kValuePrefix + convertToISOLatin1(clz.getName()) + -- createHashString(clz); -- -- classToRepStr.put(clz, repid); -- repStrToClass.put(repid, clz); -- return repid; -- } -- } -- -- /** -- * Creates a repository ID for an IDL Java Type. -- * @param ser The IDL Value object to create a repository ID for -- * @param major The major version number -- * @param minor The minor version number -- * @exception com.sun.corba.se.impl.io.TypeMismatchException if ser does not implement the -- * org.omg.CORBA.portable.IDLEntity interface which indicates it is an IDL Value type. -- **/ -- public static String createForIDLType(Class ser, int major, int minor) -- throws com.sun.corba.se.impl.io.TypeMismatchException -- { -- synchronized (classIDLToRepStr){ -- String repid = (String)classIDLToRepStr.get(ser); -- if (repid != null) -- return repid; -- -- repid = kIDLPrefix + convertToISOLatin1(ser.getName()).replace('.','/') + -- ":" + major + "." + minor; -- classIDLToRepStr.put(ser, repid); -- return repid; -- } -- } -- -- private static String getIdFromHelper(Class clazz){ -- try { -- Class helperClazz = Utility.loadClassForClass(clazz.getName()+"Helper", null, -- clazz.getClassLoader(), clazz, clazz.getClassLoader()); -- Method idMethod = helperClazz.getDeclaredMethod("id", kNoParamTypes); -- return (String)idMethod.invoke(null, kNoArgs); -- } -- catch(java.lang.ClassNotFoundException cnfe) -- { -- throw new org.omg.CORBA.MARSHAL(cnfe.toString()); -- } -- catch(java.lang.NoSuchMethodException nsme) -- { -- throw new org.omg.CORBA.MARSHAL(nsme.toString()); -- } -- catch(java.lang.reflect.InvocationTargetException ite) -- { -- throw new org.omg.CORBA.MARSHAL(ite.toString()); -- } -- catch(java.lang.IllegalAccessException iae) -- { -- throw new org.omg.CORBA.MARSHAL(iae.toString()); -- } -- } -- -- /** -- * Createa a repository ID for the type if it is either a java type -- * or an IDL type. -- * @param type The type to create rep. id for -- * @return The rep. id. -- **/ -- public static String createForAnyType(Class type) { -- try{ -- if (type.isArray()) -- return createSequenceRepID(type); -- else if (IDLEntity.class.isAssignableFrom(type)) -- { -- try{ -- return getIdFromHelper(type); -- } -- catch(Throwable t) { -- return createForIDLType(type, 1, 0); -- } -- } -- else return createForJavaType(type); -- } -- catch(com.sun.corba.se.impl.io.TypeMismatchException e){ -- return null; -- } -- -- } -- -- public static boolean isAbstractBase(Class clazz) { -- return (clazz.isInterface() && -- IDLEntity.class.isAssignableFrom(clazz) && -- (!ValueBase.class.isAssignableFrom(clazz)) && -- (!org.omg.CORBA.Object.class.isAssignableFrom(clazz))); -- -- } -- -- /** -- * Convert strings with illegal IDL identifier characters. -- * <p> -- * Section 5.5.7 of OBV spec. -- */ -- private static String convertToISOLatin1 (String name) { -- -- int length = name.length(); -- if (length == 0) { -- return name; -- } -- StringBuffer buffer = null; -- -- for (int i = 0; i < length; i++) { -- -- char c = name.charAt(i); -- -- if (c > 255 || IDL_IDENTIFIER_CHARS[c] == 0) { -- -- // We gotta convert. Have we already started? -- -- if (buffer == null) { -- -- // No, so get set up... -- -- buffer = new StringBuffer(name.substring(0,i)); -- } -- -- // Convert the character into the IDL escape syntax... -- buffer.append( -- "\\U" + -- (char)ASCII_HEX[(c & 0xF000) >>> 12] + -- (char)ASCII_HEX[(c & 0x0F00) >>> 8] + -- (char)ASCII_HEX[(c & 0x00F0) >>> 4] + -- (char)ASCII_HEX[(c & 0x000F)]); -- -- } else { -- if (buffer != null) { -- buffer.append(c); -- } -- } -- } -- -- if (buffer != null) { -- name = buffer.toString(); -- } -- -- return name; -- } -- -- /** -- * Convert strings with ISO Latin 1 escape sequences back to original strings. -- * <p> -- * Section 5.5.7 of OBV spec. -- */ -- private static String convertFromISOLatin1 (String name) { -- -- int index = -1; -- StringBuffer buf = new StringBuffer(name); -- -- while ((index = buf.toString().indexOf("\\U")) != -1){ -- String str = "0000" + buf.toString().substring(index+2, index+6); -- -- // Convert Hexadecimal -- byte[] buffer = new byte[(str.length() - 4) / 2]; -- for (int i=4, j=0; i < str.length(); i +=2, j++) { -- buffer[j] = (byte)((ORBUtility.hexOf(str.charAt(i)) << 4) & 0xF0); -- buffer[j] |= (byte)((ORBUtility.hexOf(str.charAt(i+1)) << 0) & 0x0F); -- } -- buf = new StringBuffer(delete(buf.toString(), index, index+6)); -- buf.insert(index, (char)buffer[1]); -- } -- -- return buf.toString(); -- -- -- } -- -- private static String delete(String str, int from, int to) -- { -- return str.substring(0, from) + str.substring(to, str.length()); -- } -- -- private static String replace(String target, String arg, String source) -- { -- int i = 0; -- i = target.indexOf(arg); -- -- while(i != -1) -- { -- String left = target.substring(0, i); -- String right = target.substring(i+arg.length()); -- target = new String(left+source+right); -- i = target.indexOf(arg); -- } -- return target; -- } -- -- /* -- * Load a class and check that it is assignable to a given type. -- * @param className the class name. -- * @param remoteCodebase the codebase to use. May be null. -- * @param loader the class loader of last resort. May be null. -- * @param expectedType the expected type. May be null. -- * @return the loaded class. -- */ -- private Class loadClassOfType (String className, -- String remoteCodebase, -- ClassLoader loader, -- Class expectedType, -- ClassLoader expectedTypeClassLoader) -- throws ClassNotFoundException { -- -- Class loadedClass = null; -- -- try { -- //Sequence finding of the stubs according to spec -- try{ -- //If-else is put here for speed up of J2EE. -- //According to the OMG spec, the if clause is not dead code. -- //It can occur if some compiler has allowed generation -- //into org.omg.stub hierarchy for non-offending -- //classes. This will encourage people to -- //produce non-offending class stubs in their own hierarchy. -- if(!PackagePrefixChecker -- .hasOffendingPrefix(PackagePrefixChecker -- .withoutPackagePrefix(className))){ -- loadedClass = Util.loadClass -- (PackagePrefixChecker.withoutPackagePrefix(className), -- remoteCodebase, -- loader); -- } else { -- loadedClass = Util.loadClass -- (className, -- remoteCodebase, -- loader); -- } -- } catch (ClassNotFoundException cnfe) { -- loadedClass = Util.loadClass -- (className, -- remoteCodebase, -- loader); -- } -- if (expectedType == null) -- return loadedClass; -- } catch (ClassNotFoundException cnfe) { -- if (expectedType == null) -- throw cnfe; -- } -- -- // If no class was not loaded, or if the loaded class is not of the -- // correct type, make a further attempt to load the correct class -- // using the classloader of the expected type. -- // _REVISIT_ Is this step necessary, or should the Util,loadClass -- // algorithm always produce a valid class if the setup is correct? -- // Does the OMG standard algorithm need to be changed to include -- // this step? -- if (loadedClass == null || !expectedType.isAssignableFrom(loadedClass)) { -- if (expectedType.getClassLoader() != expectedTypeClassLoader) -- throw new IllegalArgumentException("expectedTypeClassLoader not class loader of expectedType."); -- -- if (expectedTypeClassLoader != null) -- loadedClass = expectedTypeClassLoader.loadClass(className); -- else -- loadedClass = ORBClassLoader.loadClass(className); -- } -- -- return loadedClass; -- } -- -- /** -- * Checks to see if the FullValueDescription should be retrieved. -- * @exception Throws IOException if suids do not match or if the repositoryID -- * is not an RMIValueType -- */ -- public static boolean useFullValueDescription(Class clazz, String repositoryID) -- throws IOException{ -- -- String clazzRepIDStr = createForAnyType(clazz); -- -- if (clazzRepIDStr.equals(repositoryID)) -- return false; -- -- RepositoryId_1_3 targetRepid; -- RepositoryId_1_3 clazzRepid; -- -- synchronized(cache) { -- // to avoid race condition where multiple threads could be -- // accessing this method, and their access to the cache may -- // be interleaved giving unexpected results -- -- targetRepid = cache.getId(repositoryID); -- clazzRepid = cache.getId(clazzRepIDStr); -- } -- -- if ((targetRepid.isRMIValueType()) && (clazzRepid.isRMIValueType())){ -- if (!targetRepid.getSerialVersionUID().equals(clazzRepid.getSerialVersionUID())) { -- -- String mssg = "Mismatched serialization UIDs : Source (Rep. ID" + -- clazzRepid + ") = " + -- clazzRepid.getSerialVersionUID() + " whereas Target (Rep. ID " + repositoryID + -- ") = " + targetRepid.getSerialVersionUID(); -- throw new IOException(mssg); -- } else { -- return true; -- } -- } else { -- -- throw new IOException("The repository ID is not of an RMI value type (Expected ID = " + clazzRepIDStr + "; Received ID = " + repositoryID +")"); -- } -- } --} -diff --git a/src/share/classes/com/sun/corba/se/impl/orbutil/RepositoryId_1_3_1.java b/src/share/classes/com/sun/corba/se/impl/orbutil/RepositoryId_1_3_1.java -deleted file mode 100644 ---- openjdk/corba/src/share/classes/com/sun/corba/se/impl/orbutil/RepositoryId_1_3_1.java -+++ /dev/null -@@ -1,1065 +0,0 @@ --/* -- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. -- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -- * -- * This code is free software; you can redistribute it and/or modify it -- * under the terms of the GNU General Public License version 2 only, as -- * published by the Free Software Foundation. Oracle designates this -- * particular file as subject to the "Classpath" exception as provided -- * by Oracle in the LICENSE file that accompanied this code. -- * -- * This code is distributed in the hope that it will be useful, but WITHOUT -- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -- * version 2 for more details (a copy is included in the LICENSE file that -- * accompanied this code). -- * -- * You should have received a copy of the GNU General Public License version -- * 2 along with this work; if not, write to the Free Software Foundation, -- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -- * -- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -- * or visit www.oracle.com if you need additional information or have any -- * questions. -- */ -- --/* -- */ --package com.sun.corba.se.impl.orbutil; -- --import java.util.StringTokenizer; --import java.util.Hashtable; --import java.io.IOException; --import java.lang.reflect.Method; --import java.net.MalformedURLException; --import org.omg.CORBA.portable.ValueBase; --import org.omg.CORBA.portable.IDLEntity; -- --//d11638 files in the same package, therefore remove their reference --//import com.sun.corba.se.impl.util.JDKBridge; --//import com.sun.corba.se.impl.util.IdentityHashtable; --import com.sun.corba.se.impl.util.JDKBridge; --import com.sun.corba.se.impl.util.Utility; --import com.sun.corba.se.impl.util.PackagePrefixChecker; --import com.sun.corba.se.impl.util.IdentityHashtable; -- --import javax.rmi.CORBA.Util; -- --/** -- * Because all methods in RepositoryId are static, we have -- * to duplicate all of this code, freezing it in its 1.3.1 -- * form for backwards compatibility. -- * -- * For security reasons, we can't expose enough of -- * io/ObjectStreamClass, so it has to be duplicated in -- * orbutil. -- */ --public class RepositoryId_1_3_1 { -- -- // Legal IDL Identifier characters (1 = legal). Note -- // that '.' (2E) is marked as legal even though it is -- // not legal in IDL. This allows us to treat a fully -- // qualified Java name with '.' package separators -- // uniformly, and is safe because that is the only -- // legal use of '.' in a Java name. -- -- private static final byte[] IDL_IDENTIFIER_CHARS = { -- -- // 0 1 2 3 4 5 6 7 8 9 a b c d e f -- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 00-0f -- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 10-1f -- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,1,0, // 20-2f -- 1,1,1,1, 1,1,1,1, 1,1,0,0, 0,0,0,0, // 30-3f -- 0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, // 40-4f -- 1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,1, // 50-5f -- 0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, // 60-6f -- 1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,0, // 70-7f -- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 80-8f -- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 90-9f -- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // a0-af -- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // b0-bf -- 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, // c0-cf -- 0,1,1,1, 1,1,1,0, 1,1,1,1, 1,0,0,1, // d0-df -- 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, // e0-ef -- 0,1,1,1, 1,1,1,0, 1,1,1,1, 1,0,0,1, // f0-ff -- }; -- -- -- private static final long serialVersionUID = 123456789L; -- -- private static String defaultServerURL = null; -- private static boolean useCodebaseOnly = false; -- -- static { -- if (defaultServerURL == null) -- defaultServerURL = (String)JDKBridge.getLocalCodebase(); -- useCodebaseOnly = JDKBridge.useCodebaseOnly(); -- -- } -- -- private static IdentityHashtable classToRepStr = new IdentityHashtable(); -- private static IdentityHashtable classIDLToRepStr = new IdentityHashtable(); -- private static IdentityHashtable classSeqToRepStr = new IdentityHashtable(); -- -- private static IdentityHashtable repStrToByteArray = new IdentityHashtable(); -- private static Hashtable repStrToClass = new Hashtable(); -- -- private String repId = null; -- private boolean isSupportedFormat = true; -- private String typeString = null; -- private String versionString = null; -- private boolean isSequence = false; -- private boolean isRMIValueType = false; -- private boolean isIDLType = false; -- private String completeClassName = null; -- private String unqualifiedName = null; -- private String definedInId = null; -- private Class clazz = null; -- private String suid = null, actualSuid = null; -- private long suidLong = ObjectStreamClass_1_3_1.kDefaultUID, actualSuidLong = ObjectStreamClass_1_3_1.kDefaultUID; -- -- // Repository ID fragments -- private static final String kSequenceKeyword = "seq"; -- private static final String kValuePrefix = "RMI:"; -- private static final String kIDLPrefix = "IDL:"; -- private static final String kIDLNamePrefix = "omg.org/"; -- private static final String kIDLClassnamePrefix = "org.omg."; -- private static final String kSequencePrefix = "["; -- private static final String kCORBAPrefix = "CORBA/"; -- private static final String kArrayPrefix = kValuePrefix + kSequencePrefix + kCORBAPrefix; -- private static final int kValuePrefixLength = kValuePrefix.length(); -- private static final int kIDLPrefixLength = kIDLPrefix.length(); -- private static final int kSequencePrefixLength = kSequencePrefix.length(); -- private static final String kInterfaceHashCode = ":0000000000000000"; -- private static final String kInterfaceOnlyHashStr = "0000000000000000"; -- private static final String kExternalizableHashStr = "0000000000000001"; -- -- // Value tag utility methods and constants -- public static final int kInitialValueTag= 0x7fffff00; -- public static final int kNoTypeInfo = 0; -- public static final int kSingleRepTypeInfo = 0x02; -- public static final int kPartialListTypeInfo = 0x06; -- public static final int kChunkedMask = 0x08; -- public static final int kPreComputed_StandardRMIUnchunked = RepositoryId_1_3_1.computeValueTag(false, RepositoryId_1_3_1.kSingleRepTypeInfo, false); -- public static final int kPreComputed_CodeBaseRMIUnchunked = RepositoryId_1_3_1.computeValueTag(true, RepositoryId_1_3_1.kSingleRepTypeInfo, false); -- public static final int kPreComputed_StandardRMIChunked = RepositoryId_1_3_1.computeValueTag(false, RepositoryId_1_3_1.kSingleRepTypeInfo, true); -- public static final int kPreComputed_CodeBaseRMIChunked = RepositoryId_1_3_1.computeValueTag(true, RepositoryId_1_3_1.kSingleRepTypeInfo, true); -- -- public static final int kPreComputed_StandardRMIUnchunked_NoRep = RepositoryId_1_3_1.computeValueTag(false, RepositoryId_1_3_1.kNoTypeInfo, false); -- public static final int kPreComputed_CodeBaseRMIUnchunked_NoRep = RepositoryId_1_3_1.computeValueTag(true, RepositoryId_1_3_1.kNoTypeInfo, false); -- public static final int kPreComputed_StandardRMIChunked_NoRep = RepositoryId_1_3_1.computeValueTag(false, RepositoryId_1_3_1.kNoTypeInfo, true); -- public static final int kPreComputed_CodeBaseRMIChunked_NoRep = RepositoryId_1_3_1.computeValueTag(true, RepositoryId_1_3_1.kNoTypeInfo, true); -- -- // Public, well known repository IDs -- -- // _REVISIT_ : A table structure with a good search routine for all of this -- // would be more efficient and easier to maintain... -- -- // String -- public static final String kWStringValueVersion = "1.0"; -- public static final String kWStringValueHash = ":"+kWStringValueVersion; -- public static final String kWStringStubValue = "WStringValue"; -- public static final String kWStringTypeStr = "omg.org/CORBA/"+kWStringStubValue; -- public static final String kWStringValueRepID = kIDLPrefix + kWStringTypeStr + kWStringValueHash; -- -- // Any -- public static final String kAnyRepID = kIDLPrefix + "omg.org/CORBA/Any"; -- -- // Class -- // Anita4: convert to uppercase -- public static final String kClassDescValueHash = ":" + -- Long.toHexString( -- ObjectStreamClass_1_3_1.getActualSerialVersionUID(javax.rmi.CORBA.ClassDesc.class)).toUpperCase() + ":" + -- Long.toHexString( -- ObjectStreamClass_1_3_1.getSerialVersionUID(javax.rmi.CORBA.ClassDesc.class)).toUpperCase(); -- public static final String kClassDescStubValue = "ClassDesc"; -- public static final String kClassDescTypeStr = "javax.rmi.CORBA."+kClassDescStubValue; -- public static final String kClassDescValueRepID = kValuePrefix + kClassDescTypeStr + kClassDescValueHash; -- -- // Object -- public static final String kObjectValueHash = ":1.0"; -- public static final String kObjectStubValue = "Object"; -- -- // Sequence -- public static final String kSequenceValueHash = ":1.0"; -- public static final String kPrimitiveSequenceValueHash = ":0000000000000000"; -- -- // Serializable -- public static final String kSerializableValueHash = ":1.0"; -- public static final String kSerializableStubValue = "Serializable"; -- -- // Externalizable -- public static final String kExternalizableValueHash = ":1.0"; -- public static final String kExternalizableStubValue = "Externalizable"; -- -- // Remote (The empty string is used for java.rmi.Remote) -- public static final String kRemoteValueHash = ""; -- public static final String kRemoteStubValue = ""; -- public static final String kRemoteTypeStr = ""; -- public static final String kRemoteValueRepID = ""; -- -- private static final Hashtable kSpecialArrayTypeStrings = new Hashtable(); -- -- static { -- kSpecialArrayTypeStrings.put("CORBA.WStringValue", new StringBuffer(java.lang.String.class.getName())); -- kSpecialArrayTypeStrings.put("javax.rmi.CORBA.ClassDesc", new StringBuffer(java.lang.Class.class.getName())); -- kSpecialArrayTypeStrings.put("CORBA.Object", new StringBuffer(java.rmi.Remote.class.getName())); -- -- } -- -- private static final Hashtable kSpecialCasesRepIDs = new Hashtable(); -- -- static { -- kSpecialCasesRepIDs.put(java.lang.String.class, kWStringValueRepID); -- kSpecialCasesRepIDs.put(java.lang.Class.class, kClassDescValueRepID); -- kSpecialCasesRepIDs.put(java.rmi.Remote.class, kRemoteValueRepID); -- } -- -- private static final Hashtable kSpecialCasesStubValues = new Hashtable(); -- -- static { -- kSpecialCasesStubValues.put(java.lang.String.class, kWStringStubValue); -- kSpecialCasesStubValues.put(java.lang.Class.class, kClassDescStubValue); -- kSpecialCasesStubValues.put(java.lang.Object.class, kObjectStubValue); -- kSpecialCasesStubValues.put(java.io.Serializable.class, kSerializableStubValue); -- kSpecialCasesStubValues.put(java.io.Externalizable.class, kExternalizableStubValue); -- kSpecialCasesStubValues.put(java.rmi.Remote.class, kRemoteStubValue); -- } -- -- -- private static final Hashtable kSpecialCasesVersions = new Hashtable(); -- -- static { -- kSpecialCasesVersions.put(java.lang.String.class, kWStringValueHash); -- kSpecialCasesVersions.put(java.lang.Class.class, kClassDescValueHash); -- kSpecialCasesVersions.put(java.lang.Object.class, kObjectValueHash); -- kSpecialCasesVersions.put(java.io.Serializable.class, kSerializableValueHash); -- kSpecialCasesVersions.put(java.io.Externalizable.class, kExternalizableValueHash); -- kSpecialCasesVersions.put(java.rmi.Remote.class, kRemoteValueHash); -- } -- -- private static final Hashtable kSpecialCasesClasses = new Hashtable(); -- -- static { -- kSpecialCasesClasses.put(kWStringTypeStr, java.lang.String.class); -- kSpecialCasesClasses.put(kClassDescTypeStr, java.lang.Class.class); -- kSpecialCasesClasses.put(kRemoteTypeStr, java.rmi.Remote.class); -- -- kSpecialCasesClasses.put("org.omg.CORBA.WStringValue", java.lang.String.class); -- kSpecialCasesClasses.put("javax.rmi.CORBA.ClassDesc", java.lang.Class.class); -- //kSpecialCasesClasses.put(kRemoteTypeStr, java.rmi.Remote.class); -- } -- -- private static final Hashtable kSpecialCasesArrayPrefix = new Hashtable(); -- -- static { -- kSpecialCasesArrayPrefix.put(java.lang.String.class, kValuePrefix + kSequencePrefix + kCORBAPrefix); -- kSpecialCasesArrayPrefix.put(java.lang.Class.class, kValuePrefix + kSequencePrefix + "javax/rmi/CORBA/"); -- kSpecialCasesArrayPrefix.put(java.lang.Object.class, kValuePrefix + kSequencePrefix + "java/lang/"); -- kSpecialCasesArrayPrefix.put(java.io.Serializable.class, kValuePrefix + kSequencePrefix + "java/io/"); -- kSpecialCasesArrayPrefix.put(java.io.Externalizable.class, kValuePrefix + kSequencePrefix + "java/io/"); -- kSpecialCasesArrayPrefix.put(java.rmi.Remote.class, kValuePrefix + kSequencePrefix + kCORBAPrefix); -- } -- -- private static final Hashtable kSpecialPrimitives = new Hashtable(); -- -- static { -- kSpecialPrimitives.put("int","long"); -- kSpecialPrimitives.put("long","longlong"); -- kSpecialPrimitives.put("byte","octet"); -- } -- -- /** -- * Used to convert ascii to hex. -- */ -- private static final byte ASCII_HEX[] = { -- (byte)'0', -- (byte)'1', -- (byte)'2', -- (byte)'3', -- (byte)'4', -- (byte)'5', -- (byte)'6', -- (byte)'7', -- (byte)'8', -- (byte)'9', -- (byte)'A', -- (byte)'B', -- (byte)'C', -- (byte)'D', -- (byte)'E', -- (byte)'F', -- }; -- -- -- // bug fix for 4328952; to eliminate possibility of overriding this -- // in a subclass. -- public static final RepositoryIdCache_1_3_1 cache = new RepositoryIdCache_1_3_1(); -- -- // Interface Rep ID Strings -- public static final String kjava_rmi_Remote = createForAnyType(java.rmi.Remote.class); -- public static final String korg_omg_CORBA_Object = createForAnyType(org.omg.CORBA.Object.class); -- -- // Dummy arguments for getIdFromHelper method -- public static final Class kNoParamTypes[] ={}; -- public static final Object kNoArgs[] = {}; -- -- -- // To create a RepositoryID, use code similar to the following: -- // RepositoryId.cache.getId( id ); -- -- RepositoryId_1_3_1(){} -- -- RepositoryId_1_3_1(String aRepId){ -- init(aRepId); -- } -- -- RepositoryId_1_3_1 init(String aRepId){ -- -- this.repId = aRepId; -- -- // Special case for remote -- if (aRepId.length() == 0) { -- clazz = java.rmi.Remote.class; -- typeString = ""; -- isRMIValueType = true; -- suid = kInterfaceOnlyHashStr; -- return this; -- } -- else if (aRepId.equals(kWStringValueRepID)) { -- clazz = java.lang.String.class; -- typeString = kWStringTypeStr; -- isIDLType = true; -- // fix where Attempting to obtain a FullValueDescription -- // for an RMI value type with a String field causes an exception. -- completeClassName = "java.lang.String"; -- versionString = kWStringValueVersion; -- return this; -- } -- else { -- -- String repId = convertFromISOLatin1(aRepId); -- -- versionString = repId.substring(repId.indexOf(':', repId.indexOf(':')+1)); -- if (repId.startsWith(kIDLPrefix)) { -- typeString = -- repId.substring(kIDLPrefixLength, repId.indexOf(':', kIDLPrefixLength)); -- isIDLType = true; -- if (typeString.startsWith(kIDLNamePrefix)) -- completeClassName = kIDLClassnamePrefix + -- typeString.substring(kIDLNamePrefix.length()).replace('/','.'); -- else completeClassName = typeString.replace('/','.'); -- -- } -- else if (repId.startsWith(kValuePrefix)) { -- typeString = -- repId.substring(kValuePrefixLength, repId.indexOf(':', kValuePrefixLength)); -- isRMIValueType = true; -- -- if (versionString.indexOf('.') == -1) { -- actualSuid = versionString.substring(1); -- suid = actualSuid; // default if not explicitly specified -- -- if (actualSuid.indexOf(':') != -1){ -- // we have a declared hash also -- int pos = actualSuid.indexOf(':')+1; -- // actualSuid = suid.substring(pos); -- // suid = suid.substring(0, pos-1); -- suid = actualSuid.substring(pos); -- actualSuid = actualSuid.substring(0, pos-1); -- } -- -- } -- else { -- // _REVISIT_ : Special case version failure ? -- } -- } -- else isSupportedFormat = false; -- -- if (typeString.startsWith(kSequencePrefix)) { -- isSequence = true; -- } -- -- -- return this; -- } -- } -- -- public final String getUnqualifiedName() { -- if (unqualifiedName == null){ -- String className = getClassName(); -- int index = className.lastIndexOf('.'); -- if (index == -1){ -- unqualifiedName = className; -- definedInId = "IDL::1.0"; -- } -- else { -- unqualifiedName = className.substring(index); -- definedInId = "IDL:" + className.substring(0, index).replace('.','/') + ":1.0"; -- } -- } -- -- return unqualifiedName; -- } -- -- public final String getDefinedInId() { -- if (definedInId == null){ -- getUnqualifiedName(); -- } -- -- return definedInId; -- } -- -- public final String getTypeString() { -- return typeString; -- } -- -- public final String getVersionString() { -- return versionString; -- } -- -- public final String getSerialVersionUID() { -- return suid; -- } -- -- public final String getActualSerialVersionUID() { -- return actualSuid; -- } -- public final long getSerialVersionUIDAsLong() { -- return suidLong; -- } -- -- public final long getActualSerialVersionUIDAsLong() { -- return actualSuidLong; -- } -- -- public final boolean isRMIValueType() { -- return isRMIValueType; -- } -- -- public final boolean isIDLType() { -- return isIDLType; -- } -- -- public final String getRepositoryId() { -- return repId; -- } -- -- public static byte[] getByteArray(String repStr) { -- synchronized (repStrToByteArray){ -- return (byte[]) repStrToByteArray.get(repStr); -- } -- } -- -- public static void setByteArray(String repStr, byte[] repStrBytes) { -- synchronized (repStrToByteArray){ -- repStrToByteArray.put(repStr, repStrBytes); -- } -- } -- -- public final boolean isSequence() { -- return isSequence; -- } -- -- public final boolean isSupportedFormat() { -- return isSupportedFormat; -- } -- -- -- // This method will return the classname from the typestring OR if the classname turns out to be -- // a special class "pseudo" name, then the matching real classname is returned. -- public final String getClassName() { -- -- if (isRMIValueType) -- return typeString; -- else if (isIDLType) -- return completeClassName; -- else return null; -- -- } -- -- // This method calls getClazzFromType() and falls back to the repStrToClass -- // cache if no class was found. It's used where any class matching the -- // given repid is an acceptable result. -- public final Class getAnyClassFromType() throws ClassNotFoundException { -- try { -- return getClassFromType(); -- } catch (ClassNotFoundException cnfe) { -- Class clz = (Class)repStrToClass.get(repId); -- if (clz != null) -- return clz; -- else -- throw cnfe; -- } -- } -- -- public final Class getClassFromType() -- throws ClassNotFoundException { -- if (clazz != null) -- return clazz; -- -- Class specialCase = (Class)kSpecialCasesClasses.get(getClassName()); -- -- if (specialCase != null){ -- clazz = specialCase; -- return specialCase; -- } -- else -- { -- try{ -- return Util.loadClass(getClassName(), null, null); -- } -- catch(ClassNotFoundException cnfe){ -- if (defaultServerURL != null) { -- try{ -- return getClassFromType(defaultServerURL); -- } -- catch(MalformedURLException mue){ -- throw cnfe; -- } -- } -- else throw cnfe; -- } -- } -- -- } -- -- public final Class getClassFromType(Class expectedType, String codebase) -- throws ClassNotFoundException { -- if (clazz != null) -- return clazz; -- -- Class specialCase = (Class)kSpecialCasesClasses.get(getClassName()); -- -- if (specialCase != null){ -- clazz = specialCase; -- return specialCase; -- } else { -- ClassLoader expectedTypeClassLoader = (expectedType == null ? null : expectedType.getClassLoader()); -- return loadClassOfType(getClassName(), -- codebase, -- expectedTypeClassLoader, -- expectedType, -- expectedTypeClassLoader); -- } -- -- } -- -- public final Class getClassFromType(String url) -- throws ClassNotFoundException, MalformedURLException { -- return Util.loadClass(getClassName(), url, null); -- } -- -- public final String toString() { -- return repId; -- } -- -- /** -- * Checks to see if the FullValueDescription should be retrieved. -- * @exception Throws IOException if suids do not match or if the repositoryID -- * is not an RMIValueType -- */ -- public static boolean useFullValueDescription(Class clazz, String repositoryID) -- throws IOException{ -- -- String clazzRepIDStr = createForAnyType(clazz); -- -- if (clazzRepIDStr.equals(repositoryID)) -- return false; -- -- RepositoryId_1_3_1 targetRepid; -- RepositoryId_1_3_1 clazzRepid; -- -- synchronized(cache) { -- // to avoid race condition where multiple threads could be -- // accessing this method, and their access to the cache may -- // be interleaved giving unexpected results -- -- targetRepid = cache.getId(repositoryID); -- clazzRepid = cache.getId(clazzRepIDStr); -- } -- //ObjectStreamClass osc = ObjectStreamClass.lookup(clazz); -- -- if ((targetRepid.isRMIValueType()) && (clazzRepid.isRMIValueType())){ -- if (!targetRepid.getSerialVersionUID().equals(clazzRepid.getSerialVersionUID())) { -- -- String mssg = "Mismatched serialization UIDs : Source (Rep. ID" + -- clazzRepid + ") = " + -- clazzRepid.getSerialVersionUID() + " whereas Target (Rep. ID " + repositoryID + -- ") = " + targetRepid.getSerialVersionUID(); -- //com.sun.corba.se.impl.io.ValueUtility.log("RepositoryId",mssg); -- throw new IOException(mssg); -- } -- else { -- return true; -- } -- } -- else { -- -- throw new IOException("The repository ID is not of an RMI value type (Expected ID = " + clazzRepIDStr + "; Received ID = " + repositoryID +")"); -- } -- } -- -- private static String createHashString(java.io.Serializable ser) { -- -- return createHashString(ser.getClass()); -- } -- -- private static String createHashString(java.lang.Class clazz) { -- -- if (clazz.isInterface() || !java.io.Serializable.class.isAssignableFrom(clazz)) -- return kInterfaceHashCode; -- -- //ObjectStreamClass osc = ObjectStreamClass.lookup(clazz); -- -- long actualLong = ObjectStreamClass_1_3_1.getActualSerialVersionUID(clazz); -- String hash = null; -- if (actualLong == 0) -- hash = kInterfaceOnlyHashStr; -- else if (actualLong == 1) -- hash = kExternalizableHashStr; -- else -- hash = Long.toHexString(actualLong).toUpperCase(); -- while(hash.length() < 16){ -- hash = "0" + hash; -- } -- -- long declaredLong = ObjectStreamClass_1_3_1.getSerialVersionUID(clazz); -- String declared = null; -- if (declaredLong == 0) -- declared = kInterfaceOnlyHashStr; -- else if (declaredLong == 1) -- declared = kExternalizableHashStr; -- else -- declared = Long.toHexString(declaredLong).toUpperCase(); -- while (declared.length() < 16){ -- declared = "0" + declared; -- } -- hash = hash + ":" + declared; -- -- return ":" + hash; -- } -- -- /** -- * Creates a repository ID for a sequence. This is for expert users only as -- * this method assumes the object passed is an array. If passed an object -- * that is not an array, it will produce a rep id for a sequence of zero -- * length. This would be an error. -- * @param ser The Java object to create a repository ID for -- **/ -- public static String createSequenceRepID(java.lang.Object ser){ -- return createSequenceRepID(ser.getClass()); -- } -- -- /** -- * Creates a repository ID for a sequence. This is for expert users only as -- * this method assumes the object passed is an array. If passed an object -- * that is not an array, it will produce a malformed rep id. -- * @param clazz The Java class to create a repository ID for -- **/ -- public static String createSequenceRepID(java.lang.Class clazz){ -- synchronized (classSeqToRepStr){ -- -- String repid = (String)classSeqToRepStr.get(clazz); -- if (repid != null) -- return repid; -- -- Class originalClazz = clazz; -- -- Class type = null; -- int numOfDims = 0; -- -- while ((type = clazz.getComponentType()) != null) { -- numOfDims++; -- clazz = type; -- } -- -- if (clazz.isPrimitive()) -- repid = kValuePrefix + originalClazz.getName() + kPrimitiveSequenceValueHash; -- else { -- StringBuffer buf = new StringBuffer(); -- buf.append(kValuePrefix); -- while(numOfDims-- > 0) { -- buf.append("["); -- } -- buf.append("L"); -- buf.append(convertToISOLatin1(clazz.getName())); -- buf.append(";"); -- buf.append(createHashString(clazz)); -- repid = buf.toString(); -- } -- classSeqToRepStr.put(originalClazz,repid); -- return repid; -- } -- -- } -- -- -- public static String createForSpecialCase(java.lang.Class clazz){ -- if (clazz.isArray()){ -- return createSequenceRepID(clazz); -- } -- else { -- return (String)kSpecialCasesRepIDs.get(clazz); -- } -- } -- -- public static String createForSpecialCase(java.io.Serializable ser){ -- Class clazz = ser.getClass(); -- if (clazz.isArray()){ -- return createSequenceRepID(ser); -- } -- else -- return createForSpecialCase(clazz); -- } -- -- /** -- * Creates a repository ID for a normal Java Type. -- * @param ser The Java object to create a repository ID for -- * @exception com.sun.corba.se.impl.io.TypeMismatchException if ser implements the -- * org.omg.CORBA.portable.IDLEntity interface which indicates it is an IDL Value type. -- **/ -- public static String createForJavaType(java.io.Serializable ser) -- throws com.sun.corba.se.impl.io.TypeMismatchException -- { -- synchronized (classToRepStr) { -- String repid = createForSpecialCase(ser); -- if (repid != null) -- return repid; -- Class clazz = ser.getClass(); -- repid = (String)classToRepStr.get(clazz); -- -- if (repid != null) -- return repid; -- -- repid = kValuePrefix + convertToISOLatin1(clazz.getName()) + -- createHashString(clazz); -- -- classToRepStr.put(clazz, repid); -- repStrToClass.put(repid, clazz); -- return repid; -- } -- } -- -- /** -- * Creates a repository ID for a normal Java Type. -- * @param clz The Java class to create a repository ID for -- * @exception com.sun.corba.se.impl.io.TypeMismatchException if ser implements the -- * org.omg.CORBA.portable.IDLEntity interface which indicates it is an IDL Value type. -- **/ -- public static String createForJavaType(Class clz) -- throws com.sun.corba.se.impl.io.TypeMismatchException -- { -- synchronized (classToRepStr){ -- String repid = createForSpecialCase(clz); -- if (repid != null) -- return repid; -- -- repid = (String)classToRepStr.get(clz); -- if (repid != null) -- return repid; -- -- repid = kValuePrefix + convertToISOLatin1(clz.getName()) + -- createHashString(clz); -- -- classToRepStr.put(clz, repid); -- repStrToClass.put(repid, clz); -- return repid; -- } -- } -- -- /** -- * Creates a repository ID for an IDL Java Type. -- * @param ser The IDL Value object to create a repository ID for -- * @param major The major version number -- * @param minor The minor version number -- * @exception com.sun.corba.se.impl.io.TypeMismatchException if ser does not implement the -- * org.omg.CORBA.portable.IDLEntity interface which indicates it is an IDL Value type. -- **/ -- public static String createForIDLType(Class ser, int major, int minor) -- throws com.sun.corba.se.impl.io.TypeMismatchException -- { -- synchronized (classIDLToRepStr){ -- String repid = (String)classIDLToRepStr.get(ser); -- if (repid != null) -- return repid; -- -- repid = kIDLPrefix + convertToISOLatin1(ser.getName()).replace('.','/') + -- ":" + major + "." + minor; -- classIDLToRepStr.put(ser, repid); -- return repid; -- } -- } -- -- private static String getIdFromHelper(Class clazz){ -- try { -- Class helperClazz = Utility.loadClassForClass(clazz.getName()+"Helper", null, -- clazz.getClassLoader(), clazz, clazz.getClassLoader()); -- Method idMethod = helperClazz.getDeclaredMethod("id", kNoParamTypes); -- return (String)idMethod.invoke(null, kNoArgs); -- } -- catch(java.lang.ClassNotFoundException cnfe) -- { -- throw new org.omg.CORBA.MARSHAL(cnfe.toString()); -- } -- catch(java.lang.NoSuchMethodException nsme) -- { -- throw new org.omg.CORBA.MARSHAL(nsme.toString()); -- } -- catch(java.lang.reflect.InvocationTargetException ite) -- { -- throw new org.omg.CORBA.MARSHAL(ite.toString()); -- } -- catch(java.lang.IllegalAccessException iae) -- { -- throw new org.omg.CORBA.MARSHAL(iae.toString()); -- } -- } -- -- /** -- * Createa a repository ID for the type if it is either a java type -- * or an IDL type. -- * @param type The type to create rep. id for -- * @return The rep. id. -- **/ -- public static String createForAnyType(Class type) { -- try{ -- if (type.isArray()) -- return createSequenceRepID(type); -- else if (IDLEntity.class.isAssignableFrom(type)) -- { -- try{ -- return getIdFromHelper(type); -- } -- catch(Throwable t) { -- return createForIDLType(type, 1, 0); -- } -- } -- else return createForJavaType(type); -- } -- catch(com.sun.corba.se.impl.io.TypeMismatchException e){ -- return null; -- } -- -- } -- -- public static boolean isAbstractBase(Class clazz) { -- return (clazz.isInterface() && -- IDLEntity.class.isAssignableFrom(clazz) && -- (!ValueBase.class.isAssignableFrom(clazz)) && -- (!org.omg.CORBA.Object.class.isAssignableFrom(clazz))); -- -- } -- -- public static boolean isAnyRequired(Class clazz) { -- return ((clazz == java.lang.Object.class) || -- (clazz == java.io.Serializable.class) || -- (clazz == java.io.Externalizable.class)); -- } -- -- public static long fromHex(String hexNumber) { -- if (hexNumber.startsWith("0x")) -- return Long.valueOf(hexNumber.substring(2), 16).longValue(); -- else return Long.valueOf(hexNumber, 16).longValue(); -- } -- -- /** -- * Convert strings with illegal IDL identifier characters. -- * <p> -- * Section 5.5.7 of OBV spec. -- */ -- private static String convertToISOLatin1 (String name) { -- -- int length = name.length(); -- if (length == 0) { -- return name; -- } -- StringBuffer buffer = null; -- -- for (int i = 0; i < length; i++) { -- -- char c = name.charAt(i); -- -- if (c > 255 || IDL_IDENTIFIER_CHARS[c] == 0) { -- -- // We gotta convert. Have we already started? -- -- if (buffer == null) { -- -- // No, so get set up... -- -- buffer = new StringBuffer(name.substring(0,i)); -- } -- -- // Convert the character into the IDL escape syntax... -- buffer.append( -- "\\U" + -- (char)ASCII_HEX[(c & 0xF000) >>> 12] + -- (char)ASCII_HEX[(c & 0x0F00) >>> 8] + -- (char)ASCII_HEX[(c & 0x00F0) >>> 4] + -- (char)ASCII_HEX[(c & 0x000F)]); -- -- } else { -- if (buffer != null) { -- buffer.append(c); -- } -- } -- } -- -- if (buffer != null) { -- name = buffer.toString(); -- } -- -- return name; -- } -- -- /** -- * Convert strings with ISO Latin 1 escape sequences back to original strings. -- * <p> -- * Section 5.5.7 of OBV spec. -- */ -- private static String convertFromISOLatin1 (String name) { -- -- int index = -1; -- StringBuffer buf = new StringBuffer(name); -- -- while ((index = buf.toString().indexOf("\\U")) != -1){ -- String str = "0000" + buf.toString().substring(index+2, index+6); -- -- // Convert Hexadecimal -- byte[] buffer = new byte[(str.length() - 4) / 2]; -- for (int i=4, j=0; i < str.length(); i +=2, j++) { -- buffer[j] = (byte)((ORBUtility.hexOf(str.charAt(i)) << 4) & 0xF0); -- buffer[j] |= (byte)((ORBUtility.hexOf(str.charAt(i+1)) << 0) & 0x0F); -- } -- buf = new StringBuffer(delete(buf.toString(), index, index+6)); -- buf.insert(index, (char)buffer[1]); -- } -- -- return buf.toString(); -- -- -- } -- -- private static String delete(String str, int from, int to) -- { -- return str.substring(0, from) + str.substring(to, str.length()); -- } -- -- private static String replace(String target, String arg, String source) -- { -- int i = 0; -- i = target.indexOf(arg); -- -- while(i != -1) -- { -- String left = target.substring(0, i); -- String right = target.substring(i+arg.length()); -- target = new String(left+source+right); -- i = target.indexOf(arg); -- } -- return target; -- } -- -- public static int computeValueTag(boolean codeBasePresent, int typeInfo, boolean chunkedEncoding){ -- int value_tag = kInitialValueTag; -- -- if (codeBasePresent) -- value_tag = value_tag | 0x00000001; -- -- value_tag = value_tag | typeInfo; -- -- if (chunkedEncoding) -- value_tag = value_tag | kChunkedMask; -- -- return value_tag; -- } -- -- public static boolean isCodeBasePresent(int value_tag){ -- return ((value_tag & 0x00000001) == 1); -- } -- -- public static int getTypeInfo(int value_tag){ -- return (value_tag & 0x00000006); -- } -- -- public static boolean isChunkedEncoding(int value_tag){ -- return ((value_tag & kChunkedMask) != 0); -- } -- -- public static String getServerURL(){ -- return defaultServerURL; -- } -- -- /* -- * Load a class and check that it is assignable to a given type. -- * @param className the class name. -- * @param remoteCodebase the codebase to use. May be null. -- * @param loader the class loader of last resort. May be null. -- * @param expectedType the expected type. May be null. -- * @return the loaded class. -- */ -- private Class loadClassOfType (String className, -- String remoteCodebase, -- ClassLoader loader, -- Class expectedType, -- ClassLoader expectedTypeClassLoader) -- throws ClassNotFoundException { -- -- Class loadedClass = null; -- -- try { -- //Sequence finding of the stubs according to spec -- try{ -- //If-else is put here for speed up of J2EE. -- //According to the OMG spec, the if clause is not dead code. -- //It can occur if some compiler has allowed generation -- //into org.omg.stub hierarchy for non-offending -- //classes. This will encourage people to -- //produce non-offending class stubs in their own hierarchy. -- if(!PackagePrefixChecker -- .hasOffendingPrefix(PackagePrefixChecker -- .withoutPackagePrefix(className))){ -- loadedClass = Util.loadClass -- (PackagePrefixChecker.withoutPackagePrefix(className), -- remoteCodebase, -- loader); -- } else { -- loadedClass = Util.loadClass -- (className, -- remoteCodebase, -- loader); -- } -- } catch (ClassNotFoundException cnfe) { -- loadedClass = Util.loadClass -- (className, -- remoteCodebase, -- loader); -- } -- if (expectedType == null) -- return loadedClass; -- } catch (ClassNotFoundException cnfe) { -- if (expectedType == null) -- throw cnfe; -- } -- -- // If no class was not loaded, or if the loaded class is not of the -- // correct type, make a further attempt to load the correct class -- // using the classloader of the expected type. -- // _REVISIT_ Is this step necessary, or should the Util,loadClass -- // algorithm always produce a valid class if the setup is correct? -- // Does the OMG standard algorithm need to be changed to include -- // this step? -- if (loadedClass == null || !expectedType.isAssignableFrom(loadedClass)) { -- if (expectedType.getClassLoader() != expectedTypeClassLoader) -- throw new IllegalArgumentException("expectedTypeClassLoader not class loader of expectedType."); -- -- if (expectedTypeClassLoader != null) -- loadedClass = expectedTypeClassLoader.loadClass(className); -- else -- loadedClass = Class.forName(className); -- } -- -- return loadedClass; -- } --} -diff --git a/src/share/classes/com/sun/corba/se/impl/orbutil/ValueHandlerImpl_1_3.java b/src/share/classes/com/sun/corba/se/impl/orbutil/ValueHandlerImpl_1_3.java -deleted file mode 100644 ---- openjdk/corba/src/share/classes/com/sun/corba/se/impl/orbutil/ValueHandlerImpl_1_3.java -+++ /dev/null -@@ -1,251 +0,0 @@ --/* -- * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved. -- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -- * -- * This code is free software; you can redistribute it and/or modify it -- * under the terms of the GNU General Public License version 2 only, as -- * published by the Free Software Foundation. Oracle designates this -- * particular file as subject to the "Classpath" exception as provided -- * by Oracle in the LICENSE file that accompanied this code. -- * -- * This code is distributed in the hope that it will be useful, but WITHOUT -- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -- * version 2 for more details (a copy is included in the LICENSE file that -- * accompanied this code). -- * -- * You should have received a copy of the GNU General Public License version -- * 2 along with this work; if not, write to the Free Software Foundation, -- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -- * -- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -- * or visit www.oracle.com if you need additional information or have any -- * questions. -- */ --/* -- * Licensed Materials - Property of IBM -- * RMI-IIOP v1.0 -- * Copyright IBM Corp. 1998 1999 All Rights Reserved -- * -- */ -- --package com.sun.corba.se.impl.orbutil; -- --import javax.rmi.CORBA.Util; --import javax.rmi.PortableRemoteObject; -- --import java.util.Hashtable; --import java.util.Stack; --import java.io.IOException; --import java.util.EmptyStackException; -- --import com.sun.corba.se.impl.util.Utility; --import com.sun.corba.se.impl.io.IIOPInputStream; --import com.sun.corba.se.impl.io.IIOPOutputStream; --import com.sun.corba.se.impl.util.RepositoryId; --import com.sun.corba.se.impl.util.Utility; -- --import org.omg.CORBA.TCKind; --import org.omg.CORBA.MARSHAL; --import org.omg.CORBA.CompletionStatus; --import org.omg.CORBA.portable.IndirectionException; --import com.sun.org.omg.SendingContext.CodeBase; -- --import java.security.AccessController; --import java.security.PrivilegedAction; -- --/** -- * This class overrides behavior of our current ValueHandlerImpl to -- * provide backwards compatibility with JDK 1.3.0. -- */ --public class ValueHandlerImpl_1_3 extends com.sun.corba.se.impl.io.ValueHandlerImpl { -- -- public ValueHandlerImpl_1_3(){ -- super(); -- } -- -- public ValueHandlerImpl_1_3(boolean isInputStream) { -- super(isInputStream); -- } -- -- /** -- * Writes the value to the stream using java semantics. -- * @param out The stream to write the value to -- * @param value The value to be written to the stream -- **/ -- public void writeValue(org.omg.CORBA.portable.OutputStream _out, java.io.Serializable value) { -- super.writeValue(_out, value); -- } -- -- /** -- * Reads a value from the stream using java semantics. -- * @param in The stream to read the value from -- * @param clazz The type of the value to be read in -- * @param sender The sending context runtime -- **/ -- public java.io.Serializable readValue(org.omg.CORBA.portable.InputStream _in, -- int offset, -- java.lang.Class clazz, -- String repositoryID, -- org.omg.SendingContext.RunTime _sender) -- { -- return super.readValue(_in, offset, clazz, repositoryID, _sender); -- } -- -- /** -- * Returns the repository ID for the given RMI value Class. -- * @param clz The class to return a repository ID for. -- * @return the repository ID of the Class. -- **/ -- public java.lang.String getRMIRepositoryID(java.lang.Class clz) { -- return RepositoryId_1_3.createForJavaType(clz); -- } -- -- /** -- * Indicates whether the given Class performs custom or -- * default marshaling. -- * @param clz The class to test for custom marshaling. -- * @return True if the class performs custom marshaling, false -- * if it does not. -- **/ -- public boolean isCustomMarshaled(java.lang.Class clz) { -- return super.isCustomMarshaled(clz); -- } -- -- /** -- * Returns the CodeBase for this ValueHandler. This is used by -- * the ORB runtime. The server sends the service context containing -- * the IOR for this CodeBase on the first GIOP reply. The clients -- * do the same on the first GIOP request. -- * @return the SendingContext.CodeBase of this ValueHandler. -- **/ -- public org.omg.SendingContext.RunTime getRunTimeCodeBase() { -- return super.getRunTimeCodeBase(); -- } -- -- /** -- * If the value contains a writeReplace method then the result -- * is returned. Otherwise, the value itself is returned. -- * @return the true value to marshal on the wire. -- **/ -- public java.io.Serializable writeReplace(java.io.Serializable value) { -- return super.writeReplace(value); -- } -- -- // methods supported for backward compatability so that the appropriate -- // Rep-id calculations take place based on the ORB version -- -- /** -- * Returns a boolean of whether or not RepositoryId indicates -- * FullValueDescriptor. -- * used for backward compatability -- */ -- -- public boolean useFullValueDescription(Class clazz, String repositoryID) -- throws IOException -- -- { -- return RepositoryId_1_3.useFullValueDescription(clazz, repositoryID); -- } -- -- public String getClassName(String id) -- { -- RepositoryId_1_3 repID = RepositoryId_1_3.cache.getId(id); -- return repID.getClassName(); -- } -- -- public Class getClassFromType(String id) -- throws ClassNotFoundException -- { -- RepositoryId_1_3 repId = RepositoryId_1_3.cache.getId(id); -- return repId.getClassFromType(); -- } -- -- public Class getAnyClassFromType(String id) -- throws ClassNotFoundException -- { -- RepositoryId_1_3 repId = RepositoryId_1_3.cache.getId(id); -- return repId.getAnyClassFromType(); -- } -- -- public String createForAnyType(Class cl) -- { -- return RepositoryId_1_3.createForAnyType(cl); -- } -- -- public String getDefinedInId(String id) -- { -- RepositoryId_1_3 repId = RepositoryId_1_3.cache.getId(id); -- return repId.getDefinedInId(); -- } -- -- public String getUnqualifiedName(String id) -- { -- RepositoryId_1_3 repId = RepositoryId_1_3.cache.getId(id); -- return repId.getUnqualifiedName(); -- } -- -- public String getSerialVersionUID(String id) -- { -- RepositoryId_1_3 repId = RepositoryId_1_3.cache.getId(id); -- return repId.getSerialVersionUID(); -- } -- -- public boolean isAbstractBase(Class clazz) -- { -- return RepositoryId_1_3.isAbstractBase(clazz); -- } -- -- public boolean isSequence(String id) -- { -- RepositoryId_1_3 repId = RepositoryId_1_3.cache.getId(id); -- return repId.isSequence(); -- } -- -- /** -- * Preserves the incorrect 1.3 behavior which truncates Java chars in -- * arrays to 8-bit CORBA chars. Bug 4367783. This enables us to -- * continue interoperating with our legacy ORBs. If this goes into -- * Ladybird, then Ladybird and Kestrel will interoperate as long as -- * people don't use chars greater than 8-bits. -- */ -- protected void writeCharArray(org.omg.CORBA_2_3.portable.OutputStream out, -- char[] array, -- int offset, -- int length) -- { -- out.write_char_array(array, offset, length); -- } -- -- /** -- * Preserves the incorrect 1.3 behavior which truncates Java chars in -- * arrays to 8-bit CORBA chars. Bug 4367783. This enables us to -- * continue interoperating with our legacy ORBs. If this goes into -- * Ladybird, then Ladybird and Kestrel will interoperate as long as -- * people don't use chars greater than 8-bits. -- */ -- protected void readCharArray(org.omg.CORBA_2_3.portable.InputStream in, -- char[] array, -- int offset, -- int length) -- { -- in.read_char_array(array, offset, length); -- } -- -- protected final String getOutputStreamClassName() { -- return "com.sun.corba.se.impl.orbutil.IIOPOutputStream_1_3"; -- } -- -- protected final String getInputStreamClassName() { -- return "com.sun.corba.se.impl.orbutil.IIOPInputStream_1_3"; -- } -- -- /** -- * Our JDK 1.3 and JDK 1.3.1 behavior subclasses override this. -- * The correct behavior is for a Java char to map to a CORBA wchar, -- * but our older code mapped it to a CORBA char. -- */ -- protected TCKind getJavaCharTCKind() { -- return TCKind.tk_char; -- } --} -diff --git a/src/share/classes/com/sun/corba/se/impl/orbutil/ValueHandlerImpl_1_3_1.java b/src/share/classes/com/sun/corba/se/impl/orbutil/ValueHandlerImpl_1_3_1.java -deleted file mode 100644 ---- openjdk/corba/src/share/classes/com/sun/corba/se/impl/orbutil/ValueHandlerImpl_1_3_1.java -+++ /dev/null -@@ -1,77 +0,0 @@ --/* -- * Copyright (c) 2001, 2002, Oracle and/or its affiliates. All rights reserved. -- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -- * -- * This code is free software; you can redistribute it and/or modify it -- * under the terms of the GNU General Public License version 2 only, as -- * published by the Free Software Foundation. Oracle designates this -- * particular file as subject to the "Classpath" exception as provided -- * by Oracle in the LICENSE file that accompanied this code. -- * -- * This code is distributed in the hope that it will be useful, but WITHOUT -- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -- * version 2 for more details (a copy is included in the LICENSE file that -- * accompanied this code). -- * -- * You should have received a copy of the GNU General Public License version -- * 2 along with this work; if not, write to the Free Software Foundation, -- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -- * -- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -- * or visit www.oracle.com if you need additional information or have any -- * questions. -- */ --package com.sun.corba.se.impl.orbutil; -- --import org.omg.CORBA.TCKind; -- --/** -- * This class overrides behavior of our current ValueHandlerImpl to -- * provide backwards compatibility with JDK 1.3.1. -- */ --public class ValueHandlerImpl_1_3_1 -- extends com.sun.corba.se.impl.io.ValueHandlerImpl --{ -- public ValueHandlerImpl_1_3_1() {} -- -- public ValueHandlerImpl_1_3_1(boolean isInputStream) { -- super(isInputStream); -- } -- -- /** -- * Our JDK 1.3 and JDK 1.3.1 behavior subclasses override this. -- * The correct behavior is for a Java char to map to a CORBA wchar, -- * but our older code mapped it to a CORBA char. -- */ -- protected TCKind getJavaCharTCKind() { -- return TCKind.tk_char; -- } -- -- /** -- * RepositoryId_1_3_1 performs an incorrect repId calculation -- * when using serialPersistentFields and one of the fields no longer -- * exists on the class itself. -- */ -- public boolean useFullValueDescription(Class clazz, String repositoryID) -- throws java.io.IOException -- { -- return RepositoryId_1_3_1.useFullValueDescription(clazz, repositoryID); -- } -- -- /** -- * Installs the legacy IIOPOutputStream_1_3_1 which does -- * PutFields/GetFields incorrectly. Bug 4407244. -- */ -- protected final String getOutputStreamClassName() { -- return "com.sun.corba.se.impl.orbutil.IIOPOutputStream_1_3_1"; -- } -- -- /** -- * Installs the legacy IIOPInputStream_1_3_1 which does -- * PutFields/GetFields incorrectly. Bug 4407244. -- */ -- protected final String getInputStreamClassName() { -- return "com.sun.corba.se.impl.orbutil.IIOPInputStream_1_3_1"; -- } --} -diff --git a/src/share/classes/sun/corba/JavaCorbaAccess.java b/src/share/classes/sun/corba/JavaCorbaAccess.java -new file mode 100644 ---- /dev/null -+++ openjdk/corba/src/share/classes/sun/corba/JavaCorbaAccess.java -@@ -0,0 +1,32 @@ -+/* -+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. -+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -+ * -+ * This code is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 only, as -+ * published by the Free Software Foundation. Oracle designates this -+ * particular file as subject to the "Classpath" exception as provided -+ * by Oracle in the LICENSE file that accompanied this code. -+ * -+ * This code is distributed in the hope that it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * version 2 for more details (a copy is included in the LICENSE file that -+ * accompanied this code). -+ * -+ * You should have received a copy of the GNU General Public License version -+ * 2 along with this work; if not, write to the Free Software Foundation, -+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -+ * -+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -+ * or visit www.oracle.com if you need additional information or have any -+ * questions. -+ */ -+ -+package sun.corba; -+ -+import com.sun.corba.se.impl.io.ValueHandlerImpl; -+ -+public interface JavaCorbaAccess { -+ public ValueHandlerImpl newValueHandlerImpl(); -+} -diff --git a/src/share/classes/sun/corba/SharedSecrets.java b/src/share/classes/sun/corba/SharedSecrets.java -new file mode 100644 ---- /dev/null -+++ openjdk/corba/src/share/classes/sun/corba/SharedSecrets.java -@@ -0,0 +1,60 @@ -+/* -+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. -+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -+ * -+ * This code is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 only, as -+ * published by the Free Software Foundation. Oracle designates this -+ * particular file as subject to the "Classpath" exception as provided -+ * by Oracle in the LICENSE file that accompanied this code. -+ * -+ * This code is distributed in the hope that it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * version 2 for more details (a copy is included in the LICENSE file that -+ * accompanied this code). -+ * -+ * You should have received a copy of the GNU General Public License version -+ * 2 along with this work; if not, write to the Free Software Foundation, -+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -+ * -+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -+ * or visit www.oracle.com if you need additional information or have any -+ * questions. -+ */ -+ -+package sun.corba; -+ -+import com.sun.corba.se.impl.io.ValueUtility; -+import sun.misc.Unsafe; -+ -+import java.security.AccessController; -+ -+/** A repository of "shared secrets", which are a mechanism for -+ calling implementation-private methods in another package without -+ using reflection. A package-private class implements a public -+ interface and provides the ability to call package-private methods -+ within that package; the object implementing that interface is -+ provided through a third package to which access is restricted. -+ This framework avoids the primary disadvantage of using reflection -+ for this purpose, namely the loss of compile-time checking. */ -+ -+// SharedSecrets cloned in corba repo to avoid build issues -+public class SharedSecrets { -+ private static final Unsafe unsafe = Unsafe.getUnsafe(); -+ private static JavaCorbaAccess javaCorbaAccess; -+ -+ public static JavaCorbaAccess getJavaCorbaAccess() { -+ if (javaCorbaAccess == null) { -+ // Ensure ValueUtility is initialized; we know that that class -+ // provides the shared secret -+ unsafe.ensureClassInitialized(ValueUtility.class); -+ } -+ return javaCorbaAccess; -+ } -+ -+ public static void setJavaCorbaAccess(JavaCorbaAccess access) { -+ javaCorbaAccess = access; -+ } -+ -+}
--- a/patches/security/20130201/8001235.patch Tue Mar 19 00:21:31 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,37 +0,0 @@ -diff -Nru jaxp.old/build.properties jaxp/build.properties ---- openjdk/jaxp.old/build.properties 2013-02-01 21:59:17.360429006 +0000 -+++ openjdk/jaxp/build.properties 2013-02-01 22:04:56.349681812 +0000 -@@ -77,6 +77,9 @@ - # Where patches to drop bundle sources live - patches.dir=patches - -+# Patches to apply -+jaxp_src.patch.list=8001235.patch -+ - # Sanity information - sanity.info= Sanity Settings:${line.separator}\ - ant.home=${ant.home}${line.separator}\ -diff -Nru jaxp.old/patches/jaxp_src/8001235.patch jaxp/patches/jaxp_src/8001235.patch ---- openjdk/jaxp.old/patches/jaxp_src/8001235.patch 1970-01-01 01:00:00.000000000 +0100 -+++ openjdk/jaxp/patches/jaxp_src/8001235.patch 2013-02-01 22:04:27.369232768 +0000 -@@ -0,0 +1,20 @@ -+# HG changeset patch -+# User joehw -+# Date 1351536837 25200 -+# Node ID 5df9207c4378b7f4b24d70b365714c5ee6318982 -+# Parent 5449d5396bd8deee90f18f29899343129e3cdc4e -+8001235: Improve JAXP HTTP handling -+Reviewed-by: lancea, skoivu -+ -+diff --git a/src/com/sun/org/apache/xpath/internal/functions/FuncSystemProperty.java b/src/com/sun/org/apache/xpath/internal/functions/FuncSystemProperty.java -+--- src/com/sun/org/apache/xpath/internal/functions/FuncSystemProperty.java -++++ src/com/sun/org/apache/xpath/internal/functions/FuncSystemProperty.java -+@@ -165,7 +165,7 @@ public class FuncSystemProperty extends -+ * should already be fully qualified as path/filename -+ * @param target The target property bag the file will be placed into. -+ */ -+- public void loadPropertyFile(String file, Properties target) -++ private void loadPropertyFile(String file, Properties target) -+ { -+ try -+ {
--- a/patches/security/20130201/8001242.patch Tue Mar 19 00:21:31 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,61 +0,0 @@ -# HG changeset patch -# User dmocek -# Date 1353367979 28800 -# Node ID 49a37df9e80fae205a7b70d862cd303a62049c2c -# Parent 2281f5670cc599f0fe97c880cdceb6a7db837dc3 -8001242: Improve RMI HTTP conformance -Reviewed-by: ahgross, mchung, smarks - -diff --git a/src/share/classes/sun/rmi/transport/proxy/CGIHandler.java b/src/share/classes/sun/rmi/transport/proxy/CGIHandler.java ---- openjdk/jdk/src/share/classes/sun/rmi/transport/proxy/CGIHandler.java -+++ openjdk/jdk/src/share/classes/sun/rmi/transport/proxy/CGIHandler.java -@@ -285,11 +285,14 @@ final class CGIForwardCommand implements - "unexpected EOF reading server response"); - - if (line.toLowerCase().startsWith(key)) { -- if (contentLengthFound) -- ; // what would we want to do in this case?? -- responseContentLength = -- Integer.parseInt(line.substring(key.length()).trim()); -- contentLengthFound = true; -+ if (contentLengthFound) { -+ throw new CGIServerException( -+ "Multiple Content-length entries found."); -+ } else { -+ responseContentLength = -+ Integer.parseInt(line.substring(key.length()).trim()); -+ contentLengthFound = true; -+ } - } - } while ((line.length() != 0) && - (line.charAt(0) != '\r') && (line.charAt(0) != '\n')); -diff --git a/src/share/classes/sun/rmi/transport/proxy/HttpInputStream.java b/src/share/classes/sun/rmi/transport/proxy/HttpInputStream.java ---- openjdk/jdk/src/share/classes/sun/rmi/transport/proxy/HttpInputStream.java -+++ openjdk/jdk/src/share/classes/sun/rmi/transport/proxy/HttpInputStream.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 1996, 2001, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -70,11 +70,14 @@ class HttpInputStream extends FilterInpu - throw new EOFException(); - - if (line.toLowerCase().startsWith(key)) { -- if (contentLengthFound) -- ; // what would we want to do in this case?? -- bytesLeft = -- Integer.parseInt(line.substring(key.length()).trim()); -- contentLengthFound = true; -+ if (contentLengthFound) { -+ throw new IOException( -+ "Multiple Content-length entries found."); -+ } else { -+ bytesLeft = -+ Integer.parseInt(line.substring(key.length()).trim()); -+ contentLengthFound = true; -+ } - } - - // The idea here is to go past the first blank line.
--- a/patches/security/20130201/8001307.patch Tue Mar 19 00:21:31 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,27 +0,0 @@ -diff -Nru openjdk.orig/hotspot/src/share/vm/interpreter/linkResolver.cpp openjdk/hotspot/src/share/vm/interpreter/linkResolver.cpp ---- openjdk.orig/hotspot/src/share/vm/interpreter/linkResolver.cpp 2011-11-14 22:07:35.000000000 +0000 -+++ openjdk/hotspot/src/share/vm/interpreter/linkResolver.cpp 2013-02-01 21:46:24.084475305 +0000 -@@ -695,7 +695,7 @@ - - if (check_access && - // a) check if ACC_SUPER flag is set for the current class -- current_klass->is_super() && -+ (current_klass->is_super() || !AllowNonVirtualCalls) && - // b) check if the method class is a superclass of the current class (superclass relation is not reflexive!) - current_klass->is_subtype_of(method_klass()) && current_klass() != method_klass() && - // c) check if the method is not <init> -diff -Nru openjdk.orig/hotspot/src/share/vm/runtime/globals.hpp openjdk/hotspot/src/share/vm/runtime/globals.hpp ---- openjdk.orig/hotspot/src/share/vm/runtime/globals.hpp 2013-02-01 21:44:12.678449777 +0000 -+++ openjdk/hotspot/src/share/vm/runtime/globals.hpp 2013-02-01 21:46:57.300987338 +0000 -@@ -3700,7 +3700,10 @@ - product(bool, UseVMInterruptibleIO, false, \ - "(Unstable, Solaris-specific) Thread interrupt before or with " \ - "EINTR for I/O operations results in OS_INTRPT. The default value"\ -- " of this flag is true for JDK 6 and earliers") -+ " of this flag is true for JDK 6 and earlier") \ -+ \ -+ product(bool, AllowNonVirtualCalls, false, \ -+ "Obey the ACC_SUPER flag and allow invokenonvirtual calls") - - /* - * Macros for factoring of globals
--- a/patches/security/20130201/8001972.patch Tue Mar 19 00:21:31 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,438 +0,0 @@ -diff -Nru openjdk.orig/jdk/src/share/classes/sun/awt/image/ByteComponentRaster.java openjdk/jdk/src/share/classes/sun/awt/image/ByteComponentRaster.java ---- openjdk.orig/jdk/src/share/classes/sun/awt/image/ByteComponentRaster.java 2011-11-14 22:11:59.000000000 +0000 -+++ openjdk/jdk/src/share/classes/sun/awt/image/ByteComponentRaster.java 2013-02-01 21:49:28.911324533 +0000 -@@ -198,7 +198,7 @@ - } - this.bandOffset = this.dataOffsets[0]; - -- verify(false); -+ verify(); - } - - /** -@@ -857,38 +857,68 @@ - } - - /** -- * Verify that the layout parameters are consistent with -- * the data. If strictCheck -- * is false, this method will check for ArrayIndexOutOfBounds conditions. If -- * strictCheck is true, this method will check for additional error -- * conditions such as line wraparound (width of a line greater than -- * the scanline stride). -- * @return String Error string, if the layout is incompatible with -- * the data. Otherwise returns null. -- */ -- private void verify (boolean strictCheck) { -- // Make sure data for Raster is in a legal range -- for (int i=0; i < dataOffsets.length; i++) { -+ * Verify that the layout parameters are consistent with the data. -+ * -+ * The method verifies whether scanline stride and pixel stride do not -+ * cause an integer overflow during calculation of a position of the pixel -+ * in data buffer. It also verifies whether the data buffer has enough data -+ * to correspond the raster layout attributes. -+ * -+ * @throws RasterFormatException if an integer overflow is detected, -+ * or if data buffer has not enough capacity. -+ */ -+ protected final void verify() { -+ for (int i = 0; i < dataOffsets.length; i++) { - if (dataOffsets[i] < 0) { -- throw new RasterFormatException("Data offsets for band "+i+ -- "("+dataOffsets[i]+ -- ") must be >= 0"); -+ throw new RasterFormatException("Data offsets for band " + i -+ + "(" + dataOffsets[i] -+ + ") must be >= 0"); - } - } - - int maxSize = 0; - int size; - -- for (int i=0; i < numDataElements; i++) { -- size = (height-1)*scanlineStride + (width-1)*pixelStride + -- dataOffsets[i]; -+ // we can be sure that width and height are greater than 0 -+ if (scanlineStride < 0 || -+ scanlineStride > (Integer.MAX_VALUE / height)) -+ { -+ // integer overflow -+ throw new RasterFormatException("Incorrect scanline stride: " -+ + scanlineStride); -+ } -+ int lastScanOffset = (height - 1) * scanlineStride; -+ -+ if (pixelStride < 0 || -+ pixelStride > (Integer.MAX_VALUE / width)) -+ { -+ // integer overflow -+ throw new RasterFormatException("Incorrect pixel stride: " -+ + pixelStride); -+ } -+ int lastPixelOffset = (width - 1) * pixelStride; -+ -+ if (lastPixelOffset > (Integer.MAX_VALUE - lastScanOffset)) { -+ // integer overflow -+ throw new RasterFormatException("Incorrect raster attributes"); -+ } -+ lastPixelOffset += lastScanOffset; -+ -+ for (int i = 0; i < numDataElements; i++) { -+ size = lastPixelOffset + dataOffsets[i]; -+ if (dataOffsets[i] > (Integer.MAX_VALUE - lastPixelOffset)) { -+ throw new RasterFormatException("Incorrect band offset: " -+ + dataOffsets[i]); -+ -+ } -+ - if (size > maxSize) { - maxSize = size; - } - } - if (data.length < maxSize) { -- throw new RasterFormatException("Data array too small (should be "+ -- maxSize+" )"); -+ throw new RasterFormatException("Data array too small (should be " -+ + maxSize + " )"); - } - } - -diff -Nru openjdk.orig/jdk/src/share/classes/sun/awt/image/ByteInterleavedRaster.java openjdk/jdk/src/share/classes/sun/awt/image/ByteInterleavedRaster.java ---- openjdk.orig/jdk/src/share/classes/sun/awt/image/ByteInterleavedRaster.java 2011-11-14 22:11:59.000000000 +0000 -+++ openjdk/jdk/src/share/classes/sun/awt/image/ByteInterleavedRaster.java 2013-02-01 21:49:28.911324533 +0000 -@@ -250,7 +250,7 @@ - } - } - -- verify(false); -+ verify(); - } - - /** -@@ -1292,33 +1292,6 @@ - return createCompatibleWritableRaster(width,height); - } - -- /** -- * Verify that the layout parameters are consistent with -- * the data. If strictCheck -- * is false, this method will check for ArrayIndexOutOfBounds conditions. If -- * strictCheck is true, this method will check for additional error -- * conditions such as line wraparound (width of a line greater than -- * the scanline stride). -- * @return String Error string, if the layout is incompatible with -- * the data. Otherwise returns null. -- */ -- private void verify (boolean strictCheck) { -- int maxSize = 0; -- int size; -- -- for (int i=0; i < numDataElements; i++) { -- size = (height-1)*scanlineStride + (width-1)*pixelStride + -- dataOffsets[i]; -- if (size > maxSize) { -- maxSize = size; -- } -- } -- if (data.length < maxSize) { -- throw new RasterFormatException("Data array too small (should be "+ -- maxSize+" )"); -- } -- } -- - public String toString() { - return new String ("ByteInterleavedRaster: width = "+width+" height = " - + height -diff -Nru openjdk.orig/jdk/src/share/classes/sun/awt/image/ShortComponentRaster.java openjdk/jdk/src/share/classes/sun/awt/image/ShortComponentRaster.java ---- openjdk.orig/jdk/src/share/classes/sun/awt/image/ShortComponentRaster.java 2011-11-14 22:11:59.000000000 +0000 -+++ openjdk/jdk/src/share/classes/sun/awt/image/ShortComponentRaster.java 2013-02-01 21:49:28.911324533 +0000 -@@ -198,7 +198,7 @@ - } - this.bandOffset = this.dataOffsets[0]; - -- verify(false); -+ verify(); - } - - /** -@@ -791,38 +791,67 @@ - } - - /** -- * Verify that the layout parameters are consistent with -- * the data. If strictCheck -- * is false, this method will check for ArrayIndexOutOfBounds conditions. If -- * strictCheck is true, this method will check for additional error -- * conditions such as line wraparound (width of a line greater than -- * the scanline stride). -- * @return String Error string, if the layout is incompatible with -- * the data. Otherwise returns null. -- */ -- private void verify (boolean strictCheck) { -- // Make sure data for Raster is in a legal range -- for (int i=0; i < dataOffsets.length; i++) { -+ * Verify that the layout parameters are consistent with the data. -+ * -+ * The method verifies whether scanline stride and pixel stride do not -+ * cause an integer overflow during calculation of a position of the pixel -+ * in data buffer. It also verifies whether the data buffer has enough data -+ * to correspond the raster layout attributes. -+ * -+ * @throws RasterFormatException if an integer overflow is detected, -+ * or if data buffer has not enough capacity. -+ */ -+ protected final void verify() { -+ for (int i = 0; i < dataOffsets.length; i++) { - if (dataOffsets[i] < 0) { -- throw new RasterFormatException("Data offsets for band "+i+ -- "("+dataOffsets[i]+ -- ") must be >= 0"); -+ throw new RasterFormatException("Data offsets for band " + i -+ + "(" + dataOffsets[i] -+ + ") must be >= 0"); - } - } - - int maxSize = 0; - int size; - -- for (int i=0; i < numDataElements; i++) { -- size = (height-1)*scanlineStride + (width-1)*pixelStride + -- dataOffsets[i]; -+ // we can be sure that width and height are greater than 0 -+ if (scanlineStride < 0 || -+ scanlineStride > (Integer.MAX_VALUE / height)) -+ { -+ // integer overflow -+ throw new RasterFormatException("Incorrect scanline stride: " -+ + scanlineStride); -+ } -+ int lastScanOffset = (height - 1) * scanlineStride; -+ -+ if (pixelStride < 0 || -+ pixelStride > (Integer.MAX_VALUE / width)) -+ { -+ // integer overflow -+ throw new RasterFormatException("Incorrect pixel stride: " -+ + pixelStride); -+ } -+ int lastPixelOffset = (width - 1) * pixelStride; -+ -+ if (lastPixelOffset > (Integer.MAX_VALUE - lastScanOffset)) { -+ // integer overflow -+ throw new RasterFormatException("Incorrect raster attributes"); -+ } -+ lastPixelOffset += lastScanOffset; -+ -+ for (int i = 0; i < numDataElements; i++) { -+ size = lastPixelOffset + dataOffsets[i]; -+ if (dataOffsets[i] > (Integer.MAX_VALUE - lastPixelOffset)) { -+ throw new RasterFormatException("Incorrect band offset: " -+ + dataOffsets[i]); -+ } -+ - if (size > maxSize) { - maxSize = size; - } - } - if (data.length < maxSize) { -- throw new RasterFormatException("Data array too small (should be "+ -- maxSize+" )"); -+ throw new RasterFormatException("Data array too small (should be " -+ + maxSize + " )"); - } - } - -diff -Nru openjdk.orig/jdk/src/share/classes/sun/awt/image/ShortInterleavedRaster.java openjdk/jdk/src/share/classes/sun/awt/image/ShortInterleavedRaster.java ---- openjdk.orig/jdk/src/share/classes/sun/awt/image/ShortInterleavedRaster.java 2011-11-14 22:11:59.000000000 +0000 -+++ openjdk/jdk/src/share/classes/sun/awt/image/ShortInterleavedRaster.java 2013-02-01 21:49:28.911324533 +0000 -@@ -171,7 +171,7 @@ - sampleModel); - } - this.bandOffset = this.dataOffsets[0]; -- verify(false); -+ verify(); - } - - /** -@@ -762,33 +762,6 @@ - return createCompatibleWritableRaster(width,height); - } - -- /** -- * Verify that the layout parameters are consistent with -- * the data. If strictCheck -- * is false, this method will check for ArrayIndexOutOfBounds conditions. If -- * strictCheck is true, this method will check for additional error -- * conditions such as line wraparound (width of a line greater than -- * the scanline stride). -- * @return String Error string, if the layout is incompatible with -- * the data. Otherwise returns null. -- */ -- private void verify (boolean strictCheck) { -- int maxSize = 0; -- int size; -- -- for (int i=0; i < numDataElements; i++) { -- size = (height-1)*scanlineStride + (width-1)*pixelStride + -- dataOffsets[i]; -- if (size > maxSize) { -- maxSize = size; -- } -- } -- if (data.length < maxSize) { -- throw new RasterFormatException("Data array too small (should be "+ -- maxSize+" )"); -- } -- } -- - public String toString() { - return new String ("ShortInterleavedRaster: width = "+width - +" height = " + height -diff -Nru openjdk.orig/jdk/src/share/native/sun/awt/image/awt_parseImage.c openjdk/jdk/src/share/native/sun/awt/image/awt_parseImage.c ---- openjdk.orig/jdk/src/share/native/sun/awt/image/awt_parseImage.c 2011-11-14 22:12:11.000000000 +0000 -+++ openjdk/jdk/src/share/native/sun/awt/image/awt_parseImage.c 2013-02-01 21:54:40.100132273 +0000 -@@ -114,6 +114,62 @@ - return status; - } - -+/* Verifies whether the channel offsets are sane and correspond to the type of -+ * the raster. -+ * -+ * Return value: -+ * 0: Failure: channel offsets are invalid -+ * 1: Success -+ */ -+static int checkChannelOffsets(RasterS_t *rasterP, int dataArrayLength) { -+ int i, lastPixelOffset, lastScanOffset; -+ switch (rasterP->rasterType) { -+ case COMPONENT_RASTER_TYPE: -+ if (!SAFE_TO_MULT(rasterP->height, rasterP->scanlineStride)) { -+ return 0; -+ } -+ if (!SAFE_TO_MULT(rasterP->width, rasterP->pixelStride)) { -+ return 0; -+ } -+ -+ lastScanOffset = (rasterP->height - 1) * rasterP->scanlineStride; -+ lastPixelOffset = (rasterP->width - 1) * rasterP->pixelStride; -+ -+ -+ if (!SAFE_TO_ADD(lastPixelOffset, lastScanOffset)) { -+ return 0; -+ } -+ -+ lastPixelOffset += lastScanOffset; -+ -+ for (i = 0; i < rasterP->numDataElements; i++) { -+ int off = rasterP->chanOffsets[i]; -+ int size = lastPixelOffset + off; -+ -+ if (off < 0 || !SAFE_TO_ADD(lastPixelOffset, off)) { -+ return 0; -+ } -+ -+ if (size < lastPixelOffset || size >= dataArrayLength) { -+ // an overflow, or insufficient buffer capacity -+ return 0; -+ } -+ } -+ return 1; -+ case BANDED_RASTER_TYPE: -+ // NB:caller does not support the banded rasters yet, -+ // so this branch of the code must be re-defined in -+ // order to provide valid criteria for the data offsets -+ // verification, when/if banded rasters will be supported. -+ // At the moment, we prohibit banded rasters as well. -+ return 0; -+ default: -+ // PACKED_RASTER_TYPE: does not support channel offsets -+ // UNKNOWN_RASTER_TYPE: should not be used, likely indicates an error -+ return 0; -+ } -+} -+ - /* Parse the raster. All of the raster information is returned in the - * rasterP structure. - * -@@ -125,7 +181,6 @@ - int awt_parseRaster(JNIEnv *env, jobject jraster, RasterS_t *rasterP) { - jobject joffs = NULL; - /* int status;*/ -- int isDiscrete = TRUE; - - if (JNU_IsNull(env, jraster)) { - JNU_ThrowNullPointerException(env, "null Raster object"); -@@ -155,6 +210,9 @@ - return -1; - } - -+ // make sure that the raster type is initialized -+ rasterP->rasterType = UNKNOWN_RASTER_TYPE; -+ - if (rasterP->numBands <= 0 || - rasterP->numBands > MAX_NUMBANDS) - { -@@ -254,7 +312,6 @@ - } - rasterP->chanOffsets[0] = (*env)->GetIntField(env, jraster, g_BPRdataBitOffsetID); - rasterP->dataType = BYTE_DATA_TYPE; -- isDiscrete = FALSE; - } - else { - rasterP->type = sun_awt_image_IntegerComponentRaster_TYPE_CUSTOM; -@@ -265,7 +322,19 @@ - return 0; - } - -- if (isDiscrete) { -+ // do basic validation of the raster structure -+ if (rasterP->width <= 0 || rasterP->height <= 0 || -+ rasterP->pixelStride <= 0 || rasterP->scanlineStride <= 0) -+ { -+ // invalid raster -+ return -1; -+ } -+ -+ // channel (data) offsets -+ switch (rasterP->rasterType) { -+ case COMPONENT_RASTER_TYPE: -+ case BANDED_RASTER_TYPE: // note that this routine does not support banded rasters at the moment -+ // get channel (data) offsets - rasterP->chanOffsets = NULL; - if (SAFE_TO_ALLOC_2(rasterP->numDataElements, sizeof(jint))) { - rasterP->chanOffsets = -@@ -278,6 +347,17 @@ - } - (*env)->GetIntArrayRegion(env, joffs, 0, rasterP->numDataElements, - rasterP->chanOffsets); -+ if (rasterP->jdata == NULL) { -+ // unable to verify the raster -+ return -1; -+ } -+ // verify whether channel offsets look sane -+ if (!checkChannelOffsets(rasterP, (*env)->GetArrayLength(env, rasterP->jdata))) { -+ return -1; -+ } -+ break; -+ default: -+ ; // PACKED_RASTER_TYPE does not use the channel offsets. - } - - #if 0 -diff -Nru openjdk.orig/jdk/src/share/native/sun/awt/medialib/safe_alloc.h openjdk/jdk/src/share/native/sun/awt/medialib/safe_alloc.h ---- openjdk.orig/jdk/src/share/native/sun/awt/medialib/safe_alloc.h 2011-11-14 22:12:12.000000000 +0000 -+++ openjdk/jdk/src/share/native/sun/awt/medialib/safe_alloc.h 2013-02-01 21:49:28.911324533 +0000 -@@ -41,5 +41,10 @@ - (((w) > 0) && ((h) > 0) && ((sz) > 0) && \ - (((0xffffffffu / ((juint)(w))) / ((juint)(h))) > ((juint)(sz)))) - -+#define SAFE_TO_MULT(a, b) \ -+ (((a) > 0) && ((b) >= 0) && ((0x7fffffff / (a)) > (b))) -+ -+#define SAFE_TO_ADD(a, b) \ -+ (((a) >= 0) && ((b) >= 0) && ((0x7fffffff - (a)) > (b))) - - #endif // __SAFE_ALLOC_H__
--- a/patches/security/20130201/8002325.patch Tue Mar 19 00:21:31 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,59 +0,0 @@ -# HG changeset patch -# User bae -# Date 1353162084 -14400 -# Node ID 6081ed9a6461360252572f79713b20c49caa59ad -# Parent 1e4909147511ffa8f2089c488df2435af4707283 -8002325: Improve management of images -Reviewed-by: prr, ahgross - -diff --git a/src/share/native/sun/awt/image/awt_parseImage.c b/src/share/native/sun/awt/image/awt_parseImage.c ---- openjdk/jdk/src/share/native/sun/awt/image/awt_parseImage.c -+++ openjdk/jdk/src/share/native/sun/awt/image/awt_parseImage.c -@@ -223,9 +223,14 @@ int awt_parseRaster(JNIEnv *env, jobject - return 0; - } - -+ rasterP->sppsm.isUsed = 0; -+ - if ((*env)->IsInstanceOf(env, rasterP->jsampleModel, - (*env)->FindClass(env,"java/awt/image/SinglePixelPackedSampleModel"))) { - jobject jmask, joffs, jnbits; -+ -+ rasterP->sppsm.isUsed = 1; -+ - rasterP->sppsm.maxBitSize = (*env)->GetIntField(env, - rasterP->jsampleModel, - g_SPPSMmaxBitID); -@@ -711,6 +716,21 @@ setHints(JNIEnv *env, BufImageS_t *image - } - else if (cmodelP->cmType == DIRECT_CM_TYPE || cmodelP->cmType == PACKED_CM_TYPE) { - int i; -+ -+ /* do some sanity check first: make sure that -+ * - sample model is SinglePixelPackedSampleModel -+ * - number of bands in the raster corresponds to the number -+ * of color components in the color model -+ */ -+ if (!rasterP->sppsm.isUsed || -+ rasterP->numBands != cmodelP->numComponents) -+ { -+ /* given raster is not compatible with the color model, -+ * so the operation has to be aborted. -+ */ -+ return -1; -+ } -+ - if (cmodelP->maxNbits > 8) { - hintP->needToExpand = TRUE; - hintP->expandToNbits = cmodelP->maxNbits; -diff --git a/src/share/native/sun/awt/image/awt_parseImage.h b/src/share/native/sun/awt/image/awt_parseImage.h ---- openjdk/jdk/src/share/native/sun/awt/image/awt_parseImage.h -+++ openjdk/jdk/src/share/native/sun/awt/image/awt_parseImage.h -@@ -95,6 +95,7 @@ typedef struct { - jint offsets[MAX_NUMBANDS]; - jint nBits[MAX_NUMBANDS]; - jint maxBitSize; -+ jint isUsed; // flag to indicate whether the raster sample model is SPPSM - } SPPSampleModelS_t; - - /* Struct that holds information for the Raster object */
--- a/patches/security/20130219/8006446.patch Tue Mar 19 00:21:31 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,395 +0,0 @@ -diff -Nru openjdk.orig/jdk/src/share/classes/com/sun/jmx/mbeanserver/ClassLoaderRepositorySupport.java openjdk/jdk/src/share/classes/com/sun/jmx/mbeanserver/ClassLoaderRepositorySupport.java ---- openjdk.orig/jdk/src/share/classes/com/sun/jmx/mbeanserver/ClassLoaderRepositorySupport.java 2011-11-14 22:11:44.000000000 +0000 -+++ openjdk/jdk/src/share/classes/com/sun/jmx/mbeanserver/ClassLoaderRepositorySupport.java 2013-02-15 03:40:40.511587149 +0000 -@@ -36,6 +36,7 @@ - - import javax.management.ObjectName; - import javax.management.loading.PrivateClassLoader; -+import sun.reflect.misc.ReflectUtil; - - /** - * This class keeps the list of Class Loaders registered in the MBean Server. -@@ -192,6 +193,7 @@ - final ClassLoader without, - final ClassLoader stop) - throws ClassNotFoundException { -+ ReflectUtil.checkPackageAccess(className); - final int size = list.length; - for(int i=0; i<size; i++) { - try { -diff -Nru openjdk.orig/jdk/src/share/classes/com/sun/jmx/mbeanserver/JmxMBeanServer.java openjdk/jdk/src/share/classes/com/sun/jmx/mbeanserver/JmxMBeanServer.java ---- openjdk.orig/jdk/src/share/classes/com/sun/jmx/mbeanserver/JmxMBeanServer.java 2011-11-14 22:11:44.000000000 +0000 -+++ openjdk/jdk/src/share/classes/com/sun/jmx/mbeanserver/JmxMBeanServer.java 2013-02-15 03:40:40.511587149 +0000 -@@ -57,6 +57,7 @@ - import javax.management.RuntimeOperationsException; - import javax.management.MBeanServer; - import javax.management.MBeanServerDelegate; -+import javax.management.MBeanServerPermission; - import javax.management.loading.ClassLoaderRepository; - - import static com.sun.jmx.defaults.JmxProperties.MBEANSERVER_LOGGER; -@@ -1413,6 +1414,8 @@ - // Default is true. - final boolean fairLock = DEFAULT_FAIR_LOCK_POLICY; - -+ checkNewMBeanServerPermission(); -+ - // This constructor happens to disregard the value of the interceptors - // flag - that is, it always uses the default value - false. - // This is admitedly a bug, but we chose not to fix it for now -@@ -1499,4 +1502,11 @@ - } - } - -+ private static void checkNewMBeanServerPermission() { -+ SecurityManager sm = System.getSecurityManager(); -+ if (sm != null) { -+ Permission perm = new MBeanServerPermission("newMBeanServer"); -+ sm.checkPermission(perm); -+ } -+ } - } -diff -Nru openjdk.orig/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanInstantiator.java openjdk/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanInstantiator.java ---- openjdk.orig/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanInstantiator.java 2011-11-14 22:11:44.000000000 +0000 -+++ openjdk/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanInstantiator.java 2013-02-15 03:40:40.511587149 +0000 -@@ -32,11 +32,13 @@ - import java.io.ObjectInputStream; - import java.lang.reflect.Constructor; - import java.lang.reflect.InvocationTargetException; -+import java.security.Permission; - import java.util.Map; - import java.util.logging.Level; - - import javax.management.InstanceNotFoundException; - import javax.management.MBeanException; -+import javax.management.MBeanPermission; - import javax.management.NotCompliantMBeanException; - import javax.management.ObjectName; - import javax.management.OperationsException; -@@ -44,7 +46,7 @@ - import javax.management.RuntimeErrorException; - import javax.management.RuntimeMBeanException; - import javax.management.RuntimeOperationsException; -- -+import sun.reflect.misc.ConstructorUtil; - import sun.reflect.misc.ReflectUtil; - - /** -@@ -56,7 +58,6 @@ - * @since 1.5 - */ - public class MBeanInstantiator { -- - private final ModifiableClassLoaderRepository clr; - // private MetaData meta = null; - -@@ -88,6 +89,7 @@ - "Exception occurred during object instantiation"); - } - -+ ReflectUtil.checkPackageAccess(className); - try { - if (clr == null) throw new ClassNotFoundException(className); - theClass = clr.loadClass(className); -@@ -162,6 +164,7 @@ - continue; - } - -+ ReflectUtil.checkPackageAccess(signature[i]); - // Ok we do not have a primitive type ! We need to build - // the signature of the method - // -@@ -205,6 +208,9 @@ - */ - public Object instantiate(Class theClass) - throws ReflectionException, MBeanException { -+ -+ checkMBeanPermission(theClass, null, null, "instantiate"); -+ - Object moi = null; - - -@@ -260,6 +266,9 @@ - public Object instantiate(Class theClass, Object params[], - String signature[], ClassLoader loader) - throws ReflectionException, MBeanException { -+ -+ checkMBeanPermission(theClass, null, null, "instantiate"); -+ - // Instantiate the new object - - // ------------------------------ -@@ -408,6 +417,8 @@ - throw new RuntimeOperationsException(new - IllegalArgumentException(), "Null className passed in parameter"); - } -+ -+ ReflectUtil.checkPackageAccess(className); - Class theClass = null; - if (loaderName == null) { - // Load the class using the agent class loader -@@ -620,13 +631,13 @@ - **/ - static Class loadClass(String className, ClassLoader loader) - throws ReflectionException { -- - Class theClass = null; - if (className == null) { - throw new RuntimeOperationsException(new - IllegalArgumentException("The class name cannot be null"), - "Exception occurred during object instantiation"); - } -+ ReflectUtil.checkPackageAccess(className); - try { - if (loader == null) - loader = MBeanInstantiator.class.getClassLoader(); -@@ -677,6 +688,7 @@ - // We need to load the class through the class - // loader of the target object. - // -+ ReflectUtil.checkPackageAccess(signature[i]); - tab[i] = Class.forName(signature[i], false, aLoader); - } - } catch (ClassNotFoundException e) { -@@ -702,7 +714,7 @@ - - private Constructor<?> findConstructor(Class<?> c, Class<?>[] params) { - try { -- return c.getConstructor(params); -+ return ConstructorUtil.getConstructor(c, params); - } catch (Exception e) { - return null; - } -@@ -716,4 +728,18 @@ - char.class, boolean.class}) - primitiveClasses.put(c.getName(), c); - } -+ -+ private static void checkMBeanPermission(Class<?> clazz, -+ String member, -+ ObjectName objectName, -+ String actions) { -+ SecurityManager sm = System.getSecurityManager(); -+ if (clazz != null && sm != null) { -+ Permission perm = new MBeanPermission(clazz.getName(), -+ member, -+ objectName, -+ actions); -+ sm.checkPermission(perm); -+ } -+ } - } -diff -Nru openjdk.orig/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanSupport.java openjdk/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanSupport.java ---- openjdk.orig/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanSupport.java 2011-11-14 22:11:44.000000000 +0000 -+++ openjdk/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanSupport.java 2013-02-15 03:40:40.511587149 +0000 -@@ -38,6 +38,7 @@ - import javax.management.NotCompliantMBeanException; - import javax.management.ObjectName; - import javax.management.ReflectionException; -+import sun.reflect.misc.ReflectUtil; - - /** - * Base class for MBeans. There is one instance of this class for -@@ -131,6 +132,7 @@ - " is not an instance of " + mbeanInterface.getName(); - throw new NotCompliantMBeanException(msg); - } -+ ReflectUtil.checkPackageAccess(mbeanInterface); - this.resource = resource; - MBeanIntrospector<M> introspector = getMBeanIntrospector(); - this.perInterface = introspector.getPerInterface(mbeanInterface); -diff -Nru openjdk.orig/jdk/src/share/classes/sun/management/LockDataConverter.java openjdk/jdk/src/share/classes/sun/management/LockDataConverter.java ---- openjdk.orig/jdk/src/share/classes/sun/management/LockDataConverter.java 2011-11-14 22:12:00.000000000 +0000 -+++ openjdk/jdk/src/share/classes/sun/management/LockDataConverter.java 2013-02-15 03:40:40.511587149 +0000 -@@ -27,6 +27,8 @@ - - import java.lang.management.LockInfo; - import java.lang.management.ThreadInfo; -+import java.security.AccessController; -+import java.security.PrivilegedAction; - import javax.management.Attribute; - import javax.management.StandardMBean; - import javax.management.openmbean.CompositeData; -@@ -40,13 +42,13 @@ - private LockInfo lockInfo; - private LockInfo[] lockedSyncs; - -- LockDataConverter() { -+ private LockDataConverter() { - super(LockDataConverterMXBean.class, true); - this.lockInfo = null; - this.lockedSyncs = null; - } - -- LockDataConverter(ThreadInfo ti) { -+ private LockDataConverter(ThreadInfo ti) { - super(LockDataConverterMXBean.class, true); - this.lockInfo = ti.getLockInfo(); - this.lockedSyncs = ti.getLockedSynchronizers(); -@@ -104,8 +106,24 @@ - } - - static CompositeData toLockInfoCompositeData(LockInfo l) { -- LockDataConverter ldc = new LockDataConverter(); -+ LockDataConverter ldc = newLockDataConverter(); - ldc.setLockInfo(l); - return ldc.toLockInfoCompositeData(); - } -+ -+ static LockDataConverter newLockDataConverter() { -+ return AccessController.doPrivileged(new PrivilegedAction<LockDataConverter>() { -+ public LockDataConverter run() { -+ return new LockDataConverter(); -+ } -+ }); -+ } -+ -+ static LockDataConverter newLockDataConverter(final ThreadInfo ti) { -+ LockDataConverter result = newLockDataConverter(); -+ result.lockInfo = ti.getLockInfo(); -+ result.lockedSyncs = ti.getLockedSynchronizers(); -+ return result; -+ } - } -+ -diff -Nru openjdk.orig/jdk/src/share/classes/sun/management/ThreadInfoCompositeData.java openjdk/jdk/src/share/classes/sun/management/ThreadInfoCompositeData.java ---- openjdk.orig/jdk/src/share/classes/sun/management/ThreadInfoCompositeData.java 2011-11-14 22:12:01.000000000 +0000 -+++ openjdk/jdk/src/share/classes/sun/management/ThreadInfoCompositeData.java 2013-02-15 03:40:40.511587149 +0000 -@@ -85,7 +85,7 @@ - } - - // Convert MonitorInfo[] and LockInfo[] to CompositeData[] -- LockDataConverter converter = new LockDataConverter(threadInfo); -+ LockDataConverter converter = LockDataConverter.newLockDataConverter(threadInfo); - CompositeData lockInfoData = converter.toLockInfoCompositeData(); - CompositeData[] lockedSyncsData = converter.toLockedSynchronizersCompositeData(); - -@@ -315,7 +315,7 @@ - - // 6.0 new attributes - public LockInfo lockInfo() { -- LockDataConverter converter = new LockDataConverter(); -+ LockDataConverter converter = LockDataConverter.newLockDataConverter(); - CompositeData lockInfoData = (CompositeData) cdata.get(LOCK_INFO); - return converter.toLockInfo(lockInfoData); - } -@@ -336,7 +336,7 @@ - } - - public LockInfo[] lockedSynchronizers() { -- LockDataConverter converter = new LockDataConverter(); -+ LockDataConverter converter = LockDataConverter.newLockDataConverter(); - CompositeData[] lockedSyncsData = - (CompositeData[]) cdata.get(LOCKED_SYNCS); - -diff -Nru openjdk.orig/jdk/src/share/lib/security/java.security openjdk/jdk/src/share/lib/security/java.security ---- openjdk.orig/jdk/src/share/lib/security/java.security 2013-02-15 03:39:56.922892783 +0000 -+++ openjdk/jdk/src/share/lib/security/java.security 2013-02-15 03:40:40.511587149 +0000 -@@ -131,8 +131,7 @@ - com.sun.xml.internal.,\ - com.sun.imageio.,\ - com.sun.istack.internal.,\ -- com.sun.jmx.defaults.,\ -- com.sun.jmx.remote.util. -+ com.sun.jmx. - - # - # List of comma-separated packages that start with or equal this string -@@ -148,8 +147,7 @@ - com.sun.xml.internal.,\ - com.sun.imageio.,\ - com.sun.istack.internal.,\ -- com.sun.jmx.defaults.,\ -- com.sun.jmx.remote.util. -+ com.sun.jmx. - - # - # Determines whether this properties file can be appended to -diff -Nru openjdk.orig/jdk/src/share/lib/security/java.security-solaris openjdk/jdk/src/share/lib/security/java.security-solaris ---- openjdk.orig/jdk/src/share/lib/security/java.security-solaris 2013-02-15 03:39:56.902892466 +0000 -+++ openjdk/jdk/src/share/lib/security/java.security-solaris 2013-02-15 03:41:36.996489851 +0000 -@@ -131,6 +131,8 @@ - package.access=sun.,\ - com.sun.xml.internal.,\ - com.sun.imageio. -+ com.sun.istack.internal.,\ -+ com.sun.jmx. - - # - # List of comma-separated packages that start with or equal this string -@@ -145,6 +147,8 @@ - package.definition=sun.,\ - com.sun.xml.internal.,\ - com.sun.imageio. -+ com.sun.istack.internal.,\ -+ com.sun.jmx. - - # - # Determines whether this properties file can be appended to -diff -Nru openjdk.orig/jdk/src/share/lib/security/java.security-windows openjdk/jdk/src/share/lib/security/java.security-windows ---- openjdk.orig/jdk/src/share/lib/security/java.security-windows 2013-02-15 03:39:56.902892466 +0000 -+++ openjdk/jdk/src/share/lib/security/java.security-windows 2013-02-15 03:42:05.304943135 +0000 -@@ -131,6 +131,8 @@ - package.access=sun.,\ - com.sun.xml.internal.,\ - com.sun.imageio. -+ com.sun.istack.internal.,\ -+ com.sun.jmx. - - # - # List of comma-separated packages that start with or equal this string -@@ -145,6 +147,8 @@ - package.definition=sun.,\ - com.sun.xml.internal.,\ - com.sun.imageio. -+ com.sun.istack.internal.,\ -+ com.sun.jmx. - - # - # Determines whether this properties file can be appended to -diff -Nru openjdk.orig/jdk/test/javax/management/remote/mandatory/subjectDelegation/SubjectDelegation2Test.java openjdk/jdk/test/javax/management/remote/mandatory/subjectDelegation/SubjectDelegation2Test.java ---- openjdk.orig/jdk/test/javax/management/remote/mandatory/subjectDelegation/SubjectDelegation2Test.java 2011-11-14 22:12:28.000000000 +0000 -+++ openjdk/jdk/test/javax/management/remote/mandatory/subjectDelegation/SubjectDelegation2Test.java 2013-02-15 03:40:40.511587149 +0000 -@@ -119,9 +119,6 @@ - System.out.println("Create SimpleStandard MBean"); - SimpleStandard s = new SimpleStandard("monitorRole"); - mbs.registerMBean(s, new ObjectName("MBeans:type=SimpleStandard")); -- // Set Security Manager -- // -- System.setSecurityManager(new SecurityManager()); - // Create Properties containing the username/password entries - // - Properties props = new Properties(); -@@ -132,6 +129,9 @@ - HashMap env = new HashMap(); - env.put("jmx.remote.authenticator", - new JMXPluggableAuthenticator(props)); -+ // Set Security Manager -+ // -+ System.setSecurityManager(new SecurityManager()); - // Create an RMI connector server - // - System.out.println("Create an RMI connector server"); -diff -Nru openjdk.orig/jdk/test/javax/management/remote/mandatory/subjectDelegation/SubjectDelegation3Test.java openjdk/jdk/test/javax/management/remote/mandatory/subjectDelegation/SubjectDelegation3Test.java ---- openjdk.orig/jdk/test/javax/management/remote/mandatory/subjectDelegation/SubjectDelegation3Test.java 2011-11-14 22:12:28.000000000 +0000 -+++ openjdk/jdk/test/javax/management/remote/mandatory/subjectDelegation/SubjectDelegation3Test.java 2013-02-15 03:40:40.511587149 +0000 -@@ -120,9 +120,6 @@ - System.out.println("Create SimpleStandard MBean"); - SimpleStandard s = new SimpleStandard("delegate"); - mbs.registerMBean(s, new ObjectName("MBeans:type=SimpleStandard")); -- // Set Security Manager -- // -- System.setSecurityManager(new SecurityManager()); - // Create Properties containing the username/password entries - // - Properties props = new Properties(); -@@ -133,6 +130,9 @@ - HashMap env = new HashMap(); - env.put("jmx.remote.authenticator", - new JMXPluggableAuthenticator(props)); -+ // Set Security Manager -+ // -+ System.setSecurityManager(new SecurityManager()); - // Create an RMI connector server - // - System.out.println("Create an RMI connector server");
--- a/patches/security/20130219/8006777.patch Tue Mar 19 00:21:31 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1036 +0,0 @@ -# HG changeset patch -# User coffeys -# Date 1360882104 0 -# Node ID 85b3b034fdecdc94f082efa8d74e014366502deb -# Parent 617e68a3948824283f15c36fcd8cf264c1dd0a99 -8006777: Improve TLS handling of invalid messages -Reviewed-by: wetmore - -diff --git a/src/share/classes/sun/security/ssl/CipherBox.java b/src/share/classes/sun/security/ssl/CipherBox.java ---- openjdk/jdk/src/share/classes/sun/security/ssl/CipherBox.java -+++ openjdk/jdk/src/share/classes/sun/security/ssl/CipherBox.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -244,7 +244,8 @@ final class CipherBox { - * Decrypts a block of data, returning the size of the - * resulting block if padding was required. - */ -- int decrypt(byte[] buf, int offset, int len) throws BadPaddingException { -+ int decrypt(byte[] buf, int offset, int len, -+ int tagLen) throws BadPaddingException { - if (cipher == null) { - return len; - } -@@ -268,8 +269,8 @@ final class CipherBox { - } catch (IOException e) { } - } - if (blockSize != 0) { -- newLen = removePadding(buf, offset, newLen, -- blockSize, protocolVersion); -+ newLen = removePadding( -+ buf, offset, newLen, tagLen, blockSize, protocolVersion); - } - return newLen; - } catch (ShortBufferException e) { -@@ -285,7 +286,7 @@ final class CipherBox { - * limit and new limit may be different, given we may - * have stripped off some padding bytes. - */ -- int decrypt(ByteBuffer bb) throws BadPaddingException { -+ int decrypt(ByteBuffer bb, int tagLen) throws BadPaddingException { - - int len = bb.remaining(); - -@@ -309,7 +310,6 @@ final class CipherBox { - } - - if (debug != null && Debug.isOn("plaintext")) { -- bb.position(pos); - try { - HexDumpEncoder hd = new HexDumpEncoder(); - -@@ -317,7 +317,8 @@ final class CipherBox { - "Padded plaintext after DECRYPTION: len = " - + newLen); - -- hd.encodeBuffer(bb, System.out); -+ hd.encodeBuffer( -+ (ByteBuffer)bb.duplicate().position(pos), System.out); - } catch (IOException e) { } - } - -@@ -326,7 +327,8 @@ final class CipherBox { - */ - if (blockSize != 0) { - bb.position(pos); -- newLen = removePadding(bb, blockSize, protocolVersion); -+ newLen = removePadding( -+ bb, tagLen, blockSize, protocolVersion); - } - return newLen; - } catch (ShortBufferException e) { -@@ -400,6 +402,65 @@ final class CipherBox { - return newlen; - } - -+ /* -+ * A constant-time check of the padding. -+ * -+ * NOTE that we are checking both the padding and the padLen bytes here. -+ * -+ * The caller MUST ensure that the len parameter is a positive number. -+ */ -+ private static int[] checkPadding( -+ byte[] buf, int offset, int len, byte pad) { -+ -+ if (len <= 0) { -+ throw new RuntimeException("padding len must be positive"); -+ } -+ -+ // An array of hits is used to prevent Hotspot optimization for -+ // the purpose of a constant-time check -+ int[] results = {0, 0}; // {missed #, matched #} -+ for (int i = 0; i <= 256;) { -+ for (int j = 0; j < len && i <= 256; j++, i++) { // j <= i -+ if (buf[offset + j] != pad) { -+ results[0]++; // mismatched padding data -+ } else { -+ results[1]++; // matched padding data -+ } -+ } -+ } -+ -+ return results; -+ } -+ -+ /* -+ * A constant-time check of the padding. -+ * -+ * NOTE that we are checking both the padding and the padLen bytes here. -+ * -+ * The caller MUST ensure that the bb parameter has remaining. -+ */ -+ private static int[] checkPadding(ByteBuffer bb, byte pad) { -+ -+ if (!bb.hasRemaining()) { -+ throw new RuntimeException("hasRemaining() must be positive"); -+ } -+ -+ // An array of hits is used to prevent Hotspot optimization for -+ // the purpose of a constant-time check. -+ int[] results = {0, 0}; // {missed #, matched #} -+ bb.mark(); -+ for (int i = 0; i <= 256; bb.reset()) { -+ for (; bb.hasRemaining() && i <= 256; i++) { -+ if (bb.get() != pad) { -+ results[0]++; // mismatched padding data -+ } else { -+ results[1]++; // matched padding data -+ } -+ } -+ } -+ -+ return results; -+ } - - /* - * Typical TLS padding format for a 64 bit block cipher is as follows: -@@ -412,86 +473,95 @@ final class CipherBox { - * as it makes the data a multiple of the block size - */ - private static int removePadding(byte[] buf, int offset, int len, -- int blockSize, ProtocolVersion protocolVersion) -- throws BadPaddingException { -+ int tagLen, int blockSize, -+ ProtocolVersion protocolVersion) throws BadPaddingException { -+ - // last byte is length byte (i.e. actual padding length - 1) - int padOffset = offset + len - 1; -- int pad = buf[padOffset] & 0x0ff; -+ int padLen = buf[padOffset] & 0xFF; - -- int newlen = len - (pad + 1); -- if (newlen < 0) { -- throw new BadPaddingException("Padding length invalid: " + pad); -+ int newLen = len - (padLen + 1); -+ if ((newLen - tagLen) < 0) { -+ // If the buffer is not long enough to contain the padding plus -+ // a MAC tag, do a dummy constant-time padding check. -+ // -+ // Note that it is a dummy check, so we won't care about what is -+ // the actual padding data. -+ checkPadding(buf, offset, len, (byte)(padLen & 0xFF)); -+ -+ throw new BadPaddingException("Invalid Padding length: " + padLen); - } - -+ // The padding data should be filled with the padding length value. -+ int[] results = checkPadding(buf, offset + newLen, -+ padLen + 1, (byte)(padLen & 0xFF)); - if (protocolVersion.v >= ProtocolVersion.TLS10.v) { -- for (int i = 1; i <= pad; i++) { -- int val = buf[padOffset - i] & 0xff; -- if (val != pad) { -- throw new BadPaddingException -- ("Invalid TLS padding: " + val); -- } -+ if (results[0] != 0) { // padding data has invalid bytes -+ throw new BadPaddingException("Invalid TLS padding data"); - } - } else { // SSLv3 - // SSLv3 requires 0 <= length byte < block size - // some implementations do 1 <= length byte <= block size, - // so accept that as well - // v3 does not require any particular value for the other bytes -- if (pad > blockSize) { -- throw new BadPaddingException("Invalid SSLv3 padding: " + pad); -+ if (padLen > blockSize) { -+ throw new BadPaddingException("Invalid SSLv3 padding"); - } - } -- return newlen; -+ return newLen; - } - - /* - * Position/limit is equal the removed padding. - */ - private static int removePadding(ByteBuffer bb, -- int blockSize, ProtocolVersion protocolVersion) -- throws BadPaddingException { -+ int tagLen, int blockSize, -+ ProtocolVersion protocolVersion) throws BadPaddingException { - - int len = bb.remaining(); - int offset = bb.position(); - - // last byte is length byte (i.e. actual padding length - 1) - int padOffset = offset + len - 1; -- int pad = bb.get(padOffset) & 0x0ff; -+ int padLen = bb.get(padOffset) & 0xFF; - -- int newlen = len - (pad + 1); -- if (newlen < 0) { -- throw new BadPaddingException("Padding length invalid: " + pad); -+ int newLen = len - (padLen + 1); -+ if ((newLen - tagLen) < 0) { -+ // If the buffer is not long enough to contain the padding plus -+ // a MAC tag, do a dummy constant-time padding check. -+ // -+ // Note that it is a dummy check, so we won't care about what is -+ // the actual padding data. -+ checkPadding(bb.duplicate(), (byte)(padLen & 0xFF)); -+ -+ throw new BadPaddingException("Invalid Padding length: " + padLen); - } - -- /* -- * We could zero the padding area, but not much useful -- * information there. -- */ -+ // The padding data should be filled with the padding length value. -+ int[] results = checkPadding( -+ (ByteBuffer)bb.duplicate().position(offset + newLen), -+ (byte)(padLen & 0xFF)); - if (protocolVersion.v >= ProtocolVersion.TLS10.v) { -- bb.put(padOffset, (byte)0); // zero the padding. -- for (int i = 1; i <= pad; i++) { -- int val = bb.get(padOffset - i) & 0xff; -- if (val != pad) { -- throw new BadPaddingException -- ("Invalid TLS padding: " + val); -- } -+ if (results[0] != 0) { // padding data has invalid bytes -+ throw new BadPaddingException("Invalid TLS padding data"); - } - } else { // SSLv3 - // SSLv3 requires 0 <= length byte < block size - // some implementations do 1 <= length byte <= block size, - // so accept that as well - // v3 does not require any particular value for the other bytes -- if (pad > blockSize) { -- throw new BadPaddingException("Invalid SSLv3 padding: " + pad); -+ if (padLen > blockSize) { -+ throw new BadPaddingException("Invalid SSLv3 padding"); - } - } - - /* - * Reset buffer limit to remove padding. - */ -- bb.position(offset + newlen); -- bb.limit(offset + newlen); -+ bb.position(offset + newLen); -+ bb.limit(offset + newLen); - -- return newlen; -+ return newLen; - } - - /* -@@ -502,4 +572,40 @@ final class CipherBox { - boolean isCBCMode() { - return isCBCMode; - } -+ -+ /** -+ * Is the cipher null? -+ * -+ * @return true if the cipher is null, false otherwise. -+ */ -+ boolean isNullCipher() { -+ return cipher == null; -+ } -+ -+ /** -+ * Sanity check the length of a fragment before decryption. -+ * -+ * In CBC mode, check that the fragment length is one or multiple times -+ * of the block size of the cipher suite, and is at least one (one is the -+ * smallest size of padding in CBC mode) bigger than the tag size of the -+ * MAC algorithm. -+ * -+ * In non-CBC mode, check that the fragment length is not less than the -+ * tag size of the MAC algorithm. -+ * -+ * @return true if the length of a fragment matches above requirements -+ */ -+ boolean sanityCheck(int tagLen, int fragmentLen) { -+ if (!isCBCMode) { -+ return fragmentLen >= tagLen; -+ } -+ -+ if ((fragmentLen % blockSize) == 0) { -+ int minimal = tagLen + 1; -+ minimal = (minimal >= blockSize) ? minimal : blockSize; -+ return (fragmentLen >= minimal); -+ } -+ -+ return false; -+ } - } -diff --git a/src/share/classes/sun/security/ssl/CipherSuite.java b/src/share/classes/sun/security/ssl/CipherSuite.java ---- openjdk/jdk/src/share/classes/sun/security/ssl/CipherSuite.java -+++ openjdk/jdk/src/share/classes/sun/security/ssl/CipherSuite.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -451,9 +451,18 @@ final class CipherSuite implements Compa - // size of the MAC value (and MAC key) in bytes - final int size; - -- MacAlg(String name, int size) { -+ // block size of the underlying hash algorithm -+ final int hashBlockSize; -+ -+ // minimal padding size of the underlying hash algorithm -+ final int minimalPaddingSize; -+ -+ MacAlg(String name, int size, -+ int hashBlockSize, int minimalPaddingSize) { - this.name = name; - this.size = size; -+ this.hashBlockSize = hashBlockSize; -+ this.minimalPaddingSize = minimalPaddingSize; - } - - /** -@@ -497,9 +506,9 @@ final class CipherSuite implements Compa - new BulkCipher(CIPHER_AES, 32, 16, true); - - // MACs -- final static MacAlg M_NULL = new MacAlg("NULL", 0); -- final static MacAlg M_MD5 = new MacAlg("MD5", 16); -- final static MacAlg M_SHA = new MacAlg("SHA", 20); -+ final static MacAlg M_NULL = new MacAlg("NULL", 0, 0, 0); -+ final static MacAlg M_MD5 = new MacAlg("MD5", 16, 64, 9); -+ final static MacAlg M_SHA = new MacAlg("SHA", 20, 64, 9); - - static { - idMap = new HashMap<Integer,CipherSuite>(); -diff --git a/src/share/classes/sun/security/ssl/EngineInputRecord.java b/src/share/classes/sun/security/ssl/EngineInputRecord.java ---- openjdk/jdk/src/share/classes/sun/security/ssl/EngineInputRecord.java -+++ openjdk/jdk/src/share/classes/sun/security/ssl/EngineInputRecord.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -177,71 +177,6 @@ final class EngineInputRecord extends In - } - - /* -- * Verifies and removes the MAC value. Returns true if -- * the MAC checks out OK. -- * -- * On entry: -- * position = beginning of app/MAC data -- * limit = end of MAC data. -- * -- * On return: -- * position = beginning of app data -- * limit = end of app data -- */ -- boolean checkMAC(MAC signer, ByteBuffer bb) { -- if (internalData) { -- return checkMAC(signer); -- } -- -- int len = signer.MAClen(); -- if (len == 0) { // no mac -- return true; -- } -- -- /* -- * Grab the original limit -- */ -- int lim = bb.limit(); -- -- /* -- * Delineate the area to apply a MAC on. -- */ -- int macData = lim - len; -- bb.limit(macData); -- -- byte[] mac = signer.compute(contentType(), bb); -- -- if (len != mac.length) { -- throw new RuntimeException("Internal MAC error"); -- } -- -- /* -- * Delineate the MAC values, position was already set -- * by doing the compute above. -- * -- * We could zero the MAC area, but not much useful information -- * there anyway. -- */ -- bb.position(macData); -- bb.limit(lim); -- -- try { -- for (int i = 0; i < len; i++) { -- if (bb.get() != mac[i]) { // No BB.equals(byte []); ! -- return false; -- } -- } -- return true; -- } finally { -- /* -- * Position to the data. -- */ -- bb.rewind(); -- bb.limit(macData); -- } -- } -- -- /* - * Pass the data down if it's internally cached, otherwise - * do it here. - * -@@ -250,18 +185,161 @@ final class EngineInputRecord extends In - * If external data(app), return a new ByteBuffer with data to - * process. - */ -- ByteBuffer decrypt(CipherBox box, ByteBuffer bb) -- throws BadPaddingException { -+ ByteBuffer decrypt(MAC signer, -+ CipherBox box, ByteBuffer bb) throws BadPaddingException { - - if (internalData) { -- decrypt(box); -+ decrypt(signer, box); // MAC is checked during decryption - return tmpBB; - } - -- box.decrypt(bb); -- bb.rewind(); -+ BadPaddingException reservedBPE = null; -+ int tagLen = signer.MAClen(); -+ int cipheredLength = bb.remaining(); -+ -+ if (!box.isNullCipher()) { -+ // sanity check length of the ciphertext -+ if (!box.sanityCheck(tagLen, cipheredLength)) { -+ throw new BadPaddingException( -+ "ciphertext sanity check failed"); -+ } -+ -+ try { -+ // Note that the CipherBox.decrypt() does not change -+ // the capacity of the buffer. -+ box.decrypt(bb, tagLen); -+ } catch (BadPaddingException bpe) { -+ // RFC 2246 states that decryption_failed should be used -+ // for this purpose. However, that allows certain attacks, -+ // so we just send bad record MAC. We also need to make -+ // sure to always check the MAC to avoid a timing attack -+ // for the same issue. See paper by Vaudenay et al and the -+ // update in RFC 4346/5246. -+ // -+ // Failover to message authentication code checking. -+ reservedBPE = bpe; -+ } finally { -+ bb.rewind(); -+ } -+ } -+ -+ if (tagLen != 0) { -+ int macOffset = bb.limit() - tagLen; -+ -+ // Note that although it is not necessary, we run the same MAC -+ // computation and comparison on the payload for both stream -+ // cipher and CBC block cipher. -+ if (bb.remaining() < tagLen) { -+ // negative data length, something is wrong -+ if (reservedBPE == null) { -+ reservedBPE = new BadPaddingException("bad record"); -+ } -+ -+ // set offset of the dummy MAC -+ macOffset = cipheredLength - tagLen; -+ bb.limit(cipheredLength); -+ } -+ -+ // Run MAC computation and comparison on the payload. -+ if (checkMacTags(contentType(), bb, signer, false)) { -+ if (reservedBPE == null) { -+ reservedBPE = new BadPaddingException("bad record MAC"); -+ } -+ } -+ -+ // Run MAC computation and comparison on the remainder. -+ // -+ // It is only necessary for CBC block cipher. It is used to get a -+ // constant time of MAC computation and comparison on each record. -+ if (box.isCBCMode()) { -+ int remainingLen = calculateRemainingLen( -+ signer, cipheredLength, macOffset); -+ -+ // NOTE: here we use the InputRecord.buf because I did not find -+ // an effective way to work on ByteBuffer when its capacity is -+ // less than remainingLen. -+ -+ // NOTE: remainingLen may be bigger (less than 1 block of the -+ // hash algorithm of the MAC) than the cipheredLength. However, -+ // We won't need to worry about it because we always use a -+ // maximum buffer for every record. We need a change here if -+ // we use small buffer size in the future. -+ if (remainingLen > buf.length) { -+ // unlikely to happen, just a placehold -+ throw new RuntimeException( -+ "Internal buffer capacity error"); -+ } -+ -+ // Won't need to worry about the result on the remainder. And -+ // then we won't need to worry about what's actual data to -+ // check MAC tag on. We start the check from the header of the -+ // buffer so that we don't need to construct a new byte buffer. -+ checkMacTags(contentType(), buf, 0, remainingLen, signer, true); -+ } -+ -+ bb.limit(macOffset); -+ } -+ -+ // Is it a failover? -+ if (reservedBPE != null) { -+ throw reservedBPE; -+ } - - return bb.slice(); -+ } -+ -+ /* -+ * Run MAC computation and comparison -+ * -+ * Please DON'T change the content of the ByteBuffer parameter! -+ */ -+ private static boolean checkMacTags(byte contentType, ByteBuffer bb, -+ MAC signer, boolean isSimulated) { -+ -+ int tagLen = signer.MAClen(); -+ int lim = bb.limit(); -+ int macData = lim - tagLen; -+ -+ bb.limit(macData); -+ byte[] hash = signer.compute(contentType, bb, isSimulated); -+ if (hash == null || tagLen != hash.length) { -+ // Something is wrong with MAC implementation. -+ throw new RuntimeException("Internal MAC error"); -+ } -+ -+ bb.position(macData); -+ bb.limit(lim); -+ try { -+ int[] results = compareMacTags(bb, hash); -+ return (results[0] != 0); -+ } finally { -+ bb.rewind(); -+ bb.limit(macData); -+ } -+ } -+ -+ /* -+ * A constant-time comparison of the MAC tags. -+ * -+ * Please DON'T change the content of the ByteBuffer parameter! -+ */ -+ private static int[] compareMacTags(ByteBuffer bb, byte[] tag) { -+ -+ // An array of hits is used to prevent Hotspot optimization for -+ // the purpose of a constant-time check. -+ int[] results = {0, 0}; // {missed #, matched #} -+ -+ // The caller ensures there are enough bytes available in the buffer. -+ // So we won't need to check the remaining of the buffer. -+ for (int i = 0; i < tag.length; i++) { -+ if (bb.get() != tag[i]) { -+ results[0]++; // mismatched bytes -+ } else { -+ results[1]++; // matched bytes -+ } -+ } -+ -+ return results; - } - - /* -diff --git a/src/share/classes/sun/security/ssl/EngineOutputRecord.java b/src/share/classes/sun/security/ssl/EngineOutputRecord.java ---- openjdk/jdk/src/share/classes/sun/security/ssl/EngineOutputRecord.java -+++ openjdk/jdk/src/share/classes/sun/security/ssl/EngineOutputRecord.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -120,7 +120,7 @@ final class EngineOutputRecord extends O - throws IOException { - - if (signer.MAClen() != 0) { -- byte[] hash = signer.compute(contentType(), bb); -+ byte[] hash = signer.compute(contentType(), bb, false); - - /* - * position was advanced to limit in compute above. -diff --git a/src/share/classes/sun/security/ssl/InputRecord.java b/src/share/classes/sun/security/ssl/InputRecord.java ---- openjdk/jdk/src/share/classes/sun/security/ssl/InputRecord.java -+++ openjdk/jdk/src/share/classes/sun/security/ssl/InputRecord.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 1996, 2007, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -135,43 +135,173 @@ class InputRecord extends ByteArrayInput - return handshakeHash; - } - -- /* -- * Verify and remove the MAC ... used for all records. -- */ -- boolean checkMAC(MAC signer) { -- int len = signer.MAClen(); -- if (len == 0) { // no mac -- return true; -+ void decrypt(MAC signer, CipherBox box) throws BadPaddingException { -+ -+ BadPaddingException reservedBPE = null; -+ int tagLen = signer.MAClen(); -+ int cipheredLength = count - headerSize; -+ -+ if (!box.isNullCipher()) { -+ // sanity check length of the ciphertext -+ if (!box.sanityCheck(tagLen, cipheredLength)) { -+ throw new BadPaddingException( -+ "ciphertext sanity check failed"); -+ } -+ -+ try { -+ // Note that the CipherBox.decrypt() does not change -+ // the capacity of the buffer. -+ count = headerSize + -+ box.decrypt(buf, headerSize, cipheredLength, tagLen); -+ } catch (BadPaddingException bpe) { -+ // RFC 2246 states that decryption_failed should be used -+ // for this purpose. However, that allows certain attacks, -+ // so we just send bad record MAC. We also need to make -+ // sure to always check the MAC to avoid a timing attack -+ // for the same issue. See paper by Vaudenay et al and the -+ // update in RFC 4346/5246. -+ // -+ // Failover to message authentication code checking. -+ reservedBPE = bpe; -+ } - } - -- int offset = count - len; -+ if (tagLen != 0) { -+ int macOffset = count - tagLen; -+ int contentLen = macOffset - headerSize; - -- if (offset < headerSize) { -- // data length would be negative, something is wrong -- return false; -+ // Note that although it is not necessary, we run the same MAC -+ // computation and comparison on the payload for both stream -+ // cipher and CBC block cipher. -+ if (contentLen < 0) { -+ // negative data length, something is wrong -+ if (reservedBPE == null) { -+ reservedBPE = new BadPaddingException("bad record"); -+ } -+ -+ // set offset of the dummy MAC -+ macOffset = headerSize + cipheredLength - tagLen; -+ contentLen = macOffset - headerSize; -+ } -+ -+ count -= tagLen; // Set the count before any MAC checking -+ // exception occurs, so that the following -+ // process can read the actual decrypted -+ // content (minus the MAC) in the fragment -+ // if necessary. -+ -+ // Run MAC computation and comparison on the payload. -+ if (checkMacTags(contentType(), -+ buf, headerSize, contentLen, signer, false)) { -+ if (reservedBPE == null) { -+ reservedBPE = new BadPaddingException("bad record MAC"); -+ } -+ } -+ -+ // Run MAC computation and comparison on the remainder. -+ // -+ // It is only necessary for CBC block cipher. It is used to get a -+ // constant time of MAC computation and comparison on each record. -+ if (box.isCBCMode()) { -+ int remainingLen = calculateRemainingLen( -+ signer, cipheredLength, contentLen); -+ -+ // NOTE: remainingLen may be bigger (less than 1 block of the -+ // hash algorithm of the MAC) than the cipheredLength. However, -+ // We won't need to worry about it because we always use a -+ // maximum buffer for every record. We need a change here if -+ // we use small buffer size in the future. -+ if (remainingLen > buf.length) { -+ // unlikely to happen, just a placehold -+ throw new RuntimeException( -+ "Internal buffer capacity error"); -+ } -+ -+ // Won't need to worry about the result on the remainder. And -+ // then we won't need to worry about what's actual data to -+ // check MAC tag on. We start the check from the header of the -+ // buffer so that we don't need to construct a new byte buffer. -+ checkMacTags(contentType(), buf, 0, remainingLen, signer, true); -+ } - } - -- byte[] mac = signer.compute(contentType(), buf, -- headerSize, offset - headerSize); -+ // Is it a failover? -+ if (reservedBPE != null) { -+ throw reservedBPE; -+ } -+ } - -- if (len != mac.length) { -+ /* -+ * Run MAC computation and comparison -+ * -+ * Please DON'T change the content of the byte buffer parameter! -+ */ -+ static boolean checkMacTags(byte contentType, byte[] buffer, -+ int offset, int contentLen, MAC signer, boolean isSimulated) { -+ -+ int tagLen = signer.MAClen(); -+ byte[] hash = signer.compute( -+ contentType, buffer, offset, contentLen, isSimulated); -+ if (hash == null || tagLen != hash.length) { -+ // Something is wrong with MAC implementation. - throw new RuntimeException("Internal MAC error"); - } - -- for (int i = 0; i < len; i++) { -- if (buf[offset + i] != mac[i]) { -- return false; -+ int[] results = compareMacTags(buffer, offset + contentLen, hash); -+ return (results[0] != 0); -+ } -+ -+ /* -+ * A constant-time comparison of the MAC tags. -+ * -+ * Please DON'T change the content of the byte buffer parameter! -+ */ -+ private static int[] compareMacTags( -+ byte[] buffer, int offset, byte[] tag) { -+ -+ // An array of hits is used to prevent Hotspot optimization for -+ // the purpose of a constant-time check. -+ int[] results = {0, 0}; // {missed #, matched #} -+ -+ // The caller ensures there are enough bytes available in the buffer. -+ // So we won't need to check the length of the buffer. -+ for (int i = 0; i < tag.length; i++) { -+ if (buffer[offset + i] != tag[i]) { -+ results[0]++; // mismatched bytes -+ } else { -+ results[1]++; // matched bytes - } - } -- count -= len; -- return true; -+ -+ return results; - } - -- void decrypt(CipherBox box) throws BadPaddingException { -- int len = count - headerSize; -- count = headerSize + box.decrypt(buf, headerSize, len); -+ /* -+ * Calculate the length of a dummy buffer to run MAC computation -+ * and comparison on the remainder. -+ * -+ * The caller MUST ensure that the fullLen is not less than usedLen. -+ */ -+ static int calculateRemainingLen( -+ MAC signer, int fullLen, int usedLen) { -+ -+ int blockLen = signer.hashBlockLen(); -+ int minimalPaddingLen = signer.minimalPaddingLen(); -+ -+ // (blockLen - minimalPaddingLen) is the maximum message size of -+ // the last block of hash function operation. See FIPS 180-4, or -+ // MD5 specification. -+ fullLen += 13 - (blockLen - minimalPaddingLen); -+ usedLen += 13 - (blockLen - minimalPaddingLen); -+ -+ // Note: fullLen is always not less than usedLen, and blockLen -+ // is always bigger than minimalPaddingLen, so we don't worry -+ // about negative values. 0x01 is added to the result to ensure -+ // that the return value is positive. The extra one byte does -+ // not impact the overall MAC compression function evaluations. -+ return 0x01 + (int)(Math.ceil(fullLen/(1.0d * blockLen)) - -+ Math.ceil(usedLen/(1.0d * blockLen))) * signer.hashBlockLen(); - } -- - - /* - * Well ... hello_request messages are _never_ hashed since we can't -diff --git a/src/share/classes/sun/security/ssl/MAC.java b/src/share/classes/sun/security/ssl/MAC.java ---- openjdk/jdk/src/share/classes/sun/security/ssl/MAC.java -+++ openjdk/jdk/src/share/classes/sun/security/ssl/MAC.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 1996, 2007, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -44,7 +44,8 @@ import static sun.security.ssl.CipherSui - * one of several keyed hashes, as associated with the cipher suite and - * protocol version. (SSL v3.0 uses one construct, TLS uses another.) - * -- * <P>NOTE: MAC computation is the only place in the SSL protocol that the -+ * <P> -+ * NOTE: MAC computation is the only place in the SSL protocol that the - * sequence number is used. It's also reset to zero with each change of - * a cipher spec, so this is the only place this state is needed. - * -@@ -129,15 +130,31 @@ final class MAC { - } - - /** -+ * Returns the hash function block length of the MAC alorithm. -+ */ -+ int hashBlockLen() { -+ return macAlg.hashBlockSize; -+ } -+ -+ /** -+ * Returns the hash function minimal padding length of the MAC alorithm. -+ */ -+ int minimalPaddingLen() { -+ return macAlg.minimalPaddingSize; -+ } -+ -+ /** - * Computes and returns the MAC for the data in this byte array. - * - * @param type record type - * @param buf compressed record on which the MAC is computed - * @param offset start of compressed record data - * @param len the size of the compressed record -+ * @param isSimulated if true, simulate the the MAC computation - */ -- final byte[] compute(byte type, byte buf[], int offset, int len) { -- return compute(type, null, buf, offset, len); -+ final byte[] compute(byte type, byte buf[], -+ int offset, int len, boolean isSimulated) { -+ return compute(type, null, buf, offset, len, isSimulated); - } - - /** -@@ -150,9 +167,10 @@ final class MAC { - * @param type record type - * @param bb a ByteBuffer in which the position and limit - * demarcate the data to be MAC'd. -+ * @param isSimulated if true, simulate the the MAC computation - */ -- final byte[] compute(byte type, ByteBuffer bb) { -- return compute(type, bb, null, 0, bb.remaining()); -+ final byte[] compute(byte type, ByteBuffer bb, boolean isSimulated) { -+ return compute(type, bb, null, 0, bb.remaining(), isSimulated); - } - - // increment the sequence number in the block array -@@ -168,18 +186,22 @@ final class MAC { - * Compute based on either buffer type, either bb.position/limit - * or buf/offset/len. - */ -- private byte[] compute(byte type, ByteBuffer bb, byte[] buf, int offset, int len) { -+ private byte[] compute(byte type, ByteBuffer bb, byte[] buf, -+ int offset, int len, boolean isSimulated) { - - if (macSize == 0) { - return nullMAC; - } - -- block[BLOCK_OFFSET_TYPE] = type; -- block[block.length - 2] = (byte)(len >> 8); -- block[block.length - 1] = (byte)(len ); -+ // MUST NOT increase the sequence number for a simulated computation. -+ if (!isSimulated) { -+ block[BLOCK_OFFSET_TYPE] = type; -+ block[block.length - 2] = (byte)(len >> 8); -+ block[block.length - 1] = (byte)(len ); - -- mac.update(block); -- incrementSequenceNumber(); -+ mac.update(block); -+ incrementSequenceNumber(); -+ } - - // content - if (bb != null) { -diff --git a/src/share/classes/sun/security/ssl/OutputRecord.java b/src/share/classes/sun/security/ssl/OutputRecord.java ---- openjdk/jdk/src/share/classes/sun/security/ssl/OutputRecord.java -+++ openjdk/jdk/src/share/classes/sun/security/ssl/OutputRecord.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -204,7 +204,7 @@ class OutputRecord extends ByteArrayOutp - } - if (signer.MAClen() != 0) { - byte[] hash = signer.compute(contentType, buf, -- headerSize, count - headerSize); -+ headerSize, count - headerSize, false); - write(hash); - } - } -diff --git a/src/share/classes/sun/security/ssl/SSLEngineImpl.java b/src/share/classes/sun/security/ssl/SSLEngineImpl.java ---- openjdk/jdk/src/share/classes/sun/security/ssl/SSLEngineImpl.java -+++ openjdk/jdk/src/share/classes/sun/security/ssl/SSLEngineImpl.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -919,34 +919,13 @@ final public class SSLEngineImpl extends - * throw a fatal alert if the integrity check fails. - */ - try { -- decryptedBB = inputRecord.decrypt(readCipher, readBB); -+ decryptedBB = inputRecord.decrypt(readMAC, readCipher, readBB); - } catch (BadPaddingException e) { -- // RFC 2246 states that decryption_failed should be used -- // for this purpose. However, that allows certain attacks, -- // so we just send bad record MAC. We also need to make -- // sure to always check the MAC to avoid a timing attack -- // for the same issue. See paper by Vaudenay et al. -- // -- // rewind the BB if necessary. -- readBB.rewind(); -- -- inputRecord.checkMAC(readMAC, readBB); -- -- // use the same alert types as for MAC failure below - byte alertType = (inputRecord.contentType() == - Record.ct_handshake) ? - Alerts.alert_handshake_failure : - Alerts.alert_bad_record_mac; -- fatal(alertType, "Invalid padding", e); -- } -- -- if (!inputRecord.checkMAC(readMAC, decryptedBB)) { -- if (inputRecord.contentType() == Record.ct_handshake) { -- fatal(Alerts.alert_handshake_failure, -- "bad handshake record MAC"); -- } else { -- fatal(Alerts.alert_bad_record_mac, "bad record MAC"); -- } -+ fatal(alertType, e.getMessage(), e); - } - - // if (!inputRecord.decompress(c)) -diff --git a/src/share/classes/sun/security/ssl/SSLSocketImpl.java b/src/share/classes/sun/security/ssl/SSLSocketImpl.java ---- openjdk/jdk/src/share/classes/sun/security/ssl/SSLSocketImpl.java -+++ openjdk/jdk/src/share/classes/sun/security/ssl/SSLSocketImpl.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -922,27 +922,12 @@ final public class SSLSocketImpl extends - * throw a fatal alert if the integrity check fails. - */ - try { -- r.decrypt(readCipher); -+ r.decrypt(readMAC, readCipher); - } catch (BadPaddingException e) { -- // RFC 2246 states that decryption_failed should be used -- // for this purpose. However, that allows certain attacks, -- // so we just send bad record MAC. We also need to make -- // sure to always check the MAC to avoid a timing attack -- // for the same issue. See paper by Vaudenay et al. -- r.checkMAC(readMAC); -- // use the same alert types as for MAC failure below - byte alertType = (r.contentType() == Record.ct_handshake) - ? Alerts.alert_handshake_failure - : Alerts.alert_bad_record_mac; -- fatal(alertType, "Invalid padding", e); -- } -- if (!r.checkMAC(readMAC)) { -- if (r.contentType() == Record.ct_handshake) { -- fatal(Alerts.alert_handshake_failure, -- "bad handshake record MAC"); -- } else { -- fatal(Alerts.alert_bad_record_mac, "bad record MAC"); -- } -+ fatal(alertType, e.getMessage(), e); - } - - // if (!r.decompress(c))
--- a/patches/security/20130219/8007688.patch Tue Mar 19 00:21:31 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,130 +0,0 @@ -# HG changeset patch -# User coffeys -# Date 1360873966 0 -# Node ID 617e68a3948824283f15c36fcd8cf264c1dd0a99 -# Parent 25e83b78298b71abb46eb5a337ed7bddef418ca4 -8007688: Blacklist known bad certificate -Reviewed-by: mullan - -diff --git a/src/share/classes/sun/security/util/UntrustedCertificates.java b/src/share/classes/sun/security/util/UntrustedCertificates.java ---- openjdk/jdk/src/share/classes/sun/security/util/UntrustedCertificates.java -+++ openjdk/jdk/src/share/classes/sun/security/util/UntrustedCertificates.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -739,5 +739,111 @@ public final class UntrustedCertificates - "B8WfedLHjFW/TMcnXlEWKz4=\n" + - "-----END CERTIFICATE-----"); - -+ // -+ // Revoked DigiCert code signing certificates used to sign malware -+ // -+ -+ // Subject: CN=Buster Paper Comercial Ltda, -+ // O=Buster Paper Comercial Ltda, -+ // L=S?o Jos? Dos Campos, -+ // ST=S?o Paulo, -+ // C=BR -+ // Issuer: CN=DigiCert Assured ID Code Signing CA-1, -+ // OU=www.digicert.com, -+ // O=DigiCert Inc, -+ // C=US -+ // Serial: 07:b4:4c:db:ff:fb:78:de:05:f4:26:16:72:a6:73:12 -+ add("buster-paper-comercial-ltda-72A67312", -+ "-----BEGIN CERTIFICATE-----\n" + -+ "MIIGwzCCBaugAwIBAgIQB7RM2//7eN4F9CYWcqZzEjANBgkqhkiG9w0BAQUFADBv\n" + -+ "MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\n" + -+ "d3cuZGlnaWNlcnQuY29tMS4wLAYDVQQDEyVEaWdpQ2VydCBBc3N1cmVkIElEIENv\n" + -+ "ZGUgU2lnbmluZyBDQS0xMB4XDTEzMDExNzAwMDAwMFoXDTE0MDEyMjEyMDAwMFow\n" + -+ "gY4xCzAJBgNVBAYTAkJSMRMwEQYDVQQIDApTw6NvIFBhdWxvMR4wHAYDVQQHDBVT\n" + -+ "w6NvIEpvc8OpIERvcyBDYW1wb3MxJDAiBgNVBAoTG0J1c3RlciBQYXBlciBDb21l\n" + -+ "cmNpYWwgTHRkYTEkMCIGA1UEAxMbQnVzdGVyIFBhcGVyIENvbWVyY2lhbCBMdGRh\n" + -+ "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzO0l6jWIpEfO2oUpVHpL\n" + -+ "HETj5lzivNb0S9jKHgGJax917czh81PnGTxwxFXd6gLJuy/XFHvmiSi8g8jzlymn\n" + -+ "2Ji5zQ3CPaz7nomJokSUDlMVJ2qYWtctw4jrdjuI4qtn+koXXUFkWjkf8h8251I4\n" + -+ "tUs7S49HE2Go5owCYP3byajj7fsFAYR/Xb7TdVtndkZsUB/YgOjHovyACjouaNCi\n" + -+ "mDiRyQ6zLLjZGiyeD65Yiseuhp5b8/BL5h1p7w76QYMYMVQNAdtDKut2R8MBpuWf\n" + -+ "Ny7Eoi0x/gm1p9X5Rcl5aN7K0G4UtTAJKbkuUfXddsyFoM0Nx8uo8SgNQ8Y/X5Jx\n" + -+ "BwIDAQABo4IDOTCCAzUwHwYDVR0jBBgwFoAUe2jOKarAF75JeuHlP9an90WPNTIw\n" + -+ "HQYDVR0OBBYEFFLZ3n5nt/Eer7n1bvtOqMb1qKO5MA4GA1UdDwEB/wQEAwIHgDAT\n" + -+ "BgNVHSUEDDAKBggrBgEFBQcDAzBzBgNVHR8EbDBqMDOgMaAvhi1odHRwOi8vY3Js\n" + -+ "My5kaWdpY2VydC5jb20vYXNzdXJlZC1jcy0yMDExYS5jcmwwM6AxoC+GLWh0dHA6\n" + -+ "Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9hc3N1cmVkLWNzLTIwMTFhLmNybDCCAcQGA1Ud\n" + -+ "IASCAbswggG3MIIBswYJYIZIAYb9bAMBMIIBpDA6BggrBgEFBQcCARYuaHR0cDov\n" + -+ "L3d3dy5kaWdpY2VydC5jb20vc3NsLWNwcy1yZXBvc2l0b3J5Lmh0bTCCAWQGCCsG\n" + -+ "AQUFBwICMIIBVh6CAVIAQQBuAHkAIAB1AHMAZQAgAG8AZgAgAHQAaABpAHMAIABD\n" + -+ "AGUAcgB0AGkAZgBpAGMAYQB0AGUAIABjAG8AbgBzAHQAaQB0AHUAdABlAHMAIABh\n" + -+ "AGMAYwBlAHAAdABhAG4AYwBlACAAbwBmACAAdABoAGUAIABEAGkAZwBpAEMAZQBy\n" + -+ "AHQAIABDAFAALwBDAFAAUwAgAGEAbgBkACAAdABoAGUAIABSAGUAbAB5AGkAbgBn\n" + -+ "ACAAUABhAHIAdAB5ACAAQQBnAHIAZQBlAG0AZQBuAHQAIAB3AGgAaQBjAGgAIABs\n" + -+ "AGkAbQBpAHQAIABsAGkAYQBiAGkAbABpAHQAeQAgAGEAbgBkACAAYQByAGUAIABp\n" + -+ "AG4AYwBvAHIAcABvAHIAYQB0AGUAZAAgAGgAZQByAGUAaQBuACAAYgB5ACAAcgBl\n" + -+ "AGYAZQByAGUAbgBjAGUALjCBggYIKwYBBQUHAQEEdjB0MCQGCCsGAQUFBzABhhho\n" + -+ "dHRwOi8vb2NzcC5kaWdpY2VydC5jb20wTAYIKwYBBQUHMAKGQGh0dHA6Ly9jYWNl\n" + -+ "cnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENvZGVTaWduaW5nQ0Et\n" + -+ "MS5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQUFAAOCAQEAPTTQvpOIikXI\n" + -+ "hTLnNbajaFRR5GhQpTzUNgBfF9VYSlNw/wMjpGsrh5RxaJCip52jbehmTgjMRhft\n" + -+ "jRYyml44PAVsCcR9uEoDpCZYpI1fHI1R+F8jd1C9rqprbSwwOG4xlg4SmvTHYs6e\n" + -+ "gBItQ/1p9XY+Sf4Wv1qOuOFL1qvV/5VyR2zdlOQCmKCeMgxt6a/tHLBDiAA67D44\n" + -+ "/vfdoNJl0CU2It0PO60jdCPFNWIRcxL+OSDqAoePeUC7xQ+JsTEIxuUE8+d6w6fc\n" + -+ "BV2mYb1flh22t46GLjh4gyo7xw3aL6L0L0jzlTT6IcEw6NIbaPbIKj/npQnHobYj\n" + -+ "XMuKLxbh7g==\n" + -+ "-----END CERTIFICATE-----"); -+ -+ // Subject: CN=BUSTER ASSISTENCIA TECNICA ELETRONICA LTDA - ME, -+ // O=BUSTER ASSISTENCIA TECNICA ELETRONICA LTDA - ME, -+ // L=S?o Paulo, -+ // ST=S?o Paulo, -+ // C=BR -+ // Issuer: CN=DigiCert Assured ID Code Signing CA-1, -+ // OU=www.digicert.com, -+ // O=DigiCert Inc, -+ // C=US -+ // Serial: 0a:38:9b:95:ee:73:6d:d1:3b:c0:ed:74:3f:d7:4d:2f -+ add("buster-assistencia-tecnica-electronica-ltda-3FD74D2F", -+ "-----BEGIN CERTIFICATE-----\n" + -+ "MIIG4DCCBcigAwIBAgIQCjible5zbdE7wO10P9dNLzANBgkqhkiG9w0BAQUFADBv\n" + -+ "MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\n" + -+ "d3cuZGlnaWNlcnQuY29tMS4wLAYDVQQDEyVEaWdpQ2VydCBBc3N1cmVkIElEIENv\n" + -+ "ZGUgU2lnbmluZyBDQS0xMB4XDTEyMTEwOTAwMDAwMFoXDTEzMTExNDEyMDAwMFow\n" + -+ "gasxCzAJBgNVBAYTAkJSMRMwEQYDVQQIDApTw6NvIFBhdWxvMRMwEQYDVQQHDApT\n" + -+ "w6NvIFBhdWxvMTgwNgYDVQQKEy9CVVNURVIgQVNTSVNURU5DSUEgVEVDTklDQSBF\n" + -+ "TEVUUk9OSUNBIExUREEgLSBNRTE4MDYGA1UEAxMvQlVTVEVSIEFTU0lTVEVOQ0lB\n" + -+ "IFRFQ05JQ0EgRUxFVFJPTklDQSBMVERBIC0gTUUwggEiMA0GCSqGSIb3DQEBAQUA\n" + -+ "A4IBDwAwggEKAoIBAQDAqNeEs5/B2CTXGjTOkUIdu6jV6qulOZwdw4sefHWYj1UR\n" + -+ "4z6zPk9kjpUgbnb402RFq88QtfInwddZ/wXn9OxMtDd/3TnC7HrhNS7ga79ZFL2V\n" + -+ "JnmzKHum2Yvh0q82QEJ9tHBR2X9VdKpUIH08Zs3k6cWWM1H0YX0cxA/HohhesQJW\n" + -+ "kwJ3urOIJiH/HeByDk8a1NS8safcCxk5vxvW4WvCg43iT09LeHY5Aa8abKw8lqVb\n" + -+ "0tD5ZSIjdmdj3TT1U37iAHLLRM2DXbxfdbhouUX1c5U1ZHAMA67HwjKiseOiDaHj\n" + -+ "NUGbC37C+cgbc9VVM/cURD8WvS0Kj6fQv7F2QtJDAgMBAAGjggM5MIIDNTAfBgNV\n" + -+ "HSMEGDAWgBR7aM4pqsAXvkl64eU/1qf3RY81MjAdBgNVHQ4EFgQU88EXKAyDsh30\n" + -+ "o9+Gu9a4xUy+FSMwDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMD\n" + -+ "MHMGA1UdHwRsMGowM6AxoC+GLWh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9hc3N1\n" + -+ "cmVkLWNzLTIwMTFhLmNybDAzoDGgL4YtaHR0cDovL2NybDQuZGlnaWNlcnQuY29t\n" + -+ "L2Fzc3VyZWQtY3MtMjAxMWEuY3JsMIIBxAYDVR0gBIIBuzCCAbcwggGzBglghkgB\n" + -+ "hv1sAwEwggGkMDoGCCsGAQUFBwIBFi5odHRwOi8vd3d3LmRpZ2ljZXJ0LmNvbS9z\n" + -+ "c2wtY3BzLXJlcG9zaXRvcnkuaHRtMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4A\n" + -+ "eQAgAHUAcwBlACAAbwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQA\n" + -+ "ZQAgAGMAbwBuAHMAdABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUA\n" + -+ "IABvAGYAIAB0AGgAZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAA\n" + -+ "YQBuAGQAIAB0AGgAZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcA\n" + -+ "cgBlAGUAbQBlAG4AdAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIA\n" + -+ "aQBsAGkAdAB5ACAAYQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQA\n" + -+ "ZQBkACAAaABlAHIAZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMIGC\n" + -+ "BggrBgEFBQcBAQR2MHQwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0\n" + -+ "LmNvbTBMBggrBgEFBQcwAoZAaHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0Rp\n" + -+ "Z2lDZXJ0QXNzdXJlZElEQ29kZVNpZ25pbmdDQS0xLmNydDAMBgNVHRMBAf8EAjAA\n" + -+ "MA0GCSqGSIb3DQEBBQUAA4IBAQAei1QmiXepje8OIfo/WonD4MIXgpPr2dfRaquQ\n" + -+ "A8q63OpTRSveyqdQDCSPpDRF/nvO1Y30yksZvIH1tNBsW5LBdxAKN3lFdBlqBwtE\n" + -+ "Q3jHc0KVVYRJ0FBaGE/PJHmRajscdAhYIcMPhTga0u0tDK+wOHEq3993dfl6yHjA\n" + -+ "XHU2iW5pnk75ZoE39zALD5eKXT8ZXrET5c3XUFJKWA+XuGmdmyzqo0Au49PanBv9\n" + -+ "UlZnabYfqoMArqMS0tGSX4cGgi9/2E+pHG9BX4sFW+ZDumroOA2pxyMWEKjxePEL\n" + -+ "zCOfhbsRWdMLYepauaNZOIMZXmFwcrIl0TGMkTAtATz+XmZc\n" + -+ "-----END CERTIFICATE-----"); -+ - } - }
--- a/patches/security/20130304/8007014.patch Tue Mar 19 00:21:31 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,477 +0,0 @@ -# HG changeset patch -# User bae -# Date 1360857111 -14400 -# Node ID 44c99b68e36c57648829320843fbc77cf2d4c4d1 -# Parent b8b3916e20ed651fa6ad9da6ae96b2548a13f96c -8007014: Improve image handling -Reviewed-by: prr, mschoene, jgodinez - -diff --git a/src/share/classes/sun/awt/image/ByteComponentRaster.java b/src/share/classes/sun/awt/image/ByteComponentRaster.java ---- openjdk/jdk/src/share/classes/sun/awt/image/ByteComponentRaster.java -+++ openjdk/jdk/src/share/classes/sun/awt/image/ByteComponentRaster.java -@@ -868,6 +868,15 @@ - * or if data buffer has not enough capacity. - */ - protected final void verify() { -+ /* Need to re-verify the dimensions since a sample model may be -+ * specified to the constructor -+ */ -+ if (width <= 0 || height <= 0 || -+ height > (Integer.MAX_VALUE / width)) -+ { -+ throw new RasterFormatException("Invalid raster dimension"); -+ } -+ - for (int i = 0; i < dataOffsets.length; i++) { - if (dataOffsets[i] < 0) { - throw new RasterFormatException("Data offsets for band " + i -@@ -905,13 +914,14 @@ - lastPixelOffset += lastScanOffset; - - for (int i = 0; i < numDataElements; i++) { -- size = lastPixelOffset + dataOffsets[i]; - if (dataOffsets[i] > (Integer.MAX_VALUE - lastPixelOffset)) { - throw new RasterFormatException("Incorrect band offset: " - + dataOffsets[i]); - - } - -+ size = lastPixelOffset + dataOffsets[i]; -+ - if (size > maxSize) { - maxSize = size; - } -diff --git a/src/share/classes/sun/awt/image/BytePackedRaster.java b/src/share/classes/sun/awt/image/BytePackedRaster.java ---- openjdk/jdk/src/share/classes/sun/awt/image/BytePackedRaster.java -+++ openjdk/jdk/src/share/classes/sun/awt/image/BytePackedRaster.java -@@ -1368,11 +1368,35 @@ - throw new RasterFormatException("Data offsets must be >= 0"); - } - -+ /* Need to re-verify the dimensions since a sample model may be -+ * specified to the constructor -+ */ -+ if (width <= 0 || height <= 0 || -+ height > (Integer.MAX_VALUE / width)) -+ { -+ throw new RasterFormatException("Invalid raster dimension"); -+ } -+ -+ -+ /* -+ * pixelBitstride was verified in constructor, so just make -+ * sure that it is safe to multiply it by width. -+ */ -+ if ((width - 1) > Integer.MAX_VALUE / pixelBitStride) { -+ throw new RasterFormatException("Invalid raster dimension"); -+ } -+ -+ if (scanlineStride < 0 || -+ scanlineStride > (Integer.MAX_VALUE / height)) -+ { -+ throw new RasterFormatException("Invalid scanline stride"); -+ } -+ - int lastbit = (dataBitOffset - + (height-1) * scanlineStride * 8 - + (width-1) * pixelBitStride - + pixelBitStride - 1); -- if (lastbit / 8 >= data.length) { -+ if (lastbit < 0 || lastbit / 8 >= data.length) { - throw new RasterFormatException("raster dimensions overflow " + - "array bounds"); - } -diff --git a/src/share/classes/sun/awt/image/IntegerComponentRaster.java b/src/share/classes/sun/awt/image/IntegerComponentRaster.java ---- openjdk/jdk/src/share/classes/sun/awt/image/IntegerComponentRaster.java -+++ openjdk/jdk/src/share/classes/sun/awt/image/IntegerComponentRaster.java -@@ -208,7 +208,7 @@ - " SinglePixelPackedSampleModel"); - } - -- verify(false); -+ verify(); - } - - -@@ -629,16 +629,26 @@ - } - - /** -- * Verify that the layout parameters are consistent with -- * the data. If strictCheck -- * is false, this method will check for ArrayIndexOutOfBounds conditions. If -- * strictCheck is true, this method will check for additional error -- * conditions such as line wraparound (width of a line greater than -- * the scanline stride). -- * @return String Error string, if the layout is incompatible with -- * the data. Otherwise returns null. -+ * Verify that the layout parameters are consistent with the data. -+ * -+ * The method verifies whether scanline stride and pixel stride do not -+ * cause an integer overflow during calculation of a position of the pixel -+ * in data buffer. It also verifies whether the data buffer has enough data -+ * to correspond the raster layout attributes. -+ * -+ * @throws RasterFormatException if an integer overflow is detected, -+ * or if data buffer has not enough capacity. - */ -- private void verify (boolean strictCheck) { -+ protected final void verify() { -+ /* Need to re-verify the dimensions since a sample model may be -+ * specified to the constructor -+ */ -+ if (width <= 0 || height <= 0 || -+ height > (Integer.MAX_VALUE / width)) -+ { -+ throw new RasterFormatException("Invalid raster dimension"); -+ } -+ - if (dataOffsets[0] < 0) { - throw new RasterFormatException("Data offset ("+dataOffsets[0]+ - ") must be >= 0"); -@@ -647,17 +657,46 @@ - int maxSize = 0; - int size; - -- for (int i=0; i < numDataElements; i++) { -- size = (height-1)*scanlineStride + (width-1)*pixelStride + -- dataOffsets[i]; -+ // we can be sure that width and height are greater than 0 -+ if (scanlineStride < 0 || -+ scanlineStride > (Integer.MAX_VALUE / height)) -+ { -+ // integer overflow -+ throw new RasterFormatException("Incorrect scanline stride: " -+ + scanlineStride); -+ } -+ int lastScanOffset = (height - 1) * scanlineStride; -+ -+ if (pixelStride < 0 || -+ pixelStride > (Integer.MAX_VALUE / width)) -+ { -+ // integer overflow -+ throw new RasterFormatException("Incorrect pixel stride: " -+ + pixelStride); -+ } -+ int lastPixelOffset = (width - 1) * pixelStride; -+ -+ if (lastPixelOffset > (Integer.MAX_VALUE - lastScanOffset)) { -+ // integer overflow -+ throw new RasterFormatException("Incorrect raster attributes"); -+ } -+ lastPixelOffset += lastScanOffset; -+ -+ for (int i = 0; i < numDataElements; i++) { -+ if (dataOffsets[i] > (Integer.MAX_VALUE - lastPixelOffset)) { -+ throw new RasterFormatException("Incorrect band offset: " -+ + dataOffsets[i]); -+ } -+ -+ size = lastPixelOffset + dataOffsets[i]; -+ - if (size > maxSize) { - maxSize = size; - } - } - if (data.length < maxSize) { -- throw new RasterFormatException("Data array too small (should be "+ -- maxSize -- +" but is "+data.length+" )"); -+ throw new RasterFormatException("Data array too small (should be " -+ + maxSize + " )"); - } - } - -diff --git a/src/share/classes/sun/awt/image/IntegerInterleavedRaster.java b/src/share/classes/sun/awt/image/IntegerInterleavedRaster.java ---- openjdk/jdk/src/share/classes/sun/awt/image/IntegerInterleavedRaster.java -+++ openjdk/jdk/src/share/classes/sun/awt/image/IntegerInterleavedRaster.java -@@ -151,7 +151,7 @@ - throw new RasterFormatException("IntegerInterleavedRasters must have"+ - " SinglePixelPackedSampleModel"); - } -- verify(false); -+ verify(); - } - - -@@ -540,31 +540,6 @@ - return createCompatibleWritableRaster(width,height); - } - -- /** -- * Verify that the layout parameters are consistent with -- * the data. If strictCheck -- * is false, this method will check for ArrayIndexOutOfBounds conditions. If -- * strictCheck is true, this method will check for additional error -- * conditions such as line wraparound (width of a line greater than -- * the scanline stride). -- * @return String Error string, if the layout is incompatible with -- * the data. Otherwise returns null. -- */ -- private void verify (boolean strictCheck) { -- int maxSize = 0; -- int size; -- -- size = (height-1)*scanlineStride + (width-1) + dataOffsets[0]; -- if (size > maxSize) { -- maxSize = size; -- } -- if (data.length < maxSize) { -- throw new RasterFormatException("Data array too small (should be "+ -- maxSize -- +" but is "+data.length+" )"); -- } -- } -- - public String toString() { - return new String ("IntegerInterleavedRaster: width = "+width - +" height = " + height -diff --git a/src/share/classes/sun/awt/image/ShortComponentRaster.java b/src/share/classes/sun/awt/image/ShortComponentRaster.java ---- openjdk/jdk/src/share/classes/sun/awt/image/ShortComponentRaster.java -+++ openjdk/jdk/src/share/classes/sun/awt/image/ShortComponentRaster.java -@@ -802,6 +802,15 @@ - * or if data buffer has not enough capacity. - */ - protected final void verify() { -+ /* Need to re-verify the dimensions since a sample model may be -+ * specified to the constructor -+ */ -+ if (width <= 0 || height <= 0 || -+ height > (Integer.MAX_VALUE / width)) -+ { -+ throw new RasterFormatException("Invalid raster dimension"); -+ } -+ - for (int i = 0; i < dataOffsets.length; i++) { - if (dataOffsets[i] < 0) { - throw new RasterFormatException("Data offsets for band " + i -@@ -839,12 +848,13 @@ - lastPixelOffset += lastScanOffset; - - for (int i = 0; i < numDataElements; i++) { -- size = lastPixelOffset + dataOffsets[i]; - if (dataOffsets[i] > (Integer.MAX_VALUE - lastPixelOffset)) { - throw new RasterFormatException("Incorrect band offset: " - + dataOffsets[i]); - } - -+ size = lastPixelOffset + dataOffsets[i]; -+ - if (size > maxSize) { - maxSize = size; - } -diff --git a/src/share/native/sun/awt/image/awt_parseImage.c b/src/share/native/sun/awt/image/awt_parseImage.c ---- openjdk/jdk/src/share/native/sun/awt/image/awt_parseImage.c -+++ openjdk/jdk/src/share/native/sun/awt/image/awt_parseImage.c -@@ -34,6 +34,7 @@ - #include "java_awt_color_ColorSpace.h" - #include "awt_Mlib.h" - #include "safe_alloc.h" -+#include "safe_math.h" - - static int setHints(JNIEnv *env, BufImageS_t *imageP); - -diff --git a/src/share/native/sun/awt/medialib/awt_ImagingLib.c b/src/share/native/sun/awt/medialib/awt_ImagingLib.c ---- openjdk/jdk/src/share/native/sun/awt/medialib/awt_ImagingLib.c -+++ openjdk/jdk/src/share/native/sun/awt/medialib/awt_ImagingLib.c -@@ -42,6 +42,7 @@ - #include "awt_Mlib.h" - #include "gdefs.h" - #include "safe_alloc.h" -+#include "safe_math.h" - - /*************************************************************************** - * Definitions * -@@ -1970,13 +1971,23 @@ - unsigned char *dP = dataP; - #define NUM_LINES 10 - int numLines = NUM_LINES; -- int nbytes = rasterP->width*4*NUM_LINES; -+ /* it is safe to calculate the scan length, because width has been verified -+ * on creation of the mlib image -+ */ -+ int scanLength = rasterP->width * 4; -+ -+ int nbytes = 0; -+ if (!SAFE_TO_MULT(numLines, scanLength)) { -+ return -1; -+ } -+ -+ nbytes = numLines * scanLength; - - for (y=0; y < rasterP->height; y+=numLines) { - /* getData, one scanline at a time */ - if (y+numLines > rasterP->height) { - numLines = rasterP->height - y; -- nbytes = rasterP->width*4*numLines; -+ nbytes = numLines * scanLength; - } - jpixels = (*env)->CallObjectMethod(env, imageP->jimage, - g_BImgGetRGBMID, 0, y, -@@ -2106,8 +2117,14 @@ - if (cvtToDefault) { - int status = 0; - *mlibImagePP = (*sMlibSysFns.createFP)(MLIB_BYTE, 4, width, height); -+ if (*mlibImagePP == NULL) { -+ return -1; -+ } - cDataP = (unsigned char *) mlib_ImageGetData(*mlibImagePP); -- /* Make sure the image is cleared */ -+ /* Make sure the image is cleared. -+ * NB: the image dimension is already verified, so we can -+ * safely calculate the length of the buffer. -+ */ - memset(cDataP, 0, width*height*4); - - if (!isSrc) { -@@ -2357,6 +2374,9 @@ - case sun_awt_image_IntegerComponentRaster_TYPE_BYTE_PACKED_SAMPLES: - *mlibImagePP = (*sMlibSysFns.createFP)(MLIB_BYTE, rasterP->numBands, - width, height); -+ if (*mlibImagePP == NULL) { -+ return -1; -+ } - if (!isSrc) return 0; - cDataP = (unsigned char *) mlib_ImageGetData(*mlibImagePP); - return expandPackedBCR(env, rasterP, -1, cDataP); -@@ -2365,6 +2385,9 @@ - if (rasterP->sppsm.maxBitSize <= 8) { - *mlibImagePP = (*sMlibSysFns.createFP)(MLIB_BYTE, rasterP->numBands, - width, height); -+ if (*mlibImagePP == NULL) { -+ return -1; -+ } - if (!isSrc) return 0; - cDataP = (unsigned char *) mlib_ImageGetData(*mlibImagePP); - return expandPackedSCR(env, rasterP, -1, cDataP); -@@ -2374,6 +2397,9 @@ - if (rasterP->sppsm.maxBitSize <= 8) { - *mlibImagePP = (*sMlibSysFns.createFP)(MLIB_BYTE, rasterP->numBands, - width, height); -+ if (*mlibImagePP == NULL) { -+ return -1; -+ } - if (!isSrc) return 0; - cDataP = (unsigned char *) mlib_ImageGetData(*mlibImagePP); - return expandPackedICR(env, rasterP, -1, cDataP); -diff --git a/src/share/native/sun/awt/medialib/mlib_ImageCreate.c b/src/share/native/sun/awt/medialib/mlib_ImageCreate.c ---- openjdk/jdk/src/share/native/sun/awt/medialib/mlib_ImageCreate.c -+++ openjdk/jdk/src/share/native/sun/awt/medialib/mlib_ImageCreate.c -@@ -120,6 +120,7 @@ - #include "mlib_image.h" - #include "mlib_ImageRowTable.h" - #include "mlib_ImageCreate.h" -+#include "safe_math.h" - - /***************************************************************/ - mlib_image* mlib_ImageSet(mlib_image *image, -@@ -247,28 +248,50 @@ - return NULL; - }; - -+ if (!SAFE_TO_MULT(width, channels)) { -+ return NULL; -+ } -+ -+ wb = width * channels; -+ - switch (type) { - case MLIB_DOUBLE: -- wb = width * channels * 8; -+ if (!SAFE_TO_MULT(wb, 8)) { -+ return NULL; -+ } -+ wb *= 8; - break; - case MLIB_FLOAT: - case MLIB_INT: -- wb = width * channels * 4; -+ if (!SAFE_TO_MULT(wb, 4)) { -+ return NULL; -+ } -+ wb *= 4; - break; - case MLIB_USHORT: - case MLIB_SHORT: -- wb = width * channels * 2; -+ if (!SAFE_TO_MULT(wb, 4)) { -+ return NULL; -+ } -+ wb *= 2; - break; - case MLIB_BYTE: -- wb = width * channels; -+ // wb is ready - break; - case MLIB_BIT: -- wb = (width * channels + 7) / 8; -+ if (!SAFE_TO_ADD(7, wb)) { -+ return NULL; -+ } -+ wb = (wb + 7) / 8; - break; - default: - return NULL; - } - -+ if (!SAFE_TO_MULT(wb, height)) { -+ return NULL; -+ } -+ - data = mlib_malloc(wb * height); - if (data == NULL) { - return NULL; -diff --git a/src/share/native/sun/awt/medialib/safe_alloc.h b/src/share/native/sun/awt/medialib/safe_alloc.h ---- openjdk/jdk/src/share/native/sun/awt/medialib/safe_alloc.h -+++ openjdk/jdk/src/share/native/sun/awt/medialib/safe_alloc.h -@@ -41,10 +41,4 @@ - (((w) > 0) && ((h) > 0) && ((sz) > 0) && \ - (((0xffffffffu / ((juint)(w))) / ((juint)(h))) > ((juint)(sz)))) - --#define SAFE_TO_MULT(a, b) \ -- (((a) > 0) && ((b) >= 0) && ((0x7fffffff / (a)) > (b))) -- --#define SAFE_TO_ADD(a, b) \ -- (((a) >= 0) && ((b) >= 0) && ((0x7fffffff - (a)) > (b))) -- - #endif // __SAFE_ALLOC_H__ -diff --git a/src/share/native/sun/awt/medialib/safe_math.h b/src/share/native/sun/awt/medialib/safe_math.h -new file mode 100644 ---- /dev/null -+++ openjdk/jdk/src/share/native/sun/awt/medialib/safe_math.h -@@ -0,0 +1,35 @@ -+/* -+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. -+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -+ * -+ * This code is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 only, as -+ * published by the Free Software Foundation. Oracle designates this -+ * particular file as subject to the "Classpath" exception as provided -+ * by Oracle in the LICENSE file that accompanied this code. -+ * -+ * This code is distributed in the hope that it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * version 2 for more details (a copy is included in the LICENSE file that -+ * accompanied this code). -+ * -+ * You should have received a copy of the GNU General Public License version -+ * 2 along with this work; if not, write to the Free Software Foundation, -+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -+ * -+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -+ * or visit www.oracle.com if you need additional information or have any -+ * questions. -+ */ -+ -+#ifndef __SAFE_MATH_H__ -+#define __SAFE_MATH_H__ -+ -+#define SAFE_TO_MULT(a, b) \ -+ (((a) > 0) && ((b) >= 0) && ((0x7fffffff / (a)) > (b))) -+ -+#define SAFE_TO_ADD(a, b) \ -+ (((a) >= 0) && ((b) >= 0) && ((0x7fffffff - (a)) > (b))) -+ -+#endif // __SAFE_MATH_H__
--- a/patches/security/20130304/8007675.patch Tue Mar 19 00:21:31 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,416 +0,0 @@ -# HG changeset patch -# User bae -# Date 1362257363 -10800 -# Node ID 9714f53ef17344fbcb6dc2249a7b238e6292f726 -# Parent 44c99b68e36c57648829320843fbc77cf2d4c4d1 -8007675: Improve color conversion -Reviewed-by: prr, jgodinez - -diff --git a/src/share/classes/sun/java2d/cmm/lcms/LCMSImageLayout.java b/src/share/classes/sun/java2d/cmm/lcms/LCMSImageLayout.java ---- openjdk/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMSImageLayout.java -+++ openjdk/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMSImageLayout.java -@@ -99,50 +99,75 @@ - int offset; - - Object dataArray; -- private LCMSImageLayout(int np, int pixelType, int pixelSize) { -+ private int dataArrayLength; /* in bytes */ -+ -+ private LCMSImageLayout(int np, int pixelType, int pixelSize) -+ throws ImageLayoutException -+ { - this.pixelType = pixelType; - width = np; - height = 1; -- nextRowOffset = np*pixelSize; -+ nextRowOffset = safeMult(pixelSize, np); - offset = 0; - } - - private LCMSImageLayout(int width, int height, int pixelType, -- int pixelSize) { -+ int pixelSize) -+ throws ImageLayoutException -+ { - this.pixelType = pixelType; - this.width = width; - this.height = height; -- nextRowOffset = width*pixelSize; -+ nextRowOffset = safeMult(pixelSize, width); - offset = 0; - } - - -- public LCMSImageLayout(byte[] data, int np, int pixelType, int pixelSize) { -+ public LCMSImageLayout(byte[] data, int np, int pixelType, int pixelSize) -+ throws ImageLayoutException -+ { - this(np, pixelType, pixelSize); - dataType = DT_BYTE; - dataArray = data; -+ dataArrayLength = data.length; -+ -+ verify(); - } - -- public LCMSImageLayout(short[] data, int np, int pixelType, int pixelSize) { -+ public LCMSImageLayout(short[] data, int np, int pixelType, int pixelSize) -+ throws ImageLayoutException -+ { - this(np, pixelType, pixelSize); - dataType = DT_SHORT; - dataArray = data; -+ dataArrayLength = 2 * data.length; -+ -+ verify(); - } - -- public LCMSImageLayout(int[] data, int np, int pixelType, int pixelSize) { -+ public LCMSImageLayout(int[] data, int np, int pixelType, int pixelSize) -+ throws ImageLayoutException -+ { - this(np, pixelType, pixelSize); - dataType = DT_INT; - dataArray = data; -+ dataArrayLength = 4 * data.length; -+ -+ verify(); - } - - public LCMSImageLayout(double[] data, int np, int pixelType, int pixelSize) -+ throws ImageLayoutException - { - this(np, pixelType, pixelSize); - dataType = DT_DOUBLE; - dataArray = data; -+ dataArrayLength = 8 * data.length; -+ -+ verify(); - } - -- public LCMSImageLayout(BufferedImage image) { -+ public LCMSImageLayout(BufferedImage image) throws ImageLayoutException { - ShortComponentRaster shortRaster; - IntegerComponentRaster intRaster; - ByteComponentRaster byteRaster; -@@ -186,9 +211,13 @@ - case BufferedImage.TYPE_INT_ARGB: - case BufferedImage.TYPE_INT_BGR: - intRaster = (IntegerComponentRaster)image.getRaster(); -- nextRowOffset = intRaster.getScanlineStride()*4; -- offset = intRaster.getDataOffset(0)*4; -+ -+ nextRowOffset = safeMult(4, intRaster.getScanlineStride()); -+ -+ offset = safeMult(4, intRaster.getDataOffset(0)); -+ - dataArray = intRaster.getDataStorage(); -+ dataArrayLength = 4 * intRaster.getDataStorage().length; - dataType = DT_INT; - break; - -@@ -196,8 +225,10 @@ - case BufferedImage.TYPE_4BYTE_ABGR: - byteRaster = (ByteComponentRaster)image.getRaster(); - nextRowOffset = byteRaster.getScanlineStride(); -- offset = byteRaster.getDataOffset(0); -+ int firstBand = image.getSampleModel().getNumBands() - 1; -+ offset = byteRaster.getDataOffset(firstBand); - dataArray = byteRaster.getDataStorage(); -+ dataArrayLength = byteRaster.getDataStorage().length; - dataType = DT_BYTE; - break; - -@@ -206,17 +237,20 @@ - nextRowOffset = byteRaster.getScanlineStride(); - offset = byteRaster.getDataOffset(0); - dataArray = byteRaster.getDataStorage(); -+ dataArrayLength = byteRaster.getDataStorage().length; - dataType = DT_BYTE; - break; - - case BufferedImage.TYPE_USHORT_GRAY: - shortRaster = (ShortComponentRaster)image.getRaster(); -- nextRowOffset = shortRaster.getScanlineStride()*2; -- offset = shortRaster.getDataOffset(0) * 2; -+ nextRowOffset = safeMult(2, shortRaster.getScanlineStride()); -+ offset = safeMult(2, shortRaster.getDataOffset(0)); - dataArray = shortRaster.getDataStorage(); -+ dataArrayLength = 2 * shortRaster.getDataStorage().length; - dataType = DT_SHORT; - break; - } -+ verify(); - } - - public static boolean isSupported(BufferedImage image) { -@@ -232,4 +266,45 @@ - } - return false; - } -+ -+ private void verify() throws ImageLayoutException { -+ -+ if (offset < 0 || offset >= dataArrayLength) { -+ throw new ImageLayoutException("Invalid image layout"); -+ } -+ -+ int lastPixelOffset = safeMult(nextRowOffset, (height - 1)); -+ -+ lastPixelOffset = safeAdd(lastPixelOffset, (width - 1)); -+ -+ int off = safeAdd(offset, lastPixelOffset); -+ -+ if (off < 0 || off >= dataArrayLength) { -+ throw new ImageLayoutException("Invalid image layout"); -+ } -+ } -+ -+ static int safeAdd(int a, int b) throws ImageLayoutException { -+ long res = a; -+ res += b; -+ if (res < Integer.MIN_VALUE || res > Integer.MAX_VALUE) { -+ throw new ImageLayoutException("Invalid image layout"); -+ } -+ return (int)res; -+ } -+ -+ static int safeMult(int a, int b) throws ImageLayoutException { -+ long res = a; -+ res *= b; -+ if (res < Integer.MIN_VALUE || res > Integer.MAX_VALUE) { -+ throw new ImageLayoutException("Invalid image layout"); -+ } -+ return (int)res; -+ } -+ -+ public static class ImageLayoutException extends Exception { -+ public ImageLayoutException(String message) { -+ super(message); -+ } -+ } - } -diff --git a/src/share/classes/sun/java2d/cmm/lcms/LCMSTransform.java b/src/share/classes/sun/java2d/cmm/lcms/LCMSTransform.java ---- openjdk/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMSTransform.java -+++ openjdk/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMSTransform.java -@@ -51,6 +51,7 @@ - import java.awt.image.ComponentSampleModel; - import sun.java2d.cmm.*; - import sun.java2d.cmm.lcms.*; -+import static sun.java2d.cmm.lcms.LCMSImageLayout.ImageLayoutException; - - - public class LCMSTransform implements ColorTransform { -@@ -116,8 +117,12 @@ - LCMSImageLayout.isSupported(dst)) - { - synchronized(this) { -- LCMS.colorConvert(this, new LCMSImageLayout(src), -- new LCMSImageLayout(dst)); -+ try { -+ LCMS.colorConvert(this, new LCMSImageLayout(src), -+ new LCMSImageLayout(dst)); -+ } catch (ImageLayoutException e) { -+ throw new CMMException("Unable to convert images"); -+ } - } - return; - } -@@ -177,14 +182,18 @@ - } - int idx; - // TODO check for src npixels = dst npixels -- srcIL = new LCMSImageLayout( -- srcLine, srcLine.length/getNumInComponents(), -- LCMSImageLayout.CHANNELS_SH(getNumInComponents()) | -- LCMSImageLayout.BYTES_SH(1), getNumInComponents()); -- dstIL = new LCMSImageLayout( -- dstLine, dstLine.length/getNumOutComponents(), -- LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) | -- LCMSImageLayout.BYTES_SH(1), getNumOutComponents()); -+ try { -+ srcIL = new LCMSImageLayout( -+ srcLine, srcLine.length/getNumInComponents(), -+ LCMSImageLayout.CHANNELS_SH(getNumInComponents()) | -+ LCMSImageLayout.BYTES_SH(1), getNumInComponents()); -+ dstIL = new LCMSImageLayout( -+ dstLine, dstLine.length/getNumOutComponents(), -+ LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) | -+ LCMSImageLayout.BYTES_SH(1), getNumOutComponents()); -+ } catch (ImageLayoutException e) { -+ throw new CMMException("Unable to convert images"); -+ } - // process each scanline - for (int y = 0; y < h; y++) { - // convert src scanline -@@ -234,16 +243,19 @@ - alpha = new float[w]; - } - int idx; -- srcIL = new LCMSImageLayout( -- srcLine, srcLine.length/getNumInComponents(), -- LCMSImageLayout.CHANNELS_SH(getNumInComponents()) | -- LCMSImageLayout.BYTES_SH(2), getNumInComponents()*2); -+ try { -+ srcIL = new LCMSImageLayout( -+ srcLine, srcLine.length/getNumInComponents(), -+ LCMSImageLayout.CHANNELS_SH(getNumInComponents()) | -+ LCMSImageLayout.BYTES_SH(2), getNumInComponents()*2); - -- dstIL = new LCMSImageLayout( -- dstLine, dstLine.length/getNumOutComponents(), -- LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) | -- LCMSImageLayout.BYTES_SH(2), getNumOutComponents()*2); -- -+ dstIL = new LCMSImageLayout( -+ dstLine, dstLine.length/getNumOutComponents(), -+ LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) | -+ LCMSImageLayout.BYTES_SH(2), getNumOutComponents()*2); -+ } catch (ImageLayoutException e) { -+ throw new CMMException("Unable to convert images"); -+ } - // process each scanline - for (int y = 0; y < h; y++) { - // convert src scanline -@@ -353,16 +365,19 @@ - short[] srcLine = new short[w * srcNumBands]; - short[] dstLine = new short[w * dstNumBands]; - int idx; -- srcIL = new LCMSImageLayout( -- srcLine, srcLine.length/getNumInComponents(), -- LCMSImageLayout.CHANNELS_SH(getNumInComponents()) | -- LCMSImageLayout.BYTES_SH(2), getNumInComponents()*2); -+ try { -+ srcIL = new LCMSImageLayout( -+ srcLine, srcLine.length/getNumInComponents(), -+ LCMSImageLayout.CHANNELS_SH(getNumInComponents()) | -+ LCMSImageLayout.BYTES_SH(2), getNumInComponents()*2); - -- dstIL = new LCMSImageLayout( -- dstLine, dstLine.length/getNumOutComponents(), -- LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) | -- LCMSImageLayout.BYTES_SH(2), getNumOutComponents()*2); -- -+ dstIL = new LCMSImageLayout( -+ dstLine, dstLine.length/getNumOutComponents(), -+ LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) | -+ LCMSImageLayout.BYTES_SH(2), getNumOutComponents()*2); -+ } catch (ImageLayoutException e) { -+ throw new CMMException("Unable to convert rasters"); -+ } - // process each scanline - for (int y = 0; y < h; y++, ys++, yd++) { - // get src scanline -@@ -447,15 +462,18 @@ - byte[] dstLine = new byte[w * dstNumBands]; - int idx; - // TODO check for src npixels = dst npixels -- srcIL = new LCMSImageLayout( -- srcLine, srcLine.length/getNumInComponents(), -- LCMSImageLayout.CHANNELS_SH(getNumInComponents()) | -- LCMSImageLayout.BYTES_SH(1), getNumInComponents()); -- dstIL = new LCMSImageLayout( -- dstLine, dstLine.length/getNumOutComponents(), -- LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) | -- LCMSImageLayout.BYTES_SH(1), getNumOutComponents()); -- -+ try { -+ srcIL = new LCMSImageLayout( -+ srcLine, srcLine.length/getNumInComponents(), -+ LCMSImageLayout.CHANNELS_SH(getNumInComponents()) | -+ LCMSImageLayout.BYTES_SH(1), getNumInComponents()); -+ dstIL = new LCMSImageLayout( -+ dstLine, dstLine.length/getNumOutComponents(), -+ LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) | -+ LCMSImageLayout.BYTES_SH(1), getNumOutComponents()); -+ } catch (ImageLayoutException e) { -+ throw new CMMException("Unable to convert rasters"); -+ } - // process each scanline - for (int y = 0; y < h; y++, ys++, yd++) { - // get src scanline -@@ -489,16 +507,20 @@ - short[] srcLine = new short[w * srcNumBands]; - short[] dstLine = new short[w * dstNumBands]; - int idx; -- srcIL = new LCMSImageLayout( -- srcLine, srcLine.length/getNumInComponents(), -- LCMSImageLayout.CHANNELS_SH(getNumInComponents()) | -- LCMSImageLayout.BYTES_SH(2), getNumInComponents()*2); - -- dstIL = new LCMSImageLayout( -- dstLine, dstLine.length/getNumOutComponents(), -- LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) | -- LCMSImageLayout.BYTES_SH(2), getNumOutComponents()*2); -+ try { -+ srcIL = new LCMSImageLayout( -+ srcLine, srcLine.length/getNumInComponents(), -+ LCMSImageLayout.CHANNELS_SH(getNumInComponents()) | -+ LCMSImageLayout.BYTES_SH(2), getNumInComponents()*2); - -+ dstIL = new LCMSImageLayout( -+ dstLine, dstLine.length/getNumOutComponents(), -+ LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) | -+ LCMSImageLayout.BYTES_SH(2), getNumOutComponents()*2); -+ } catch (ImageLayoutException e) { -+ throw new CMMException("Unable to convert rasters"); -+ } - // process each scanline - for (int y = 0; y < h; y++, ys++, yd++) { - // get src scanline -@@ -540,15 +562,19 @@ - dst = new short [(src.length/getNumInComponents())*getNumOutComponents()]; - } - -- LCMSImageLayout srcIL = new LCMSImageLayout( -- src, src.length/getNumInComponents(), -- LCMSImageLayout.CHANNELS_SH(getNumInComponents()) | -- LCMSImageLayout.BYTES_SH(2), getNumInComponents()*2); -+ try { -+ LCMSImageLayout srcIL = new LCMSImageLayout( -+ src, src.length/getNumInComponents(), -+ LCMSImageLayout.CHANNELS_SH(getNumInComponents()) | -+ LCMSImageLayout.BYTES_SH(2), getNumInComponents()*2); - -- LCMSImageLayout dstIL = new LCMSImageLayout( -- dst, dst.length/getNumOutComponents(), -- LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) | -- LCMSImageLayout.BYTES_SH(2), getNumOutComponents()*2); -+ LCMSImageLayout dstIL = new LCMSImageLayout( -+ dst, dst.length/getNumOutComponents(), -+ LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) | -+ LCMSImageLayout.BYTES_SH(2), getNumOutComponents()*2); -+ } catch (ImageLayoutException e) { -+ throw new CMMException("Unable to convert data"); -+ } - - synchronized(this) { - LCMS.colorConvert(this, srcIL, dstIL); -@@ -562,15 +588,19 @@ - dst = new byte [(src.length/getNumInComponents())*getNumOutComponents()]; - } - -- LCMSImageLayout srcIL = new LCMSImageLayout( -- src, src.length/getNumInComponents(), -- LCMSImageLayout.CHANNELS_SH(getNumInComponents()) | -- LCMSImageLayout.BYTES_SH(1), getNumInComponents()); -+ try { -+ LCMSImageLayout srcIL = new LCMSImageLayout( -+ src, src.length/getNumInComponents(), -+ LCMSImageLayout.CHANNELS_SH(getNumInComponents()) | -+ LCMSImageLayout.BYTES_SH(1), getNumInComponents()); - -- LCMSImageLayout dstIL = new LCMSImageLayout( -- dst, dst.length/getNumOutComponents(), -- LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) | -- LCMSImageLayout.BYTES_SH(1), getNumOutComponents()); -+ LCMSImageLayout dstIL = new LCMSImageLayout( -+ dst, dst.length/getNumOutComponents(), -+ LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) | -+ LCMSImageLayout.BYTES_SH(1), getNumOutComponents()); -+ } catch (ImageLayoutException e) { -+ throw new CMMException("Unable to convert data"); -+ } - - synchronized(this) { - LCMS.colorConvert(this, srcIL, dstIL);