diff options
| author | Jung-uk Kim <jkim@FreeBSD.org> | 2013-03-06 00:50:28 +0000 | 
|---|---|---|
| committer | Jung-uk Kim <jkim@FreeBSD.org> | 2013-03-06 00:50:28 +0000 | 
| commit | 0f7f30e0b6084a2cbd4b8718e0629ee43e430afb (patch) | |
| tree | d7cc0e27c2e50cd501beef2b9faad0637d0b5537 /java | |
| parent | Update to 25.0.1364.152 (diff) | |
Add multiple security patches from IcedTea6 1.12.3.
http://mail.openjdk.java.net/pipermail/distro-pkg-dev/2013-February/021858.html
http://mail.openjdk.java.net/pipermail/distro-pkg-dev/2013-February/021998.html
Obtained from:	IcedTea Project
Diffstat (limited to 'java')
36 files changed, 22745 insertions, 5 deletions
diff --git a/java/openjdk6-jre/Makefile b/java/openjdk6-jre/Makefile index c7c90243e91e..e80fcfcd0174 100644 --- a/java/openjdk6-jre/Makefile +++ b/java/openjdk6-jre/Makefile @@ -1,6 +1,6 @@  # $FreeBSD$ -PORTREVISION=	3 +PORTREVISION=	4  CATEGORIES=	java devel  PKGNAMESUFFIX=	-jre diff --git a/java/openjdk6/Makefile b/java/openjdk6/Makefile index cbb7444f8b41..71ad10ae9922 100644 --- a/java/openjdk6/Makefile +++ b/java/openjdk6/Makefile @@ -3,7 +3,7 @@  PORTNAME=	openjdk6  PORTVERSION=	b27 -PORTREVISION?=	1 +PORTREVISION?=	2  CATEGORIES=	java devel  MASTER_SITES=	http://download.java.net/openjdk/jdk6/promoted/${PORTVERSION}/ \  		http://download.java.net/jaxp/openjdk/jdk6/:jaxp \ @@ -39,6 +39,40 @@ RUN_DEPENDS=	javavm:${PORTSDIR}/java/javavmwrapper \  OPENJDK_BUILDDATE=	26_oct_2012 +EXTRA_PATCHES=	${FILESDIR}/icedtea/security/20120830/7182135-impossible_to_use_some_editors_directly.patch \ +		${FILESDIR}/icedtea/security/20130201/7201068.patch \ +		${FILESDIR}/icedtea/security/20130201/6563318.patch \ +		${FILESDIR}/icedtea/security/20130201/6664509.patch \ +		${FILESDIR}/icedtea/security/20130201/6776941.patch \ +		${FILESDIR}/icedtea/security/20130201/7141694.patch \ +		${FILESDIR}/icedtea/security/20130201/7173145.patch \ +		${FILESDIR}/icedtea/security/20130201/7186945.patch \ +		${FILESDIR}/icedtea/security/20130201/7186948.patch \ +		${FILESDIR}/icedtea/security/20130201/7186952.patch \ +		${FILESDIR}/icedtea/security/20130201/7186954.patch \ +		${FILESDIR}/icedtea/security/20130201/7192392.patch \ +		${FILESDIR}/icedtea/security/20130201/7192393.patch \ +		${FILESDIR}/icedtea/security/20130201/7192977.patch \ +		${FILESDIR}/icedtea/security/20130201/7197546.patch \ +		${FILESDIR}/icedtea/security/20130201/7200491.patch \ +		${FILESDIR}/icedtea/security/20130201/7200500.patch \ +		${FILESDIR}/icedtea/security/20130201/7201064.patch \ +		${FILESDIR}/icedtea/security/20130201/7201066.patch \ +		${FILESDIR}/icedtea/security/20130201/7201070.patch \ +		${FILESDIR}/icedtea/security/20130201/7201071.patch \ +		${FILESDIR}/icedtea/security/20130201/8000210.patch \ +		${FILESDIR}/icedtea/security/20130201/8000537.patch \ +		${FILESDIR}/icedtea/security/20130201/8000540.patch \ +		${FILESDIR}/icedtea/security/20130201/8000631.patch \ +		${FILESDIR}/icedtea/security/20130201/8001242.patch \ +		${FILESDIR}/icedtea/security/20130201/8001307.patch \ +		${FILESDIR}/icedtea/security/20130201/8001972.patch \ +		${FILESDIR}/icedtea/security/20130201/8002325.patch \ +		${FILESDIR}/icedtea/security/20130201/8001235.patch \ +		${FILESDIR}/icedtea/security/20130219/8006446.patch \ +		${FILESDIR}/icedtea/security/20130219/8006777.patch \ +		${FILESDIR}/icedtea/security/20130219/8007688.patch +  OPTIONS_DEFINE=	ICEDTEA IPV6 POLICY SOUND TZUPDATE  OPTIONS_DEFAULT=ICEDTEA IPV6 TZUPDATE  ICEDTEA_DESC=	Apply additional patches from IcedTea diff --git a/java/openjdk6/files/icedtea/security/20120830/7182135-impossible_to_use_some_editors_directly.patch b/java/openjdk6/files/icedtea/security/20120830/7182135-impossible_to_use_some_editors_directly.patch new file mode 100644 index 000000000000..0653b33c02a7 --- /dev/null +++ b/java/openjdk6/files/icedtea/security/20120830/7182135-impossible_to_use_some_editors_directly.patch @@ -0,0 +1,519 @@ +diff --git a/make/sun/Makefile b/make/sun/Makefile +--- jdk/make/sun/Makefile ++++ jdk/make/sun/Makefile +@@ -64,7 +64,7 @@ + SUBDIRS = jar security javazic misc net audio $(RENDER_SUBDIR) image \ + 	  awt splashscreen $(XAWT_SUBDIR) $(MOTIF_SUBDIRS) \ +           $(HEADLESS_SUBDIR) $(DGA_SUBDIR) \ +-	  font jpeg cmm applet rmi $(JDBC_SUBDIR) \ ++	  font jpeg cmm applet rmi beans $(JDBC_SUBDIR) \ + 	  jawt text nio launcher management $(ORG_SUBDIR) \ +           native2ascii serialver tools jconsole +  +diff --git a/make/sun/beans/Makefile b/make/sun/beans/Makefile +new file mode 100644 +--- /dev/null ++++ jdk/make/sun/beans/Makefile +@@ -0,0 +1,43 @@ ++# ++# Copyright (c) 1997, 2005, 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. ++# ++ ++# ++# Makefile for building sun.beans.* ++# ++ ++BUILDDIR = ../.. ++PACKAGE = sun.beans ++PRODUCT = sun ++include $(BUILDDIR)/common/Defs.gmk ++ ++# ++# Files ++# ++AUTO_FILES_JAVA_DIRS = sun/beans ++ ++# ++# Rules ++# ++include $(BUILDDIR)/common/Classes.gmk +diff --git a/src/share/classes/com/sun/beans/editors/EnumEditor.java b/src/share/classes/com/sun/beans/editors/EnumEditor.java +--- jdk/src/share/classes/com/sun/beans/editors/EnumEditor.java ++++ jdk/src/share/classes/com/sun/beans/editors/EnumEditor.java +@@ -42,7 +42,7 @@ +  * +  * @author Sergey A. Malenkov +  */ +-public final class EnumEditor implements PropertyEditor { ++public class EnumEditor implements PropertyEditor { +     private final List<PropertyChangeListener> listeners = new ArrayList<PropertyChangeListener>(); +  +     private final Class type; +diff --git a/src/share/classes/sun/beans/editors/BooleanEditor.java b/src/share/classes/sun/beans/editors/BooleanEditor.java +new file mode 100644 +--- /dev/null ++++ jdk/src/share/classes/sun/beans/editors/BooleanEditor.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.beans.editors; ++ ++/** ++ * FOR BACKWARD COMPATIBILITY ONLY - DO NOT USE. ++ */ ++public class BooleanEditor extends com.sun.beans.editors.BooleanEditor { ++} +diff --git a/src/share/classes/sun/beans/editors/ByteEditor.java b/src/share/classes/sun/beans/editors/ByteEditor.java +new file mode 100644 +--- /dev/null ++++ jdk/src/share/classes/sun/beans/editors/ByteEditor.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.beans.editors; ++ ++/** ++ * FOR BACKWARD COMPATIBILITY ONLY - DO NOT USE. ++ */ ++public class ByteEditor extends com.sun.beans.editors.ByteEditor { ++} +diff --git a/src/share/classes/sun/beans/editors/ColorEditor.java b/src/share/classes/sun/beans/editors/ColorEditor.java +new file mode 100644 +--- /dev/null ++++ jdk/src/share/classes/sun/beans/editors/ColorEditor.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.beans.editors; ++ ++/** ++ * FOR BACKWARD COMPATIBILITY ONLY - DO NOT USE. ++ */ ++public class ColorEditor extends com.sun.beans.editors.ColorEditor { ++} +diff --git a/src/share/classes/sun/beans/editors/DoubleEditor.java b/src/share/classes/sun/beans/editors/DoubleEditor.java +new file mode 100644 +--- /dev/null ++++ jdk/src/share/classes/sun/beans/editors/DoubleEditor.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.beans.editors; ++ ++/** ++ * FOR BACKWARD COMPATIBILITY ONLY - DO NOT USE. ++ */ ++public class DoubleEditor extends com.sun.beans.editors.DoubleEditor { ++} +diff --git a/src/share/classes/sun/beans/editors/EnumEditor.java b/src/share/classes/sun/beans/editors/EnumEditor.java +new file mode 100644 +--- /dev/null ++++ jdk/src/share/classes/sun/beans/editors/EnumEditor.java +@@ -0,0 +1,35 @@ ++/* ++ * 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.beans.editors; ++ ++/** ++ * FOR BACKWARD COMPATIBILITY ONLY - DO NOT USE. ++ */ ++public class EnumEditor extends com.sun.beans.editors.EnumEditor { ++    public EnumEditor(Class type) { ++        super(type); ++    } ++} +diff --git a/src/share/classes/sun/beans/editors/FloatEditor.java b/src/share/classes/sun/beans/editors/FloatEditor.java +new file mode 100644 +--- /dev/null ++++ jdk/src/share/classes/sun/beans/editors/FloatEditor.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.beans.editors; ++ ++/** ++ * FOR BACKWARD COMPATIBILITY ONLY - DO NOT USE. ++ */ ++public class FloatEditor extends com.sun.beans.editors.FloatEditor { ++} +diff --git a/src/share/classes/sun/beans/editors/FontEditor.java b/src/share/classes/sun/beans/editors/FontEditor.java +new file mode 100644 +--- /dev/null ++++ jdk/src/share/classes/sun/beans/editors/FontEditor.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.beans.editors; ++ ++/** ++ * FOR BACKWARD COMPATIBILITY ONLY - DO NOT USE. ++ */ ++public class FontEditor extends com.sun.beans.editors.FontEditor { ++} +diff --git a/src/share/classes/sun/beans/editors/IntegerEditor.java b/src/share/classes/sun/beans/editors/IntegerEditor.java +new file mode 100644 +--- /dev/null ++++ jdk/src/share/classes/sun/beans/editors/IntegerEditor.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.beans.editors; ++ ++/** ++ * FOR BACKWARD COMPATIBILITY ONLY - DO NOT USE. ++ */ ++public class IntegerEditor extends com.sun.beans.editors.IntegerEditor { ++} +diff --git a/src/share/classes/sun/beans/editors/LongEditor.java b/src/share/classes/sun/beans/editors/LongEditor.java +new file mode 100644 +--- /dev/null ++++ jdk/src/share/classes/sun/beans/editors/LongEditor.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.beans.editors; ++ ++/** ++ * FOR BACKWARD COMPATIBILITY ONLY - DO NOT USE. ++ */ ++public class LongEditor extends com.sun.beans.editors.LongEditor { ++} +diff --git a/src/share/classes/sun/beans/editors/NumberEditor.java b/src/share/classes/sun/beans/editors/NumberEditor.java +new file mode 100644 +--- /dev/null ++++ jdk/src/share/classes/sun/beans/editors/NumberEditor.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.beans.editors; ++ ++/** ++ * FOR BACKWARD COMPATIBILITY ONLY - DO NOT USE. ++ */ ++abstract public class NumberEditor extends com.sun.beans.editors.NumberEditor { ++} +diff --git a/src/share/classes/sun/beans/editors/ShortEditor.java b/src/share/classes/sun/beans/editors/ShortEditor.java +new file mode 100644 +--- /dev/null ++++ jdk/src/share/classes/sun/beans/editors/ShortEditor.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.beans.editors; ++ ++/** ++ * FOR BACKWARD COMPATIBILITY ONLY - DO NOT USE. ++ */ ++public class ShortEditor extends com.sun.beans.editors.ShortEditor { ++} +diff --git a/src/share/classes/sun/beans/editors/StringEditor.java b/src/share/classes/sun/beans/editors/StringEditor.java +new file mode 100644 +--- /dev/null ++++ jdk/src/share/classes/sun/beans/editors/StringEditor.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.beans.editors; ++ ++/** ++ * FOR BACKWARD COMPATIBILITY ONLY - DO NOT USE. ++ */ ++public class StringEditor extends com.sun.beans.editors.StringEditor { ++} diff --git a/java/openjdk6/files/icedtea/security/20130201/6563318.patch b/java/openjdk6/files/icedtea/security/20130201/6563318.patch new file mode 100644 index 000000000000..8935ed6666c8 --- /dev/null +++ b/java/openjdk6/files/icedtea/security/20130201/6563318.patch @@ -0,0 +1,36 @@ +# 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 +--- jdk/src/share/classes/sun/rmi/transport/proxy/CGIHandler.java ++++ 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); diff --git a/java/openjdk6/files/icedtea/security/20130201/6664509.patch b/java/openjdk6/files/icedtea/security/20130201/6664509.patch new file mode 100644 index 000000000000..8d8f3191d014 --- /dev/null +++ b/java/openjdk6/files/icedtea/security/20130201/6664509.patch @@ -0,0 +1,1322 @@ +# 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 +--- jdk/src/share/classes/java/util/logging/Level.java ++++ 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 +--- jdk/src/share/classes/java/util/logging/LogManager.java ++++ 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 +--- jdk/src/share/classes/java/util/logging/Logger.java ++++ 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 +--- jdk/src/share/classes/java/util/logging/Logging.java ++++ 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 +--- jdk/src/share/classes/java/util/logging/SimpleFormatter.java ++++ 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 +--- jdk/src/share/classes/sun/awt/AppContext.java ++++ 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 +--- jdk/src/share/classes/sun/misc/JavaAWTAccess.java ++++ 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 +--- jdk/src/share/lib/security/java.security ++++ 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 diff --git a/java/openjdk6/files/icedtea/security/20130201/6776941.patch b/java/openjdk6/files/icedtea/security/20130201/6776941.patch new file mode 100644 index 000000000000..7604b50b9b22 --- /dev/null +++ b/java/openjdk6/files/icedtea/security/20130201/6776941.patch @@ -0,0 +1,272 @@ +# 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 +--- jdk/src/share/classes/java/util/concurrent/ThreadPoolExecutor.java ++++ 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(); diff --git a/java/openjdk6/files/icedtea/security/20130201/7141694.patch b/java/openjdk6/files/icedtea/security/20130201/7141694.patch new file mode 100644 index 000000000000..66d69a7b69a7 --- /dev/null +++ b/java/openjdk6/files/icedtea/security/20130201/7141694.patch @@ -0,0 +1,87 @@ +# 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 +--- corba/src/share/classes/com/sun/corba/se/spi/orb/ORB.java ++++ 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() diff --git a/java/openjdk6/files/icedtea/security/20130201/7173145.patch b/java/openjdk6/files/icedtea/security/20130201/7173145.patch new file mode 100644 index 000000000000..b7971618d3d7 --- /dev/null +++ b/java/openjdk6/files/icedtea/security/20130201/7173145.patch @@ -0,0 +1,22 @@ +# 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 +--- jdk/src/share/native/sun/awt/splashscreen/splashscreen_jpeg.c ++++ 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); diff --git a/java/openjdk6/files/icedtea/security/20130201/7186945.patch b/java/openjdk6/files/icedtea/security/20130201/7186945.patch new file mode 100644 index 000000000000..007ff979f1b7 --- /dev/null +++ b/java/openjdk6/files/icedtea/security/20130201/7186945.patch @@ -0,0 +1,10819 @@ +# 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 +--- jdk/src/share/classes/com/sun/java/util/jar/pack/BandStructure.java ++++ 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 +--- jdk/src/share/classes/com/sun/java/util/jar/pack/ConstantPool.java ++++ 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 +--- jdk/src/share/classes/com/sun/java/util/jar/pack/NativeUnpack.java ++++ 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 +--- jdk/src/share/classes/com/sun/java/util/jar/pack/PackerImpl.java ++++ 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 +--- jdk/src/share/classes/com/sun/java/util/jar/pack/UnpackerImpl.java ++++ 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 +--- jdk/src/share/native/com/sun/java/util/jar/pack/bands.cpp ++++ 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 +--- jdk/src/share/native/com/sun/java/util/jar/pack/bands.h ++++ 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 +--- jdk/src/share/native/com/sun/java/util/jar/pack/defines.h ++++ 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 +--- jdk/src/share/native/com/sun/java/util/jar/pack/jni.cpp ++++ 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 +--- jdk/src/share/native/com/sun/java/util/jar/pack/unpack.cpp ++++ 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 + } ++ ++ diff --git a/java/openjdk6/files/icedtea/security/20130201/7186948.patch b/java/openjdk6/files/icedtea/security/20130201/7186948.patch new file mode 100644 index 000000000000..1313561fda6a --- /dev/null +++ b/java/openjdk6/files/icedtea/security/20130201/7186948.patch @@ -0,0 +1,20 @@ +# 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 +--- jdk/src/share/classes/javax/swing/UIDefaults.java ++++ 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) { diff --git a/java/openjdk6/files/icedtea/security/20130201/7186952.patch b/java/openjdk6/files/icedtea/security/20130201/7186952.patch new file mode 100644 index 000000000000..0c6c8ee2e67e --- /dev/null +++ b/java/openjdk6/files/icedtea/security/20130201/7186952.patch @@ -0,0 +1,127 @@ +# 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 +--- jdk/src/share/classes/java/awt/TextComponent.java ++++ 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 +--- jdk/src/windows/native/sun/windows/awt_TextComponent.cpp ++++ 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 +--- jdk/src/windows/native/sun/windows/awt_TextComponent.h ++++ 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(); +  diff --git a/java/openjdk6/files/icedtea/security/20130201/7186954.patch b/java/openjdk6/files/icedtea/security/20130201/7186954.patch new file mode 100644 index 000000000000..b3fbfcaafb0b --- /dev/null +++ b/java/openjdk6/files/icedtea/security/20130201/7186954.patch @@ -0,0 +1,81 @@ +# 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 +--- jdk/src/share/classes/sun/net/httpserver/ChunkedInputStream.java ++++ 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 +--- jdk/src/share/classes/sun/net/www/http/ChunkedInputStream.java ++++ 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; diff --git a/java/openjdk6/files/icedtea/security/20130201/7192392.patch b/java/openjdk6/files/icedtea/security/20130201/7192392.patch new file mode 100644 index 000000000000..5e51b99c7e64 --- /dev/null +++ b/java/openjdk6/files/icedtea/security/20130201/7192392.patch @@ -0,0 +1,695 @@ +# 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 +--- jdk/src/share/classes/com/sun/crypto/provider/DHKeyAgreement.java ++++ 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 +--- jdk/src/share/classes/sun/security/pkcs11/P11KeyAgreement.java ++++ 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 +--- jdk/src/share/classes/sun/security/ssl/ClientHandshaker.java ++++ 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 +--- jdk/src/share/classes/sun/security/ssl/DHClientKeyExchange.java ++++ 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 +--- jdk/src/share/classes/sun/security/ssl/DHCrypt.java ++++ 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 +--- jdk/src/share/classes/sun/security/ssl/HandshakeMessage.java ++++ 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 +--- jdk/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java ++++ 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 +--- jdk/src/share/classes/sun/security/ssl/ServerHandshaker.java ++++ 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 +--- 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 ++++ 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. ++    } ++} diff --git a/java/openjdk6/files/icedtea/security/20130201/7192393.patch b/java/openjdk6/files/icedtea/security/20130201/7192393.patch new file mode 100644 index 000000000000..f9c312d5f019 --- /dev/null +++ b/java/openjdk6/files/icedtea/security/20130201/7192393.patch @@ -0,0 +1,60 @@ +# 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 +--- jdk/src/share/classes/sun/security/ssl/ClientHandshaker.java ++++ 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 +--- jdk/src/share/classes/sun/security/ssl/ServerHandshaker.java ++++ 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 diff --git a/java/openjdk6/files/icedtea/security/20130201/7192977.patch b/java/openjdk6/files/icedtea/security/20130201/7192977.patch new file mode 100644 index 000000000000..19e366b08377 --- /dev/null +++ b/java/openjdk6/files/icedtea/security/20130201/7192977.patch @@ -0,0 +1,436 @@ +diff --git a/src/share/classes/java/awt/EventQueue.java b/src/share/classes/java/awt/EventQueue.java +--- jdk/src/share/classes/java/awt/EventQueue.java ++++ 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 +--- jdk/src/share/classes/java/awt/Window.java ++++ 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 +--- jdk/src/share/classes/javax/swing/RepaintManager.java ++++ 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 +--- jdk/src/share/classes/sun/applet/AppletPanel.java ++++ 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 +--- jdk/src/share/classes/sun/awt/AWTAccessor.java ++++ 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 +--- jdk/src/windows/classes/sun/awt/windows/WComponentPeer.java ++++ 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)); +         } +     } +  diff --git a/java/openjdk6/files/icedtea/security/20130201/7197546.patch b/java/openjdk6/files/icedtea/security/20130201/7197546.patch new file mode 100644 index 000000000000..890ae091d9f0 --- /dev/null +++ b/java/openjdk6/files/icedtea/security/20130201/7197546.patch @@ -0,0 +1,479 @@ +# 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 +--- jdk/src/share/classes/java/lang/Class.java ++++ 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 +--- jdk/src/share/classes/java/lang/reflect/Proxy.java ++++ 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 +--- jdk/src/share/classes/sun/reflect/misc/ReflectUtil.java ++++ 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"; + } diff --git a/java/openjdk6/files/icedtea/security/20130201/7200491.patch b/java/openjdk6/files/icedtea/security/20130201/7200491.patch new file mode 100644 index 000000000000..c8bfbf50eb27 --- /dev/null +++ b/java/openjdk6/files/icedtea/security/20130201/7200491.patch @@ -0,0 +1,49 @@ +# 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 +--- jdk/src/share/classes/com/sun/java/swing/plaf/nimbus/NimbusLookAndFeel.java ++++ 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 +--- jdk/src/share/classes/javax/swing/JTable.java ++++ 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); diff --git a/java/openjdk6/files/icedtea/security/20130201/7200500.patch b/java/openjdk6/files/icedtea/security/20130201/7200500.patch new file mode 100644 index 000000000000..20106060ee3b --- /dev/null +++ b/java/openjdk6/files/icedtea/security/20130201/7200500.patch @@ -0,0 +1,60 @@ +# 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 +--- jdk/src/share/bin/parse_manifest.c ++++ 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); diff --git a/java/openjdk6/files/icedtea/security/20130201/7201064.patch b/java/openjdk6/files/icedtea/security/20130201/7201064.patch new file mode 100644 index 000000000000..3ab97af24fc9 --- /dev/null +++ b/java/openjdk6/files/icedtea/security/20130201/7201064.patch @@ -0,0 +1,117 @@ +diff --git a/src/share/classes/java/awt/Dialog.java b/src/share/classes/java/awt/Dialog.java +--- jdk/src/share/classes/java/awt/Dialog.java ++++ 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; ++ +     } +  +     /* diff --git a/java/openjdk6/files/icedtea/security/20130201/7201066.patch b/java/openjdk6/files/icedtea/security/20130201/7201066.patch new file mode 100644 index 000000000000..2a38f116a6f0 --- /dev/null +++ b/java/openjdk6/files/icedtea/security/20130201/7201066.patch @@ -0,0 +1,66 @@ +# 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 +--- corba/src/share/classes/com/sun/corba/se/impl/activation/ServerMain.java ++++ 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 +--- corba/src/share/classes/com/sun/corba/se/impl/io/ObjectStreamClass.java ++++ 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 +--- corba/src/share/classes/com/sun/corba/se/impl/orbutil/ObjectStreamClass_1_3_1.java ++++ 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. diff --git a/java/openjdk6/files/icedtea/security/20130201/7201068.patch b/java/openjdk6/files/icedtea/security/20130201/7201068.patch new file mode 100644 index 000000000000..a9e9e7f859ad --- /dev/null +++ b/java/openjdk6/files/icedtea/security/20130201/7201068.patch @@ -0,0 +1,83 @@ +# 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 +--- jdk/src/share/lib/security/java.security ++++ 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 +--- jdk/src/share/lib/security/java.security-solaris ++++ 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 +--- jdk/src/share/lib/security/java.security-windows ++++ 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 diff --git a/java/openjdk6/files/icedtea/security/20130201/7201070.patch b/java/openjdk6/files/icedtea/security/20130201/7201070.patch new file mode 100644 index 000000000000..77df21d28374 --- /dev/null +++ b/java/openjdk6/files/icedtea/security/20130201/7201070.patch @@ -0,0 +1,31 @@ +# 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 +--- jdk/src/share/classes/java/io/ObjectInputStream.java ++++ 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; diff --git a/java/openjdk6/files/icedtea/security/20130201/7201071.patch b/java/openjdk6/files/icedtea/security/20130201/7201071.patch new file mode 100644 index 000000000000..58329d174c3a --- /dev/null +++ b/java/openjdk6/files/icedtea/security/20130201/7201071.patch @@ -0,0 +1,553 @@ +# 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 +--- jdk/src/share/classes/java/net/InetSocketAddress.java ++++ 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 +--- jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java ++++ 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 +--- jdk/src/solaris/native/sun/nio/ch/DatagramChannelImpl.c ++++ 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 +--- jdk/src/windows/native/sun/nio/ch/DatagramChannelImpl.c ++++ 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 +--- jdk/test/java/nio/channels/DatagramChannel/SendToUnresolved.java ++++ 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(); +     } diff --git a/java/openjdk6/files/icedtea/security/20130201/8000210.patch b/java/openjdk6/files/icedtea/security/20130201/8000210.patch new file mode 100644 index 000000000000..28bcddfb2ab6 --- /dev/null +++ b/java/openjdk6/files/icedtea/security/20130201/8000210.patch @@ -0,0 +1,104 @@ +# 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 +--- jdk/src/share/classes/java/util/jar/JarFile.java ++++ 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 +--- jdk/src/share/classes/sun/security/util/DerIndefLenConverter.java ++++ 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; +  diff --git a/java/openjdk6/files/icedtea/security/20130201/8000537.patch b/java/openjdk6/files/icedtea/security/20130201/8000537.patch new file mode 100644 index 000000000000..8e7bb54a4644 --- /dev/null +++ b/java/openjdk6/files/icedtea/security/20130201/8000537.patch @@ -0,0 +1,334 @@ +# 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 +--- jdk/src/share/classes/javax/management/modelmbean/RequiredModelMBean.java ++++ 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; +     } +  +  diff --git a/java/openjdk6/files/icedtea/security/20130201/8000540.patch b/java/openjdk6/files/icedtea/security/20130201/8000540.patch new file mode 100644 index 000000000000..4b0495c400f4 --- /dev/null +++ b/java/openjdk6/files/icedtea/security/20130201/8000540.patch @@ -0,0 +1,187 @@ +# 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 +--- corba/src/share/classes/com/sun/corba/se/impl/io/ObjectStreamClass.java ++++ 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 ; +-        } +     } +  +     /* diff --git a/java/openjdk6/files/icedtea/security/20130201/8000631.patch b/java/openjdk6/files/icedtea/security/20130201/8000631.patch new file mode 100644 index 000000000000..bdf6781e30a5 --- /dev/null +++ b/java/openjdk6/files/icedtea/security/20130201/8000631.patch @@ -0,0 +1,3964 @@ +# 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 +--- corba/make/com/sun/corba/minclude/com_sun_corba_se_impl_orbutil.jmk ++++ 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 +--- corba/src/share/classes/com/sun/corba/se/impl/corba/AnyImpl.java ++++ 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 +--- corba/src/share/classes/com/sun/corba/se/impl/encoding/CDRInputStream_1_0.java ++++ 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 +--- corba/src/share/classes/com/sun/corba/se/impl/encoding/CDROutputStream_1_0.java ++++ 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 +--- corba/src/share/classes/com/sun/corba/se/impl/io/FVDCodeBaseImpl.java ++++ 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 +--- corba/src/share/classes/com/sun/corba/se/impl/io/ValueHandlerImpl.java ++++ 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 +--- corba/src/share/classes/com/sun/corba/se/impl/io/ValueUtility.java ++++ 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 +--- corba/src/share/classes/com/sun/corba/se/impl/javax/rmi/CORBA/Util.java ++++ 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 +--- corba/src/share/classes/com/sun/corba/se/impl/orb/ORBImpl.java ++++ 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 +--- 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 +--- 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 +--- 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 +--- 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 +--- corba/src/share/classes/com/sun/corba/se/impl/orbutil/ORBUtility.java ++++ 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 +--- 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 +--- 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 +--- 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 +--- 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 +--- corba/src/share/classes/com/sun/corba/se/impl/orbutil/RepositoryIdFactory.java ++++ 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 +--- 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 +--- 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 +--- 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 +--- 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 ++++ 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 ++++ 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; ++    } ++ ++} diff --git a/java/openjdk6/files/icedtea/security/20130201/8001235.patch b/java/openjdk6/files/icedtea/security/20130201/8001235.patch new file mode 100644 index 000000000000..73d700c3bc30 --- /dev/null +++ b/java/openjdk6/files/icedtea/security/20130201/8001235.patch @@ -0,0 +1,37 @@ +diff -Nru jaxp.old/build.properties jaxp/build.properties +--- jaxp.old/build.properties	2013-02-01 21:59:17.360429006 +0000 ++++ 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 +--- jaxp.old/patches/jaxp_src/8001235.patch	1970-01-01 01:00:00.000000000 +0100 ++++ 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 ++     { diff --git a/java/openjdk6/files/icedtea/security/20130201/8001242.patch b/java/openjdk6/files/icedtea/security/20130201/8001242.patch new file mode 100644 index 000000000000..5c983c3dc11d --- /dev/null +++ b/java/openjdk6/files/icedtea/security/20130201/8001242.patch @@ -0,0 +1,61 @@ +# 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 +--- jdk/src/share/classes/sun/rmi/transport/proxy/CGIHandler.java ++++ 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 +--- jdk/src/share/classes/sun/rmi/transport/proxy/HttpInputStream.java ++++ 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. diff --git a/java/openjdk6/files/icedtea/security/20130201/8001307.patch b/java/openjdk6/files/icedtea/security/20130201/8001307.patch new file mode 100644 index 000000000000..4794f95418a7 --- /dev/null +++ b/java/openjdk6/files/icedtea/security/20130201/8001307.patch @@ -0,0 +1,27 @@ +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 ++++ 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 ++++ 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 diff --git a/java/openjdk6/files/icedtea/security/20130201/8001972.patch b/java/openjdk6/files/icedtea/security/20130201/8001972.patch new file mode 100644 index 000000000000..b379b7a6b9ec --- /dev/null +++ b/java/openjdk6/files/icedtea/security/20130201/8001972.patch @@ -0,0 +1,438 @@ +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 ++++ 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 ++++ 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 ++++ 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 ++++ 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 ++++ 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 ++++ 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__ diff --git a/java/openjdk6/files/icedtea/security/20130201/8002325.patch b/java/openjdk6/files/icedtea/security/20130201/8002325.patch new file mode 100644 index 000000000000..9de38623270b --- /dev/null +++ b/java/openjdk6/files/icedtea/security/20130201/8002325.patch @@ -0,0 +1,59 @@ +# 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 +--- jdk/src/share/native/sun/awt/image/awt_parseImage.c ++++ 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 +--- jdk/src/share/native/sun/awt/image/awt_parseImage.h ++++ 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 */ diff --git a/java/openjdk6/files/icedtea/security/20130219/8006446.patch b/java/openjdk6/files/icedtea/security/20130219/8006446.patch new file mode 100644 index 000000000000..80501ea62890 --- /dev/null +++ b/java/openjdk6/files/icedtea/security/20130219/8006446.patch @@ -0,0 +1,395 @@ +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 ++++ 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 ++++ 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 ++++ 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 ++++ 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 ++++ 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 ++++ 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 ++++ 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 ++++ 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 ++++ 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 ++++ 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 ++++ 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"); diff --git a/java/openjdk6/files/icedtea/security/20130219/8006777.patch b/java/openjdk6/files/icedtea/security/20130219/8006777.patch new file mode 100644 index 000000000000..913617accfd5 --- /dev/null +++ b/java/openjdk6/files/icedtea/security/20130219/8006777.patch @@ -0,0 +1,1036 @@ +# 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 +--- jdk/src/share/classes/sun/security/ssl/CipherBox.java ++++ 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 +--- jdk/src/share/classes/sun/security/ssl/CipherSuite.java ++++ 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 +--- jdk/src/share/classes/sun/security/ssl/EngineInputRecord.java ++++ 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 +--- jdk/src/share/classes/sun/security/ssl/EngineOutputRecord.java ++++ 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 +--- jdk/src/share/classes/sun/security/ssl/InputRecord.java ++++ 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 +--- jdk/src/share/classes/sun/security/ssl/MAC.java ++++ 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 +--- jdk/src/share/classes/sun/security/ssl/OutputRecord.java ++++ 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 +--- jdk/src/share/classes/sun/security/ssl/SSLEngineImpl.java ++++ 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 +--- jdk/src/share/classes/sun/security/ssl/SSLSocketImpl.java ++++ 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)) diff --git a/java/openjdk6/files/icedtea/security/20130219/8007688.patch b/java/openjdk6/files/icedtea/security/20130219/8007688.patch new file mode 100644 index 000000000000..bc13a982ab4f --- /dev/null +++ b/java/openjdk6/files/icedtea/security/20130219/8007688.patch @@ -0,0 +1,130 @@ +# 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 +--- jdk/src/share/classes/sun/security/util/UntrustedCertificates.java ++++ 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-----"); ++ +     } + } diff --git a/java/openjdk6/files/patch-set b/java/openjdk6/files/patch-set index ae59dafe8471..0fabe80c09e8 100644 --- a/java/openjdk6/files/patch-set +++ b/java/openjdk6/files/patch-set @@ -11233,9 +11233,9 @@   typedef unsigned long uLong;   #endif  +#endif - #ifdef _MSC_VER - typedef LONGLONG        jlong; - typedef DWORDLONG       julong; + #ifdef _MSC_VER  + typedef LONGLONG 	jlong; + typedef DWORDLONG 	julong;  --- jdk/src/share/native/com/sun/java/util/jar/pack/main.cpp  +++ jdk/src/share/native/com/sun/java/util/jar/pack/main.cpp  @@ -33,9 +33,14 @@  | 
