Merge
authordfuchs
Fri, 13 Mar 2009 14:25:48 +0100
changeset 2286 39d833fd1ef7
parent 2285 37fdbed8178f (current diff)
parent 2281 34fd38495efa (diff)
child 2287 81ef4b88c590
Merge
jdk/src/share/classes/sun/misc/JavaIODeleteOnExitAccess.java
--- a/jdk/make/docs/Makefile	Thu Mar 12 15:36:14 2009 +0100
+++ b/jdk/make/docs/Makefile	Fri Mar 13 14:25:48 2009 +0100
@@ -1,5 +1,5 @@
 #
-# Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -204,6 +204,9 @@
 JDI_HEADER      = "Java Debug Interface"
 # JDI_PKGS is located in NON_CORE_PKGS.gmk
 
+# Variables used by security components
+SECURITYAPI_JAVADOCBOTTOM = '<font size="-1"><a href="http://bugs.sun.com/services/bugreport/index.jsp">Report a bug or request a feature.</a><br>Copyright $(THIS_YEAR) Sun Microsystems, Inc. All Rights Reserved. Use is subject to license terms.</font>'
+
 #
 # Variables used by JAAS target
 #
@@ -221,6 +224,7 @@
                    -windowtitle $(JAAS_WINDOWTITLE)              \
                    -doctitle $(JAAS_DOCTITLE)                    \
                    -header $(JAAS_JAVADOCHEADER)                 \
+                   -bottom $(SECURITYAPI_JAVADOCBOTTOM)                      \
                    -linkoffline ../../../../../api $(DOCSDIR)/api/	 \
                    -overview $(TOPDIR)/src/share/classes/com/sun/security/auth/jaas-overview.html
 JAAS_WINDOWTITLE = "Java Authentication and Authorization Service "
@@ -243,6 +247,7 @@
                    -windowtitle $(JGSS_WINDOWTITLE)             \
                    -doctitle $(JGSS_DOCTITLE)                   \
                    -header $(JGSS_JAVADOCHEADER)                \
+                   -bottom $(SECURITYAPI_JAVADOCBOTTOM)                      \
                    -linkoffline ../../../../../api $(DOCSDIR)/api/ \
                    -overview $(JGSS_SOURCEPATH)/com/sun/security/jgss/jgss-overview.html
 
@@ -266,6 +271,7 @@
                    -windowtitle $(SMARTCARDIO_WINDOWTITLE)             \
                    -doctitle $(SMARTCARDIO_DOCTITLE)                   \
                    -header $(SMARTCARDIO_JAVADOCHEADER)                \
+                   -bottom $(SECURITYAPI_JAVADOCBOTTOM)                      \
                    -linkoffline ../../../../../api $(DOCSDIR)/api/
 
 SMARTCARDIO_WINDOWTITLE = "Java Smart Card I/O"
--- a/jdk/make/java/java/FILES_java.gmk	Thu Mar 12 15:36:14 2009 +0100
+++ b/jdk/make/java/java/FILES_java.gmk	Fri Mar 13 14:25:48 2009 +0100
@@ -449,7 +449,6 @@
     sun/misc/Service.java \
     sun/misc/JavaLangAccess.java \
     sun/misc/JavaIOAccess.java \
-    sun/misc/JavaIODeleteOnExitAccess.java \
     sun/misc/JavaIOFileDescriptorAccess.java \
     sun/misc/JavaNioAccess.java
 
--- a/jdk/src/share/classes/java/io/Console.java	Thu Mar 12 15:36:14 2009 +0100
+++ b/jdk/src/share/classes/java/io/Console.java	Fri Mar 13 14:25:48 2009 +0100
@@ -503,6 +503,21 @@
 
     // Set up JavaIOAccess in SharedSecrets
     static {
+
+        // Add a shutdown hook to restore console's echo state should
+        // it be necessary.
+        sun.misc.SharedSecrets.getJavaLangAccess()
+            .registerShutdownHook(0 /* shutdown hook invocation order */,
+                new Runnable() {
+                    public void run() {
+                        try {
+                            if (echoOff) {
+                                echo(true);
+                            }
+                        } catch (IOException x) { }
+                    }
+                });
+
         sun.misc.SharedSecrets.setJavaIOAccess(new sun.misc.JavaIOAccess() {
             public Console console() {
                 if (istty()) {
@@ -513,20 +528,6 @@
                 return null;
             }
 
-            // Add a shutdown hook to restore console's echo state should
-            // it be necessary.
-            public Runnable consoleRestoreHook() {
-                return new Runnable() {
-                    public void run() {
-                        try {
-                            if (echoOff) {
-                                echo(true);
-                            }
-                        } catch (IOException x) {}
-                    }
-                };
-            }
-
             public Charset charset() {
                 // This method is called in sun.security.util.Password,
                 // cons already exists when this method is called
--- a/jdk/src/share/classes/java/io/DeleteOnExitHook.java	Thu Mar 12 15:36:14 2009 +0100
+++ b/jdk/src/share/classes/java/io/DeleteOnExitHook.java	Fri Mar 13 14:25:48 2009 +0100
@@ -34,17 +34,18 @@
  */
 
 class DeleteOnExitHook {
-    private static DeleteOnExitHook instance = null;
+    static {
+         sun.misc.SharedSecrets.getJavaLangAccess()
+             .registerShutdownHook(2 /* Shutdown hook invocation order */,
+                 new Runnable() {
+                     public void run() {
+                        runHooks();
+                     }
+                 });
+    }
 
     private static LinkedHashSet<String> files = new LinkedHashSet<String>();
 
-    static DeleteOnExitHook hook() {
-        if (instance == null)
-            instance = new DeleteOnExitHook();
-
-        return instance;
-    }
-
     private DeleteOnExitHook() {}
 
     static synchronized void add(String file) {
@@ -54,7 +55,7 @@
         files.add(file);
     }
 
-    void run() {
+    static void runHooks() {
         LinkedHashSet<String> theFiles;
 
         synchronized (DeleteOnExitHook.class) {
--- a/jdk/src/share/classes/java/io/File.java	Thu Mar 12 15:36:14 2009 +0100
+++ b/jdk/src/share/classes/java/io/File.java	Fri Mar 13 14:25:48 2009 +0100
@@ -2147,18 +2147,6 @@
     /** use serialVersionUID from JDK 1.0.2 for interoperability */
     private static final long serialVersionUID = 301077366599181567L;
 
-    // Set up JavaIODeleteOnExitAccess in SharedSecrets
-    // Added here as DeleteOnExitHook is package-private and SharedSecrets cannot easily access it.
-    static {
-        sun.misc.SharedSecrets.setJavaIODeleteOnExitAccess(
-            new sun.misc.JavaIODeleteOnExitAccess() {
-                public void run() {
-                    DeleteOnExitHook.hook().run();
-                }
-            }
-        );
-    }
-
     // -- Integration with java.nio.file --
 
     private volatile transient Path filePath;
--- a/jdk/src/share/classes/java/lang/ApplicationShutdownHooks.java	Thu Mar 12 15:36:14 2009 +0100
+++ b/jdk/src/share/classes/java/lang/ApplicationShutdownHooks.java	Fri Mar 13 14:25:48 2009 +0100
@@ -34,19 +34,19 @@
  * @see java.lang.Runtime#removeShutdownHook
  */
 
-class ApplicationShutdownHooks implements Runnable {
-    private static ApplicationShutdownHooks instance = null;
+class ApplicationShutdownHooks {
+    static {
+        Shutdown.add(1 /* shutdown hook invocation order */,
+            new Runnable() {
+                public void run() {
+                    runHooks();
+                }
+            });
+    }
 
     /* The set of registered hooks */
     private static IdentityHashMap<Thread, Thread> hooks = new IdentityHashMap<Thread, Thread>();
 
-    static synchronized ApplicationShutdownHooks hook() {
-        if (instance == null)
-            instance = new ApplicationShutdownHooks();
-
-        return instance;
-    }
-
     private ApplicationShutdownHooks() {}
 
     /* Add a new shutdown hook.  Checks the shutdown state and the hook itself,
@@ -82,7 +82,7 @@
      * to run in. Hooks are run concurrently and this method waits for
      * them to finish.
      */
-    public void run() {
+    static void runHooks() {
         Collection<Thread> threads;
         synchronized(ApplicationShutdownHooks.class) {
             threads = hooks.keySet();
--- a/jdk/src/share/classes/java/lang/Shutdown.java	Thu Mar 12 15:36:14 2009 +0100
+++ b/jdk/src/share/classes/java/lang/Shutdown.java	Fri Mar 13 14:25:48 2009 +0100
@@ -25,8 +25,6 @@
 
 package java.lang;
 
-import java.util.ArrayList;
-
 
 /**
  * Package-private utility class containing data structures and logic
@@ -47,8 +45,13 @@
     /* Should we run all finalizers upon exit? */
     private static boolean runFinalizersOnExit = false;
 
-    /* The set of registered, wrapped hooks, or null if there aren't any */
-    private static ArrayList<Runnable> hooks = new ArrayList<Runnable>();
+    // The system shutdown hooks are registered with a predefined slot.
+    // The list of shutdown hooks is as follows:
+    // (0) Console restore hook
+    // (1) Application hooks
+    // (2) DeleteOnExit hook
+    private static final int MAX_SYSTEM_HOOKS = 10;
+    private static final Runnable[] hooks = new Runnable[MAX_SYSTEM_HOOKS];
 
     /* The preceding static fields are protected by this lock */
     private static class Lock { };
@@ -68,33 +71,18 @@
     /* Add a new shutdown hook.  Checks the shutdown state and the hook itself,
      * but does not do any security checks.
      */
-    static void add(Runnable hook) {
+    static void add(int slot, Runnable hook) {
         synchronized (lock) {
             if (state > RUNNING)
                 throw new IllegalStateException("Shutdown in progress");
 
-            hooks.add(hook);
+            if (hooks[slot] != null)
+                throw new InternalError("Shutdown hook at slot " + slot + " already registered");
+
+            hooks[slot] = hook;
         }
     }
 
-
-    /* Remove a previously-registered hook.  Like the add method, this method
-     * does not do any security checks.
-     */
-    static boolean remove(Runnable hook) {
-        synchronized (lock) {
-            if (state > RUNNING)
-                throw new IllegalStateException("Shutdown in progress");
-            if (hook == null) throw new NullPointerException();
-            if (hooks == null) {
-                return false;
-            } else {
-                return hooks.remove(hook);
-            }
-        }
-    }
-
-
     /* Run all registered shutdown hooks
      */
     private static void runHooks() {
@@ -103,7 +91,7 @@
          */
         for (Runnable hook : hooks) {
             try {
-                hook.run();
+                if (hook != null) hook.run();
             } catch(Throwable t) {
                 if (t instanceof ThreadDeath) {
                     ThreadDeath td = (ThreadDeath)t;
--- a/jdk/src/share/classes/java/lang/System.java	Thu Mar 12 15:36:14 2009 +0100
+++ b/jdk/src/share/classes/java/lang/System.java	Fri Mar 13 14:25:48 2009 +0100
@@ -1121,14 +1121,6 @@
         // Setup Java signal handlers for HUP, TERM, and INT (where available).
         Terminator.setup();
 
-        // The order in with the hooks are added here is important as it
-        // determines the order in which they are run.
-        // (1)Console restore hook needs to be called first.
-        // (2)Application hooks must be run before calling deleteOnExitHook.
-        Shutdown.add(sun.misc.SharedSecrets.getJavaIOAccess().consoleRestoreHook());
-        Shutdown.add(ApplicationShutdownHooks.hook());
-        Shutdown.add(sun.misc.SharedSecrets.getJavaIODeleteOnExitAccess());
-
         // Initialize any miscellenous operating system settings that need to be
         // set for the class libraries. Currently this is no-op everywhere except
         // for Windows where the process-wide error mode is set before the java.io
@@ -1174,6 +1166,9 @@
             public void blockedOn(Thread t, Interruptible b) {
                 t.blockedOn(b);
             }
+            public void registerShutdownHook(int slot, Runnable r) {
+                Shutdown.add(slot, r);
+            }
         });
     }
 
--- a/jdk/src/share/classes/sun/misc/FormattedFloatingDecimal.java	Thu Mar 12 15:36:14 2009 +0100
+++ b/jdk/src/share/classes/sun/misc/FormattedFloatingDecimal.java	Fri Mar 13 14:25:48 2009 +0100
@@ -978,15 +978,6 @@
         return new String(result);
     }
 
-    // This method should only ever be called if this object is constructed
-    // without Form.DECIMAL_FLOAT because the perThreadBuffer is not large
-    // enough to handle floating-point numbers of large precision.
-    public String toJavaFormatString() {
-        char result[] = (char[])(perThreadBuffer.get());
-        int i = getChars(result);
-        return new String(result, 0, i);
-    }
-
     // returns the exponent before rounding
     public int getExponent() {
         return decExponent - 1;
@@ -1157,265 +1148,6 @@
             }
         };
 
-    // This method should only ever be called if this object is constructed
-    // without Form.DECIMAL_FLOAT because the perThreadBuffer is not large
-    // enough to handle floating-point numbers of large precision.
-    public void appendTo(Appendable buf) {
-        char result[] = (char[])(perThreadBuffer.get());
-        int i = getChars(result);
-        if (buf instanceof StringBuilder)
-            ((StringBuilder) buf).append(result, 0, i);
-        else if (buf instanceof StringBuffer)
-            ((StringBuffer) buf).append(result, 0, i);
-        else
-            assert false;
-    }
-
-    public static FormattedFloatingDecimal
-    readJavaFormatString( String in ) throws NumberFormatException {
-        boolean isNegative = false;
-        boolean signSeen   = false;
-        int     decExp;
-        char    c;
-
-    parseNumber:
-        try{
-            in = in.trim(); // don't fool around with white space.
-                            // throws NullPointerException if null
-            int l = in.length();
-            if ( l == 0 ) throw new NumberFormatException("empty String");
-            int i = 0;
-            switch ( c = in.charAt( i ) ){
-            case '-':
-                isNegative = true;
-                //FALLTHROUGH
-            case '+':
-                i++;
-                signSeen = true;
-            }
-
-            // Check for NaN and Infinity strings
-            c = in.charAt(i);
-            if(c == 'N' || c == 'I') { // possible NaN or infinity
-                boolean potentialNaN = false;
-                char targetChars[] = null;  // char arrary of "NaN" or "Infinity"
-
-                if(c == 'N') {
-                    targetChars = notANumber;
-                    potentialNaN = true;
-                } else {
-                    targetChars = infinity;
-                }
-
-                // compare Input string to "NaN" or "Infinity"
-                int j = 0;
-                while(i < l && j < targetChars.length) {
-                    if(in.charAt(i) == targetChars[j]) {
-                        i++; j++;
-                    }
-                    else // something is amiss, throw exception
-                        break parseNumber;
-                }
-
-                // For the candidate string to be a NaN or infinity,
-                // all characters in input string and target char[]
-                // must be matched ==> j must equal targetChars.length
-                // and i must equal l
-                if( (j == targetChars.length) && (i == l) ) { // return NaN or infinity
-                    return (potentialNaN ? new FormattedFloatingDecimal(Double.NaN) // NaN has no sign
-                            : new FormattedFloatingDecimal(isNegative?
-                                                  Double.NEGATIVE_INFINITY:
-                                                  Double.POSITIVE_INFINITY)) ;
-                }
-                else { // something went wrong, throw exception
-                    break parseNumber;
-                }
-
-            } else if (c == '0')  { // check for hexadecimal floating-point number
-                if (l > i+1 ) {
-                    char ch = in.charAt(i+1);
-                    if (ch == 'x' || ch == 'X' ) // possible hex string
-                        return parseHexString(in);
-                }
-            }  // look for and process decimal floating-point string
-
-            char[] digits = new char[ l ];
-            int    nDigits= 0;
-            boolean decSeen = false;
-            int decPt = 0;
-            int nLeadZero = 0;
-            int nTrailZero= 0;
-        digitLoop:
-            while ( i < l ){
-                switch ( c = in.charAt( i ) ){
-                case '0':
-                    if ( nDigits > 0 ){
-                        nTrailZero += 1;
-                    } else {
-                        nLeadZero += 1;
-                    }
-                    break; // out of switch.
-                case '1':
-                case '2':
-                case '3':
-                case '4':
-                case '5':
-                case '6':
-                case '7':
-                case '8':
-                case '9':
-                    while ( nTrailZero > 0 ){
-                        digits[nDigits++] = '0';
-                        nTrailZero -= 1;
-                    }
-                    digits[nDigits++] = c;
-                    break; // out of switch.
-                case '.':
-                    if ( decSeen ){
-                        // already saw one ., this is the 2nd.
-                        throw new NumberFormatException("multiple points");
-                    }
-                    decPt = i;
-                    if ( signSeen ){
-                        decPt -= 1;
-                    }
-                    decSeen = true;
-                    break; // out of switch.
-                default:
-                    break digitLoop;
-                }
-                i++;
-            }
-            /*
-             * At this point, we've scanned all the digits and decimal
-             * point we're going to see. Trim off leading and trailing
-             * zeros, which will just confuse us later, and adjust
-             * our initial decimal exponent accordingly.
-             * To review:
-             * we have seen i total characters.
-             * nLeadZero of them were zeros before any other digits.
-             * nTrailZero of them were zeros after any other digits.
-             * if ( decSeen ), then a . was seen after decPt characters
-             * ( including leading zeros which have been discarded )
-             * nDigits characters were neither lead nor trailing
-             * zeros, nor point
-             */
-            /*
-             * special hack: if we saw no non-zero digits, then the
-             * answer is zero!
-             * Unfortunately, we feel honor-bound to keep parsing!
-             */
-            if ( nDigits == 0 ){
-                digits = zero;
-                nDigits = 1;
-                if ( nLeadZero == 0 ){
-                    // we saw NO DIGITS AT ALL,
-                    // not even a crummy 0!
-                    // this is not allowed.
-                    break parseNumber; // go throw exception
-                }
-
-            }
-
-            /* Our initial exponent is decPt, adjusted by the number of
-             * discarded zeros. Or, if there was no decPt,
-             * then its just nDigits adjusted by discarded trailing zeros.
-             */
-            if ( decSeen ){
-                decExp = decPt - nLeadZero;
-            } else {
-                decExp = nDigits+nTrailZero;
-            }
-
-            /*
-             * Look for 'e' or 'E' and an optionally signed integer.
-             */
-            if ( (i < l) &&  (((c = in.charAt(i) )=='e') || (c == 'E') ) ){
-                int expSign = 1;
-                int expVal  = 0;
-                int reallyBig = Integer.MAX_VALUE / 10;
-                boolean expOverflow = false;
-                switch( in.charAt(++i) ){
-                case '-':
-                    expSign = -1;
-                    //FALLTHROUGH
-                case '+':
-                    i++;
-                }
-                int expAt = i;
-            expLoop:
-                while ( i < l  ){
-                    if ( expVal >= reallyBig ){
-                        // the next character will cause integer
-                        // overflow.
-                        expOverflow = true;
-                    }
-                    switch ( c = in.charAt(i++) ){
-                    case '0':
-                    case '1':
-                    case '2':
-                    case '3':
-                    case '4':
-                    case '5':
-                    case '6':
-                    case '7':
-                    case '8':
-                    case '9':
-                        expVal = expVal*10 + ( (int)c - (int)'0' );
-                        continue;
-                    default:
-                        i--;           // back up.
-                        break expLoop; // stop parsing exponent.
-                    }
-                }
-                int expLimit = bigDecimalExponent+nDigits+nTrailZero;
-                if ( expOverflow || ( expVal > expLimit ) ){
-                    //
-                    // The intent here is to end up with
-                    // infinity or zero, as appropriate.
-                    // The reason for yielding such a small decExponent,
-                    // rather than something intuitive such as
-                    // expSign*Integer.MAX_VALUE, is that this value
-                    // is subject to further manipulation in
-                    // doubleValue() and floatValue(), and I don't want
-                    // it to be able to cause overflow there!
-                    // (The only way we can get into trouble here is for
-                    // really outrageous nDigits+nTrailZero, such as 2 billion. )
-                    //
-                    decExp = expSign*expLimit;
-                } else {
-                    // this should not overflow, since we tested
-                    // for expVal > (MAX+N), where N >= abs(decExp)
-                    decExp = decExp + expSign*expVal;
-                }
-
-                // if we saw something not a digit ( or end of string )
-                // after the [Ee][+-], without seeing any digits at all
-                // this is certainly an error. If we saw some digits,
-                // but then some trailing garbage, that might be ok.
-                // so we just fall through in that case.
-                // HUMBUG
-                if ( i == expAt )
-                    break parseNumber; // certainly bad
-            }
-            /*
-             * We parsed everything we could.
-             * If there are leftovers, then this is not good input!
-             */
-            if ( i < l &&
-                ((i != l - 1) ||
-                (in.charAt(i) != 'f' &&
-                 in.charAt(i) != 'F' &&
-                 in.charAt(i) != 'd' &&
-                 in.charAt(i) != 'D'))) {
-                break parseNumber; // go throw exception
-            }
-
-            return new FormattedFloatingDecimal( isNegative, decExp, digits, nDigits,  false, Integer.MAX_VALUE, Form.COMPATIBLE );
-        } catch ( StringIndexOutOfBoundsException e ){ }
-        throw new NumberFormatException("For input string: \"" + in + "\"");
-    }
-
     /*
      * Take a FormattedFloatingDecimal, which we presumably just scanned in,
      * and find out what its value is, as a double.
@@ -2035,548 +1767,4 @@
     private static final char infinity[] = { 'I', 'n', 'f', 'i', 'n', 'i', 't', 'y' };
     private static final char notANumber[] = { 'N', 'a', 'N' };
     private static final char zero[] = { '0', '0', '0', '0', '0', '0', '0', '0' };
-
-
-    /*
-     * Grammar is compatible with hexadecimal floating-point constants
-     * described in section 6.4.4.2 of the C99 specification.
-     */
-    private static Pattern hexFloatPattern = Pattern.compile(
-                   //1           234                   56                7                   8      9
-                    "([-+])?0[xX](((\\p{XDigit}+)\\.?)|((\\p{XDigit}*)\\.(\\p{XDigit}+)))[pP]([-+])?(\\p{Digit}+)[fFdD]?"
-                    );
-
-    /*
-     * Convert string s to a suitable floating decimal; uses the
-     * double constructor and set the roundDir variable appropriately
-     * in case the value is later converted to a float.
-     */
-   static FormattedFloatingDecimal parseHexString(String s) {
-        // Verify string is a member of the hexadecimal floating-point
-        // string language.
-        Matcher m = hexFloatPattern.matcher(s);
-        boolean validInput = m.matches();
-
-        if (!validInput) {
-            // Input does not match pattern
-            throw new NumberFormatException("For input string: \"" + s + "\"");
-        } else { // validInput
-            /*
-             * We must isolate the sign, significand, and exponent
-             * fields.  The sign value is straightforward.  Since
-             * floating-point numbers are stored with a normalized
-             * representation, the significand and exponent are
-             * interrelated.
-             *
-             * After extracting the sign, we normalized the
-             * significand as a hexadecimal value, calculating an
-             * exponent adjust for any shifts made during
-             * normalization.  If the significand is zero, the
-             * exponent doesn't need to be examined since the output
-             * will be zero.
-             *
-             * Next the exponent in the input string is extracted.
-             * Afterwards, the significand is normalized as a *binary*
-             * value and the input value's normalized exponent can be
-             * computed.  The significand bits are copied into a
-             * double significand; if the string has more logical bits
-             * than can fit in a double, the extra bits affect the
-             * round and sticky bits which are used to round the final
-             * value.
-             */
-
-            //  Extract significand sign
-            String group1 = m.group(1);
-            double sign = (( group1 == null ) || group1.equals("+"))? 1.0 : -1.0;
-
-
-            //  Extract Significand magnitude
-            /*
-             * Based on the form of the significand, calculate how the
-             * binary exponent needs to be adjusted to create a
-             * normalized *hexadecimal* floating-point number; that
-             * is, a number where there is one nonzero hex digit to
-             * the left of the (hexa)decimal point.  Since we are
-             * adjusting a binary, not hexadecimal exponent, the
-             * exponent is adjusted by a multiple of 4.
-             *
-             * There are a number of significand scenarios to consider;
-             * letters are used in indicate nonzero digits:
-             *
-             * 1. 000xxxx       =>      x.xxx   normalized
-             *    increase exponent by (number of x's - 1)*4
-             *
-             * 2. 000xxx.yyyy =>        x.xxyyyy        normalized
-             *    increase exponent by (number of x's - 1)*4
-             *
-             * 3. .000yyy  =>   y.yy    normalized
-             *    decrease exponent by (number of zeros + 1)*4
-             *
-             * 4. 000.00000yyy => y.yy normalized
-             *    decrease exponent by (number of zeros to right of point + 1)*4
-             *
-             * If the significand is exactly zero, return a properly
-             * signed zero.
-             */
-
-            String significandString =null;
-            int signifLength = 0;
-            int exponentAdjust = 0;
-            {
-                int leftDigits  = 0; // number of meaningful digits to
-                                     // left of "decimal" point
-                                     // (leading zeros stripped)
-                int rightDigits = 0; // number of digits to right of
-                                     // "decimal" point; leading zeros
-                                     // must always be accounted for
-                /*
-                 * The significand is made up of either
-                 *
-                 * 1. group 4 entirely (integer portion only)
-                 *
-                 * OR
-                 *
-                 * 2. the fractional portion from group 7 plus any
-                 * (optional) integer portions from group 6.
-                 */
-                String group4;
-                if( (group4 = m.group(4)) != null) {  // Integer-only significand
-                    // Leading zeros never matter on the integer portion
-                    significandString = stripLeadingZeros(group4);
-                    leftDigits = significandString.length();
-                }
-                else {
-                    // Group 6 is the optional integer; leading zeros
-                    // never matter on the integer portion
-                    String group6 = stripLeadingZeros(m.group(6));
-                    leftDigits = group6.length();
-
-                    // fraction
-                    String group7 = m.group(7);
-                    rightDigits = group7.length();
-
-                    // Turn "integer.fraction" into "integer"+"fraction"
-                    significandString =
-                        ((group6 == null)?"":group6) + // is the null
-                        // check necessary?
-                        group7;
-                }
-
-                significandString = stripLeadingZeros(significandString);
-                signifLength  = significandString.length();
-
-                /*
-                 * Adjust exponent as described above
-                 */
-                if (leftDigits >= 1) {  // Cases 1 and 2
-                    exponentAdjust = 4*(leftDigits - 1);
-                } else {                // Cases 3 and 4
-                    exponentAdjust = -4*( rightDigits - signifLength + 1);
-                }
-
-                // If the significand is zero, the exponent doesn't
-                // matter; return a properly signed zero.
-
-                if (signifLength == 0) { // Only zeros in input
-                    return new FormattedFloatingDecimal(sign * 0.0);
-                }
-            }
-
-            //  Extract Exponent
-            /*
-             * Use an int to read in the exponent value; this should
-             * provide more than sufficient range for non-contrived
-             * inputs.  If reading the exponent in as an int does
-             * overflow, examine the sign of the exponent and
-             * significand to determine what to do.
-             */
-            String group8 = m.group(8);
-            boolean positiveExponent = ( group8 == null ) || group8.equals("+");
-            long unsignedRawExponent;
-            try {
-                unsignedRawExponent = Integer.parseInt(m.group(9));
-            }
-            catch (NumberFormatException e) {
-                // At this point, we know the exponent is
-                // syntactically well-formed as a sequence of
-                // digits.  Therefore, if an NumberFormatException
-                // is thrown, it must be due to overflowing int's
-                // range.  Also, at this point, we have already
-                // checked for a zero significand.  Thus the signs
-                // of the exponent and significand determine the
-                // final result:
-                //
-                //                      significand
-                //                      +               -
-                // exponent     +       +infinity       -infinity
-                //              -       +0.0            -0.0
-                return new FormattedFloatingDecimal(sign * (positiveExponent ?
-                                                   Double.POSITIVE_INFINITY : 0.0));
-            }
-
-            long rawExponent =
-                (positiveExponent ? 1L : -1L) * // exponent sign
-                unsignedRawExponent;            // exponent magnitude
-
-            // Calculate partially adjusted exponent
-            long exponent = rawExponent + exponentAdjust ;
-
-            // Starting copying non-zero bits into proper position in
-            // a long; copy explicit bit too; this will be masked
-            // later for normal values.
-
-            boolean round = false;
-            boolean sticky = false;
-            int bitsCopied=0;
-            int nextShift=0;
-            long significand=0L;
-            // First iteration is different, since we only copy
-            // from the leading significand bit; one more exponent
-            // adjust will be needed...
-
-            // IMPORTANT: make leadingDigit a long to avoid
-            // surprising shift semantics!
-            long leadingDigit = getHexDigit(significandString, 0);
-
-            /*
-             * Left shift the leading digit (53 - (bit position of
-             * leading 1 in digit)); this sets the top bit of the
-             * significand to 1.  The nextShift value is adjusted
-             * to take into account the number of bit positions of
-             * the leadingDigit actually used.  Finally, the
-             * exponent is adjusted to normalize the significand
-             * as a binary value, not just a hex value.
-             */
-            if (leadingDigit == 1) {
-                significand |= leadingDigit << 52;
-                nextShift = 52 - 4;
-                /* exponent += 0 */     }
-            else if (leadingDigit <= 3) { // [2, 3]
-                significand |= leadingDigit << 51;
-                nextShift = 52 - 5;
-                exponent += 1;
-            }
-            else if (leadingDigit <= 7) { // [4, 7]
-                significand |= leadingDigit << 50;
-                nextShift = 52 - 6;
-                exponent += 2;
-            }
-            else if (leadingDigit <= 15) { // [8, f]
-                significand |= leadingDigit << 49;
-                nextShift = 52 - 7;
-                exponent += 3;
-            } else {
-                throw new AssertionError("Result from digit converstion too large!");
-            }
-            // The preceding if-else could be replaced by a single
-            // code block based on the high-order bit set in
-            // leadingDigit.  Given leadingOnePosition,
-
-            // significand |= leadingDigit << (SIGNIFICAND_WIDTH - leadingOnePosition);
-            // nextShift = 52 - (3 + leadingOnePosition);
-            // exponent += (leadingOnePosition-1);
-
-
-            /*
-             * Now the exponent variable is equal to the normalized
-             * binary exponent.  Code below will make representation
-             * adjustments if the exponent is incremented after
-             * rounding (includes overflows to infinity) or if the
-             * result is subnormal.
-             */
-
-            // Copy digit into significand until the significand can't
-            // hold another full hex digit or there are no more input
-            // hex digits.
-            int i = 0;
-            for(i = 1;
-                i < signifLength && nextShift >= 0;
-                i++) {
-                long currentDigit = getHexDigit(significandString, i);
-                significand |= (currentDigit << nextShift);
-                nextShift-=4;
-            }
-
-            // After the above loop, the bulk of the string is copied.
-            // Now, we must copy any partial hex digits into the
-            // significand AND compute the round bit and start computing
-            // sticky bit.
-
-            if ( i < signifLength ) { // at least one hex input digit exists
-                long currentDigit = getHexDigit(significandString, i);
-
-                // from nextShift, figure out how many bits need
-                // to be copied, if any
-                switch(nextShift) { // must be negative
-                case -1:
-                    // three bits need to be copied in; can
-                    // set round bit
-                    significand |= ((currentDigit & 0xEL) >> 1);
-                    round = (currentDigit & 0x1L)  != 0L;
-                    break;
-
-                case -2:
-                    // two bits need to be copied in; can
-                    // set round and start sticky
-                    significand |= ((currentDigit & 0xCL) >> 2);
-                    round = (currentDigit &0x2L)  != 0L;
-                    sticky = (currentDigit & 0x1L) != 0;
-                    break;
-
-                case -3:
-                    // one bit needs to be copied in
-                    significand |= ((currentDigit & 0x8L)>>3);
-                    // Now set round and start sticky, if possible
-                    round = (currentDigit &0x4L)  != 0L;
-                    sticky = (currentDigit & 0x3L) != 0;
-                    break;
-
-                case -4:
-                    // all bits copied into significand; set
-                    // round and start sticky
-                    round = ((currentDigit & 0x8L) != 0);  // is top bit set?
-                    // nonzeros in three low order bits?
-                    sticky = (currentDigit & 0x7L) != 0;
-                    break;
-
-                default:
-                    throw new AssertionError("Unexpected shift distance remainder.");
-                    // break;
-                }
-
-                // Round is set; sticky might be set.
-
-                // For the sticky bit, it suffices to check the
-                // current digit and test for any nonzero digits in
-                // the remaining unprocessed input.
-                i++;
-                while(i < signifLength && !sticky) {
-                    currentDigit =  getHexDigit(significandString,i);
-                    sticky = sticky || (currentDigit != 0);
-                    i++;
-                }
-
-            }
-            // else all of string was seen, round and sticky are
-            // correct as false.
-
-
-            // Check for overflow and update exponent accordingly.
-
-            if (exponent > DoubleConsts.MAX_EXPONENT) {         // Infinite result
-                // overflow to properly signed infinity
-                return new FormattedFloatingDecimal(sign * Double.POSITIVE_INFINITY);
-            } else {  // Finite return value
-                if (exponent <= DoubleConsts.MAX_EXPONENT && // (Usually) normal result
-                    exponent >= DoubleConsts.MIN_EXPONENT) {
-
-                    // The result returned in this block cannot be a
-                    // zero or subnormal; however after the
-                    // significand is adjusted from rounding, we could
-                    // still overflow in infinity.
-
-                    // AND exponent bits into significand; if the
-                    // significand is incremented and overflows from
-                    // rounding, this combination will update the
-                    // exponent correctly, even in the case of
-                    // Double.MAX_VALUE overflowing to infinity.
-
-                    significand = (( ((long)exponent +
-                                      (long)DoubleConsts.EXP_BIAS) <<
-                                     (DoubleConsts.SIGNIFICAND_WIDTH-1))
-                                   & DoubleConsts.EXP_BIT_MASK) |
-                        (DoubleConsts.SIGNIF_BIT_MASK & significand);
-
-                }  else  {  // Subnormal or zero
-                    // (exponent < DoubleConsts.MIN_EXPONENT)
-
-                    if (exponent < (DoubleConsts.MIN_SUB_EXPONENT -1 )) {
-                        // No way to round back to nonzero value
-                        // regardless of significand if the exponent is
-                        // less than -1075.
-                        return new FormattedFloatingDecimal(sign * 0.0);
-                    } else { //  -1075 <= exponent <= MIN_EXPONENT -1 = -1023
-                        /*
-                         * Find bit position to round to; recompute
-                         * round and sticky bits, and shift
-                         * significand right appropriately.
-                         */
-
-                        sticky = sticky || round;
-                        round = false;
-
-                        // Number of bits of significand to preserve is
-                        // exponent - abs_min_exp +1
-                        // check:
-                        // -1075 +1074 + 1 = 0
-                        // -1023 +1074 + 1 = 52
-
-                        int bitsDiscarded = 53 -
-                            ((int)exponent - DoubleConsts.MIN_SUB_EXPONENT + 1);
-                        assert bitsDiscarded >= 1 && bitsDiscarded <= 53;
-
-                        // What to do here:
-                        // First, isolate the new round bit
-                        round = (significand & (1L << (bitsDiscarded -1))) != 0L;
-                        if (bitsDiscarded > 1) {
-                            // create mask to update sticky bits; low
-                            // order bitsDiscarded bits should be 1
-                            long mask = ~((~0L) << (bitsDiscarded -1));
-                            sticky = sticky || ((significand & mask) != 0L ) ;
-                        }
-
-                        // Now, discard the bits
-                        significand = significand >> bitsDiscarded;
-
-                        significand = (( ((long)(DoubleConsts.MIN_EXPONENT -1) + // subnorm exp.
-                                          (long)DoubleConsts.EXP_BIAS) <<
-                                         (DoubleConsts.SIGNIFICAND_WIDTH-1))
-                                       & DoubleConsts.EXP_BIT_MASK) |
-                            (DoubleConsts.SIGNIF_BIT_MASK & significand);
-                    }
-                }
-
-                // The significand variable now contains the currently
-                // appropriate exponent bits too.
-
-                /*
-                 * Determine if significand should be incremented;
-                 * making this determination depends on the least
-                 * significant bit and the round and sticky bits.
-                 *
-                 * Round to nearest even rounding table, adapted from
-                 * table 4.7 in "Computer Arithmetic" by IsraelKoren.
-                 * The digit to the left of the "decimal" point is the
-                 * least significant bit, the digits to the right of
-                 * the point are the round and sticky bits
-                 *
-                 * Number       Round(x)
-                 * x0.00        x0.
-                 * x0.01        x0.
-                 * x0.10        x0.
-                 * x0.11        x1. = x0. +1
-                 * x1.00        x1.
-                 * x1.01        x1.
-                 * x1.10        x1. + 1
-                 * x1.11        x1. + 1
-                 */
-                boolean incremented = false;
-                boolean leastZero  = ((significand & 1L) == 0L);
-                if( (  leastZero  && round && sticky ) ||
-                    ((!leastZero) && round )) {
-                    incremented = true;
-                    significand++;
-                }
-
-                FormattedFloatingDecimal fd = new FormattedFloatingDecimal(FpUtils.rawCopySign(
-                                                                 Double.longBitsToDouble(significand),
-                                                                 sign));
-
-                /*
-                 * Set roundingDir variable field of fd properly so
-                 * that the input string can be properly rounded to a
-                 * float value.  There are two cases to consider:
-                 *
-                 * 1. rounding to double discards sticky bit
-                 * information that would change the result of a float
-                 * rounding (near halfway case between two floats)
-                 *
-                 * 2. rounding to double rounds up when rounding up
-                 * would not occur when rounding to float.
-                 *
-                 * For former case only needs to be considered when
-                 * the bits rounded away when casting to float are all
-                 * zero; otherwise, float round bit is properly set
-                 * and sticky will already be true.
-                 *
-                 * The lower exponent bound for the code below is the
-                 * minimum (normalized) subnormal exponent - 1 since a
-                 * value with that exponent can round up to the
-                 * minimum subnormal value and the sticky bit
-                 * information must be preserved (i.e. case 1).
-                 */
-                if ((exponent >= FloatConsts.MIN_SUB_EXPONENT-1) &&
-                    (exponent <= FloatConsts.MAX_EXPONENT ) ){
-                    // Outside above exponent range, the float value
-                    // will be zero or infinity.
-
-                    /*
-                     * If the low-order 28 bits of a rounded double
-                     * significand are 0, the double could be a
-                     * half-way case for a rounding to float.  If the
-                     * double value is a half-way case, the double
-                     * significand may have to be modified to round
-                     * the the right float value (see the stickyRound
-                     * method).  If the rounding to double has lost
-                     * what would be float sticky bit information, the
-                     * double significand must be incremented.  If the
-                     * double value's significand was itself
-                     * incremented, the float value may end up too
-                     * large so the increment should be undone.
-                     */
-                    if ((significand & 0xfffffffL) ==  0x0L) {
-                        // For negative values, the sign of the
-                        // roundDir is the same as for positive values
-                        // since adding 1 increasing the significand's
-                        // magnitude and subtracting 1 decreases the
-                        // significand's magnitude.  If neither round
-                        // nor sticky is true, the double value is
-                        // exact and no adjustment is required for a
-                        // proper float rounding.
-                        if( round || sticky) {
-                            if (leastZero) { // prerounding lsb is 0
-                                // If round and sticky were both true,
-                                // and the least significant
-                                // significand bit were 0, the rounded
-                                // significand would not have its
-                                // low-order bits be zero.  Therefore,
-                                // we only need to adjust the
-                                // significand if round XOR sticky is
-                                // true.
-                                if (round ^ sticky) {
-                                    fd.roundDir =  1;
-                                }
-                            }
-                            else { // prerounding lsb is 1
-                                // If the prerounding lsb is 1 and the
-                                // resulting significand has its
-                                // low-order bits zero, the significand
-                                // was incremented.  Here, we undo the
-                                // increment, which will ensure the
-                                // right guard and sticky bits for the
-                                // float rounding.
-                                if (round)
-                                    fd.roundDir =  -1;
-                            }
-                        }
-                    }
-                }
-
-                fd.fromHex = true;
-                return fd;
-            }
-        }
-    }
-
-    /**
-     * Return <code>s</code> with any leading zeros removed.
-     */
-    static String stripLeadingZeros(String s) {
-        return  s.replaceFirst("^0+", "");
-    }
-
-    /**
-     * Extract a hexadecimal digit from position <code>position</code>
-     * of string <code>s</code>.
-     */
-    static int getHexDigit(String s, int position) {
-        int value = Character.digit(s.charAt(position), 16);
-        if (value <= -1 || value >= 16) {
-            throw new AssertionError("Unxpected failure of digit converstion of " +
-                                     s.charAt(position));
-        }
-        return value;
-    }
-
-
 }
--- a/jdk/src/share/classes/sun/misc/JavaIOAccess.java	Thu Mar 12 15:36:14 2009 +0100
+++ b/jdk/src/share/classes/sun/misc/JavaIOAccess.java	Fri Mar 13 14:25:48 2009 +0100
@@ -29,6 +29,5 @@
 
 public interface JavaIOAccess {
     public Console console();
-    public Runnable consoleRestoreHook();
     public Charset charset();
 }
--- a/jdk/src/share/classes/sun/misc/JavaIODeleteOnExitAccess.java	Thu Mar 12 15:36:14 2009 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-
-package sun.misc;
-
-public interface JavaIODeleteOnExitAccess extends Runnable {
-    public void run();
-}
--- a/jdk/src/share/classes/sun/misc/JavaLangAccess.java	Thu Mar 12 15:36:14 2009 +0100
+++ b/jdk/src/share/classes/sun/misc/JavaLangAccess.java	Fri Mar 13 14:25:48 2009 +0100
@@ -54,4 +54,7 @@
 
     /** Set thread's blocker field. */
     void blockedOn(Thread t, Interruptible b);
+
+    /** register shutdown hook */
+    void registerShutdownHook(int slot, Runnable r);
 }
--- a/jdk/src/share/classes/sun/misc/SharedSecrets.java	Thu Mar 12 15:36:14 2009 +0100
+++ b/jdk/src/share/classes/sun/misc/SharedSecrets.java	Fri Mar 13 14:25:48 2009 +0100
@@ -44,7 +44,6 @@
     private static JavaUtilJarAccess javaUtilJarAccess;
     private static JavaLangAccess javaLangAccess;
     private static JavaIOAccess javaIOAccess;
-    private static JavaIODeleteOnExitAccess javaIODeleteOnExitAccess;
     private static JavaNetAccess javaNetAccess;
     private static JavaNioAccess javaNioAccess;
     private static JavaIOFileDescriptorAccess javaIOFileDescriptorAccess;
@@ -103,17 +102,6 @@
         return javaIOAccess;
     }
 
-    public static void setJavaIODeleteOnExitAccess(JavaIODeleteOnExitAccess jida) {
-        javaIODeleteOnExitAccess = jida;
-    }
-
-    public static JavaIODeleteOnExitAccess getJavaIODeleteOnExitAccess() {
-        if (javaIODeleteOnExitAccess == null) {
-            unsafe.ensureClassInitialized(File.class);
-        }
-        return javaIODeleteOnExitAccess;
-    }
-
     public static void setJavaIOFileDescriptorAccess(JavaIOFileDescriptorAccess jiofda) {
         javaIOFileDescriptorAccess = jiofda;
     }
--- a/jdk/src/share/classes/sun/security/jgss/spnego/NegTokenInit.java	Thu Mar 12 15:36:14 2009 +0100
+++ b/jdk/src/share/classes/sun/security/jgss/spnego/NegTokenInit.java	Fri Mar 13 14:25:48 2009 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2005-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -66,11 +66,11 @@
     private byte[] mechTypes = null;
     private Oid[] mechTypeList = null;
 
-    private byte[] reqFlags = null;
+    private BitArray reqFlags = null;
     private byte[] mechToken = null;
     private byte[] mechListMIC = null;
 
-    NegTokenInit(byte[] mechTypes, byte[] flags,
+    NegTokenInit(byte[] mechTypes, BitArray flags,
                 byte[] token, byte[] mechListMIC)
     {
         super(NEG_TOKEN_INIT_ID);
@@ -101,7 +101,7 @@
             // write context flags with CONTEXT 01
             if (reqFlags != null) {
                 DerOutputStream flags = new DerOutputStream();
-                flags.putBitString(reqFlags);
+                flags.putUnalignedBitString(reqFlags);
                 initToken.write(DerValue.createTag(DerValue.TAG_CONTEXT,
                                                 true, (byte) 0x01), flags);
             }
@@ -237,7 +237,7 @@
         return mechTypeList;
     }
 
-    byte[] getReqFlags() {
+    BitArray getReqFlags() {
         return reqFlags;
     }
 
--- a/jdk/src/share/classes/sun/security/jgss/spnego/SpNegoContext.java	Thu Mar 12 15:36:14 2009 +0100
+++ b/jdk/src/share/classes/sun/security/jgss/spnego/SpNegoContext.java	Fri Mar 13 14:25:48 2009 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2005-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -53,13 +53,6 @@
 
     private int state = STATE_NEW;
 
-    private static final int CHECKSUM_DELEG_FLAG    = 1;
-    private static final int CHECKSUM_MUTUAL_FLAG   = 2;
-    private static final int CHECKSUM_REPLAY_FLAG   = 4;
-    private static final int CHECKSUM_SEQUENCE_FLAG = 8;
-    private static final int CHECKSUM_CONF_FLAG     = 16;
-    private static final int CHECKSUM_INTEG_FLAG    = 32;
-
     /*
      * Optional features that the application can set and their default
      * values.
@@ -697,25 +690,17 @@
     /**
      * get the context flags
      */
-    private byte[] getContextFlags() {
-        int flags = 0;
+    private BitArray getContextFlags() {
+        BitArray out = new BitArray(7);
 
-        if (getCredDelegState())
-            flags |= CHECKSUM_DELEG_FLAG;
-        if (getMutualAuthState())
-            flags |= CHECKSUM_MUTUAL_FLAG;
-        if (getReplayDetState())
-            flags |= CHECKSUM_REPLAY_FLAG;
-        if (getSequenceDetState())
-            flags |= CHECKSUM_SEQUENCE_FLAG;
-        if (getIntegState())
-            flags |= CHECKSUM_INTEG_FLAG;
-        if (getConfState())
-            flags |= CHECKSUM_CONF_FLAG;
+        if (getCredDelegState()) out.set(0, true);
+        if (getMutualAuthState()) out.set(1, true);
+        if (getReplayDetState()) out.set(2, true);
+        if (getSequenceDetState()) out.set(3, true);
+        if (getConfState()) out.set(5, true);
+        if (getIntegState()) out.set(6, true);
 
-        byte[] temp = new byte[1];
-        temp[0] = (byte)(flags & 0xff);
-        return temp;
+        return out;
     }
 
     private void setContextFlags() {
--- a/jdk/src/share/classes/sun/security/provider/certpath/OCSPResponse.java	Thu Mar 12 15:36:14 2009 +0100
+++ b/jdk/src/share/classes/sun/security/provider/certpath/OCSPResponse.java	Fri Mar 13 14:25:48 2009 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2003-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,8 +28,6 @@
 import java.io.*;
 import java.math.BigInteger;
 import java.security.*;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateFactory;
 import java.security.cert.CertPathValidatorException;
 import java.security.cert.CRLReason;
 import java.security.cert.X509Certificate;
@@ -335,7 +333,7 @@
 
             // Check whether the cert returned by the responder is trusted
             if (x509Certs != null && x509Certs[0] != null) {
-                X509Certificate cert = x509Certs[0];
+                X509CertImpl cert = x509Certs[0];
 
                 // First check if the cert matches the responder cert which
                 // was set locally.
@@ -344,8 +342,8 @@
 
                 // Next check if the cert was issued by the responder cert
                 // which was set locally.
-                } else if (cert.getIssuerDN().equals(
-                    responderCert.getSubjectDN())) {
+                } else if (cert.getIssuerX500Principal().equals(
+                    responderCert.getSubjectX500Principal())) {
 
                     // Check for the OCSPSigning key purpose
                     List<String> keyPurposes = cert.getExtendedKeyUsage();
@@ -360,6 +358,43 @@
                             "OCSP responses");
                     }
 
+                    // check the validity
+                    try {
+                        Date dateCheckedAgainst = params.getDate();
+                        if (dateCheckedAgainst == null) {
+                            cert.checkValidity();
+                        } else {
+                            cert.checkValidity(dateCheckedAgainst);
+                        }
+                    } catch (GeneralSecurityException e) {
+                        if (DEBUG != null) {
+                            DEBUG.println("Responder's certificate is not " +
+                                "within the validity period.");
+                        }
+                        throw new CertPathValidatorException(
+                            "Responder's certificate not within the " +
+                            "validity period");
+                    }
+
+                    // check for revocation
+                    //
+                    // A CA may specify that an OCSP client can trust a
+                    // responder for the lifetime of the responder's
+                    // certificate. The CA does so by including the
+                    // extension id-pkix-ocsp-nocheck.
+                    //
+                    Extension noCheck =
+                            cert.getExtension(PKIXExtensions.OCSPNoCheck_Id);
+                    if (noCheck != null) {
+                        if (DEBUG != null) {
+                            DEBUG.println("Responder's certificate includes " +
+                                "the extension id-pkix-ocsp-nocheck.");
+                        }
+                    } else {
+                        // we should do the revocating checking of the
+                        // authorized responder in a future update.
+                    }
+
                     // verify the signature
                     try {
                         cert.verify(responderCert.getPublicKey());
@@ -369,6 +404,14 @@
                     } catch (GeneralSecurityException e) {
                         responderCert = null;
                     }
+                } else {
+                    if (DEBUG != null) {
+                        DEBUG.println("Responder's certificate is not " +
+                            "authorized to sign OCSP responses.");
+                    }
+                    throw new CertPathValidatorException(
+                        "Responder's certificate not authorized to sign " +
+                        "OCSP responses");
                 }
             }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/security/x509/OCSPNoCheckExtension.java	Fri Mar 13 14:25:48 2009 +0100
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.security.x509;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Enumeration;
+
+import sun.security.util.*;
+
+/**
+ * Represent the OCSP NoCheck Extension from RFC2560.
+ * <p>
+ * A CA may specify that an OCSP client can trust a responder for the
+ * lifetime of the responder's certificate. The CA does so by including
+ * the extension id-pkix-ocsp-nocheck. This SHOULD be a non-critical
+ * extension. The value of the extension should be NULL. CAs issuing
+ * such a certificate should realized that a compromise of the
+ * responder's key, is as serious as the compromise of a CA key used to
+ * sign CRLs, at least for the validity period of this certificate. CA's
+ * may choose to issue this type of certificate with a very short
+ * lifetime and renew it frequently.
+ * <pre>
+ * id-pkix-ocsp-nocheck OBJECT IDENTIFIER ::= { id-pkix-ocsp 5 }
+ * </pre>
+ *
+ * @author Xuelei Fan
+ * @see Extension
+ * @see CertAttrSet
+ */
+public class OCSPNoCheckExtension extends Extension
+    implements CertAttrSet<String> {
+
+    /**
+     * Identifier for this attribute, to be used with the
+     * get, set, delete methods of Certificate, x509 type.
+     */
+    public static final String IDENT =
+                         "x509.info.extensions.OCSPNoCheck";
+    /**
+     * Attribute names.
+     */
+    public static final String NAME = "OCSPNoCheck";
+
+    /**
+     * Create a OCSPNoCheckExtension
+     */
+    public OCSPNoCheckExtension() throws IOException {
+        this.extensionId = PKIXExtensions.OCSPNoCheck_Id;
+        this.critical = false;
+        this.extensionValue = new byte[0];
+    }
+
+    /**
+     * Create the extension from the passed DER encoded value.
+     *
+     * @param critical true if the extension is to be treated as critical.
+     * @param value an array of DER encoded bytes of the actual value.
+     * @exception IOException on error.
+     */
+    public OCSPNoCheckExtension(Boolean critical, Object value)
+        throws IOException {
+
+        this.extensionId = PKIXExtensions.OCSPNoCheck_Id;
+        this.critical = critical.booleanValue();
+
+        // the value should be null, just ignore it here.
+        this.extensionValue = new byte[0];
+    }
+
+    /**
+     * Set the attribute value.
+     */
+    public void set(String name, Object obj) throws IOException {
+        throw new IOException("No attribute is allowed by " +
+                        "CertAttrSet:OCSPNoCheckExtension.");
+    }
+
+    /**
+     * Get the attribute value.
+     */
+    public Object get(String name) throws IOException {
+        throw new IOException("No attribute is allowed by " +
+                        "CertAttrSet:OCSPNoCheckExtension.");
+    }
+
+    /**
+     * Delete the attribute value.
+     */
+    public void delete(String name) throws IOException {
+        throw new IOException("No attribute is allowed by " +
+                        "CertAttrSet:OCSPNoCheckExtension.");
+    }
+
+    /**
+     * Return an enumeration of names of attributes existing within this
+     * attribute.
+     */
+    public Enumeration<String> getElements() {
+        return (new AttributeNameEnumeration()).elements();
+    }
+
+    /**
+     * Return the name of this attribute.
+     */
+    public String getName() {
+        return NAME;
+    }
+}
--- a/jdk/src/share/classes/sun/security/x509/OIDMap.java	Thu Mar 12 15:36:14 2009 +0100
+++ b/jdk/src/share/classes/sun/security/x509/OIDMap.java	Fri Mar 13 14:25:48 2009 +0100
@@ -100,6 +100,8 @@
                                         DeltaCRLIndicatorExtension.NAME;
     private static final String FRESHEST_CRL = ROOT + "." +
                                         FreshestCRLExtension.NAME;
+    private static final String OCSPNOCHECK = ROOT + "." +
+                                        OCSPNoCheckExtension.NAME;
 
     private static final int NetscapeCertType_data[] =
         { 2, 16, 840, 1, 113730, 1, 1 };
@@ -161,6 +163,8 @@
                     "sun.security.x509.DeltaCRLIndicatorExtension");
         addInternal(FRESHEST_CRL, PKIXExtensions.FreshestCRL_Id,
                     "sun.security.x509.FreshestCRLExtension");
+        addInternal(OCSPNOCHECK, PKIXExtensions.OCSPNoCheck_Id,
+                    "sun.security.x509.OCSPNoCheckExtension");
     }
 
     /**
--- a/jdk/src/share/classes/sun/security/x509/PKIXExtensions.java	Thu Mar 12 15:36:14 2009 +0100
+++ b/jdk/src/share/classes/sun/security/x509/PKIXExtensions.java	Fri Mar 13 14:25:48 2009 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -74,6 +74,8 @@
     private static final int AuthInfoAccess_data [] = { 1, 3, 6, 1, 5, 5, 7, 1, 1};
     private static final int SubjectInfoAccess_data [] = { 1, 3, 6, 1, 5, 5, 7, 1, 11};
     private static final int FreshestCRL_data [] = { 2, 5, 29, 46 };
+    private static final int OCSPNoCheck_data [] = { 1, 3, 6, 1, 5, 5, 7,
+                                                    48, 1, 5};
 
     /**
      * Identifies the particular public key used to sign the certificate.
@@ -216,6 +218,12 @@
      */
     public static final ObjectIdentifier FreshestCRL_Id;
 
+    /**
+     * Identifies the OCSP client can trust the responder for the
+     * lifetime of the responder's certificate.
+     */
+    public static final ObjectIdentifier OCSPNoCheck_Id;
+
     static {
         AuthorityKey_Id = ObjectIdentifier.newInternal(AuthorityKey_data);
         SubjectKey_Id   = ObjectIdentifier.newInternal(SubjectKey_data);
@@ -257,5 +265,6 @@
         SubjectInfoAccess_Id =
             ObjectIdentifier.newInternal(SubjectInfoAccess_data);
         FreshestCRL_Id = ObjectIdentifier.newInternal(FreshestCRL_data);
+        OCSPNoCheck_Id = ObjectIdentifier.newInternal(OCSPNoCheck_data);
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/krb5/auto/SpnegoReqFlags.java	Fri Mar 13 14:25:48 2009 +0100
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6815182
+ * @summary GSSAPI/SPNEGO does not work with server using MIT Kerberos library
+ */
+
+import sun.security.jgss.GSSUtil;
+import sun.security.util.BitArray;
+import sun.security.util.DerInputStream;
+import sun.security.util.DerValue;
+
+public class SpnegoReqFlags {
+
+    public static void main(String[] args)
+            throws Exception {
+
+        // Create and start the KDC
+        new OneKDC(null).writeJAASConf();
+        new SpnegoReqFlags().go();
+    }
+
+    void go() throws Exception {
+        Context c = Context.fromJAAS("client");
+        c.startAsClient(OneKDC.SERVER, GSSUtil.GSS_SPNEGO_MECH_OID);
+
+        byte[] token = c.doAs(new Action() {
+            @Override
+            public byte[] run(Context me, byte[] input) throws Exception {
+                me.x().requestCredDeleg(true);
+                me.x().requestReplayDet(false);
+                me.x().requestSequenceDet(false);
+                return me.x().initSecContext(new byte[0], 0, 0);
+            }
+        }, null);
+
+        DerValue d = new DerValue(token);   // GSSToken
+        DerInputStream ins = d.data;        // OID + mech token
+        d.data.getDerValue();               // skip OID
+        d = d.data.getDerValue();           // NegTokenInit
+        d = d.data.getDerValue();           // The SEQUENCE inside
+
+        boolean found = false;
+
+        // Go through all fields inside NegTokenInit. The reqFlags field
+        // is optional. It's even not recommended in RFC 4178.
+        while (d.data.available() > 0) {
+            DerValue d2 = d.data.getDerValue();
+            if (d2.isContextSpecific((byte)1)) {
+                found = true;
+                System.out.println("regFlags field located.");
+                BitArray ba = d2.data.getUnalignedBitString();
+                if (ba.length() != 7) {
+                    throw new Exception("reqFlags should contain 7 bits");
+                }
+                if (!ba.get(0)) {
+                    throw new Exception("delegFlag should be true");
+                }
+                if (ba.get(2) || ba.get(3)) {
+                    throw new Exception("replay/sequenceFlag should be false");
+                }
+            }
+        }
+
+        if (!found) {
+            System.out.println("Warning: regFlags field not found, too new?");
+        }
+        c.dispose();
+    }
+}