--- a/jdk/make/mkdemo/nio/zipfs/Makefile Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/make/mkdemo/nio/zipfs/Makefile Mon Nov 22 10:18:33 2010 -0500
@@ -42,3 +42,10 @@
#
include $(BUILDDIR)/common/Demo.gmk
+#EXTJAR = $(EXTDIR)/$(DEMONAME).jar
+#
+#all : build $(EXTJAR)
+#
+#$(EXTJAR) : $(DEMO_JAR)
+# $(prep-target)
+# $(CP) $(DEMO_JAR) $(EXTJAR)
--- a/jdk/make/sun/nio/cs/FILES_java.gmk Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/make/sun/nio/cs/FILES_java.gmk Mon Nov 22 10:18:33 2010 -0500
@@ -85,6 +85,7 @@
sun/io/ByteToCharCp500.java \
sun/io/ByteToCharCp737.java \
sun/io/ByteToCharCp775.java \
+ sun/io/ByteToCharCp833.java \
sun/io/ByteToCharCp834.java \
sun/io/ByteToCharCp838.java \
sun/io/ByteToCharCp850.java \
@@ -214,6 +215,7 @@
sun/io/CharToByteCp500.java \
sun/io/CharToByteCp737.java \
sun/io/CharToByteCp775.java \
+ sun/io/CharToByteCp833.java \
sun/io/CharToByteCp834.java \
sun/io/CharToByteCp838.java \
sun/io/CharToByteCp850.java \
@@ -331,6 +333,7 @@
sun/nio/cs/ext/IBM420.java \
sun/nio/cs/ext/IBM424.java \
sun/nio/cs/ext/IBM500.java \
+ sun/nio/cs/ext/IBM833.java \
sun/nio/cs/ext/IBM838.java \
sun/nio/cs/ext/IBM856.java \
sun/nio/cs/ext/IBM860.java \
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/tools/CharsetMapping/IBM833.c2b Mon Nov 22 10:18:33 2010 -0500
@@ -0,0 +1,94 @@
+0x5A U+FF01
+0x7F U+FF02
+0x7B U+FF03
+0x5B U+FF04
+0x6C U+FF05
+0x50 U+FF06
+0x7D U+FF07
+0x4D U+FF08
+0x5D U+FF09
+0x5C U+FF0A
+0x4E U+FF0B
+0x6B U+FF0C
+0x60 U+FF0D
+0x4B U+FF0E
+0x61 U+FF0F
+0xF0 U+FF10
+0xF1 U+FF11
+0xF2 U+FF12
+0xF3 U+FF13
+0xF4 U+FF14
+0xF5 U+FF15
+0xF6 U+FF16
+0xF7 U+FF17
+0xF8 U+FF18
+0xF9 U+FF19
+0x7A U+FF1A
+0x5E U+FF1B
+0x4C U+FF1C
+0x7E U+FF1D
+0x6E U+FF1E
+0x6F U+FF1F
+0x7C U+FF20
+0xC1 U+FF21
+0xC2 U+FF22
+0xC3 U+FF23
+0xC4 U+FF24
+0xC5 U+FF25
+0xC6 U+FF26
+0xC7 U+FF27
+0xC8 U+FF28
+0xC9 U+FF29
+0xD1 U+FF2A
+0xD2 U+FF2B
+0xD3 U+FF2C
+0xD4 U+FF2D
+0xD5 U+FF2E
+0xD6 U+FF2F
+0xD7 U+FF30
+0xD8 U+FF31
+0xD9 U+FF32
+0xE2 U+FF33
+0xE3 U+FF34
+0xE4 U+FF35
+0xE5 U+FF36
+0xE6 U+FF37
+0xE7 U+FF38
+0xE8 U+FF39
+0xE9 U+FF3A
+0x70 U+FF3B
+0xB2 U+FF3C
+0x80 U+FF3D
+0xB0 U+FF3E
+0x6D U+FF3F
+0x79 U+FF40
+0x81 U+FF41
+0x82 U+FF42
+0x83 U+FF43
+0x84 U+FF44
+0x85 U+FF45
+0x86 U+FF46
+0x87 U+FF47
+0x88 U+FF48
+0x89 U+FF49
+0x91 U+FF4A
+0x92 U+FF4B
+0x93 U+FF4C
+0x94 U+FF4D
+0x95 U+FF4E
+0x96 U+FF4F
+0x97 U+FF50
+0x98 U+FF51
+0x99 U+FF52
+0xA2 U+FF53
+0xA3 U+FF54
+0xA4 U+FF55
+0xA5 U+FF56
+0xA6 U+FF57
+0xA7 U+FF58
+0xA8 U+FF59
+0xA9 U+FF5A
+0xC0 U+FF5B
+0x4F U+FF5C
+0xD0 U+FF5D
+0xA1 U+FF5E
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/tools/CharsetMapping/IBM833.map Mon Nov 22 10:18:33 2010 -0500
@@ -0,0 +1,217 @@
+0x00 U+0000
+0x01 U+0001
+0x02 U+0002
+0x03 U+0003
+0x37 U+0004
+0x2D U+0005
+0x2E U+0006
+0x2F U+0007
+0x16 U+0008
+0x05 U+0009
+0x25 U+000A
+0x0B U+000B
+0x0C U+000C
+0x0D U+000D
+0x0E U+000E
+0x0F U+000F
+0x10 U+0010
+0x11 U+0011
+0x12 U+0012
+0x13 U+0013
+0x3C U+0014
+0x3D U+0015
+0x32 U+0016
+0x26 U+0017
+0x18 U+0018
+0x19 U+0019
+0x3F U+001A
+0x27 U+001B
+0x1C U+001C
+0x1D U+001D
+0x1E U+001E
+0x1F U+001F
+0x40 U+0020
+0x5A U+0021
+0x7F U+0022
+0x7B U+0023
+0x5B U+0024
+0x6C U+0025
+0x50 U+0026
+0x7D U+0027
+0x4D U+0028
+0x5D U+0029
+0x5C U+002A
+0x4E U+002B
+0x6B U+002C
+0x60 U+002D
+0x4B U+002E
+0x61 U+002F
+0xF0 U+0030
+0xF1 U+0031
+0xF2 U+0032
+0xF3 U+0033
+0xF4 U+0034
+0xF5 U+0035
+0xF6 U+0036
+0xF7 U+0037
+0xF8 U+0038
+0xF9 U+0039
+0x7A U+003A
+0x5E U+003B
+0x4C U+003C
+0x7E U+003D
+0x6E U+003E
+0x6F U+003F
+0x7C U+0040
+0xC1 U+0041
+0xC2 U+0042
+0xC3 U+0043
+0xC4 U+0044
+0xC5 U+0045
+0xC6 U+0046
+0xC7 U+0047
+0xC8 U+0048
+0xC9 U+0049
+0xD1 U+004A
+0xD2 U+004B
+0xD3 U+004C
+0xD4 U+004D
+0xD5 U+004E
+0xD6 U+004F
+0xD7 U+0050
+0xD8 U+0051
+0xD9 U+0052
+0xE2 U+0053
+0xE3 U+0054
+0xE4 U+0055
+0xE5 U+0056
+0xE6 U+0057
+0xE7 U+0058
+0xE8 U+0059
+0xE9 U+005A
+0x70 U+005B
+0xB2 U+005C
+0x80 U+005D
+0xB0 U+005E
+0x6D U+005F
+0x79 U+0060
+0x81 U+0061
+0x82 U+0062
+0x83 U+0063
+0x84 U+0064
+0x85 U+0065
+0x86 U+0066
+0x87 U+0067
+0x88 U+0068
+0x89 U+0069
+0x91 U+006A
+0x92 U+006B
+0x93 U+006C
+0x94 U+006D
+0x95 U+006E
+0x96 U+006F
+0x97 U+0070
+0x98 U+0071
+0x99 U+0072
+0xA2 U+0073
+0xA3 U+0074
+0xA4 U+0075
+0xA5 U+0076
+0xA6 U+0077
+0xA7 U+0078
+0xA8 U+0079
+0xA9 U+007A
+0xC0 U+007B
+0x4F U+007C
+0xD0 U+007D
+0xA1 U+007E
+0x07 U+007F
+0x20 U+0080
+0x21 U+0081
+0x22 U+0082
+0x23 U+0083
+0x24 U+0084
+0x15 U+0085
+0x06 U+0086
+0x17 U+0087
+0x28 U+0088
+0x29 U+0089
+0x2A U+008A
+0x2B U+008B
+0x2C U+008C
+0x09 U+008D
+0x0A U+008E
+0x1B U+008F
+0x30 U+0090
+0x31 U+0091
+0x1A U+0092
+0x33 U+0093
+0x34 U+0094
+0x35 U+0095
+0x36 U+0096
+0x08 U+0097
+0x38 U+0098
+0x39 U+0099
+0x3A U+009A
+0x3B U+009B
+0x04 U+009C
+0x14 U+009D
+0x3E U+009E
+0xFF U+009F
+0x4A U+00A2
+0x6A U+00A6
+0x5F U+00AC
+0xA0 U+203E
+0xE0 U+20A9
+0x42 U+FFA0
+0x43 U+FFA1
+0x44 U+FFA2
+0x45 U+FFA3
+0x46 U+FFA4
+0x47 U+FFA5
+0x48 U+FFA6
+0x49 U+FFA7
+0x52 U+FFA8
+0x53 U+FFA9
+0x54 U+FFAA
+0x55 U+FFAB
+0x56 U+FFAC
+0x57 U+FFAD
+0x58 U+FFAE
+0x59 U+FFAF
+0x62 U+FFB0
+0x63 U+FFB1
+0x64 U+FFB2
+0x65 U+FFB3
+0x66 U+FFB4
+0x67 U+FFB5
+0x68 U+FFB6
+0x69 U+FFB7
+0x72 U+FFB8
+0x73 U+FFB9
+0x74 U+FFBA
+0x75 U+FFBB
+0x76 U+FFBC
+0x77 U+FFBD
+0x78 U+FFBE
+0x8A U+FFC2
+0x8B U+FFC3
+0x8C U+FFC4
+0x8D U+FFC5
+0x8E U+FFC6
+0x8F U+FFC7
+0x9A U+FFCA
+0x9B U+FFCB
+0x9C U+FFCC
+0x9D U+FFCD
+0x9E U+FFCE
+0x9F U+FFCF
+0xAA U+FFD2
+0xAB U+FFD3
+0xAC U+FFD4
+0xAD U+FFD5
+0xAE U+FFD6
+0xAF U+FFD7
+0xBA U+FFDA
+0xBB U+FFDB
+0xBC U+FFDC
--- a/jdk/make/tools/CharsetMapping/extsbcs Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/make/tools/CharsetMapping/extsbcs Mon Nov 22 10:18:33 2010 -0500
@@ -32,6 +32,7 @@
IBM420 IBM420 Cp420 false sun.nio.cs.ext
IBM424 IBM424 Cp424 false sun.nio.cs.ext
IBM500 IBM500 Cp500 false sun.nio.cs.ext
+IBM833 IBM833 Cp833 false sun.nio.cs.ext
IBM838 IBM-Thai Cp838 false sun.nio.cs.ext
IBM856 x-IBM856 Cp856 false sun.nio.cs.ext
IBM860 IBM860 Cp860 false sun.nio.cs.ext
--- a/jdk/src/share/classes/com/sun/net/httpserver/HttpsConfigurator.java Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/src/share/classes/com/sun/net/httpserver/HttpsConfigurator.java Mon Nov 22 10:18:33 2010 -0500
@@ -91,6 +91,7 @@
return context;
}
+//BEGIN_TIGER_EXCLUDE
/**
* Called by the HttpsServer to configure the parameters
* for a https connection currently being established.
@@ -111,4 +112,5 @@
public void configure (HttpsParameters params) {
params.setSSLParameters (getSSLContext().getDefaultSSLParameters());
}
+//END_TIGER_EXCLUDE
}
--- a/jdk/src/share/classes/com/sun/net/httpserver/HttpsParameters.java Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/src/share/classes/com/sun/net/httpserver/HttpsParameters.java Mon Nov 22 10:18:33 2010 -0500
@@ -25,7 +25,9 @@
package com.sun.net.httpserver;
import java.net.InetSocketAddress;
+//BEGIN_TIGER_EXCLUDE
import javax.net.ssl.SSLParameters;
+//END_TIGER_EXCLUDE
/**
* Represents the set of parameters for each https
@@ -67,6 +69,7 @@
*/
public abstract InetSocketAddress getClientAddress();
+//BEGIN_TIGER_EXCLUDE
/**
* Sets the SSLParameters to use for this HttpsParameters.
* The parameters must be supported by the SSLContext contained
@@ -79,6 +82,7 @@
* invalid or unsupported.
*/
public abstract void setSSLParameters (SSLParameters params);
+//END_TIGER_EXCLUDE
/**
* Returns a copy of the array of ciphersuites or null if none
--- a/jdk/src/share/classes/com/sun/rowset/RowSetResourceBundle.properties Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/src/share/classes/com/sun/rowset/RowSetResourceBundle.properties Mon Nov 22 10:18:33 2010 -0500
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2005, 2010, 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
@@ -140,7 +140,7 @@
#WebRowSetXmlReader exception
wrsxmlreader.invalidcp = End of RowSet reached. Invalid cursor position
wrsxmlreader.readxml = readXML : {0}
-wrsxmlreader.parseerr = ** Parsing Error : {0} , line : {0} , uri : {0}
+wrsxmlreader.parseerr = ** Parsing Error : {0} , line : {1} , uri : {2}
#WebRowSetXmlWriter exceptions
wrsxmlwriter.ioex = IOException : {0}
@@ -151,7 +151,7 @@
#XmlReaderContentHandler exceptions
xmlrch.errmap = Error setting Map : {0}
xmlrch.errmetadata = Error setting metadata : {0}
-xmlrch.errinsert = Error inserting values : {0}
+xmlrch.errinsertval = Error inserting values : {0}
xmlrch.errconstr = Error constructing row : {0}
xmlrch.errdel = Error deleting row : {0}
xmlrch.errinsert = Error constructing insert row : {0}
@@ -161,7 +161,7 @@
xmlrch.chars = characters :
xmlrch.badvalue = Bad value ; non-nullable property
xmlrch.badvalue1 = Bad value ; non-nullable metadata
-xmlrch.warning = ** Warning : {0} , line : {0} , uri : {0}
+xmlrch.warning = ** Warning : {0} , line : {1} , uri : {2}
#RIOptimisticProvider Exceptions
riop.locking = Locking classification is not supported
--- a/jdk/src/share/classes/com/sun/rowset/internal/XmlReaderContentHandler.java Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/src/share/classes/com/sun/rowset/internal/XmlReaderContentHandler.java Mon Nov 22 10:18:33 2010 -0500
@@ -738,7 +738,7 @@
// columnValue now need to be reset to the empty string
columnValue = "";
} catch (SQLException ex) {
- throw new SAXException(MessageFormat.format(resBundle.handleGetObject("xmlrch.errinsert").toString(), ex.getMessage()));
+ throw new SAXException(MessageFormat.format(resBundle.handleGetObject("xmlrch.errinsertval").toString(), ex.getMessage()));
}
break;
case RowTag:
--- a/jdk/src/share/classes/java/io/BufferedInputStream.java Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/src/share/classes/java/io/BufferedInputStream.java Mon Nov 22 10:18:33 2010 -0500
@@ -395,7 +395,11 @@
* or an I/O error occurs.
*/
public synchronized int available() throws IOException {
- return getInIfOpen().available() + (count - pos);
+ int n = count - pos;
+ int avail = getInIfOpen().available();
+ return n > (Integer.MAX_VALUE - avail)
+ ? Integer.MAX_VALUE
+ : n + avail;
}
/**
--- a/jdk/src/share/classes/java/io/PushbackInputStream.java Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/src/share/classes/java/io/PushbackInputStream.java Mon Nov 22 10:18:33 2010 -0500
@@ -273,7 +273,11 @@
*/
public int available() throws IOException {
ensureOpen();
- return (buf.length - pos) + super.available();
+ int n = buf.length - pos;
+ int avail = super.available();
+ return n > (Integer.MAX_VALUE - avail)
+ ? Integer.MAX_VALUE
+ : n + avail;
}
/**
--- a/jdk/src/share/classes/java/lang/Readable.java Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/src/share/classes/java/lang/Readable.java Mon Nov 22 10:18:33 2010 -0500
@@ -44,11 +44,11 @@
* rewinding of the buffer is performed.
*
* @param cb the buffer to read characters into
- * @return @return The number of <tt>char</tt> values added to the buffer,
+ * @return The number of {@code char} values added to the buffer,
* or -1 if this source of characters is at its end
* @throws IOException if an I/O error occurs
* @throws NullPointerException if cb is null
- * @throws ReadOnlyBufferException if cb is a read only buffer
+ * @throws java.nio.ReadOnlyBufferException if cb is a read only buffer
*/
public int read(java.nio.CharBuffer cb) throws IOException;
--- a/jdk/src/share/classes/java/nio/StringCharBuffer.java Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/src/share/classes/java/nio/StringCharBuffer.java Mon Nov 22 10:18:33 2010 -0500
@@ -47,7 +47,7 @@
0,
this.remaining(),
this.remaining(),
- this.position());
+ offset + this.position());
}
private StringCharBuffer(CharSequence s,
--- a/jdk/src/share/classes/java/sql/SQLPermission.java Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/src/share/classes/java/sql/SQLPermission.java Mon Nov 22 10:18:33 2010 -0500
@@ -84,7 +84,7 @@
* {@code setJNDIContext} and {@code setLogger}</td>
* <td>Permits an application to specify the JNDI context from which the
* {@code SyncProvider} implementations can be retrieved from and the logging
- * object to be used by the{@codeSyncProvider} implementation.</td>
+ * object to be used by the {@code SyncProvider} implementation.</td>
* </tr>
*
* <tr>
--- a/jdk/src/share/classes/java/util/Formatter.java Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/src/share/classes/java/util/Formatter.java Mon Nov 22 10:18:33 2010 -0500
@@ -1581,6 +1581,7 @@
* instance of the Java virtual machine.
*
* <tr><td valign="top">{@code 'Z'}
+ * <td valign="top"> <tt>'\u005a'</tt>
* <td> A string representing the abbreviation for the time zone. This
* value will be adjusted as necessary for Daylight Saving Time. For
* {@code long}, {@link Long}, and {@link Date} the time zone used is
--- a/jdk/src/share/classes/java/util/jar/JarInputStream.java Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/src/share/classes/java/util/jar/JarInputStream.java Mon Nov 22 10:18:33 2010 -0500
@@ -28,6 +28,7 @@
import java.util.zip.*;
import java.io.*;
import sun.security.util.ManifestEntryVerifier;
+import sun.misc.JarIndex;
/**
* The <code>JarInputStream</code> class is used to read the contents of
@@ -47,7 +48,8 @@
private JarEntry first;
private JarVerifier jv;
private ManifestEntryVerifier mev;
-
+ private final boolean doVerify;
+ private boolean tryManifest;
/**
* Creates a new <code>JarInputStream</code> and reads the optional
@@ -72,25 +74,33 @@
*/
public JarInputStream(InputStream in, boolean verify) throws IOException {
super(in);
+ this.doVerify = verify;
+
+ // This implementation assumes the META-INF/MANIFEST.MF entry
+ // should be either the first or the second entry (when preceded
+ // by the dir META-INF/). It skips the META-INF/ and then
+ // "consumes" the MANIFEST.MF to initialize the Manifest object.
JarEntry e = (JarEntry)super.getNextEntry();
-
if (e != null && e.getName().equalsIgnoreCase("META-INF/"))
e = (JarEntry)super.getNextEntry();
+ first = checkManifest(e);
+ }
+ private JarEntry checkManifest(JarEntry e)
+ throws IOException
+ {
if (e != null && JarFile.MANIFEST_NAME.equalsIgnoreCase(e.getName())) {
man = new Manifest();
byte bytes[] = getBytes(new BufferedInputStream(this));
man.read(new ByteArrayInputStream(bytes));
- //man.read(new BufferedInputStream(this));
closeEntry();
- if (verify) {
+ if (doVerify) {
jv = new JarVerifier(bytes);
mev = new ManifestEntryVerifier(man);
}
- first = getNextJarEntry();
- } else {
- first = e;
+ return (JarEntry)super.getNextEntry();
}
+ return e;
}
private byte[] getBytes(InputStream is)
@@ -98,10 +108,7 @@
{
byte[] buffer = new byte[8192];
ByteArrayOutputStream baos = new ByteArrayOutputStream(2048);
-
int n;
-
- baos.reset();
while ((n = is.read(buffer, 0, buffer.length)) != -1) {
baos.write(buffer, 0, n);
}
@@ -133,8 +140,14 @@
JarEntry e;
if (first == null) {
e = (JarEntry)super.getNextEntry();
+ if (tryManifest) {
+ e = checkManifest(e);
+ tryManifest = false;
+ }
} else {
e = first;
+ if (first.getName().equalsIgnoreCase(JarIndex.INDEX_NAME))
+ tryManifest = true;
first = null;
}
if (jv != null && e != null) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/io/ByteToCharCp833.java Mon Nov 22 10:18:33 2010 -0500
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2010 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.io;
+
+import sun.nio.cs.ext.IBM833;
+
+public class ByteToCharCp833 extends ByteToCharSingleByte {
+
+ private final static IBM833 nioCoder = new IBM833();
+
+ public String getCharacterEncoding() {
+ return "Cp833";
+ }
+
+ public ByteToCharCp833() {
+ super.byteToCharTable = nioCoder.getDecoderSingleByteMappings();
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/io/CharToByteCp833.java Mon Nov 22 10:18:33 2010 -0500
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2010 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.io;
+
+import sun.nio.cs.ext.IBM833;
+
+public class CharToByteCp833 extends CharToByteSingleByte {
+
+ private final static IBM833 nioCoder = new IBM833();
+
+ public String getCharacterEncoding() {
+ return "Cp833";
+ }
+
+ public CharToByteCp833() {
+ super.mask1 = 0xFF00;
+ super.mask2 = 0x00FF;
+ super.shift = 8;
+ super.index1 = nioCoder.getEncoderIndex1();
+ super.index2 = nioCoder.getEncoderIndex2();
+ }
+}
+
--- a/jdk/src/share/classes/sun/io/CharacterEncoding.java Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/src/share/classes/sun/io/CharacterEncoding.java Mon Nov 22 10:18:33 2010 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2010, 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
@@ -406,6 +406,11 @@
aliasTable.put("cp775", "Cp775");
aliasTable.put("775", "Cp775");
+ aliasTable.put("ibm833", "Cp833");
+ aliasTable.put("ibm-833", "Cp833");
+ aliasTable.put("cp833", "Cp833");
+ aliasTable.put("833", "Cp833");
+
aliasTable.put("ibm834", "Cp834");
aliasTable.put("ibm-834", "Cp834");
aliasTable.put("cp834", "Cp834");
--- a/jdk/src/share/classes/sun/net/httpserver/ChunkedInputStream.java Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/src/share/classes/sun/net/httpserver/ChunkedInputStream.java Mon Nov 22 10:18:33 2010 -0500
@@ -110,6 +110,7 @@
if (remaining == 0) {
eof = true;
consumeCRLF();
+ t.getServerImpl().requestCompleted (t.getConnection());
return -1;
}
needToReadHeader = false;
--- a/jdk/src/share/classes/sun/net/httpserver/Event.java Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/src/share/classes/sun/net/httpserver/Event.java Mon Nov 22 10:18:33 2010 -0500
@@ -40,5 +40,7 @@
class WriteFinishedEvent extends Event {
WriteFinishedEvent (ExchangeImpl t) {
super (t);
+ assert !t.writefinished;
+ t.writefinished = true;
}
}
--- a/jdk/src/share/classes/sun/net/httpserver/ExchangeImpl.java Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/src/share/classes/sun/net/httpserver/ExchangeImpl.java Mon Nov 22 10:18:33 2010 -0500
@@ -38,6 +38,7 @@
Headers reqHdrs, rspHdrs;
Request req;
String method;
+ boolean writefinished;
URI uri;
HttpConnection connection;
long reqContentLen;
--- a/jdk/src/share/classes/sun/net/httpserver/FixedLengthInputStream.java Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/src/share/classes/sun/net/httpserver/FixedLengthInputStream.java Mon Nov 22 10:18:33 2010 -0500
@@ -56,6 +56,9 @@
int n = in.read(b, off, len);
if (n > -1) {
remaining -= n;
+ if (remaining == 0) {
+ t.getServerImpl().requestCompleted (t.getConnection());
+ }
}
return n;
}
--- a/jdk/src/share/classes/sun/net/httpserver/HttpConnection.java Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/src/share/classes/sun/net/httpserver/HttpConnection.java Mon Nov 22 10:18:33 2010 -0500
@@ -55,10 +55,15 @@
SelectionKey selectionKey;
String protocol;
long time;
+ volatile long creationTime; // time this connection was created
+ volatile long rspStartedTime; // time we started writing the response
int remaining;
boolean closed = false;
Logger logger;
+ public enum State {IDLE, REQUEST, RESPONSE};
+ volatile State state;
+
public String toString() {
String s = null;
if (chan != null) {
@@ -78,6 +83,14 @@
context = ctx;
}
+ State getState() {
+ return state;
+ }
+
+ void setState (State s) {
+ state = s;
+ }
+
void setParameters (
InputStream in, OutputStream rawout, SocketChannel chan,
SSLEngine engine, SSLStreams sslStreams, SSLContext sslContext, String protocol,
--- a/jdk/src/share/classes/sun/net/httpserver/Request.java Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/src/share/classes/sun/net/httpserver/Request.java Mon Nov 22 10:18:33 2010 -0500
@@ -201,32 +201,22 @@
static class ReadStream extends InputStream {
SocketChannel channel;
- SelectorCache sc;
- Selector selector;
ByteBuffer chanbuf;
- SelectionKey key;
- int available;
byte[] one;
- boolean closed = false, eof = false;
+ private boolean closed = false, eof = false;
ByteBuffer markBuf; /* reads may be satisifed from this buffer */
boolean marked;
boolean reset;
int readlimit;
static long readTimeout;
ServerImpl server;
-
- static {
- readTimeout = ServerConfig.getReadTimeout();
- }
+ final static int BUFSIZE = 8 * 1024;
public ReadStream (ServerImpl server, SocketChannel chan) throws IOException {
this.channel = chan;
this.server = server;
- sc = SelectorCache.getSelectorCache();
- selector = sc.getSelector();
- chanbuf = ByteBuffer.allocate (8* 1024);
- key = chan.register (selector, SelectionKey.OP_READ);
- available = 0;
+ chanbuf = ByteBuffer.allocate (BUFSIZE);
+ chanbuf.clear();
one = new byte[1];
closed = marked = reset = false;
}
@@ -255,6 +245,12 @@
return -1;
}
+ assert channel.isBlocking();
+
+ if (off < 0 || srclen < 0|| srclen > (b.length-off)) {
+ throw new IndexOutOfBoundsException ();
+ }
+
if (reset) { /* satisfy from markBuf */
canreturn = markBuf.remaining ();
willreturn = canreturn>srclen ? srclen : canreturn;
@@ -263,17 +259,19 @@
reset = false;
}
} else { /* satisfy from channel */
- canreturn = available();
- while (canreturn == 0 && !eof) {
- block ();
- canreturn = available();
+ chanbuf.clear ();
+ if (srclen < BUFSIZE) {
+ chanbuf.limit (srclen);
}
- if (eof) {
+ do {
+ willreturn = channel.read (chanbuf);
+ } while (willreturn == 0);
+ if (willreturn == -1) {
+ eof = true;
return -1;
}
- willreturn = canreturn>srclen ? srclen : canreturn;
+ chanbuf.flip ();
chanbuf.get(b, off, willreturn);
- available -= willreturn;
if (marked) { /* copy into markBuf */
try {
@@ -286,6 +284,11 @@
return willreturn;
}
+ public boolean markSupported () {
+ return true;
+ }
+
+ /* Does not query the OS socket */
public synchronized int available () throws IOException {
if (closed)
throw new IOException ("Stream is closed");
@@ -296,36 +299,7 @@
if (reset)
return markBuf.remaining();
- if (available > 0)
- return available;
-
- chanbuf.clear ();
- available = channel.read (chanbuf);
- if (available > 0) {
- chanbuf.flip();
- } else if (available == -1) {
- eof = true;
- available = 0;
- }
- return available;
- }
-
- /**
- * block() only called when available==0 and buf is empty
- */
- private synchronized void block () throws IOException {
- long currtime = server.getTime();
- long maxtime = currtime + readTimeout;
-
- while (currtime < maxtime) {
- if (selector.select (readTimeout) == 1) {
- selector.selectedKeys().clear();
- available ();
- return;
- }
- currtime = server.getTime();
- }
- throw new SocketTimeoutException ("no data received");
+ return chanbuf.remaining();
}
public void close () throws IOException {
@@ -333,8 +307,6 @@
return;
}
channel.close ();
- selector.selectNow();
- sc.freeSelector(selector);
closed = true;
}
@@ -362,23 +334,14 @@
SocketChannel channel;
ByteBuffer buf;
SelectionKey key;
- SelectorCache sc;
- Selector selector;
boolean closed;
byte[] one;
ServerImpl server;
- static long writeTimeout;
-
- static {
- writeTimeout = ServerConfig.getWriteTimeout();
- }
public WriteStream (ServerImpl server, SocketChannel channel) throws IOException {
this.channel = channel;
this.server = server;
- sc = SelectorCache.getSelectorCache();
- selector = sc.getSelector();
- key = channel.register (selector, SelectionKey.OP_WRITE);
+ assert channel.isBlocking();
closed = false;
one = new byte [1];
buf = ByteBuffer.allocate (4096);
@@ -411,31 +374,14 @@
l -= n;
if (l == 0)
return;
- block();
}
}
- void block () throws IOException {
- long currtime = server.getTime();
- long maxtime = currtime + writeTimeout;
-
- while (currtime < maxtime) {
- if (selector.select (writeTimeout) == 1) {
- selector.selectedKeys().clear ();
- return;
- }
- currtime = server.getTime();
- }
- throw new SocketTimeoutException ("write blocked too long");
- }
-
-
public void close () throws IOException {
if (closed)
return;
+ //server.logStackTrace ("Request.OS.close: isOpen="+channel.isOpen());
channel.close ();
- selector.selectNow();
- sc.freeSelector(selector);
closed = true;
}
}
--- a/jdk/src/share/classes/sun/net/httpserver/SSLStreams.java Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/src/share/classes/sun/net/httpserver/SSLStreams.java Mon Nov 22 10:18:33 2010 -0500
@@ -53,8 +53,6 @@
EngineWrapper wrapper;
OutputStream os;
InputStream is;
- static long readTimeout = ServerConfig.getReadTimeout();
- static long writeTimeout = ServerConfig.getWriteTimeout();
/* held by thread doing the hand-shake on this connection */
Lock handshaking = new ReentrantLock();
@@ -77,10 +75,13 @@
if (cfg != null) {
Parameters params = new Parameters (cfg, addr);
cfg.configure (params);
+//BEGIN_TIGER_EXCLUDE
SSLParameters sslParams = params.getSSLParameters();
if (sslParams != null) {
engine.setSSLParameters (sslParams);
- } else {
+ } else
+//END_TIGER_EXCLUDE
+ {
/* tiger compatibility */
if (params.getCipherSuites() != null) {
try {
@@ -104,7 +105,6 @@
class Parameters extends HttpsParameters {
InetSocketAddress addr;
- SSLParameters params;
HttpsConfigurator cfg;
Parameters (HttpsConfigurator cfg, InetSocketAddress addr) {
@@ -117,12 +117,15 @@
public HttpsConfigurator getHttpsConfigurator() {
return cfg;
}
+//BEGIN_TIGER_EXCLUDE
+ SSLParameters params;
public void setSSLParameters (SSLParameters p) {
params = p;
}
SSLParameters getSSLParameters () {
return params;
}
+//END_TIGER_EXCLUDE
}
/**
@@ -245,9 +248,6 @@
SocketChannel chan;
SSLEngine engine;
- SelectorCache sc;
- Selector write_selector, read_selector;
- SelectionKey wkey, rkey;
Object wrapLock, unwrapLock;
ByteBuffer unwrap_src, wrap_dst;
boolean closed = false;
@@ -260,16 +260,9 @@
unwrapLock = new Object();
unwrap_src = allocate(BufType.PACKET);
wrap_dst = allocate(BufType.PACKET);
- sc = SelectorCache.getSelectorCache();
- write_selector = sc.getSelector();
- wkey = chan.register (write_selector, SelectionKey.OP_WRITE);
- read_selector = sc.getSelector();
- wkey = chan.register (read_selector, SelectionKey.OP_READ);
}
void close () throws IOException {
- sc.freeSelector (write_selector);
- sc.freeSelector (read_selector);
}
/* try to wrap and send the data in src. Handles OVERFLOW.
@@ -304,15 +297,7 @@
wrap_dst.flip();
int l = wrap_dst.remaining();
assert l == r.result.bytesProduced();
- long currtime = time.getTime();
- long maxtime = currtime + writeTimeout;
while (l>0) {
- write_selector.select(writeTimeout); // timeout
- currtime = time.getTime();
- if (currtime > maxtime) {
- throw new SocketTimeoutException ("write timed out");
- }
- write_selector.selectedKeys().clear();
l -= chan.write (wrap_dst);
}
}
@@ -342,20 +327,12 @@
needData = true;
}
synchronized (unwrapLock) {
- int x,y;
+ int x;
do {
if (needData) {
- long currTime = time.getTime();
- long maxtime = currTime + readTimeout;
do {
- if (currTime > maxtime) {
- throw new SocketTimeoutException ("read timedout");
- }
- y = read_selector.select (readTimeout);
- currTime = time.getTime();
- } while (y != 1);
- read_selector.selectedKeys().clear();
x = chan.read (unwrap_src);
+ } while (x == 0);
if (x == -1) {
throw new IOException ("connection closed for reading");
}
--- a/jdk/src/share/classes/sun/net/httpserver/SelectorCache.java Mon Nov 22 10:16:07 2010 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,134 +0,0 @@
-/*
- * Copyright (c) 2006, 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.net.httpserver;
-
-import java.util.*;
-import java.nio.*;
-import java.net.*;
-import java.io.*;
-import java.security.*;
-import java.nio.channels.*;
-
-/*
- * Implements a cache of java.nio.channels.Selector
- * where Selectors are allocated on demand and placed
- * in a temporary cache for a period of time, so they
- * can be reused. If a period of between 2 and 4 minutes
- * elapses without being used, then they are closed.
- */
-public class SelectorCache {
-
- static SelectorCache cache = null;
-
- private SelectorCache () {
- freeSelectors = new LinkedList<SelectorWrapper>();
- CacheCleaner c = AccessController.doPrivileged(
- new PrivilegedAction<CacheCleaner>() {
- public CacheCleaner run() {
- CacheCleaner cleaner = new CacheCleaner();
- cleaner.setDaemon (true);
- return cleaner;
- }
- });
- c.start();
- }
-
- /**
- * factory method for creating single instance
- */
- public static SelectorCache getSelectorCache () {
- synchronized (SelectorCache.class) {
- if (cache == null) {
- cache = new SelectorCache ();
- }
- }
- return cache;
- }
-
- private static class SelectorWrapper {
- private Selector sel;
- private boolean deleteFlag;
- private SelectorWrapper (Selector sel) {
- this.sel = sel;
- this.deleteFlag = false;
- }
- public Selector getSelector() { return sel;}
- public boolean getDeleteFlag () {return deleteFlag;}
- public void setDeleteFlag (boolean b) {deleteFlag = b;}
- }
-
- /* list of free selectors. Can be re-allocated for a period
- * of time, after which if not allocated will be closed
- * and removed from the list (by CacheCleaner thread)
- */
- LinkedList<SelectorWrapper> freeSelectors;
-
- synchronized Selector getSelector () throws IOException {
- SelectorWrapper wrapper = null;
- Selector selector;
-
- if (freeSelectors.size() > 0) {
- wrapper = freeSelectors.remove();
- selector = wrapper.getSelector();
- } else {
- selector = Selector.open();
- }
- return selector;
- }
-
- synchronized void freeSelector (Selector selector) {
- freeSelectors.add (new SelectorWrapper (selector));
- }
-
- /* Thread ensures that entries on freeSelector list
- * remain there for at least 2 minutes and no longer
- * than 4 minutes.
- */
- class CacheCleaner extends Thread {
- public void run () {
- long timeout = ServerConfig.getSelCacheTimeout() * 1000;
- while (true) {
- try {Thread.sleep (timeout); } catch (Exception e) {}
- synchronized (freeSelectors) {
- ListIterator<SelectorWrapper> l = freeSelectors.listIterator();
- while (l.hasNext()) {
- SelectorWrapper w = l.next();
- if (w.getDeleteFlag()) {
- /* 2nd pass. Close the selector */
- try {
- w.getSelector().close();
- } catch (IOException e) {}
- l.remove();
- } else {
- /* 1st pass. Set the flag */
- w.setDeleteFlag (true);
- }
- }
- }
- }
- }
- }
-}
--- a/jdk/src/share/classes/sun/net/httpserver/ServerConfig.java Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/src/share/classes/sun/net/httpserver/ServerConfig.java Mon Nov 22 10:18:33 2010 -0500
@@ -27,6 +27,8 @@
import com.sun.net.httpserver.*;
import com.sun.net.httpserver.spi.*;
+import java.util.logging.Logger;
+import java.security.PrivilegedAction;
/**
* Parameters that users will not likely need to set
@@ -37,23 +39,26 @@
static int clockTick;
- static int defaultClockTick = 10000 ; // 10 sec.
+ static final int DEFAULT_CLOCK_TICK = 10000 ; // 10 sec.
/* These values must be a reasonable multiple of clockTick */
- static long defaultReadTimeout = 20 ; // 20 sec.
- static long defaultWriteTimeout = 60 ; // 60 sec.
- static long defaultIdleInterval = 300 ; // 5 min
- static long defaultSelCacheTimeout = 120 ; // seconds
- static int defaultMaxIdleConnections = 200 ;
+ static final long DEFAULT_IDLE_INTERVAL = 300 ; // 5 min
+ static final int DEFAULT_MAX_IDLE_CONNECTIONS = 200 ;
- static long defaultDrainAmount = 64 * 1024;
+ static final long DEFAULT_MAX_REQ_TIME = -1; // default: forever
+ static final long DEFAULT_MAX_RSP_TIME = -1; // default: forever
+ static final long DEFAULT_TIMER_MILLIS = 1000;
- static long readTimeout;
- static long writeTimeout;
+ static final long DEFAULT_DRAIN_AMOUNT = 64 * 1024;
+
static long idleInterval;
- static long selCacheTimeout;
static long drainAmount; // max # of bytes to drain from an inputstream
static int maxIdleConnections;
+
+ // max time a request or response is allowed to take
+ static long maxReqTime;
+ static long maxRspTime;
+ static long timerMillis;
static boolean debug = false;
static {
@@ -61,49 +66,79 @@
idleInterval = ((Long)java.security.AccessController.doPrivileged(
new sun.security.action.GetLongAction(
"sun.net.httpserver.idleInterval",
- defaultIdleInterval))).longValue() * 1000;
+ DEFAULT_IDLE_INTERVAL))).longValue() * 1000;
clockTick = ((Integer)java.security.AccessController.doPrivileged(
new sun.security.action.GetIntegerAction(
"sun.net.httpserver.clockTick",
- defaultClockTick))).intValue();
+ DEFAULT_CLOCK_TICK))).intValue();
maxIdleConnections = ((Integer)java.security.AccessController.doPrivileged(
new sun.security.action.GetIntegerAction(
"sun.net.httpserver.maxIdleConnections",
- defaultMaxIdleConnections))).intValue();
-
- readTimeout = ((Long)java.security.AccessController.doPrivileged(
- new sun.security.action.GetLongAction(
- "sun.net.httpserver.readTimeout",
- defaultReadTimeout))).longValue()* 1000;
-
- selCacheTimeout = ((Long)java.security.AccessController.doPrivileged(
- new sun.security.action.GetLongAction(
- "sun.net.httpserver.selCacheTimeout",
- defaultSelCacheTimeout))).longValue()* 1000;
-
- writeTimeout = ((Long)java.security.AccessController.doPrivileged(
- new sun.security.action.GetLongAction(
- "sun.net.httpserver.writeTimeout",
- defaultWriteTimeout))).longValue()* 1000;
+ DEFAULT_MAX_IDLE_CONNECTIONS))).intValue();
drainAmount = ((Long)java.security.AccessController.doPrivileged(
new sun.security.action.GetLongAction(
"sun.net.httpserver.drainAmount",
- defaultDrainAmount))).longValue();
+ DEFAULT_DRAIN_AMOUNT))).longValue();
+
+ maxReqTime = ((Long)java.security.AccessController.doPrivileged(
+ new sun.security.action.GetLongAction(
+ "sun.net.httpserver.maxReqTime",
+ DEFAULT_MAX_REQ_TIME))).longValue();
+
+ maxRspTime = ((Long)java.security.AccessController.doPrivileged(
+ new sun.security.action.GetLongAction(
+ "sun.net.httpserver.maxRspTime",
+ DEFAULT_MAX_RSP_TIME))).longValue();
+
+ timerMillis = ((Long)java.security.AccessController.doPrivileged(
+ new sun.security.action.GetLongAction(
+ "sun.net.httpserver.timerMillis",
+ DEFAULT_TIMER_MILLIS))).longValue();
debug = ((Boolean)java.security.AccessController.doPrivileged(
new sun.security.action.GetBooleanAction(
"sun.net.httpserver.debug"))).booleanValue();
}
- static long getReadTimeout () {
- return readTimeout;
- }
+
+ static void checkLegacyProperties (final Logger logger) {
+
+ // legacy properties that are no longer used
+ // print a warning to logger if they are set.
- static long getSelCacheTimeout () {
- return selCacheTimeout;
+ java.security.AccessController.doPrivileged(
+ new PrivilegedAction<Void>() {
+ public Void run () {
+ if (System.getProperty("sun.net.httpserver.readTimeout")
+ !=null)
+ {
+ logger.warning ("sun.net.httpserver.readTimeout "+
+ "property is no longer used. "+
+ "Use sun.net.httpserver.maxReqTime instead."
+ );
+ }
+ if (System.getProperty("sun.net.httpserver.writeTimeout")
+ !=null)
+ {
+ logger.warning ("sun.net.httpserver.writeTimeout "+
+ "property is no longer used. Use "+
+ "sun.net.httpserver.maxRspTime instead."
+ );
+ }
+ if (System.getProperty("sun.net.httpserver.selCacheTimeout")
+ !=null)
+ {
+ logger.warning ("sun.net.httpserver.selCacheTimeout "+
+ "property is no longer used."
+ );
+ }
+ return null;
+ }
+ }
+ );
}
static boolean debugEnabled () {
@@ -122,11 +157,19 @@
return maxIdleConnections;
}
- static long getWriteTimeout () {
- return writeTimeout;
- }
-
static long getDrainAmount () {
return drainAmount;
}
+
+ static long getMaxReqTime () {
+ return maxReqTime;
+ }
+
+ static long getMaxRspTime () {
+ return maxRspTime;
+ }
+
+ static long getTimerMillis () {
+ return timerMillis;
+ }
}
--- a/jdk/src/share/classes/sun/net/httpserver/ServerImpl.java Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/src/share/classes/sun/net/httpserver/ServerImpl.java Mon Nov 22 10:18:33 2010 -0500
@@ -37,6 +37,7 @@
import javax.net.ssl.*;
import com.sun.net.httpserver.*;
import com.sun.net.httpserver.spi.*;
+import sun.net.httpserver.HttpConnection.State;
/**
* Provides implementation for both HTTP and HTTPS
@@ -55,6 +56,12 @@
private SelectionKey listenerKey;
private Set<HttpConnection> idleConnections;
private Set<HttpConnection> allConnections;
+ /* following two are used to keep track of the times
+ * when a connection/request is first received
+ * and when we start to send the response
+ */
+ private Set<HttpConnection> reqConnections;
+ private Set<HttpConnection> rspConnections;
private List<Event> events;
private Object lolock = new Object();
private volatile boolean finished = false;
@@ -62,14 +69,19 @@
private boolean bound = false;
private boolean started = false;
private volatile long time; /* current time */
+ private volatile long subticks = 0;
private volatile long ticks; /* number of clock ticks since server started */
private HttpServer wrapper;
final static int CLOCK_TICK = ServerConfig.getClockTick();
final static long IDLE_INTERVAL = ServerConfig.getIdleInterval();
final static int MAX_IDLE_CONNECTIONS = ServerConfig.getMaxIdleConnections();
+ final static long TIMER_MILLIS = ServerConfig.getTimerMillis ();
+ final static long MAX_REQ_TIME=getTimeMillis(ServerConfig.getMaxReqTime());
+ final static long MAX_RSP_TIME=getTimeMillis(ServerConfig.getMaxRspTime());
+ final static boolean timer1Enabled = MAX_REQ_TIME != -1 || MAX_RSP_TIME != -1;
- private Timer timer;
+ private Timer timer, timer1;
private Logger logger;
ServerImpl (
@@ -79,6 +91,7 @@
this.protocol = protocol;
this.wrapper = wrapper;
this.logger = Logger.getLogger ("com.sun.net.httpserver");
+ ServerConfig.checkLegacyProperties (logger);
https = protocol.equalsIgnoreCase ("https");
this.address = addr;
contexts = new ContextList();
@@ -94,9 +107,18 @@
dispatcher = new Dispatcher();
idleConnections = Collections.synchronizedSet (new HashSet<HttpConnection>());
allConnections = Collections.synchronizedSet (new HashSet<HttpConnection>());
+ reqConnections = Collections.synchronizedSet (new HashSet<HttpConnection>());
+ rspConnections = Collections.synchronizedSet (new HashSet<HttpConnection>());
time = System.currentTimeMillis();
timer = new Timer ("server-timer", true);
timer.schedule (new ServerTimerTask(), CLOCK_TICK, CLOCK_TICK);
+ if (timer1Enabled) {
+ timer1 = new Timer ("server-timer1", true);
+ timer1.schedule (new ServerTimerTask1(),TIMER_MILLIS,TIMER_MILLIS);
+ logger.config ("HttpServer timer1 enabled period in ms: "+TIMER_MILLIS);
+ logger.config ("MAX_REQ_TIME: "+MAX_REQ_TIME);
+ logger.config ("MAX_RSP_TIME: "+MAX_RSP_TIME);
+ }
events = new LinkedList<Event>();
logger.config ("HttpServer created "+protocol+" "+ addr);
}
@@ -181,6 +203,9 @@
allConnections.clear();
idleConnections.clear();
timer.cancel();
+ if (timer1Enabled) {
+ timer1.cancel();
+ }
}
Dispatcher dispatcher;
@@ -236,13 +261,6 @@
}
}
- int resultSize () {
- synchronized (lolock) {
- return events.size ();
- }
- }
-
-
/* main server listener task */
class Dispatcher implements Runnable {
@@ -257,7 +275,7 @@
if (terminating && exchanges == 0) {
finished = true;
}
- SocketChannel chan = c.getChannel();
+ responseCompleted (c);
LeftOverInputStream is = t.getOriginalInputStream();
if (!is.isEOF()) {
t.close = true;
@@ -268,17 +286,10 @@
} else {
if (is.isDataBuffered()) {
/* don't re-enable the interestops, just handle it */
+ requestStarted (c);
handle (c.getChannel(), c);
} else {
- /* re-enable interestops */
- SelectionKey key = c.getSelectionKey();
- if (key.isValid()) {
- key.interestOps (
- key.interestOps()|SelectionKey.OP_READ
- );
- }
- c.time = getTime() + IDLE_INTERVAL;
- idleConnections.add (c);
+ connsToRegister.add (c);
}
}
}
@@ -290,22 +301,51 @@
}
}
+ final LinkedList<HttpConnection> connsToRegister =
+ new LinkedList<HttpConnection>();
+
+ void reRegister (HttpConnection c) {
+ /* re-register with selector */
+ try {
+ SocketChannel chan = c.getChannel();
+ chan.configureBlocking (false);
+ SelectionKey key = chan.register (selector, SelectionKey.OP_READ);
+ key.attach (c);
+ c.selectionKey = key;
+ c.time = getTime() + IDLE_INTERVAL;
+ idleConnections.add (c);
+ } catch (IOException e) {
+ dprint(e);
+ logger.log(Level.FINER, "Dispatcher(8)", e);
+ c.close();
+ }
+ }
+
public void run() {
while (!finished) {
try {
-
- /* process the events list first */
+ ListIterator<HttpConnection> li =
+ connsToRegister.listIterator();
+ for (HttpConnection c : connsToRegister) {
+ reRegister(c);
+ }
+ connsToRegister.clear();
- while (resultSize() > 0) {
- Event r;
- synchronized (lolock) {
- r = events.remove(0);
+ List<Event> list = null;
+ selector.select(1000);
+ synchronized (lolock) {
+ if (events.size() > 0) {
+ list = events;
+ events = new LinkedList<Event>();
+ }
+ }
+
+ if (list != null) {
+ for (Event r: list) {
handleEvent (r);
}
}
- selector.select(1000);
-
/* process the selected list now */
Set<SelectionKey> selected = selector.selectedKeys();
@@ -327,6 +367,7 @@
c.selectionKey = newkey;
c.setChannel (chan);
newkey.attach (c);
+ requestStarted (c);
allConnections.add (c);
} else {
try {
@@ -334,27 +375,44 @@
boolean closed;
SocketChannel chan = (SocketChannel)key.channel();
HttpConnection conn = (HttpConnection)key.attachment();
- // interestOps will be restored at end of read
- key.interestOps (0);
+
+ key.cancel();
+ chan.configureBlocking (true);
+ if (idleConnections.remove(conn)) {
+ // was an idle connection so add it
+ // to reqConnections set.
+ requestStarted (conn);
+ }
handle (chan, conn);
} else {
assert false;
}
+ } catch (CancelledKeyException e) {
+ handleException(key, null);
} catch (IOException e) {
- HttpConnection conn = (HttpConnection)key.attachment();
- logger.log (
- Level.FINER, "Dispatcher (2)", e
- );
- conn.close();
+ handleException(key, e);
}
}
}
+ // call the selector just to process the cancelled keys
+ selector.selectNow();
+ } catch (IOException e) {
+ logger.log (Level.FINER, "Dispatcher (4)", e);
} catch (Exception e) {
- logger.log (Level.FINER, "Dispatcher (3)", e);
+ e.printStackTrace();
+ logger.log (Level.FINER, "Dispatcher (7)", e);
}
}
}
+ private void handleException (SelectionKey key, Exception e) {
+ HttpConnection conn = (HttpConnection)key.attachment();
+ if (e != null) {
+ logger.log (Level.FINER, "Dispatcher (2)", e);
+ }
+ closeConnection(conn);
+ }
+
public void handle (SocketChannel chan, HttpConnection conn)
throws IOException
{
@@ -363,10 +421,10 @@
executor.execute (t);
} catch (HttpError e1) {
logger.log (Level.FINER, "Dispatcher (4)", e1);
- conn.close();
+ closeConnection(conn);
} catch (IOException e) {
logger.log (Level.FINER, "Dispatcher (5)", e);
- conn.close();
+ closeConnection(conn);
}
}
}
@@ -390,7 +448,26 @@
return logger;
}
- /* per exchange task */
+ private void closeConnection(HttpConnection conn) {
+ conn.close();
+ allConnections.remove(conn);
+ switch (conn.getState()) {
+ case REQUEST:
+ reqConnections.remove(conn);
+ break;
+ case RESPONSE:
+ rspConnections.remove(conn);
+ break;
+ case IDLE:
+ idleConnections.remove(conn);
+ break;
+ }
+ assert !reqConnections.remove(conn);
+ assert !rspConnections.remove(conn);
+ assert !idleConnections.remove(conn);
+ }
+
+ /* per exchange task */
class Exchange implements Runnable {
SocketChannel chan;
@@ -450,8 +527,7 @@
requestLine = req.requestLine();
if (requestLine == null) {
/* connection closed */
- connection.close();
- allConnections.remove(connection);
+ closeConnection(connection);
return;
}
int space = requestLine.indexOf (' ');
@@ -482,6 +558,9 @@
if (s != null) {
clen = Long.parseLong(s);
}
+ if (clen == 0) {
+ requestCompleted (connection);
+ }
}
ctx = contexts.findContext (protocol, uri.getPath());
if (ctx == null) {
@@ -560,7 +639,7 @@
} catch (IOException e1) {
logger.log (Level.FINER, "ServerImpl.Exchange (1)", e1);
- connection.close();
+ closeConnection(connection);
} catch (NumberFormatException e3) {
reject (Code.HTTP_BAD_REQUEST,
requestLine, "NumberFormatException thrown");
@@ -569,7 +648,7 @@
requestLine, "URISyntaxException thrown");
} catch (Exception e4) {
logger.log (Level.FINER, "ServerImpl.Exchange (2)", e4);
- connection.close();
+ closeConnection(connection);
}
}
@@ -591,47 +670,60 @@
rejected = true;
logReply (code, requestStr, message);
sendReply (
- code, true, "<h1>"+code+Code.msg(code)+"</h1>"+message
+ code, false, "<h1>"+code+Code.msg(code)+"</h1>"+message
);
- /* connection is already closed by sendReply, now remove it */
- allConnections.remove(connection);
+ closeConnection(connection);
}
void sendReply (
int code, boolean closeNow, String text)
{
try {
- String s = "HTTP/1.1 " + code + Code.msg(code) + "\r\n";
+ StringBuilder builder = new StringBuilder (512);
+ builder.append ("HTTP/1.1 ")
+ .append (code).append (Code.msg(code)).append ("\r\n");
+
if (text != null && text.length() != 0) {
- s = s + "Content-Length: "+text.length()+"\r\n";
- s = s + "Content-Type: text/html\r\n";
+ builder.append ("Content-Length: ")
+ .append (text.length()).append ("\r\n")
+ .append ("Content-Type: text/html\r\n");
} else {
- s = s + "Content-Length: 0\r\n";
+ builder.append ("Content-Length: 0\r\n");
text = "";
}
if (closeNow) {
- s = s + "Connection: close\r\n";
+ builder.append ("Connection: close\r\n");
}
- s = s + "\r\n" + text;
+ builder.append ("\r\n").append (text);
+ String s = builder.toString();
byte[] b = s.getBytes("ISO8859_1");
rawout.write (b);
rawout.flush();
if (closeNow) {
- connection.close();
+ closeConnection(connection);
}
} catch (IOException e) {
logger.log (Level.FINER, "ServerImpl.sendReply", e);
- connection.close();
+ closeConnection(connection);
}
}
}
void logReply (int code, String requestStr, String text) {
+ if (!logger.isLoggable(Level.FINE)) {
+ return;
+ }
if (text == null) {
text = "";
}
- String message = requestStr + " [" + code + " " +
+ String r;
+ if (requestStr.length() > 80) {
+ r = requestStr.substring (0, 80) + "<TRUNCATED>";
+ } else {
+ r = requestStr;
+ }
+ String message = r + " [" + code + " " +
Code.msg(code) + "] ("+text+")";
logger.fine (message);
}
@@ -667,6 +759,34 @@
return wrapper;
}
+ void requestStarted (HttpConnection c) {
+ c.creationTime = getTime();
+ c.setState (State.REQUEST);
+ reqConnections.add (c);
+ }
+
+ // called after a request has been completely read
+ // by the server. This stops the timer which would
+ // close the connection if the request doesn't arrive
+ // quickly enough. It then starts the timer
+ // that ensures the client reads the response in a timely
+ // fashion.
+
+ void requestCompleted (HttpConnection c) {
+ assert c.getState() == State.REQUEST;
+ reqConnections.remove (c);
+ c.rspStartedTime = getTime();
+ rspConnections.add (c);
+ c.setState (State.RESPONSE);
+ }
+
+ // called after response has been sent
+ void responseCompleted (HttpConnection c) {
+ assert c.getState() == State.RESPONSE;
+ rspConnections.remove (c);
+ c.setState (State.IDLE);
+ }
+
/**
* TimerTask run every CLOCK_TICK ms
*/
@@ -689,4 +809,62 @@
}
}
}
+
+ class ServerTimerTask1 extends TimerTask {
+
+ // runs every TIMER_MILLIS
+ public void run () {
+ LinkedList<HttpConnection> toClose = new LinkedList<HttpConnection>();
+ time = System.currentTimeMillis();
+ synchronized (reqConnections) {
+ if (MAX_REQ_TIME != -1) {
+ for (HttpConnection c : reqConnections) {
+ if (c.creationTime + TIMER_MILLIS + MAX_REQ_TIME <= time) {
+ toClose.add (c);
+ }
+ }
+ for (HttpConnection c : toClose) {
+ logger.log (Level.FINE, "closing: no request: " + c);
+ reqConnections.remove (c);
+ allConnections.remove (c);
+ c.close();
+ }
+ }
+ }
+ toClose = new LinkedList<HttpConnection>();
+ synchronized (rspConnections) {
+ if (MAX_RSP_TIME != -1) {
+ for (HttpConnection c : rspConnections) {
+ if (c.rspStartedTime + TIMER_MILLIS +MAX_RSP_TIME <= time) {
+ toClose.add (c);
+ }
+ }
+ for (HttpConnection c : toClose) {
+ logger.log (Level.FINE, "closing: no response: " + c);
+ rspConnections.remove (c);
+ allConnections.remove (c);
+ c.close();
+ }
+ }
+ }
+ }
+ }
+
+ void logStackTrace (String s) {
+ logger.finest (s);
+ StringBuilder b = new StringBuilder ();
+ StackTraceElement[] e = Thread.currentThread().getStackTrace();
+ for (int i=0; i<e.length; i++) {
+ b.append (e[i].toString()).append("\n");
+ }
+ logger.finest (b.toString());
+ }
+
+ static long getTimeMillis(long secs) {
+ if (secs == -1) {
+ return -1;
+ } else {
+ return secs * 1000;
+ }
+ }
}
--- a/jdk/src/share/classes/sun/nio/cs/UTF_8.java Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/src/share/classes/sun/nio/cs/UTF_8.java Mon Nov 22 10:18:33 2010 -0500
@@ -358,7 +358,7 @@
private static class Encoder extends CharsetEncoder {
private Encoder(Charset cs) {
- super(cs, 1.1f, 4.0f);
+ super(cs, 1.1f, 3.0f);
}
public boolean canEncode(char c) {
--- a/jdk/src/share/classes/sun/nio/cs/ext/ExtendedCharsets.java Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/src/share/classes/sun/nio/cs/ext/ExtendedCharsets.java Mon Nov 22 10:18:33 2010 -0500
@@ -778,6 +778,13 @@
"csIBM500"
});
+ charset("x-IBM833", "IBM833",
+ new String[] {
+ "cp833",
+ "ibm833",
+ "ibm-833"
+ });
+
//EBCDIC DBCS-only Korean
charset("x-IBM834", "IBM834",
new String[] {
--- a/jdk/src/share/classes/sun/security/krb5/internal/ccache/CCacheInputStream.java Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/src/share/classes/sun/security/krb5/internal/ccache/CCacheInputStream.java Mon Nov 22 10:18:33 2010 -0500
@@ -250,16 +250,16 @@
else return null;
}
- Ticket readData() throws IOException, RealmException, KrbApErrException, Asn1Exception {
+ byte[] readData() throws IOException {
int length;
length = read(4);
- if (length > 0) {
+ if (length == 0) {
+ return null;
+ } else {
byte[] bytes = new byte[length];
read(bytes, 0, length);
- Ticket ticket = new Ticket(bytes);
- return ticket;
+ return bytes;
}
- else return null;
}
boolean[] readFlags() throws IOException {
@@ -328,6 +328,17 @@
}
return flags;
}
+
+ /**
+ * Reads the next cred in stream.
+ * @return the next cred, null if ticket or second_ticket unparseable.
+ *
+ * Note: MIT krb5 1.8.1 might generate a config entry with server principal
+ * X-CACHECONF:/krb5_ccache_conf_data/fast_avail/krbtgt/REALM@REALM. The
+ * entry is used by KDC to inform the client that it support certain
+ * features. Its ticket is not a valid krb5 ticket and thus this method
+ * returns null.
+ */
Credentials readCred(int version) throws IOException,RealmException, KrbApErrException, Asn1Exception {
PrincipalName cpname = readPrincipal(version);
if (DEBUG)
@@ -367,17 +378,17 @@
if (auData != null) {
auData = new AuthorizationData(auDataEntry);
}
- Ticket ticket = readData();
- if (DEBUG) {
- System.out.println(">>>DEBUG <CCacheInputStream>");
- if (ticket == null) {
- System.out.println("///ticket is null");
- }
+ byte[] ticketData = readData();
+ byte[] ticketData2 = readData();
+
+ try {
+ return new Credentials(cpname, spname, key, authtime, starttime,
+ endtime, renewTill, skey, tFlags,
+ addrs, auData,
+ ticketData != null ? new Ticket(ticketData) : null,
+ ticketData2 != null ? new Ticket(ticketData2) : null);
+ } catch (Exception e) { // If any of new Ticket(*) fails.
+ return null;
}
- Ticket secTicket = readData();
- Credentials cred = new Credentials(cpname, spname, key, authtime, starttime,
- endtime, renewTill, skey, tFlags,
- addrs, auData, ticket, secTicket);
- return cred;
}
}
--- a/jdk/src/share/classes/sun/security/krb5/internal/ccache/FileCredentialsCache.java Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/src/share/classes/sun/security/krb5/internal/ccache/FileCredentialsCache.java Mon Nov 22 10:18:33 2010 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2010, 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
@@ -186,7 +186,10 @@
primaryRealm = primaryPrincipal.getRealm();
credentialsList = new Vector<Credentials> ();
while (cis.available() > 0) {
- credentialsList.addElement(cis.readCred(version));
+ Credentials cred = cis.readCred(version);
+ if (cred != null) {
+ credentialsList.addElement(cred);
+ }
}
cis.close();
}
--- a/jdk/src/share/classes/sun/security/pkcs11/P11Cipher.java Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/src/share/classes/sun/security/pkcs11/P11Cipher.java Mon Nov 22 10:18:33 2010 -0500
@@ -74,7 +74,7 @@
// DEC: return the length of trailing padding bytes given the specified
// padded data
int unpad(byte[] paddedData, int len)
- throws BadPaddingException;
+ throws BadPaddingException, IllegalBlockSizeException;
}
private static class PKCS5Padding implements Padding {
@@ -96,9 +96,10 @@
}
public int unpad(byte[] paddedData, int len)
- throws BadPaddingException {
- if (len < 1 || len > paddedData.length) {
- throw new BadPaddingException("Invalid pad array length!");
+ throws BadPaddingException, IllegalBlockSizeException {
+ if ((len < 1) || (len % blockSize != 0)) {
+ throw new IllegalBlockSizeException
+ ("Input length must be multiples of " + blockSize);
}
byte padValue = paddedData[len - 1];
if (padValue < 1 || padValue > blockSize) {
--- a/jdk/src/share/classes/sun/security/ssl/Krb5Helper.java Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/src/share/classes/sun/security/ssl/Krb5Helper.java Mon Nov 22 10:18:33 2010 -0500
@@ -10,7 +10,7 @@
*
* 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
+ * 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).
*
--- a/jdk/src/share/classes/sun/security/ssl/Krb5Proxy.java Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/src/share/classes/sun/security/ssl/Krb5Proxy.java Mon Nov 22 10:18:33 2010 -0500
@@ -10,7 +10,7 @@
*
* 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
+ * 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).
*
--- a/jdk/src/share/classes/sun/security/ssl/krb5/Krb5ProxyImpl.java Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/src/share/classes/sun/security/ssl/krb5/Krb5ProxyImpl.java Mon Nov 22 10:18:33 2010 -0500
@@ -10,7 +10,7 @@
*
* 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
+ * 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).
*
--- a/jdk/src/share/demo/nio/zipfs/Demo.java Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/src/share/demo/nio/zipfs/Demo.java Mon Nov 22 10:18:33 2010 -0500
@@ -75,9 +75,15 @@
// copy an external src file into zipfile
// as entry dst
+ copyin_attrs, // <java Demo copyin_attrs zipfile src dst>
+ // copy an external src file into zipfile
+ // as entry dst, with attributes (timestamp)
+
copyout, // <java Demo copyout zipfile src dst>
// copy zipfile entry src" out to file dst
+ copyout_attrs, // <java Demo copyout_attrs zipfile src dst>
+
zzmove, // <java Demo zzmove zfsrc zfdst path>
// move entry path/dir from zfsrc to zfdst
@@ -94,6 +100,9 @@
setmtime, // <java Demo setmtime zipfile "MM/dd/yy-HH:mm:ss" path...>
// set the lastModifiedTime of entry path
+ setatime, // <java Demo setatime zipfile "MM/dd/yy-HH:mm:ss" path...>
+ setctime, // <java Demo setctime zipfile "MM/dd/yy-HH:mm:ss" path...>
+
lsdir, // <java Demo lsdir zipfile dir>
// list dir's direct child files/dirs
@@ -135,12 +144,14 @@
attrs2, // <java Demo attrs2 zipfile file [...]>
// test different ways to print attrs
+
+ prof,
}
public static void main(String[] args) throws Throwable {
- Action action = Action.valueOf(args[0]);;
- Map<String, Object> env = env = new HashMap<String, Object>();
+ Action action = Action.valueOf(args[0]);
+ Map<String, Object> env = env = new HashMap<>();
if (action == Action.create)
env.put("createNew", true);
if (action == Action.tlist || action == Action.twalk)
@@ -185,6 +196,16 @@
dst = fs.getPath(args[3]);
src.copyTo(dst);
break;
+ case copyin_attrs:
+ src = Paths.get(args[2]);
+ dst = fs.getPath(args[3]);
+ src.copyTo(dst, COPY_ATTRIBUTES);
+ break;
+ case copyout_attrs:
+ src = fs.getPath(args[2]);
+ dst = Paths.get(args[3]);
+ src.copyTo(dst, COPY_ATTRIBUTES);
+ break;
case zzmove:
fs2 = FileSystems.newFileSystem(
URI.create("zip" + Paths.get(args[2]).toUri().toString().substring(4)),
@@ -206,6 +227,7 @@
case attrs:
for (int i = 2; i < args.length; i++) {
path = fs.getPath(args[i]);
+ System.out.println(path);
System.out.println(
Attributes.readBasicFileAttributes(path).toString());
}
@@ -221,6 +243,28 @@
Attributes.readBasicFileAttributes(path).toString());
}
break;
+ case setctime:
+ df = new SimpleDateFormat("MM/dd/yyyy-HH:mm:ss");
+ newDatetime = df.parse(args[2]);
+ for (int i = 3; i < args.length; i++) {
+ path = fs.getPath(args[i]);
+ path.setAttribute("creationTime",
+ FileTime.fromMillis(newDatetime.getTime()));
+ System.out.println(
+ Attributes.readBasicFileAttributes(path).toString());
+ }
+ break;
+ case setatime:
+ df = new SimpleDateFormat("MM/dd/yyyy-HH:mm:ss");
+ newDatetime = df.parse(args[2]);
+ for (int i = 3; i < args.length; i++) {
+ path = fs.getPath(args[i]);
+ path.setAttribute("lastAccessTime",
+ FileTime.fromMillis(newDatetime.getTime()));
+ System.out.println(
+ Attributes.readBasicFileAttributes(path).toString());
+ }
+ break;
case attrsspace:
path = fs.getPath("/");
FileStore fstore = path.getFileStore();
@@ -293,6 +337,7 @@
case attrs2:
for (int i = 2; i < args.length; i++) {
path = fs.getPath(args[i]);
+ System.out.printf("%n%s%n", path);
System.out.println("-------(1)---------");
System.out.println(
Attributes.readBasicFileAttributes(path).toString());
@@ -308,6 +353,13 @@
}
}
break;
+ case prof:
+ list(fs.getPath("/"), false);
+ while (true) {
+ Thread.sleep(10000);
+ //list(fs.getPath("/"), true);
+ System.out.println("sleeping...");
+ }
}
} catch (Exception x) {
x.printStackTrace();
@@ -501,10 +553,11 @@
}
private static void list(Path path, boolean verbose ) throws IOException {
- if (verbose)
- System.out.println(Attributes.readBasicFileAttributes(path).toString());
- else
- System.out.printf(" %s%n", path.toString());
+ if (!"/".equals(path.toString())) {
+ System.out.printf(" %s%n", path.toString());
+ if (verbose)
+ System.out.println(Attributes.readBasicFileAttributes(path).toString());
+ }
if (path.notExists())
return;
if (Attributes.readBasicFileAttributes(path).isDirectory()) {
--- a/jdk/src/share/demo/nio/zipfs/README.txt Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/src/share/demo/nio/zipfs/README.txt Mon Nov 22 10:18:33 2010 -0500
@@ -2,7 +2,7 @@
JAR file as a java.nio.file.FileSystem.
To deploy the provider you must copy zipfs.jar into your extensions
-directory or else add <JDK_HOME>/demo/nio/ZipFileSystem/zipfs.jar
+directory or else add <JDK_HOME>/demo/nio/zipfs/zipfs.jar
to your class path.
The factory methods defined by the java.nio.file.FileSystems class can be
@@ -10,8 +10,8 @@
// use file type detection
Map<String,?> env = Collections.emptyMap();
- Path jarfile = Path.get("foo.jar");
- FileSystem fs = FileSystems.newFileSystem(jarfile, env);
+ Path jarfile = Paths.get("foo.jar");
+ FileSystem fs = FileSystems.newFileSystem(jarfile, env, null);
-or
--- a/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/JarFileSystemProvider.java Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/JarFileSystemProvider.java Mon Nov 22 10:18:33 2010 -0500
@@ -68,4 +68,21 @@
throw new AssertionError(e); //never thrown
}
}
+
+ @Override
+ public Path getPath(URI uri) {
+ FileSystem fs = getFileSystem(uri);
+ String path = uri.getFragment();
+ if (path == null) {
+ String uristr = uri.toString();
+ int off = uristr.indexOf("!/");
+ if (off != -1)
+ path = uristr.substring(off + 2);
+ }
+ if (path != null)
+ return fs.getPath(path);
+ throw new IllegalArgumentException("URI: "
+ + uri
+ + " does not contain path fragment ex. jar:///c:/foo.zip!/BAR");
+ }
}
--- a/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipConstants.java Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipConstants.java Mon Nov 22 10:18:33 2010 -0500
@@ -31,7 +31,6 @@
package com.sun.nio.zipfs;
-import java.nio.ByteBuffer;
/**
*
@@ -48,6 +47,7 @@
static final int METHOD_BZIP2 = 12;
static final int METHOD_LZMA = 14;
static final int METHOD_LZ77 = 19;
+ static final int METHOD_AES = 99;
/*
* General purpose big flag
@@ -168,7 +168,8 @@
static final int EXTID_ZIP64 = 0x0001; // ZIP64
static final int EXTID_NTFS = 0x000a; // NTFS
static final int EXTID_UNIX = 0x000d; // UNIX
-
+ static final int EXTID_EFS = 0x0017; // Strong Encryption
+ static final int EXTID_EXTT = 0x5455; // Info-ZIP Extended Timestamp
/*
* fields access methods
@@ -226,34 +227,23 @@
static final long ZIP64_ENDOFF(byte[] b) { return LL(b, 48);} // central directory offset
static final long ZIP64_LOCOFF(byte[] b) { return LL(b, 8);} // zip64 end offset
- //////////////////////////////////////////
- static final int CH(ByteBuffer b, int pos) {
- return b.get(pos) & 0xff;
- }
- static final int SH(ByteBuffer b, int pos) {
- return b.getShort(pos) & 0xffff;
- }
- static final long LG(ByteBuffer b, int pos) {
- return b.getInt(pos) & 0xffffffffL;
- }
-
- // central directory header (END) fields
- static final long CENSIG(ByteBuffer b, int pos) { return LG(b, pos + 0); }
- static final int CENVEM(ByteBuffer b, int pos) { return SH(b, pos + 4); }
- static final int CENVER(ByteBuffer b, int pos) { return SH(b, pos + 6); }
- static final int CENFLG(ByteBuffer b, int pos) { return SH(b, pos + 8); }
- static final int CENHOW(ByteBuffer b, int pos) { return SH(b, pos + 10);}
- static final long CENTIM(ByteBuffer b, int pos) { return LG(b, pos + 12);}
- static final long CENCRC(ByteBuffer b, int pos) { return LG(b, pos + 16);}
- static final long CENSIZ(ByteBuffer b, int pos) { return LG(b, pos + 20);}
- static final long CENLEN(ByteBuffer b, int pos) { return LG(b, pos + 24);}
- static final int CENNAM(ByteBuffer b, int pos) { return SH(b, pos + 28);}
- static final int CENEXT(ByteBuffer b, int pos) { return SH(b, pos + 30);}
- static final int CENCOM(ByteBuffer b, int pos) { return SH(b, pos + 32);}
- static final int CENDSK(ByteBuffer b, int pos) { return SH(b, pos + 34);}
- static final int CENATT(ByteBuffer b, int pos) { return SH(b, pos + 36);}
- static final long CENATX(ByteBuffer b, int pos) { return LG(b, pos + 38);}
- static final long CENOFF(ByteBuffer b, int pos) { return LG(b, pos + 42);}
+ // central directory header (CEN) fields
+ static final long CENSIG(byte[] b, int pos) { return LG(b, pos + 0); }
+ static final int CENVEM(byte[] b, int pos) { return SH(b, pos + 4); }
+ static final int CENVER(byte[] b, int pos) { return SH(b, pos + 6); }
+ static final int CENFLG(byte[] b, int pos) { return SH(b, pos + 8); }
+ static final int CENHOW(byte[] b, int pos) { return SH(b, pos + 10);}
+ static final long CENTIM(byte[] b, int pos) { return LG(b, pos + 12);}
+ static final long CENCRC(byte[] b, int pos) { return LG(b, pos + 16);}
+ static final long CENSIZ(byte[] b, int pos) { return LG(b, pos + 20);}
+ static final long CENLEN(byte[] b, int pos) { return LG(b, pos + 24);}
+ static final int CENNAM(byte[] b, int pos) { return SH(b, pos + 28);}
+ static final int CENEXT(byte[] b, int pos) { return SH(b, pos + 30);}
+ static final int CENCOM(byte[] b, int pos) { return SH(b, pos + 32);}
+ static final int CENDSK(byte[] b, int pos) { return SH(b, pos + 34);}
+ static final int CENATT(byte[] b, int pos) { return SH(b, pos + 36);}
+ static final long CENATX(byte[] b, int pos) { return LG(b, pos + 38);}
+ static final long CENOFF(byte[] b, int pos) { return LG(b, pos + 42);}
/* The END header is followed by a variable length comment of size < 64k. */
static final long END_MAXLEN = 0xFFFF + ENDHDR;
--- a/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipDirectoryStream.java Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipDirectoryStream.java Mon Nov 22 10:18:33 2010 -0500
@@ -38,7 +38,6 @@
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.io.IOException;
-import static com.sun.nio.zipfs.ZipUtils.*;
/**
*
@@ -77,7 +76,7 @@
} catch (IOException e) {
throw new IllegalStateException(e);
}
- return new Iterator<Path>() {
+ return new Iterator<>() {
private Path next;
@Override
public boolean hasNext() {
--- a/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileAttributeView.java Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileAttributeView.java Mon Nov 22 10:18:33 2010 -0500
@@ -32,7 +32,6 @@
package com.sun.nio.zipfs;
-import java.nio.file.ReadOnlyFileSystemException;
import java.nio.file.attribute.BasicFileAttributeView;
import java.nio.file.attribute.FileAttributeView;
import java.nio.file.attribute.FileTime;
@@ -113,6 +112,10 @@
try {
if (AttrID.valueOf(attribute) == AttrID.lastModifiedTime)
setTimes ((FileTime)value, null, null);
+ if (AttrID.valueOf(attribute) == AttrID.lastAccessTime)
+ setTimes (null, (FileTime)value, null);
+ if (AttrID.valueOf(attribute) == AttrID.creationTime)
+ setTimes (null, null, (FileTime)value);
return;
} catch (IllegalArgumentException x) {}
throw new UnsupportedOperationException("'" + attribute +
--- a/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileAttributes.java Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileAttributes.java Mon Nov 22 10:18:33 2010 -0500
@@ -56,7 +56,7 @@
@Override
public FileTime creationTime() {
if (e.ctime != -1)
- return FileTime.fromMillis(dosToJavaTime(e.ctime));
+ return FileTime.fromMillis(e.ctime);
return null;
}
@@ -78,13 +78,13 @@
@Override
public FileTime lastAccessTime() {
if (e.atime != -1)
- return FileTime.fromMillis(dosToJavaTime(e.atime));
+ return FileTime.fromMillis(e.atime);
return null;
}
@Override
public FileTime lastModifiedTime() {
- return FileTime.fromMillis(dosToJavaTime(e.mtime));
+ return FileTime.fromMillis(e.mtime);
}
@Override
@@ -103,10 +103,6 @@
}
///////// zip entry attributes ///////////
- public byte[] name() {
- return Arrays.copyOf(e.name, e.name.length);
- }
-
public long compressedSize() {
return e.csize;
}
@@ -132,10 +128,13 @@
}
public String toString() {
- StringBuilder sb = new StringBuilder();
+ StringBuilder sb = new StringBuilder(1024);
Formatter fm = new Formatter(sb);
- fm.format("[/%s]%n", new String(e.name)); // TBD encoding
- fm.format(" creationTime : %s%n", creationTime());
+ if (creationTime() != null)
+ fm.format(" creationTime : %tc%n", creationTime().toMillis());
+ else
+ fm.format(" creationTime : null%n");
+
if (lastAccessTime() != null)
fm.format(" lastAccessTime : %tc%n", lastAccessTime().toMillis());
else
--- a/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileSystem.java Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileSystem.java Mon Nov 22 10:18:33 2010 -0500
@@ -35,19 +35,18 @@
import java.io.ByteArrayOutputStream;
import java.io.EOFException;
import java.io.File;
-import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
import java.nio.MappedByteBuffer;
import java.nio.channels.*;
import java.nio.file.*;
import java.nio.file.attribute.*;
import java.nio.file.spi.*;
-import java.net.URI;
import java.util.*;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.regex.Pattern;
import java.util.zip.CRC32;
import java.util.zip.Inflater;
@@ -76,8 +75,6 @@
private final Path zfpath;
private final ZipCoder zc;
- private final Object lock = new Object();
-
// configurable by env map
private final String defaultDir; // default dir for the file system
private final String nameEncoding; // default encoding for name/comment
@@ -85,6 +82,8 @@
private final boolean useTempFile; // use a temp file for newOS, default
// is to use BAOS for better performance
private final boolean createNew; // create a new zip if not exists
+ private static final boolean isWindows =
+ System.getProperty("os.name").startsWith("Windows");
ZipFileSystem(ZipFileSystemProvider provider,
Path zfpath,
@@ -92,13 +91,13 @@
throws IOException
{
// configurable env setup
- this.buildDirTree = TRUE.equals(env.get("buildDirTree"));
- this.useTempFile = TRUE.equals(env.get("useTempFile"));
- this.createNew = TRUE.equals(env.get("createNew"));
+ this.buildDirTree = TRUE.equals(env.get("buildDirTreea"));
+ this.useTempFile = TRUE.equals(env.get("useTempFile"));
+ this.createNew = TRUE.equals(env.get("createNew"));
this.nameEncoding = env.containsKey("nameEncoding") ?
(String)env.get("nameEncoding") : "UTF-8";
- this.defaultDir = env.containsKey("default.dir") ?
- (String)env.get("default.dir") : "/";
+ this.defaultDir = env.containsKey("default.dir") ?
+ (String)env.get("default.dir") : "/";
if (this.defaultDir.charAt(0) != '/')
throw new IllegalArgumentException("default dir should be absolute");
@@ -121,7 +120,8 @@
}
this.zc = ZipCoder.get(nameEncoding);
this.defaultdir = new ZipPath(this, getBytes(defaultDir));
- initZipFile();
+ this.ch = zfpath.newByteChannel(READ);
+ this.cen = initCEN();
}
@Override
@@ -183,7 +183,7 @@
@Override
public Iterable<FileStore> getFileStores() {
- ArrayList<FileStore> list = new ArrayList<FileStore>(1);
+ ArrayList<FileStore> list = new ArrayList<>(1);
list.add(new ZipFileStore(new ZipPath(this, new byte[]{'/'})));
return list;
}
@@ -240,19 +240,27 @@
@Override
public void close() throws IOException {
- synchronized (lock) {
+ beginWrite();
+ try {
if (!isOpen)
return;
- isOpen = false;
- if (!streams.isEmpty()) {
- synchronized(streams) {
- for (InputStream is: streams)
- is.close();
- }
- }
+ isOpen = false; // set closed
+ } finally {
+ endWrite();
+ }
+ if (!streams.isEmpty()) { // unlock and close all remaining streams
+ Set<InputStream> copy = new HashSet<>(streams);
+ for (InputStream is: copy)
+ is.close();
+ }
+ beginWrite(); // lock and sync
+ try {
sync();
- ch.close();
+ ch.close(); // close the ch just in case no update
+ } finally { // and sync dose not close the ch
+ endWrite();
}
+
synchronized (inflaters) {
for (Inflater inf : inflaters)
inf.end();
@@ -261,97 +269,101 @@
for (Deflater def : deflaters)
def.end();
}
- for (Path p: tmppaths) {
- try {
- p.deleteIfExists();
- } catch (IOException x) {
- x.printStackTrace();
+
+ synchronized (tmppaths) {
+ for (Path p: tmppaths) {
+ try {
+ p.deleteIfExists();
+ } catch (IOException x) {
+ x.printStackTrace();
+ }
}
}
provider.removeFileSystem(zfpath);
}
- ZipFileAttributes[] getAllAttributes() throws IOException {
- ensureOpen();
- int n = inodes.size();
- ZipFileAttributes[] zes = new ZipFileAttributes[n];
- Iterator<IndexNode> itr = inodes.values().iterator();
- int i = 0;
- while(itr.hasNext()) {
- zes[i++] = new ZipFileAttributes(Entry.readCEN(cen, itr.next().pos));
- }
- return zes;
- }
-
- EntryName[] getEntryNames() throws IOException {
- ensureOpen();
- return inodes.keySet().toArray(new EntryName[0]);
- }
-
ZipFileAttributes getFileAttributes(byte[] path)
throws IOException
{
- synchronized (lock) {
- Entry e = getEntry0(path);
- if (e == null) {
- if (path.length == 0) {
- e = new Entry(new byte[0]); // root
- } else if (buildDirTree) {
- IndexNode inode = getDirs().get(new EntryName(path));
- if (inode == null)
- return null;
- e = new Entry(inode.name);
- } else {
+ Entry e;
+ beginRead();
+ try {
+ ensureOpen();
+ e = getEntry0(path);
+ } finally {
+ endRead();
+ }
+ if (e == null) {
+ if (path.length == 0) {
+ e = new Entry(new byte[0]); // root
+ } else if (buildDirTree) {
+ IndexNode inode = getDirs().get(IndexNode.keyOf(path));
+ if (inode == null)
return null;
- }
- e.method = METHOD_STORED; // STORED for dir
- BasicFileAttributes bfas = Attributes.readBasicFileAttributes(zfpath);
- if (bfas.lastModifiedTime() != null)
- e.mtime = javaToDosTime(bfas.lastModifiedTime().toMillis());
- if (bfas.lastAccessTime() != null)
- e.atime = javaToDosTime(bfas.lastAccessTime().toMillis());
- if (bfas.creationTime() != null)
- e.ctime = javaToDosTime(bfas.creationTime().toMillis());
+ e = new Entry(inode.name);
+ } else {
+ return null;
}
- return new ZipFileAttributes(e);
+ e.method = METHOD_STORED; // STORED for dir
+ BasicFileAttributes bfas = Attributes.readBasicFileAttributes(zfpath);
+ if (bfas.lastModifiedTime() != null)
+ e.mtime = bfas.lastModifiedTime().toMillis();
+ if (bfas.lastAccessTime() != null)
+ e.atime = bfas.lastAccessTime().toMillis();
+ if (bfas.creationTime() != null)
+ e.ctime = bfas.creationTime().toMillis();
}
+ return new ZipFileAttributes(e);
}
void setTimes(byte[] path, FileTime mtime, FileTime atime, FileTime ctime)
throws IOException
{
checkWritable();
- synchronized (lock) {
+ beginWrite();
+ try {
+ ensureOpen();
Entry e = getEntry0(path); // ensureOpen checked
if (e == null)
throw new NoSuchFileException(getString(path));
if (e.type == Entry.CEN)
e.type = Entry.COPY; // copy e
if (mtime != null)
- e.mtime = javaToDosTime(mtime.toMillis());
+ e.mtime = mtime.toMillis();
if (atime != null)
- e.atime = javaToDosTime(atime.toMillis());
+ e.atime = atime.toMillis();
if (ctime != null)
- e.ctime = javaToDosTime(ctime.toMillis());
+ e.ctime = ctime.toMillis();
update(e);
+ } finally {
+ endWrite();
}
}
boolean exists(byte[] path)
throws IOException
{
- return getEntry0(path) != null;
+ beginRead();
+ try {
+ ensureOpen();
+ return getEntry0(path) != null;
+ } finally {
+ endRead();
+ }
}
boolean isDirectory(byte[] path)
throws IOException
{
- synchronized (lock) {
- if (buildDirTree) {
- return getDirs().containsKey(new EntryName(path));
- }
+ if (buildDirTree)
+ return getDirs().containsKey(IndexNode.keyOf(path));
+
+ beginRead();
+ try {
Entry e = getEntry0(path);
return (e != null && e.isDir()) || path.length == 0;
+ } finally {
+ endRead();
}
}
@@ -368,12 +380,14 @@
DirectoryStream.Filter<? super Path> filter)
throws IOException
{
- synchronized (lock) {
+ beginWrite(); // iteration of inodes needs exclusive lock
+ try {
+ ensureOpen();
if (buildDirTree) {
- IndexNode inode = getDirs().get(new EntryName(path));
+ IndexNode inode = getDirs().get(IndexNode.keyOf(path));
if (inode == null)
throw new NotDirectoryException(getString(path));
- List<Path> list = new ArrayList<Path>();
+ List<Path> list = new ArrayList<>();
IndexNode child = inode.child;
while (child != null) {
ZipPath zp = toZipPath(child.name);
@@ -386,25 +400,26 @@
if (!isDirectory(path))
throw new NotDirectoryException(getString(path));
- List<Path> list = new ArrayList<Path>();
- EntryName[] entries = getEntryNames();
+ List<Path> list = new ArrayList<>();
path = toDirectoryPath(path);
- for (EntryName en :entries) {
- if (!isParentOf(path, en.name)) // is "path" the parent of "name"
+ for (IndexNode key : inodes.keySet()) {
+ if (!isParentOf(path, key.name)) // is "path" the parent of "name"
continue;
int off = path.length;
- while (off < en.name.length) {
- if (en.name[off] == '/')
+ while (off < key.name.length) {
+ if (key.name[off] == '/')
break;
off++;
}
- if (off < (en.name.length - 1))
+ if (off < (key.name.length - 1))
continue;
- ZipPath zp = toZipPath(en.name);
+ ZipPath zp = toZipPath(key.name);
if (filter == null || filter.accept(zp))
list.add(zp);
}
return list.iterator();
+ } finally {
+ endWrite();
}
}
@@ -413,16 +428,18 @@
{
checkWritable();
dir = toDirectoryPath(dir);
- synchronized (lock) {
+ beginWrite();
+ try {
ensureOpen();
- // pseudo root dir, or exiting dir
- if (dir.length == 0 || exists(dir))
+ if (dir.length == 0 || exists(dir)) // root dir, or exiting dir
throw new FileAlreadyExistsException(getString(dir));
+
checkParents(dir);
-
Entry e = new Entry(dir, Entry.NEW);
- e.method = METHOD_STORED; // STORED for dir
+ e.method = METHOD_STORED; // STORED for dir
update(e);
+ } finally {
+ endWrite();
}
}
@@ -432,7 +449,10 @@
checkWritable();
if (Arrays.equals(src, dst))
return; // do nothing, src and dst are the same
- synchronized (lock) {
+
+ beginWrite();
+ try {
+ ensureOpen();
Entry eSrc = getEntry0(src); // ensureOpen checked
if (eSrc == null)
throw new NoSuchFileException(getString(src));
@@ -457,11 +477,6 @@
}
Entry u = new Entry(eSrc, Entry.COPY); // copy eSrc entry
u.name = dst; // change name
- // don't touch the "nlen and elen" here. writeLOC() always
- // re-calculate from "name" and "extra" for the correct length,
- // copyLOCEntry however needs the original lengths to skip the
- // loc header.
- // u.nlen = dst.length;
if (eSrc.type == Entry.NEW || eSrc.type == Entry.FILECH)
{
u.type = eSrc.type; // make it the same type
@@ -475,10 +490,12 @@
}
}
if (!hasCopyAttrs)
- u.mtime = u.atime= u.ctime = javaToDosTime(System.currentTimeMillis());
+ u.mtime = u.atime= u.ctime = System.currentTimeMillis();
update(u);
if (deletesrc)
updateDelete(eSrc);
+ } finally {
+ endWrite();
}
}
@@ -501,7 +518,9 @@
if (opt == APPEND)
hasAppend = true;
}
- synchronized (lock) {
+ beginRead(); // only need a readlock, the "update()" will
+ try { // try to obtain a writelock when the os is
+ ensureOpen(); // being closed.
Entry e = getEntry0(path);
if (e != null) {
if (e.isDir() || hasCreateNew)
@@ -512,27 +531,33 @@
copyStream(is, os);
is.close();
return os;
- }
- return getOutputStream(new Entry(e, Entry.NEW));
+ }
+ return getOutputStream(new Entry(e, Entry.NEW));
} else {
if (!hasCreate && !hasCreateNew)
throw new NoSuchFileException(getString(path));
checkParents(path);
return getOutputStream(new Entry(path, Entry.NEW));
}
+ } finally {
+ endRead();
}
}
// Returns an input stream for reading the contents of the specified
// file entry.
InputStream newInputStream(byte[] path) throws IOException {
- synchronized (lock) {
+ beginRead();
+ try {
+ ensureOpen();
Entry e = getEntry0(path);
if (e == null)
throw new NoSuchFileException(getString(path));
if (e.isDir())
throw new FileSystemException(getString(path), "is a directory", null);
return getInputStream(e);
+ } finally {
+ endRead();
}
}
@@ -559,78 +584,111 @@
if (options.contains(StandardOpenOption.WRITE) ||
options.contains(StandardOpenOption.APPEND)) {
checkWritable();
- final WritableByteChannel wbc = Channels.newChannel(newOutputStream(path,
- options.toArray(new OpenOption[0])));
- long leftover = 0;;
- if (options.contains(StandardOpenOption.APPEND)) {
- Entry e = getEntry0(path);
- if (e != null && e.size >= 0)
- leftover = e.size;
- }
- final long offset = leftover;
- return new SeekableByteChannel() {
- long written = offset;
- public boolean isOpen() {
- return wbc.isOpen();
- }
- public long position() throws IOException {
- return written;
- }
- public SeekableByteChannel position(long pos) throws IOException {
- throw new UnsupportedOperationException();
- }
- public int read(ByteBuffer dst) throws IOException {
- throw new UnsupportedOperationException();
- }
- public SeekableByteChannel truncate(long size) throws IOException {
- throw new UnsupportedOperationException();
- }
- public int write(ByteBuffer src) throws IOException {
- int n = wbc.write(src);
- written += n;
- return n;
- }
- public long size() throws IOException {
- return written;
+ beginRead();
+ try {
+ final WritableByteChannel wbc = Channels.newChannel(
+ newOutputStream(path, options.toArray(new OpenOption[0])));
+ long leftover = 0;
+ if (options.contains(StandardOpenOption.APPEND)) {
+ Entry e = getEntry0(path);
+ if (e != null && e.size >= 0)
+ leftover = e.size;
}
- public void close() throws IOException {
- wbc.close();
- }
- };
+ final long offset = leftover;
+ return new SeekableByteChannel() {
+ long written = offset;
+ public boolean isOpen() {
+ return wbc.isOpen();
+ }
+
+ public long position() throws IOException {
+ return written;
+ }
+
+ public SeekableByteChannel position(long pos)
+ throws IOException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public int read(ByteBuffer dst) throws IOException {
+ throw new UnsupportedOperationException();
+ }
+
+ public SeekableByteChannel truncate(long size)
+ throws IOException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public int write(ByteBuffer src) throws IOException {
+ int n = wbc.write(src);
+ written += n;
+ return n;
+ }
+
+ public long size() throws IOException {
+ return written;
+ }
+
+ public void close() throws IOException {
+ wbc.close();
+ }
+ };
+ } finally {
+ endRead();
+ }
} else {
- Entry e = getEntry0(path);
- if (e == null || e.isDir())
- throw new NoSuchFileException(getString(path));
- final ReadableByteChannel rbc =
- Channels.newChannel(getInputStream(e));
- final long size = e.size;
- return new SeekableByteChannel() {
- long read = 0;
- public boolean isOpen() {
- return rbc.isOpen();
- }
- public long position() throws IOException {
- return read;
- }
- public SeekableByteChannel position(long pos) throws IOException {
- throw new UnsupportedOperationException();
- }
- public int read(ByteBuffer dst) throws IOException {
- return rbc.read(dst);
- }
- public SeekableByteChannel truncate(long size) throws IOException {
- throw new NonWritableChannelException();
- }
- public int write (ByteBuffer src) throws IOException {
- throw new NonWritableChannelException();
- }
- public long size() throws IOException {
- return size;
- }
- public void close() throws IOException {
- rbc.close();
- }
- };
+ beginRead();
+ try {
+ ensureOpen();
+ Entry e = getEntry0(path);
+ if (e == null || e.isDir())
+ throw new NoSuchFileException(getString(path));
+ final ReadableByteChannel rbc =
+ Channels.newChannel(getInputStream(e));
+ final long size = e.size;
+ return new SeekableByteChannel() {
+ long read = 0;
+ public boolean isOpen() {
+ return rbc.isOpen();
+ }
+
+ public long position() throws IOException {
+ return read;
+ }
+
+ public SeekableByteChannel position(long pos)
+ throws IOException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public int read(ByteBuffer dst) throws IOException {
+ return rbc.read(dst);
+ }
+
+ public SeekableByteChannel truncate(long size)
+ throws IOException
+ {
+ throw new NonWritableChannelException();
+ }
+
+ public int write (ByteBuffer src) throws IOException {
+ throw new NonWritableChannelException();
+ }
+
+ public long size() throws IOException {
+ return size;
+ }
+
+ public void close() throws IOException {
+ rbc.close();
+ }
+ };
+ } finally {
+ endRead();
+ }
}
}
@@ -647,125 +705,131 @@
checkOptions(options);
final boolean forWrite = (options.contains(StandardOpenOption.WRITE) ||
options.contains(StandardOpenOption.APPEND));
- Entry e = getEntry0(path);
- if (forWrite) {
- checkWritable();
- if (e == null) {
+ beginRead();
+ try {
+ ensureOpen();
+ Entry e = getEntry0(path);
+ if (forWrite) {
+ checkWritable();
+ if (e == null) {
if (!options.contains(StandardOpenOption.CREATE_NEW))
throw new NoSuchFileException(getString(path));
- } else {
- if (options.contains(StandardOpenOption.CREATE_NEW))
- throw new FileAlreadyExistsException(getString(path));
- if (e.isDir())
- throw new FileAlreadyExistsException("directory <"
- + getString(path) + "> exists");
- }
- options.remove(StandardOpenOption.CREATE_NEW); // for tmpfile
- } else if (e == null || e.isDir()) {
- throw new NoSuchFileException(getString(path));
- }
-
- final boolean isFCH = (e != null && e.type == Entry.FILECH);
- final Path tmpfile = isFCH ? e.file : getTempPathForEntry(path);
- final FileChannel fch = tmpfile.getFileSystem()
- .provider()
- .newFileChannel(tmpfile, options, attrs);
- final Entry u = isFCH ? e : new Entry(path, tmpfile, Entry.FILECH);
- if (forWrite) {
- u.flag = FLAG_DATADESCR;
- u.method = METHOD_DEFLATED;
- }
- // is there a better way to hook into the FileChannel's close method?
- return new FileChannel() {
- public int write(ByteBuffer src) throws IOException {
- return fch.write(src);
+ } else {
+ if (options.contains(StandardOpenOption.CREATE_NEW))
+ throw new FileAlreadyExistsException(getString(path));
+ if (e.isDir())
+ throw new FileAlreadyExistsException("directory <"
+ + getString(path) + "> exists");
+ }
+ options.remove(StandardOpenOption.CREATE_NEW); // for tmpfile
+ } else if (e == null || e.isDir()) {
+ throw new NoSuchFileException(getString(path));
}
- public long write(ByteBuffer[] srcs, int offset, int length)
- throws IOException
- {
- return fch.write(srcs, offset, length);
- }
- public long position() throws IOException {
- return fch.position();
- }
- public FileChannel position(long newPosition)
- throws IOException
- {
- fch.position(newPosition);
- return this;
- }
- public long size() throws IOException {
- return fch.size();
- }
- public FileChannel truncate(long size)
- throws IOException
- {
- fch.truncate(size);
- return this;
- }
- public void force(boolean metaData)
- throws IOException
- {
- fch.force(metaData);
+
+ final boolean isFCH = (e != null && e.type == Entry.FILECH);
+ final Path tmpfile = isFCH ? e.file : getTempPathForEntry(path);
+ final FileChannel fch = tmpfile.getFileSystem()
+ .provider()
+ .newFileChannel(tmpfile, options, attrs);
+ final Entry u = isFCH ? e : new Entry(path, tmpfile, Entry.FILECH);
+ if (forWrite) {
+ u.flag = FLAG_DATADESCR;
+ u.method = METHOD_DEFLATED;
}
- public long transferTo(long position, long count,
- WritableByteChannel target)
- throws IOException
- {
- return fch.transferTo(position, count, target);
- }
- public long transferFrom(ReadableByteChannel src,
- long position, long count)
- throws IOException
- {
- return fch.transferFrom(src, position, count);
- }
- public int read(ByteBuffer dst) throws IOException {
- return fch.read(dst);
- }
- public int read(ByteBuffer dst, long position)
- throws IOException
- {
- return fch.read(dst, position);
- }
- public long read(ByteBuffer[] dsts, int offset, int length)
- throws IOException
- {
- return fch.read(dsts, offset, length);
- }
- public int write(ByteBuffer src, long position)
- throws IOException
- {
- return fch.write(src, position);
- }
- public MappedByteBuffer map(MapMode mode,
- long position, long size)
- throws IOException
- {
- throw new UnsupportedOperationException();
- }
- public FileLock lock(long position, long size, boolean shared)
- throws IOException
- {
- return fch.lock(position, size, shared);
- }
- public FileLock tryLock(long position, long size, boolean shared)
- throws IOException
- {
- return fch.tryLock(position, size, shared);
- }
- protected void implCloseChannel() throws IOException {
- fch.close();
- if (forWrite) {
- u.mtime = javaToDosTime(System.currentTimeMillis());
- u.size = Attributes.readBasicFileAttributes(u.file).size();
- update(u);
- } else {
- if (!isFCH) // if this is a new fch for reading
- removeTempPathForEntry(tmpfile);
+ // is there a better way to hook into the FileChannel's close method?
+ return new FileChannel() {
+ public int write(ByteBuffer src) throws IOException {
+ return fch.write(src);
+ }
+ public long write(ByteBuffer[] srcs, int offset, int length)
+ throws IOException
+ {
+ return fch.write(srcs, offset, length);
+ }
+ public long position() throws IOException {
+ return fch.position();
+ }
+ public FileChannel position(long newPosition)
+ throws IOException
+ {
+ fch.position(newPosition);
+ return this;
+ }
+ public long size() throws IOException {
+ return fch.size();
+ }
+ public FileChannel truncate(long size)
+ throws IOException
+ {
+ fch.truncate(size);
+ return this;
+ }
+ public void force(boolean metaData)
+ throws IOException
+ {
+ fch.force(metaData);
+ }
+ public long transferTo(long position, long count,
+ WritableByteChannel target)
+ throws IOException
+ {
+ return fch.transferTo(position, count, target);
+ }
+ public long transferFrom(ReadableByteChannel src,
+ long position, long count)
+ throws IOException
+ {
+ return fch.transferFrom(src, position, count);
}
- }
- };
+ public int read(ByteBuffer dst) throws IOException {
+ return fch.read(dst);
+ }
+ public int read(ByteBuffer dst, long position)
+ throws IOException
+ {
+ return fch.read(dst, position);
+ }
+ public long read(ByteBuffer[] dsts, int offset, int length)
+ throws IOException
+ {
+ return fch.read(dsts, offset, length);
+ }
+ public int write(ByteBuffer src, long position)
+ throws IOException
+ {
+ return fch.write(src, position);
+ }
+ public MappedByteBuffer map(MapMode mode,
+ long position, long size)
+ throws IOException
+ {
+ throw new UnsupportedOperationException();
+ }
+ public FileLock lock(long position, long size, boolean shared)
+ throws IOException
+ {
+ return fch.lock(position, size, shared);
+ }
+ public FileLock tryLock(long position, long size, boolean shared)
+ throws IOException
+ {
+ return fch.tryLock(position, size, shared);
+ }
+ protected void implCloseChannel() throws IOException {
+ fch.close();
+ if (forWrite) {
+ u.mtime = System.currentTimeMillis();
+ u.size = Attributes.readBasicFileAttributes(u.file).size();
+ update(u);
+ } else {
+ if (!isFCH) // if this is a new fch for reading
+ removeTempPathForEntry(tmpfile);
+ }
+ }
+ };
+ } finally {
+ endRead();
+ }
}
// the outstanding input streams that need to be closed
@@ -776,11 +840,9 @@
// input streams are all closed by the obtainers.
private Set<ExChannelCloser> exChClosers = new HashSet<>();
- private Set<Path> tmppaths = new HashSet<>();
+ private Set<Path> tmppaths = Collections.synchronizedSet(new HashSet<Path>());
private Path getTempPathForEntry(byte[] path) throws IOException {
Path tmpPath = createTempFileInSameDirectoryAs(zfpath);
- tmppaths.add(tmpPath);
-
if (path != null) {
Entry e = getEntry0(path);
if (e != null) {
@@ -805,9 +867,14 @@
// check if all parents really exit. ZIP spec does not require
// the existence of any "parent directory".
private void checkParents(byte[] path) throws IOException {
- while ((path = getParent(path)) != null) {
- if (!inodes.containsKey(new EntryName(path)))
- throw new NoSuchFileException(getString(path));
+ beginRead();
+ try {
+ while ((path = getParent(path)) != null) {
+ if (!inodes.containsKey(IndexNode.keyOf(path)))
+ throw new NoSuchFileException(getString(path));
+ }
+ } finally {
+ endRead();
}
}
@@ -839,25 +906,40 @@
return true;
}
- ///////////////////////////////////////////////////////////////////
- private void initZipFile() throws IOException {
- ch = zfpath.newByteChannel(READ);
- initCEN();
+ private final void beginWrite() {
+ rwlock.writeLock().lock();
+ }
+
+ private final void endWrite() {
+ rwlock.writeLock().unlock();
}
+ private final void beginRead() {
+ rwlock.readLock().lock();
+ }
+
+ private final void endRead() {
+ rwlock.readLock().unlock();
+ }
+
+ ///////////////////////////////////////////////////////////////////
+
private volatile boolean isOpen = true;
- private SeekableByteChannel ch; // channel to the zipfile
- ByteBuffer cen; // CEN & ENDHDR
+ private final SeekableByteChannel ch; // channel to the zipfile
+ final byte[] cen; // CEN & ENDHDR
private END end;
private long locpos; // position of first LOC header (usually 0)
- // name -> pos (in cen), package private for ZipInfo
- LinkedHashMap<EntryName, IndexNode> inodes;
+ private final ReadWriteLock rwlock = new ReentrantReadWriteLock();
- byte[] getBytes(String name) {
+ // name -> pos (in cen), IndexNode itself can be used as a "key"
+ private LinkedHashMap<IndexNode, IndexNode> inodes;
+
+ final byte[] getBytes(String name) {
return zc.getBytes(name);
}
- String getString(byte[] name) {
+
+ final String getString(byte[] name) {
return zc.toString(name);
}
@@ -881,7 +963,7 @@
// Reads len bytes of data from the specified offset into buf.
// Returns the total number of bytes read.
// Each/every byte read from here (except the cen, which is mapped).
- private long readFullyAt(byte[] buf, int off, long len, long pos)
+ final long readFullyAt(byte[] buf, int off, long len, long pos)
throws IOException
{
ByteBuffer bb = ByteBuffer.wrap(buf);
@@ -890,7 +972,7 @@
return readFullyAt(bb, pos);
}
- private long readFullyAt(ByteBuffer bb, long pos)
+ private final long readFullyAt(ByteBuffer bb, long pos)
throws IOException
{
synchronized(ch) {
@@ -971,12 +1053,12 @@
// CEN header, otherwise returns -1 if an error occured. If zip->msg != NULL
// then the error was a zip format error and zip->msg has the error text.
// Always pass in -1 for knownTotal; it's used for a recursive call.
- private long initCEN() throws IOException {
+ private byte[] initCEN() throws IOException {
end = findEND();
if (end.endpos == 0) {
- inodes = new LinkedHashMap<EntryName, IndexNode>(10);
+ inodes = new LinkedHashMap<>(10);
locpos = 0;
- return 0; // only END header present
+ return null; // only END header present
}
if (end.cenlen > end.endpos)
zerror("invalid END header (bad central directory size)");
@@ -989,18 +1071,14 @@
zerror("invalid END header (bad central directory offset)");
// read in the CEN and END
- cen = ByteBuffer.allocate((int)(end.cenlen + ENDHDR));
- if (readFullyAt(cen, cenpos) != end.cenlen + ENDHDR) {
+ byte[] cen = new byte[(int)(end.cenlen + ENDHDR)];
+ if (readFullyAt(cen, 0, cen.length, cenpos) != end.cenlen + ENDHDR) {
zerror("read CEN tables failed");
}
- cen.order(ByteOrder.LITTLE_ENDIAN).flip();
-
// Iterate through the entries in the central directory
- inodes = new LinkedHashMap<EntryName, IndexNode>(end.centot + 1);
+ inodes = new LinkedHashMap<>(end.centot + 1);
int pos = 0;
- int limit = cen.remaining() - ENDHDR;
- int i = 0;
- byte[] bBuf = new byte[1024];
+ int limit = cen.length - ENDHDR;
while (pos < limit) {
if (CENSIG(cen, pos) != CENSIG)
zerror("invalid CEN header (bad signature)");
@@ -1011,24 +1089,19 @@
if ((CENFLG(cen, pos) & 1) != 0)
zerror("invalid CEN header (encrypted entry)");
if (method != METHOD_STORED && method != METHOD_DEFLATED)
- zerror("invalid CEN header (bad compression method: " + method + ")");
+ zerror("invalid CEN header (unsupported compression method: " + method + ")");
if (pos + CENHDR + nlen > limit)
zerror("invalid CEN header (bad header size)");
- if (bBuf.length < nlen)
- bBuf = new byte[nlen];
- cen.position(pos + CENHDR);
- byte[] name = new byte[nlen];
- cen.get(name);
- inodes.put(new EntryName(name), new IndexNode(name, pos));
+ byte[] name = Arrays.copyOfRange(cen, pos + CENHDR, pos + CENHDR + nlen);
+ IndexNode inode = new IndexNode(name, pos);
+ inodes.put(inode, inode);
// skip ext and comment
- cen.position(pos += (CENHDR + nlen + elen + clen));
- i++;
+ pos += (CENHDR + nlen + elen + clen);
}
- if (cen.remaining() != ENDHDR) {
+ if (pos + ENDHDR != cen.length) {
zerror("invalid CEN header (bad header size)");
}
- dirs = null; // clear the dir map
- return cenpos;
+ return cen;
}
private void ensureOpen() throws IOException {
@@ -1038,27 +1111,40 @@
// Creates a new empty temporary file in the same directory as the
// specified file. A variant of File.createTempFile.
- private static Path createTempFileInSameDirectoryAs(Path path)
+ private Path createTempFileInSameDirectoryAs(Path path)
throws IOException
{
Path parent = path.toAbsolutePath().getParent();
String dir = (parent == null)? "." : parent.toString();
- return File.createTempFile("zipfstmp", null, new File(dir)).toPath();
+ Path tmpPath = File.createTempFile("zipfstmp", null, new File(dir)).toPath();
+ tmppaths.add(tmpPath);
+ return tmpPath;
}
////////////////////update & sync //////////////////////////////////////
private boolean hasUpdate = false;
+
private void updateDelete(Entry e) {
- EntryName en = new EntryName(e.name);
- inodes.remove(en);
- hasUpdate = true;
+ beginWrite();
+ try {
+ inodes.remove(IndexNode.keyOf(e.name)); //inodes.remove(e.name);
+ hasUpdate = true;
+ dirs = null;
+ } finally {
+ endWrite();
+ }
}
private void update(Entry e) {
- EntryName en = new EntryName(e.name);
- inodes.put(en, e);
- hasUpdate = true;
+ beginWrite();
+ try {
+ inodes.put(IndexNode.keyOf(e.name), e); //inodes.put(e, e);
+ hasUpdate = true;
+ dirs = null;
+ } finally {
+ endWrite();
+ }
}
// copy over the whole LOC entry (header if necessary, data and ext) from
@@ -1080,13 +1166,18 @@
else
size = 16;
}
- if (updateHeader) { // if we need update the loc header
- locoff += LOCHDR + e.nlen + e.elen; // skip header
+ // read loc, use the original loc.elen/nlen
+ if (readFullyAt(buf, 0, LOCHDR , locoff) != LOCHDR)
+ throw new ZipException("loc: reading failed");
+ if (updateHeader) {
+ locoff += LOCHDR + LOCNAM(buf) + LOCEXT(buf); // skip header
size += e.csize;
written = e.writeLOC(os) + size;
} else {
- size += LOCHDR + e.nlen + e.elen + e.csize;
- written = size;
+ os.write(buf, 0, LOCHDR); // write out the loc header
+ locoff += LOCHDR;
+ size += LOCNAM(buf) + LOCEXT(buf) + LOCSIZ(buf);
+ written = LOCHDR + size;
}
int n;
while (size > 0 &&
@@ -1103,7 +1194,7 @@
// sync the zip file system, if there is any udpate
private void sync() throws IOException {
- assert Thread.holdsLock(this);
+ //System.out.printf("->sync(%s) starting....!%n", toString());
// check ex-closer
if (!exChClosers.isEmpty()) {
@@ -1117,7 +1208,6 @@
}
if (!hasUpdate)
return;
-
Path tmpFile = createTempFileInSameDirectoryAs(zfpath);
OutputStream os = tmpFile.newOutputStream(WRITE);
ArrayList<Entry> elist = new ArrayList<>(inodes.size());
@@ -1174,7 +1264,7 @@
x.printStackTrace(); // skip any in-accurate entry
}
} else { // unchanged inode
- e = Entry.readCEN(cen, inode.pos);
+ e = Entry.readCEN(this, inode.pos);
try {
written += copyLOCEntry(e, false, os, written, buf);
elist.add(e);
@@ -1195,6 +1285,11 @@
os.close();
if (!streams.isEmpty()) {
+ //
+ // TBD: ExChannelCloser should not be necessary if we only
+ // sync when being closed, all streams should have been
+ // closed already. Keep the logic here for now.
+ //
// There are outstanding input streams open on existing "ch",
// so, don't close the "cha" and delete the "file for now, let
// the "ex-channel-closer" to handle them
@@ -1209,45 +1304,41 @@
ch.close();
zfpath.delete();
}
+
tmpFile.moveTo(zfpath, REPLACE_EXISTING);
hasUpdate = false; // clear
-
+ /*
if (isOpen) {
ch = zfpath.newByteChannel(READ); // re-fresh "ch" and "cen"
- initCEN();
+ cen = initCEN();
}
- //System.out.println("->sync() done!");
+ */
+ //System.out.printf("->sync(%s) done!%n", toString());
}
private Entry getEntry0(byte[] path) throws IOException {
- assert Thread.holdsLock(this);
-
if (path == null)
throw new NullPointerException("path");
if (path.length == 0)
return null;
- EntryName en = new EntryName(path);
IndexNode inode = null;
- synchronized (lock) {
- ensureOpen();
- if ((inode = inodes.get(en)) == null) {
- if (path[path.length -1] == '/') // already has a slash
- return null;
- path = Arrays.copyOf(path, path.length + 1);
- path[path.length - 1] = '/';
- en.name(path);
- if ((inode = inodes.get(en)) == null)
- return null;
- }
- if (inode instanceof Entry)
- return (Entry)inode;
- return Entry.readCEN(cen, inode.pos);
+ IndexNode key = IndexNode.keyOf(path);
+ if ((inode = inodes.get(key)) == null) {
+ if (path[path.length -1] == '/') // already has a slash
+ return null;
+ path = Arrays.copyOf(path, path.length + 1);
+ path[path.length - 1] = '/';
+ if ((inode = inodes.get(key.as(path))) == null)
+ return null;
}
+ if (inode instanceof Entry)
+ return (Entry)inode;
+ return Entry.readCEN(this, inode.pos);
}
// Test if the "name" a parent directory of any entry (dir empty)
boolean isAncestor(byte[] name) {
- for (Map.Entry<EntryName, IndexNode> entry : inodes.entrySet()) {
+ for (Map.Entry<IndexNode, IndexNode> entry : inodes.entrySet()) {
byte[] ename = entry.getKey().name;
if (isParentOf(name, ename))
return true;
@@ -1259,18 +1350,16 @@
throws IOException
{
checkWritable();
- synchronized(lock) {
- Entry e = getEntry0(path);
- if (e == null) {
- if (path != null && path.length == 0)
- throw new ZipException("root directory </> can't not be delete");
- if (failIfNotExists)
- throw new NoSuchFileException(getString(path));
- } else {
- if (e.isDir() && isAncestor(path))
- throw new DirectoryNotEmptyException(getString(path));
- updateDelete(e);
- }
+ Entry e = getEntry0(path);
+ if (e == null) {
+ if (path != null && path.length == 0)
+ throw new ZipException("root directory </> can't not be delete");
+ if (failIfNotExists)
+ throw new NoSuchFileException(getString(path));
+ } else {
+ if (e.isDir() && isAncestor(path))
+ throw new DirectoryNotEmptyException(getString(path));
+ updateDelete(e);
}
}
@@ -1289,9 +1378,8 @@
// (2) updating/replacing the contents of the specified existing entry.
private OutputStream getOutputStream(Entry e) throws IOException {
- ensureOpen();
if (e.mtime == -1)
- e.mtime = javaToDosTime(System.currentTimeMillis());
+ e.mtime = System.currentTimeMillis();
if (e.method == -1)
e.method = METHOD_DEFLATED; // TBD: use default method
// store size, compressed size, and crc-32 in LOC header
@@ -1334,7 +1422,7 @@
long bufSize = e.size + 2; // Inflater likes a bit of slack
if (bufSize > 65536)
bufSize = 8192;
- final long size = e.size;;
+ final long size = e.size;
eis = new InflaterInputStream(eis, getInflater(), (int)bufSize) {
private boolean isClosed = false;
@@ -1343,6 +1431,7 @@
releaseInflater(inf);
this.in.close();
isClosed = true;
+ streams.remove(this);
}
}
// Override fill() method to provide an extra "dummy" byte
@@ -1372,7 +1461,9 @@
Integer.MAX_VALUE : (int) avail;
}
};
- } else if (e.method != METHOD_STORED) {
+ } else if (e.method == METHOD_STORED) {
+ // TBD: wrap/ it does not seem necessary
+ } else {
throw new ZipException("invalid compression method");
}
streams.add(eis);
@@ -1382,11 +1473,11 @@
// Inner class implementing the input stream used to read
// a (possibly compressed) zip file entry.
private class EntryInputStream extends InputStream {
- private SeekableByteChannel zfch; // local ref to zipfs's "ch". zipfs.ch might
+ private final SeekableByteChannel zfch; // local ref to zipfs's "ch". zipfs.ch might
// point to a new channel after sync()
private long pos; // current position within entry data
protected long rem; // number of remaining bytes within entry
- protected long size; // uncompressed size of this entry
+ protected final long size; // uncompressed size of this entry
EntryInputStream(Entry e, SeekableByteChannel zfch)
throws IOException
@@ -1527,14 +1618,14 @@
}
}
- private static void zerror(String msg) {
+ static void zerror(String msg) {
throw new ZipError(msg);
}
// Maxmum number of de/inflater we cache
private final int MAX_FLATER = 20;
// List of available Inflater objects for decompression
- private List<Inflater> inflaters = new ArrayList<>();
+ private final List<Inflater> inflaters = new ArrayList<>();
// Gets an inflater from the list of available inflaters or allocates
// a new one.
@@ -1563,7 +1654,7 @@
}
// List of available Deflater objects for compression
- private List<Deflater> deflaters = new ArrayList<>();
+ private final List<Deflater> deflaters = new ArrayList<>();
// Gets an deflater from the list of available deflaters or allocates
// a new one.
@@ -1660,44 +1751,40 @@
}
}
- // wrapper for the byte[] name
- static class EntryName {
+ // Internal node that links a "name" to its pos in cen table.
+ // The node itself can be used as a "key" to lookup itself in
+ // the HashMap inodes.
+ static class IndexNode {
byte[] name;
- int hashcode; // node is hashable/hashed by its name
-
- public EntryName (byte[] name) {
- name(name);
+ int hashcode; // node is hashable/hashed by its name
+ int pos = -1; // postion in cen table, -1 menas the
+ // entry does not exists in zip file
+ IndexNode(byte[] name, int pos) {
+ as(name);
+ this.pos = pos;
}
- void name(byte[] name) {
- this.name = name;
+ final static IndexNode keyOf(byte[] name) { // get a lookup key;
+ return new IndexNode(name, -1);
+ }
+
+ final IndexNode as(byte[] name) { // reuse the node, mostly
+ this.name = name; // as a lookup "key"
this.hashcode = Arrays.hashCode(name);
+ return this;
}
public boolean equals(Object other) {
- if (!(other instanceof EntryName))
+ if (!(other instanceof IndexNode))
return false;
- return Arrays.equals(name, ((EntryName)other).name);
+ return Arrays.equals(name, ((IndexNode)other).name);
}
public int hashCode() {
return hashcode;
}
- }
-
- // can simply use Integer instead, if we don't use it to
- // build a internal node tree.
- static class IndexNode {
- byte[] name;
- int pos = -1; // postion in cen table, -1 menas the
- // entry does not exists in zip file
- IndexNode(byte[] name, int pos) {
- this.name = name;
- this.pos = pos;
- }
IndexNode() {}
-
IndexNode sibling;
IndexNode child; // 1st child
}
@@ -1723,37 +1810,25 @@
long crc = -1; // crc-32 of entry data
long csize = -1; // compressed size of entry data
long size = -1; // uncompressed size of entry data
- int nlen;
- int elen;
byte[] extra;
- // loc
- long startPos;
- long endPos; // exclusive
-
// cen
int versionMade;
int disk;
int attrs;
long attrsEx;
long locoff;
-
- int clen;
byte[] comment;
- // ZIP64 flag
- boolean hasZip64;
-
Entry() {}
Entry(byte[] name) {
- this.name = name;
- //this.nlen = name.length;
- this.mtime = javaToDosTime(System.currentTimeMillis());
- this.crc = 0;
- this.size = 0;
- this.csize = 0;
- this.method = METHOD_DEFLATED;
+ this.name = name;
+ this.mtime = System.currentTimeMillis();
+ this.crc = 0;
+ this.size = 0;
+ this.csize = 0;
+ this.method = METHOD_DEFLATED;
}
Entry(byte[] name, int type) {
@@ -1761,16 +1836,9 @@
this.type = type;
}
- Entry (byte[] name, Path file, int type) {
- this(name, type);
- this.file = file;
- this.method = METHOD_STORED;
- }
-
- Entry(Entry e) {
+ Entry (Entry e, int type) {
this.version = e.version;
- this.name = e.name; // copyOf?
- this.nlen = e.nlen;
+ this.name = e.name;
this.ctime = e.ctime;
this.atime = e.atime;
this.mtime = e.mtime;
@@ -1778,25 +1846,21 @@
this.size = e.size;
this.csize = e.csize;
this.method = e.method;
- this.extra = (e.extra == null)?
- null:Arrays.copyOf(e.extra, e.extra.length);
- this.elen = e.elen;
+ this.extra = e.extra;
this.versionMade = e.versionMade;
this.disk = e.disk;
this.attrs = e.attrs;
this.attrsEx = e.attrsEx;
this.locoff = e.locoff;
- this.clen = e.clen;
- this.comment = (e.comment == null)?
- null:Arrays.copyOf(e.comment, e.comment.length);
- this.startPos = e.startPos;
- this.endPos = e.endPos;
- this.hasZip64 = e.hasZip64;;
+ this.comment = e.comment;
+
+ this.type = type;
}
- Entry (Entry e, int type) {
- this(e);
- this.type = type;
+ Entry (byte[] name, Path file, int type) {
+ this(name, type);
+ this.file = file;
+ this.method = METHOD_STORED;
}
boolean isDir() {
@@ -1814,77 +1878,45 @@
}
///////////////////// CEN //////////////////////
- static Entry readCEN(ByteBuffer cen, int pos) throws IOException
+ static Entry readCEN(ZipFileSystem zipfs, int pos)
+ throws IOException
{
- return new Entry().cen(cen, pos);
+ return new Entry().cen(zipfs, pos);
}
- private Entry cen(ByteBuffer cen, int pos) throws IOException
+ private Entry cen(ZipFileSystem zipfs, int pos)
+ throws IOException
{
+ byte[] cen = zipfs.cen;
if (CENSIG(cen, pos) != CENSIG)
zerror("invalid CEN header (bad signature)");
versionMade = CENVEM(cen, pos);
version = CENVER(cen, pos);
flag = CENFLG(cen, pos);
method = CENHOW(cen, pos);
- mtime = CENTIM(cen, pos);
+ mtime = dosToJavaTime(CENTIM(cen, pos));
crc = CENCRC(cen, pos);
csize = CENSIZ(cen, pos);
size = CENLEN(cen, pos);
- nlen = CENNAM(cen, pos);
- elen = CENEXT(cen, pos);
- clen = CENCOM(cen, pos);
+ int nlen = CENNAM(cen, pos);
+ int elen = CENEXT(cen, pos);
+ int clen = CENCOM(cen, pos);
disk = CENDSK(cen, pos);
attrs = CENATT(cen, pos);
attrsEx = CENATX(cen, pos);
locoff = CENOFF(cen, pos);
- cen.position(pos + CENHDR);
- name = new byte[nlen];
- cen.get(name);
+ pos += CENHDR;
+ name = Arrays.copyOfRange(cen, pos, pos + nlen);
+ pos += nlen;
if (elen > 0) {
- extra = new byte[elen];
- cen.get(extra);
- if (csize == ZIP64_MINVAL || size == ZIP64_MINVAL ||
- locoff == ZIP64_MINVAL) {
- int off = 0;
- while (off + 4 < elen) {
- // extra spec: HeaderID+DataSize+Data
- int sz = SH(extra, off + 2);
- if (SH(extra, off) == EXTID_ZIP64) {
- off += 4;
- if (size == ZIP64_MINVAL) {
- // if invalid zip64 extra fields, just skip
- if (sz < 8 || (off + 8) > elen)
- break;
- size = LL(extra, off);
- sz -= 8;
- off += 8;
- }
- if (csize == ZIP64_MINVAL) {
- if (sz < 8 || (off + 8) > elen)
- break;
- csize = LL(extra, off);
- sz -= 8;
- off += 8;
- }
- if (locoff == ZIP64_MINVAL) {
- if (sz < 8 || (off + 8) > elen)
- break;
- locoff = LL(extra, off);
- sz -= 8;
- off += 8;
- }
- break;
- }
- off += (sz + 4);
- }
- }
+ extra = Arrays.copyOfRange(cen, pos, pos + elen);
+ pos += elen;
+ readExtra(zipfs);
}
if (clen > 0) {
- comment = new byte[clen];
- cen.get(comment);
+ comment = Arrays.copyOfRange(cen, pos, pos + clen);
}
return this;
}
@@ -1897,31 +1929,37 @@
long csize0 = csize;
long size0 = size;
long locoff0 = locoff;
- int e64len = 0;
+ int elen64 = 0; // extra for ZIP64
+ int elenNTFS = 0; // extra for NTFS (a/c/mtime)
+ int elenEXTT = 0; // extra for Extended Timestamp
// confirm size/length
- nlen = (name != null) ? name.length : 0;
- elen = (extra != null) ? extra.length : 0;
- clen = (comment != null) ? comment.length : 0;
-
- boolean hasZip64 = false;
+ int nlen = (name != null) ? name.length : 0;
+ int elen = (extra != null) ? extra.length : 0;
+ int clen = (comment != null) ? comment.length : 0;
if (csize >= ZIP64_MINVAL) {
csize0 = ZIP64_MINVAL;
- e64len += 8; // csize(8)
- hasZip64 = true;
+ elen64 += 8; // csize(8)
}
if (size >= ZIP64_MINVAL) {
size0 = ZIP64_MINVAL; // size(8)
- e64len += 8;
- hasZip64 = true;
+ elen64 += 8;
}
if (locoff >= ZIP64_MINVAL) {
locoff0 = ZIP64_MINVAL;
- e64len += 8; // offset(8)
- hasZip64 = true;
+ elen64 += 8; // offset(8)
+ }
+ if (elen64 != 0)
+ elen64 += 4; // header and data sz 4 bytes
+
+ if (atime != -1) {
+ if (isWindows) // use NTFS
+ elenNTFS = 36; // total 36 bytes
+ else // Extended Timestamp otherwise
+ elenEXTT = 9; // only mtime in cen
}
writeInt(os, CENSIG); // CEN header signature
- if (hasZip64) {
+ if (elen64 != 0) {
writeShort(os, 45); // ver 4.5 for zip64
writeShort(os, 45);
} else {
@@ -1930,18 +1968,14 @@
}
writeShort(os, flag); // general purpose bit flag
writeShort(os, method); // compression method
- writeInt(os, mtime); // last modification time
+ // last modification time
+ writeInt(os, (int)javaToDosTime(mtime));
writeInt(os, crc); // crc-32
writeInt(os, csize0); // compressed size
writeInt(os, size0); // uncompressed size
writeShort(os, name.length);
+ writeShort(os, elen + elen64 + elenNTFS + elenEXTT);
- if (hasZip64) {
- // + headid(2) + datasize(2)
- writeShort(os, e64len + 4 + elen);
- } else {
- writeShort(os, elen);
- }
if (comment != null) {
writeShort(os, Math.min(clen, 0xffff));
} else {
@@ -1952,9 +1986,9 @@
writeInt(os, 0); // external file attributes (unused)
writeInt(os, locoff0); // relative offset of local header
writeBytes(os, name);
- if (hasZip64) {
+ if (elen64 != 0) {
writeShort(os, EXTID_ZIP64);// Zip64 extra
- writeShort(os, e64len);
+ writeShort(os, elen64); // size of "this" extra block
if (size0 == ZIP64_MINVAL)
writeLong(os, size);
if (csize0 == ZIP64_MINVAL)
@@ -1962,58 +1996,73 @@
if (locoff0 == ZIP64_MINVAL)
writeLong(os, locoff);
}
- if (extra != null) {
- writeBytes(os, extra);
+ if (elenNTFS != 0) {
+ // System.out.println("writing NTFS:" + elenNTFS);
+ writeShort(os, EXTID_NTFS);
+ writeShort(os, elenNTFS - 4);
+ writeInt(os, 0); // reserved
+ writeShort(os, 0x0001); // NTFS attr tag
+ writeShort(os, 24);
+ writeLong(os, javaToWinTime(mtime));
+ writeLong(os, javaToWinTime(atime));
+ writeLong(os, javaToWinTime(ctime));
}
- if (comment != null) {
- //TBD: 0, Math.min(commentBytes.length, 0xffff));
+ if (elenEXTT != 0) {
+ writeShort(os, EXTID_EXTT);
+ writeShort(os, elenEXTT - 4);
+ if (ctime == -1)
+ os.write(0x3); // mtime and atime
+ else
+ os.write(0x7); // mtime, atime and ctime
+ writeInt(os, javaToUnixTime(mtime));
+ }
+ if (extra != null) // whatever not recognized
+ writeBytes(os, extra);
+ if (comment != null) //TBD: 0, Math.min(commentBytes.length, 0xffff));
writeBytes(os, comment);
- }
- return CENHDR + nlen + elen + clen + (hasZip64?(e64len + 4):0);
+ return CENHDR + nlen + elen + clen + elen64 + elenNTFS + elenEXTT;
}
///////////////////// LOC //////////////////////
- static Entry readLOC(ZipFileSystem zf, long pos)
+ static Entry readLOC(ZipFileSystem zipfs, long pos)
throws IOException
{
- return readLOC(zf, pos, new byte[1024]);
+ return readLOC(zipfs, pos, new byte[1024]);
}
- static Entry readLOC(ZipFileSystem zf, long pos, byte[] buf)
+ static Entry readLOC(ZipFileSystem zipfs, long pos, byte[] buf)
throws IOException
{
- return new Entry().loc(zf, pos, buf);
+ return new Entry().loc(zipfs, pos, buf);
}
- Entry loc(ZipFileSystem zf, long pos, byte[] buf)
+ Entry loc(ZipFileSystem zipfs, long pos, byte[] buf)
throws IOException
{
assert (buf.length >= LOCHDR);
- if (zf.readFullyAt(buf, 0, LOCHDR , pos) != LOCHDR) {
+ if (zipfs.readFullyAt(buf, 0, LOCHDR , pos) != LOCHDR)
throw new ZipException("loc: reading failed");
- }
- if (LOCSIG(buf) != LOCSIG) {
+ if (LOCSIG(buf) != LOCSIG)
throw new ZipException("loc: wrong sig ->"
+ Long.toString(LOCSIG(buf), 16));
- }
- startPos = pos;
+ //startPos = pos;
version = LOCVER(buf);
flag = LOCFLG(buf);
method = LOCHOW(buf);
- mtime = LOCTIM(buf);
+ mtime = dosToJavaTime(LOCTIM(buf));
crc = LOCCRC(buf);
csize = LOCSIZ(buf);
size = LOCLEN(buf);
- nlen = LOCNAM(buf);
- elen = LOCEXT(buf);
+ int nlen = LOCNAM(buf);
+ int elen = LOCEXT(buf);
name = new byte[nlen];
- if (zf.readFullyAt(name, 0, nlen, pos + LOCHDR) != nlen) {
+ if (zipfs.readFullyAt(name, 0, nlen, pos + LOCHDR) != nlen) {
throw new ZipException("loc: name reading failed");
}
if (elen > 0) {
extra = new byte[elen];
- if (zf.readFullyAt(extra, 0, elen, pos + LOCHDR + nlen)
+ if (zipfs.readFullyAt(extra, 0, elen, pos + LOCHDR + nlen)
!= elen) {
throw new ZipException("loc: ext reading failed");
}
@@ -2021,7 +2070,7 @@
pos += (LOCHDR + nlen + elen);
if ((flag & FLAG_DATADESCR) != 0) {
// Data Descriptor
- Entry e = zf.getEntry0(name); // get the size/csize from cen
+ Entry e = zipfs.getEntry0(name); // get the size/csize from cen
if (e == null)
throw new ZipException("loc: name not found in cen");
size = e.size;
@@ -2032,7 +2081,6 @@
else
pos += 16;
} else {
- boolean hasZip64 = false;
if (extra != null &&
(size == ZIP64_MINVAL || csize == ZIP64_MINVAL)) {
// zip64 ext: must include both size and csize
@@ -2042,7 +2090,6 @@
if (SH(extra, off) == EXTID_ZIP64 && sz == 16) {
size = LL(extra, off + 4);
csize = LL(extra, off + 12);
- hasZip64 = true;
break;
}
off += (sz + 4);
@@ -2050,7 +2097,6 @@
}
pos += (method == METHOD_STORED ? size : csize);
}
- endPos = pos;
return this;
}
@@ -2058,14 +2104,18 @@
throws IOException
{
writeInt(os, LOCSIG); // LOC header signature
+ int version = version();
- int version = version();
+ int nlen = (name != null) ? name.length : 0;
+ int elen = (extra != null) ? extra.length : 0;
+ int elen64 = 0;
+ int elenEXTT = 0;
if ((flag & FLAG_DATADESCR) != 0) {
writeShort(os, version()); // version needed to extract
writeShort(os, flag); // general purpose bit flag
writeShort(os, method); // compression method
- writeInt(os, mtime); // last modification time
-
+ // last modification time
+ writeInt(os, (int)javaToDosTime(mtime));
// store size, uncompressed size, and crc-32 in data descriptor
// immediately following compressed entry data
writeInt(os, 0);
@@ -2073,7 +2123,7 @@
writeInt(os, 0);
} else {
if (csize >= ZIP64_MINVAL || size >= ZIP64_MINVAL) {
- hasZip64 = true;
+ elen64 = 20; //headid(2) + size(2) + size(8) + csize(8)
writeShort(os, 45); // ver 4.5 for zip64
} else {
writeShort(os, version()); // version needed to extract
@@ -2082,29 +2132,45 @@
writeShort(os, method); // compression method
writeInt(os, mtime); // last modification time
writeInt(os, crc); // crc-32
- if (hasZip64) {
+ if (elen64 != 0) {
writeInt(os, ZIP64_MINVAL);
writeInt(os, ZIP64_MINVAL);
- //TBD: e.elen += 20; //headid(2) + size(2) + size(8) + csize(8)
} else {
writeInt(os, csize); // compressed size
writeInt(os, size); // uncompressed size
}
}
+ if (atime != -1 && !isWindows) { // on unix use "ext time"
+ if (ctime == -1)
+ elenEXTT = 13;
+ else
+ elenEXTT = 17;
+ }
writeShort(os, name.length);
- writeShort(os, elen + (hasZip64 ? 20 : 0));
+ writeShort(os, elen + elen64 + elenEXTT);
writeBytes(os, name);
- if (hasZip64) {
- // TBD: should we update extra directory?
+ if (elen64 != 0) {
writeShort(os, EXTID_ZIP64);
writeShort(os, 16);
writeLong(os, size);
writeLong(os, csize);
}
+ if (elenEXTT != 0) {
+ writeShort(os, EXTID_EXTT);
+ writeShort(os, elenEXTT - 4);// size for the folowing data block
+ if (ctime == -1)
+ os.write(0x3); // mtime and atime
+ else
+ os.write(0x7); // mtime, atime and ctime
+ writeInt(os, javaToUnixTime(mtime));
+ writeInt(os, javaToUnixTime(atime));
+ if (ctime != -1)
+ writeInt(os, javaToUnixTime(ctime));
+ }
if (extra != null) {
writeBytes(os, extra);
}
- return LOCHDR + name.length + elen + (hasZip64 ? 20 : 0);
+ return LOCHDR + name.length + elen + elen64 + elenEXTT;
}
// Data Descriptior
@@ -2125,17 +2191,18 @@
}
// read NTFS, UNIX and ZIP64 data from cen.extra
- void readExtra() {
+ void readExtra(ZipFileSystem zipfs) throws IOException {
if (extra == null)
return;
int elen = extra.length;
int off = 0;
+ int newOff = 0;
while (off + 4 < elen) {
// extra spec: HeaderID+DataSize+Data
- int sz = SH(extra, off + 2);
- int tag = SH(extra, off);
- off += 4;
int pos = off;
+ int tag = SH(extra, pos);
+ int sz = SH(extra, pos + 2);
+ pos += 4;
if (pos + sz > elen) // invalid data
break;
switch (tag) {
@@ -2165,18 +2232,66 @@
break;
if (SH(extra, pos + 2) != 24)
break;
- mtime = LL(extra, pos + 4);
- atime = LL(extra, pos + 12);
- ctime = LL(extra, pos + 20);
+ // override the loc field, datatime here is
+ // more "accurate"
+ mtime = winToJavaTime(LL(extra, pos + 4));
+ atime = winToJavaTime(LL(extra, pos + 12));
+ ctime = winToJavaTime(LL(extra, pos + 20));
break;
- case EXTID_UNIX:
- atime = LG(extra, pos);
- mtime = LG(extra, pos + 4);
+ case EXTID_EXTT:
+ // spec says the Extened timestamp in cen only has mtime
+ // need to read the loc to get the extra a/ctime
+ byte[] buf = new byte[LOCHDR];
+ if (zipfs.readFullyAt(buf, 0, buf.length , locoff)
+ != buf.length)
+ throw new ZipException("loc: reading failed");
+ if (LOCSIG(buf) != LOCSIG)
+ throw new ZipException("loc: wrong sig ->"
+ + Long.toString(LOCSIG(buf), 16));
+
+ int locElen = LOCEXT(buf);
+ if (locElen < 9) // EXTT is at lease 9 bytes
+ break;
+ int locNlen = LOCNAM(buf);
+ buf = new byte[locElen];
+ if (zipfs.readFullyAt(buf, 0, buf.length , locoff + LOCHDR + locNlen)
+ != buf.length)
+ throw new ZipException("loc extra: reading failed");
+ int locPos = 0;
+ while (locPos + 4 < buf.length) {
+ int locTag = SH(buf, locPos);
+ int locSZ = SH(buf, locPos + 2);
+ locPos += 4;
+ if (locTag != EXTID_EXTT) {
+ locPos += locSZ;
+ continue;
+ }
+ int flag = CH(buf, locPos++);
+ if ((flag & 0x1) != 0) {
+ mtime = unixToJavaTime(LG(buf, locPos));
+ locPos += 4;
+ }
+ if ((flag & 0x2) != 0) {
+ atime = unixToJavaTime(LG(buf, locPos));
+ locPos += 4;
+ }
+ if ((flag & 0x4) != 0) {
+ ctime = unixToJavaTime(LG(buf, locPos));
+ locPos += 4;
+ }
+ break;
+ }
break;
- default: // unknow
+ default: // unknown tag
+ System.arraycopy(extra, off, extra, newOff, sz + 4);
+ newOff += (sz + 4);
}
- off += sz;
+ off += (sz + 4);
}
+ if (newOff != 0 && newOff != extra.length)
+ extra = Arrays.copyOf(extra, newOff);
+ else
+ extra = null;
}
}
@@ -2201,9 +2316,9 @@
// structure.
// A possible solution is to build the node tree ourself as
// implemented below.
- private HashMap<EntryName, IndexNode> dirs;
+ private HashMap<IndexNode, IndexNode> dirs;
private IndexNode root;
- private IndexNode addToDir(EntryName child) {
+ private IndexNode addToDir(IndexNode child) {
IndexNode cinode = dirs.get(child);
if (cinode != null)
return cinode;
@@ -2213,7 +2328,7 @@
IndexNode pinode;
if (pname != null)
- pinode = addToDir(new EntryName(pname));
+ pinode = addToDir(IndexNode.keyOf(pname));
else
pinode = root;
cinode = inodes.get(child);
@@ -2222,8 +2337,8 @@
pinode.child = cinode;
return null;
}
- cinode = dirs.get(child);
- if (cinode == null) // pseudo directry entry
+ //cinode = dirs.get(child);
+ if (cinode == null) // pseudo directry entry
cinode = new IndexNode(cname, -1);
cinode.sibling = pinode.child;
pinode.child = cinode;
@@ -2232,26 +2347,21 @@
return cinode;
}
- private HashMap<EntryName, IndexNode> getDirs()
+ private HashMap<IndexNode, IndexNode> getDirs()
throws IOException
{
- if (hasUpdate)
- sync();
- if (dirs != null)
+ beginWrite();
+ try {
+ if (dirs != null)
+ return dirs;
+ dirs = new HashMap<>();
+ root = new IndexNode(new byte[0], -1);
+ dirs.put(root, root);
+ for (IndexNode node : inodes.keySet())
+ addToDir(node);
return dirs;
- dirs = new HashMap<EntryName, IndexNode>();
- byte[] empty = new byte[0];
- root = new IndexNode(empty, -1);
- dirs.put(new EntryName(empty), root);
-
- EntryName[] names = inodes.keySet().toArray(new EntryName[0]);
- int i = names.length;
- while (--i >= 0) {
- addToDir(names[i]);
+ } finally {
+ endWrite();
}
- // for (int i EntryName en : inodes.keySet()) {
- // addToDir(en);
- // }
- return dirs;
}
}
--- a/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileSystemProvider.java Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileSystemProvider.java Mon Nov 22 10:18:33 2010 -0500
@@ -55,6 +55,8 @@
*/
public class ZipFileSystemProvider extends FileSystemProvider {
+
+
private final Map<Path, ZipFileSystem> filesystems = new HashMap<>();
public ZipFileSystemProvider() {}
@@ -101,10 +103,16 @@
throws IOException
{
synchronized(filesystems) {
- if (filesystems.containsKey(path))
- throw new FileSystemAlreadyExistsException();
+ Path realPath = null;
+ if (path.exists()) {
+ realPath = path.toRealPath(true);
+ if (filesystems.containsKey(realPath))
+ throw new FileSystemAlreadyExistsException();
+ }
ZipFileSystem zipfs = new ZipFileSystem(this, path, env);
- filesystems.put(path, zipfs);
+ if (realPath == null)
+ realPath = path.toRealPath(true);
+ filesystems.put(realPath, zipfs);
return zipfs;
}
}
@@ -137,16 +145,21 @@
@Override
public FileSystem getFileSystem(URI uri) {
synchronized (filesystems) {
- ZipFileSystem zipfs = filesystems.get(uriToPath(uri));
+ ZipFileSystem zipfs = null;
+ try {
+ zipfs = filesystems.get(uriToPath(uri).toRealPath(true));
+ } catch (IOException x) {
+ // ignore the ioe from toRealPath(), return FSNFE
+ }
if (zipfs == null)
throw new FileSystemNotFoundException();
return zipfs;
}
}
- void removeFileSystem(Path zfpath) {
+ void removeFileSystem(Path zfpath) throws IOException {
synchronized (filesystems) {
- filesystems.remove(zfpath);
+ filesystems.remove(zfpath.toRealPath(true));
}
}
}
--- a/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipInfo.java Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipInfo.java Mon Nov 22 10:18:33 2010 -0500
@@ -31,7 +31,6 @@
package com.sun.nio.zipfs;
-import java.io.PrintStream;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.Iterator;
@@ -41,7 +40,7 @@
import static com.sun.nio.zipfs.ZipUtils.*;
/**
- * Print the loc and cen tables of the ZIP file
+ * Print all loc and cen headers of the ZIP file
*
* @author Xueming Shen
*/
@@ -49,34 +48,38 @@
public class ZipInfo {
public static void main(String[] args) throws Throwable {
- if (args.length < 2) {
- print("Usage: java ZipInfo [cen|loc] zfname");
+ if (args.length < 1) {
+ print("Usage: java ZipInfo zfname");
} else {
Map<String, ?> env = Collections.emptyMap();
ZipFileSystem zfs = (ZipFileSystem)(new ZipFileSystemProvider()
- .newFileSystem(Paths.get(args[1]), env));
-
- long pos = 0;
+ .newFileSystem(Paths.get(args[0]), env));
+ byte[] cen = zfs.cen;
+ if (cen == null) {
+ print("zip file is empty%n");
+ return;
+ }
+ int pos = 0;
+ byte[] buf = new byte[1024];
+ int no = 1;
+ while (pos + CENHDR < cen.length) {
+ print("----------------#%d--------------------%n", no++);
+ printCEN(cen, pos);
- if ("loc".equals(args[0])) {
- print("[Local File Header]%n");
- byte[] buf = new byte[1024];
- for (int i = 0; i < zfs.getEntryNames().length; i++) {
- Entry loc = Entry.readLOC(zfs, pos, buf);
- print("--------loc[%x]--------%n", pos);
- printLOC(loc);
- pos = loc.endPos;
+ // use size CENHDR as the extra bytes to read, just in case the
+ // loc.extra is bigger than the cen.extra, try to avoid to read
+ // twice
+ long len = LOCHDR + CENNAM(cen, pos) + CENEXT(cen, pos) + CENHDR;
+ if (zfs.readFullyAt(buf, 0, len, locoff(cen, pos)) != len)
+ zfs.zerror("read loc header failed");
+ if (LOCEXT(buf) > CENEXT(cen, pos) + CENHDR) {
+ // have to read the second time;
+ len = LOCHDR + LOCNAM(buf) + LOCEXT(buf);
+ if (zfs.readFullyAt(buf, 0, len, locoff(cen, pos)) != len)
+ zfs.zerror("read loc header failed");
}
- } if ("cen".equals(args[0])) {
- int i = 0;
- Iterator<ZipFileSystem.IndexNode> itr = zfs.inodes.values().iterator();
- print("[Central Directory Header]%n");
- while (itr.hasNext()) {
- Entry cen = Entry.readCEN(zfs.cen, itr.next().pos);
- print("--------cen[%d]--------%n", i);
- printCEN(cen);
- i++;
- }
+ printLOC(buf);
+ pos += CENHDR + CENNAM(cen, pos) + CENEXT(cen, pos) + CENCOM(cen, pos);
}
zfs.close();
}
@@ -86,47 +89,135 @@
System.out.printf(fmt, objs);
}
- static void printLOC(Entry loc) {
- print(" [%x, %x]%n", loc.startPos, loc.endPos);
- print(" Signature : %8x%n", LOCSIG);
- print(" Version : %4x [%d.%d]%n",
- loc.version, loc. version/10, loc. version%10);
- print(" Flag : %4x%n", loc.flag);
- print(" Method : %4x%n", loc. method);
- print(" LastMTime : %8x [%tc]%n",
- loc.mtime, dosToJavaTime(loc.mtime));
- print(" CRC : %8x%n", loc.crc);
- print(" CSize : %8x%n", loc.csize);
- print(" Size : %8x%n", loc.size);
- print(" NameLength : %4x [%s]%n",
- loc.nlen, new String(loc.name));
- print(" ExtraLength : %4x%n", loc.elen);
- if (loc.hasZip64)
- print(" *ZIP64*%n");
+ static void printLOC(byte[] loc) {
+ print("%n");
+ print("[Local File Header]%n");
+ print(" Signature : %#010x%n", LOCSIG(loc));
+ if (LOCSIG(loc) != LOCSIG) {
+ print(" Wrong signature!");
+ return;
+ }
+ print(" Version : %#6x [%d.%d]%n",
+ LOCVER(loc), LOCVER(loc) / 10, LOCVER(loc) % 10);
+ print(" Flag : %#6x%n", LOCFLG(loc));
+ print(" Method : %#6x%n", LOCHOW(loc));
+ print(" LastMTime : %#10x [%tc]%n",
+ LOCTIM(loc), dosToJavaTime(LOCTIM(loc)));
+ print(" CRC : %#10x%n", LOCCRC(loc));
+ print(" CSize : %#10x%n", LOCSIZ(loc));
+ print(" Size : %#10x%n", LOCLEN(loc));
+ print(" NameLength : %#6x [%s]%n",
+ LOCNAM(loc), new String(loc, LOCHDR, LOCNAM(loc)));
+ print(" ExtraLength : %#6x%n", LOCEXT(loc));
+ if (LOCEXT(loc) != 0)
+ printExtra(loc, LOCHDR + LOCNAM(loc), LOCEXT(loc));
+ }
+
+ static void printCEN(byte[] cen, int off) {
+ print("[Central Directory Header]%n");
+ print(" Signature : %#010x%n", CENSIG(cen, off));
+ if (CENSIG(cen, off) != CENSIG) {
+ print(" Wrong signature!");
+ return;
+ }
+ print(" VerMadeby : %#6x [%d, %d.%d]%n",
+ CENVEM(cen, off), (CENVEM(cen, off) >> 8),
+ (CENVEM(cen, off) & 0xff) / 10,
+ (CENVEM(cen, off) & 0xff) % 10);
+ print(" VerExtract : %#6x [%d.%d]%n",
+ CENVER(cen, off), CENVER(cen, off) / 10, CENVER(cen, off) % 10);
+ print(" Flag : %#6x%n", CENFLG(cen, off));
+ print(" Method : %#6x%n", CENHOW(cen, off));
+ print(" LastMTime : %#10x [%tc]%n",
+ CENTIM(cen, off), dosToJavaTime(CENTIM(cen, off)));
+ print(" CRC : %#10x%n", CENCRC(cen, off));
+ print(" CSize : %#10x%n", CENSIZ(cen, off));
+ print(" Size : %#10x%n", CENLEN(cen, off));
+ print(" NameLen : %#6x [%s]%n",
+ CENNAM(cen, off), new String(cen, off + CENHDR, CENNAM(cen, off)));
+ print(" ExtraLen : %#6x%n", CENEXT(cen, off));
+ if (CENEXT(cen, off) != 0)
+ printExtra(cen, off + CENHDR + CENNAM(cen, off), CENEXT(cen, off));
+ print(" CommentLen : %#6x%n", CENCOM(cen, off));
+ print(" DiskStart : %#6x%n", CENDSK(cen, off));
+ print(" Attrs : %#6x%n", CENATT(cen, off));
+ print(" AttrsEx : %#10x%n", CENATX(cen, off));
+ print(" LocOff : %#10x%n", CENOFF(cen, off));
+
}
- static void printCEN(Entry cen) {
- print(" Signature : %08x%n", CENSIG);
- print(" VerMadeby : %4x [%d.%d]%n",
- cen.versionMade, cen.versionMade/10, cen.versionMade%10);
- print(" VerExtract : %4x [%d.%d]%n",
- cen.version, cen.version/10, cen.version%10);
- print(" Flag : %4x%n", cen.flag);
- print(" Method : %4x%n", cen.method);
- print(" LastMTime : %8x [%tc]%n",
- cen.mtime, dosToJavaTime(cen.mtime));
- print(" CRC : %8x%n", cen.crc);
- print(" CSize : %8x%n", cen.csize);
- print(" Size : %8x%n", cen.size);
- print(" NameLen : %4x [%s]%n",
- cen.nlen, new String(cen.name));
- print(" ExtraLen : %4x%n", cen.elen);
- print(" CommentLen : %4x%n", cen.clen);
- print(" DiskStart : %4x%n", cen.disk);
- print(" Attrs : %4x%n", cen.attrs);
- print(" AttrsEx : %8x%n", cen.attrsEx);
- print(" LocOff : %8x%n", cen.locoff);
- if (cen.hasZip64)
- print(" *ZIP64*%n");
+ static long locoff(byte[] cen, int pos) {
+ long locoff = CENOFF(cen, pos);
+ if (locoff == ZIP64_MINVAL) { //ZIP64
+ int off = pos + CENHDR + CENNAM(cen, pos);
+ int end = off + CENEXT(cen, pos);
+ while (off + 4 < end) {
+ int tag = SH(cen, off);
+ int sz = SH(cen, off + 2);
+ if (tag != EXTID_ZIP64) {
+ off += 4 + sz;
+ continue;
+ }
+ off += 4;
+ if (CENLEN(cen, pos) == ZIP64_MINVAL)
+ off += 8;
+ if (CENSIZ(cen, pos) == ZIP64_MINVAL)
+ off += 8;
+ return LL(cen, off);
+ }
+ // should never be here
+ }
+ return locoff;
+ }
+
+ static void printExtra(byte[] extra, int off, int len) {
+ int end = off + len;
+ while (off + 4 < end) {
+ int tag = SH(extra, off);
+ int sz = SH(extra, off + 2);
+ print(" [tag=0x%04x, sz=%d, data= ", tag, sz);
+ if (off + sz > end) {
+ print(" Error: Invalid extra data, beyond extra length");
+ break;
+ }
+ off += 4;
+ for (int i = 0; i < sz; i++)
+ print("%02x ", extra[off + i]);
+ print("]%n");
+ switch (tag) {
+ case EXTID_ZIP64 :
+ print(" ->ZIP64: ");
+ int pos = off;
+ while (pos + 8 <= off + sz) {
+ print(" *0x%x ", LL(extra, pos));
+ pos += 8;
+ }
+ print("%n");
+ break;
+ case EXTID_NTFS:
+ print(" ->PKWare NTFS%n");
+ // 4 bytes reserved
+ if (SH(extra, off + 4) != 0x0001 || SH(extra, off + 6) != 24)
+ print(" Error: Invalid NTFS sub-tag or subsz");
+ print(" mtime:%tc%n",
+ winToJavaTime(LL(extra, off + 8)));
+ print(" atime:%tc%n",
+ winToJavaTime(LL(extra, off + 16)));
+ print(" ctime:%tc%n",
+ winToJavaTime(LL(extra, off + 24)));
+ break;
+ case EXTID_EXTT:
+ print(" ->Inof-ZIP Extended Timestamp: flag=%x%n",extra[off]);
+ pos = off + 1 ;
+ while (pos + 4 <= off + sz) {
+ print(" *%tc%n",
+ unixToJavaTime(LG(extra, pos)));
+ pos += 4;
+ }
+ break;
+ default:
+ }
+ off += sz;
+ }
}
}
--- a/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipPath.java Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipPath.java Mon Nov 22 10:18:33 2010 -0500
@@ -32,24 +32,19 @@
package com.sun.nio.zipfs;
import java.io.File;
-import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
-import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.SeekableByteChannel;
import java.nio.file.*;
import java.nio.file.DirectoryStream.Filter;
-import java.nio.file.spi.FileSystemProvider;
import java.nio.file.attribute.BasicFileAttributeView;
import java.nio.file.attribute.FileAttribute;
import java.nio.file.attribute.FileAttributeView;
import java.nio.file.attribute.FileTime;
import java.util.*;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
import static java.nio.file.StandardOpenOption.*;
import static java.nio.file.StandardCopyOption.*;
@@ -599,7 +594,7 @@
}
private static final DirectoryStream.Filter<Path> acceptAllFilter =
- new DirectoryStream.Filter<Path>() {
+ new DirectoryStream.Filter<>() {
@Override public boolean accept(Path entry) { return true; }
};
@@ -625,7 +620,7 @@
// create a matcher and return a filter that uses it.
final PathMatcher matcher = getFileSystem().getPathMatcher("glob:" + glob);
- DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>() {
+ DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<>() {
@Override
public boolean accept(Path entry) {
return matcher.matches(entry.getName());
@@ -758,7 +753,7 @@
@Override
public Iterator<Path> iterator() {
- return new Iterator<Path>() {
+ return new Iterator<>() {
private int i = 0;
@Override
@@ -803,7 +798,7 @@
@Override
public SeekableByteChannel newByteChannel(OpenOption... options)
throws IOException {
- Set<OpenOption> set = new HashSet<OpenOption>(options.length);
+ Set<OpenOption> set = new HashSet<>(options.length);
Collections.addAll(set, options);
return newByteChannel(set);
}
@@ -908,7 +903,7 @@
if (opt == REPLACE_EXISTING)
replaceExisting = true;
else if (opt == COPY_ATTRIBUTES)
- copyAttrs = false;
+ copyAttrs = true;
}
// attributes of source file
ZipFileAttributes zfas = getAttributes();
@@ -951,7 +946,9 @@
BasicFileAttributeView view =
target.getFileAttributeView(BasicFileAttributeView.class);
try {
- view.setTimes(zfas.lastModifiedTime(), null, null);
+ view.setTimes(zfas.lastModifiedTime(),
+ zfas.lastAccessTime(),
+ zfas.creationTime());
} catch (IOException x) {
// rollback?
try {
--- a/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipUtils.java Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipUtils.java Mon Nov 22 10:18:33 2010 -0500
@@ -36,6 +36,7 @@
import java.util.Arrays;
import java.util.Date;
import java.util.regex.PatternSyntaxException;
+import java.util.concurrent.TimeUnit;
/**
*
@@ -48,7 +49,7 @@
* Writes a 16-bit short to the output stream in little-endian byte order.
*/
public static void writeShort(OutputStream os, int v) throws IOException {
- os.write((v >>> 0) & 0xff);
+ os.write(v & 0xff);
os.write((v >>> 8) & 0xff);
}
@@ -56,7 +57,7 @@
* Writes a 32-bit int to the output stream in little-endian byte order.
*/
public static void writeInt(OutputStream os, long v) throws IOException {
- os.write((int)((v >>> 0) & 0xff));
+ os.write((int)(v & 0xff));
os.write((int)((v >>> 8) & 0xff));
os.write((int)((v >>> 16) & 0xff));
os.write((int)((v >>> 24) & 0xff));
@@ -66,7 +67,7 @@
* Writes a 64-bit int to the output stream in little-endian byte order.
*/
public static void writeLong(OutputStream os, long v) throws IOException {
- os.write((int)((v >>> 0) & 0xff));
+ os.write((int)(v & 0xff));
os.write((int)((v >>> 8) & 0xff));
os.write((int)((v >>> 16) & 0xff));
os.write((int)((v >>> 24) & 0xff));
@@ -132,6 +133,27 @@
d.getSeconds() >> 1;
}
+
+ // used to adjust values between Windows and java epoch
+ private static final long WINDOWS_EPOCH_IN_MICROSECONDS = -11644473600000000L;
+ public static final long winToJavaTime(long wtime) {
+ return TimeUnit.MILLISECONDS.convert(
+ wtime / 10 + WINDOWS_EPOCH_IN_MICROSECONDS, TimeUnit.MICROSECONDS);
+ }
+
+ public static final long javaToWinTime(long time) {
+ return (TimeUnit.MICROSECONDS.convert(time, TimeUnit.MILLISECONDS)
+ - WINDOWS_EPOCH_IN_MICROSECONDS) * 10;
+ }
+
+ public static final long unixToJavaTime(long utime) {
+ return TimeUnit.MILLISECONDS.convert(utime, TimeUnit.SECONDS);
+ }
+
+ public static final long javaToUnixTime(long time) {
+ return TimeUnit.SECONDS.convert(time, TimeUnit.MILLISECONDS);
+ }
+
private static final String regexMetaChars = ".^$+{[]|()";
private static final String globMetaChars = "\\*?[{";
private static boolean isRegexMeta(char c) {
--- a/jdk/src/share/lib/security/sunpkcs11-solaris.cfg Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/src/share/lib/security/sunpkcs11-solaris.cfg Mon Nov 22 10:18:33 2010 -0500
@@ -31,5 +31,9 @@
CKM_SHA256_RSA_PKCS
CKM_SHA384_RSA_PKCS
CKM_SHA512_RSA_PKCS
+# the following mechanisms are disabled to ensure backward compatibility (Solaris bug 6545046)
+ CKM_DES_CBC_PAD
+ CKM_DES3_CBC_PAD
+ CKM_AES_CBC_PAD
}
--- a/jdk/src/share/native/java/util/zip/zip_util.c Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/src/share/native/java/util/zip/zip_util.c Mon Nov 22 10:18:33 2010 -0500
@@ -314,7 +314,7 @@
if (pos < 0) {
/* Pretend there are some NUL bytes before start of file */
off = -pos;
- memset(buf, '\0', off);
+ memset(buf, '\0', (size_t)off);
}
if (readFullyAt(zfd, buf + off, sizeof(buf) - off,
@@ -426,7 +426,7 @@
isMetaName(const char *name, int length)
{
const char *s;
- if (length < sizeof("META-INF/") - 1)
+ if (length < (int)sizeof("META-INF/") - 1)
return 0;
for (s = "META-INF/"; *s != '\0'; s++) {
char c = *name++;
@@ -912,7 +912,7 @@
ZFILE zfd = zip->zfd;
char *cen;
if (bufsize > zip->len - cenpos)
- bufsize = zip->len - cenpos;
+ bufsize = (jint)(zip->len - cenpos);
if ((cen = malloc(bufsize)) == NULL) goto Catch;
if (readFullyAt(zfd, cen, bufsize, cenpos) == -1) goto Catch;
censize = CENSIZE(cen);
@@ -1256,6 +1256,9 @@
* file had been previously locked with ZIP_Lock(). Returns the
* number of bytes read, or -1 if an error occurred. If zip->msg != 0
* then a zip error occurred and zip->msg contains the error text.
+ *
+ * The current implementation does not support reading an entry that
+ * has the size bigger than 2**32 bytes in ONE invocation.
*/
jint
ZIP_Read(jzfile *zip, jzentry *entry, jlong pos, void *buf, jint len)
@@ -1276,7 +1279,7 @@
if (len <= 0)
return 0;
if (len > entry_size - pos)
- len = entry_size - pos;
+ len = (jint)(entry_size - pos);
/* Get file offset to start reading data */
start = ZIP_GetEntryDataOffset(zip, entry);
@@ -1306,6 +1309,9 @@
* from ZIP/JAR files specified in the class path. It is defined here
* so that it can be dynamically loaded by the runtime if the zip library
* is found.
+ *
+ * The current implementation does not support reading an entry that
+ * has the size bigger than 2**32 bytes in ONE invocation.
*/
jboolean
InflateFully(jzfile *zip, jzentry *entry, void *buf, char **msg)
@@ -1314,7 +1320,6 @@
char tmp[BUF_SIZE];
jlong pos = 0;
jlong count = entry->csize;
- jboolean status;
*msg = 0; /* Reset error message */
@@ -1330,10 +1335,10 @@
}
strm.next_out = buf;
- strm.avail_out = entry->size;
+ strm.avail_out = (uInt)entry->size;
while (count > 0) {
- jint n = count > (jlong)sizeof(tmp) ? (jint)sizeof(tmp) : count;
+ jint n = count > (jlong)sizeof(tmp) ? (jint)sizeof(tmp) : (jint)count;
ZIP_Lock(zip);
n = ZIP_Read(zip, entry, pos, tmp, n);
ZIP_Unlock(zip);
@@ -1368,12 +1373,16 @@
return JNI_TRUE;
}
+/*
+ * The current implementation does not support reading an entry that
+ * has the size bigger than 2**32 bytes in ONE invocation.
+ */
jzentry * JNICALL
ZIP_FindEntry(jzfile *zip, char *name, jint *sizeP, jint *nameLenP)
{
jzentry *entry = ZIP_GetEntry(zip, name, 0);
if (entry) {
- *sizeP = entry->size;
+ *sizeP = (jint)entry->size;
*nameLenP = strlen(entry->name);
}
return entry;
--- a/jdk/src/share/native/java/util/zip/zlib-1.2.3/compress.c Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/src/share/native/java/util/zip/zlib-1.2.3/compress.c Mon Nov 22 10:18:33 2010 -0500
@@ -75,7 +75,7 @@
deflateEnd(&stream);
return err == Z_OK ? Z_BUF_ERROR : err;
}
- *destLen = stream.total_out;
+ *destLen = (uLong)stream.total_out;
err = deflateEnd(&stream);
return err;
--- a/jdk/src/share/native/java/util/zip/zlib-1.2.3/uncompr.c Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/src/share/native/java/util/zip/zlib-1.2.3/uncompr.c Mon Nov 22 10:18:33 2010 -0500
@@ -78,7 +78,7 @@
return Z_DATA_ERROR;
return err;
}
- *destLen = stream.total_out;
+ *destLen = (uLong)stream.total_out;
err = inflateEnd(&stream);
return err;
--- a/jdk/test/ProblemList.txt Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/test/ProblemList.txt Mon Nov 22 10:18:33 2010 -0500
@@ -734,10 +734,6 @@
# Problems on windows, jmap.exe hangs? (these run jmap), fails on Solaris 10 x86
java/util/concurrent/locks/Lock/TimedAcquireLeak.java generic-all
-# Solaris sparc client, some failures, "1 not equal to 3"?
-# also Linux problems with samevm mode, -server linux i586? 1 not equal to 3?
-java/util/concurrent/Executors/AutoShutdown.java generic-all
-
# Fails on solaris-sparc -server (Set not equal to copy. 1)
java/util/EnumSet/EnumSetBash.java solaris-sparc
--- a/jdk/test/com/sun/net/httpserver/Test.java Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/test/com/sun/net/httpserver/Test.java Mon Nov 22 10:18:33 2010 -0500
@@ -22,8 +22,20 @@
*/
import com.sun.net.httpserver.*;
+import java.util.logging.*;
public class Test {
+
+ static Logger logger;
+
+ static void enableLogging() {
+ logger = Logger.getLogger("com.sun.net.httpserver");
+ Handler h = new ConsoleHandler();
+ h.setLevel(Level.ALL);
+ logger.setLevel(Level.ALL);
+ logger.addHandler(h);
+ }
+
static void delay () {
try {
Thread.sleep (1000);
--- a/jdk/test/com/sun/net/httpserver/Test1.java Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/test/com/sun/net/httpserver/Test1.java Mon Nov 22 10:18:33 2010 -0500
@@ -25,6 +25,7 @@
* @test
* @bug 6270015
* @run main/othervm Test1
+ * @run main/othervm -Dsun.net.httpserver.maxReqTime=10 Test1
* @summary Light weight HTTP server
*/
--- a/jdk/test/com/sun/net/httpserver/Test13.java Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/test/com/sun/net/httpserver/Test13.java Mon Nov 22 10:18:33 2010 -0500
@@ -31,6 +31,7 @@
import com.sun.net.httpserver.*;
import java.util.concurrent.*;
+import java.util.logging.*;
import java.io.*;
import java.net.*;
@@ -45,12 +46,19 @@
static SSLContext ctx;
+ final static int NUM = 32; // was 32
+
static boolean fail = false;
public static void main (String[] args) throws Exception {
HttpServer s1 = null;
HttpsServer s2 = null;
ExecutorService executor=null;
+ Logger l = Logger.getLogger ("com.sun.net.httpserver");
+ Handler ha = new ConsoleHandler();
+ ha.setLevel(Level.ALL);
+ l.setLevel(Level.ALL);
+ l.addHandler(ha);
try {
String root = System.getProperty ("test.src")+ "/docs";
System.out.print ("Test13: ");
@@ -70,10 +78,10 @@
int port = s1.getAddress().getPort();
int httpsport = s2.getAddress().getPort();
- Runner r[] = new Runner[64];
- for (int i=0; i<32; i++) {
+ Runner r[] = new Runner[NUM*2];
+ for (int i=0; i<NUM; i++) {
r[i] = new Runner (true, "http", root+"/test1", port, "smallfile.txt", 23);
- r[i+32] = new Runner (true, "https", root+"/test1", port, "smallfile.txt", 23);
+ r[i+NUM] = new Runner (true, "https", root+"/test1", httpsport, "smallfile.txt", 23);
}
start (r);
join (r);
@@ -91,6 +99,7 @@
static void start (Runner[] x) {
for (int i=0; i<x.length; i++) {
+ if (x[i] != null)
x[i].start();
}
}
@@ -98,6 +107,7 @@
static void join (Runner[] x) {
for (int i=0; i<x.length; i++) {
try {
+ if (x[i] != null)
x[i].join();
} catch (InterruptedException e) {}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/net/httpserver/bugs/6725892/Test.java Mon Nov 22 10:18:33 2010 -0500
@@ -0,0 +1,266 @@
+/*
+ * Copyright (c) 2005, 2006, 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.
+ *
+ * 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.
+ */
+
+/**
+ * @test
+ * @bug 6725892
+ * @run main/othervm -Dsun.net.httpserver.maxReqTime=2 Test
+ * @summary
+ */
+
+import com.sun.net.httpserver.*;
+
+import java.util.concurrent.*;
+import java.util.logging.*;
+import java.io.*;
+import java.net.*;
+import javax.net.ssl.*;
+
+public class Test {
+
+ static HttpServer s1;
+ static int port;
+ static URL url;
+ static final String RESPONSE_BODY = "response";
+ static boolean failed = false;
+
+ static class Handler implements HttpHandler {
+
+ public void handle (HttpExchange t)
+ throws IOException
+ {
+ InputStream is = t.getRequestBody();
+ InetSocketAddress rem = t.getRemoteAddress();
+ System.out.println ("Request from: " + rem);
+ while (is.read () != -1) ;
+ is.close();
+ String requrl = t.getRequestURI().toString();
+ OutputStream os = t.getResponseBody();
+ t.sendResponseHeaders (200, RESPONSE_BODY.length());
+ os.write (RESPONSE_BODY.getBytes());
+ t.close();
+ }
+ }
+
+ public static void main (String[] args) throws Exception {
+
+ ExecutorService exec = Executors.newCachedThreadPool();
+
+ try {
+ InetSocketAddress addr = new InetSocketAddress (0);
+ s1 = HttpServer.create (addr, 0);
+ HttpHandler h = new Handler ();
+ HttpContext c1 = s1.createContext ("/", h);
+ s1.setExecutor(exec);
+ s1.start();
+
+ port = s1.getAddress().getPort();
+ System.out.println ("Server on port " + port);
+ url = new URL ("http://127.0.0.1:"+port+"/foo");
+ test1();
+ test2();
+ test3();
+ Thread.sleep (2000);
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.out.println ("FAIL");
+ throw new RuntimeException ();
+ } finally {
+ s1.stop(0);
+ System.out.println ("After Shutdown");
+ exec.shutdown();
+ }
+ }
+
+ // open TCP connection without sending anything. Check server closes it.
+
+ static void test1() throws IOException {
+ failed = false;
+ Socket s = new Socket ("127.0.0.1", port);
+ InputStream is = s.getInputStream();
+ // server should close connection after 2 seconds. We wait up to 10
+ s.setSoTimeout (10000);
+ try {
+ is.read();
+ } catch (SocketTimeoutException e) {
+ failed = true;
+ }
+ s.close();
+ if (failed) {
+ System.out.println ("test1: FAIL");
+ throw new RuntimeException ();
+ } else {
+ System.out.println ("test1: OK");
+ }
+ }
+
+ // send request and don't read response. Check server closes connection
+
+ static void test2() throws IOException {
+ HttpURLConnection urlc = (HttpURLConnection) url.openConnection();
+ urlc.setReadTimeout (20 * 1000);
+ InputStream is = urlc.getInputStream();
+ // we won't read response and check if it times out
+ // on server. If it timesout at client then there is a problem
+ try {
+ Thread.sleep (10 * 1000);
+ while (is.read() != -1) ;
+ } catch (InterruptedException e) {
+ System.out.println (e);
+ System.out.println ("test2: FAIL");
+ throw new RuntimeException ("unexpected error");
+ } catch (SocketTimeoutException e1) {
+ System.out.println (e1);
+ System.out.println ("test2: FAIL");
+ throw new RuntimeException ("client timedout");
+ } finally {
+ is.close();
+ }
+ System.out.println ("test2: OK");
+ }
+
+ // same as test2, but repeated with multiple connections
+ // including a number of valid request/responses
+
+ // Worker: a thread opens a connection to the server in one of three modes.
+ // NORMAL - sends a request, waits for response, and checks valid response
+ // REQUEST - sends a partial request, and blocks, to see if
+ // server closes the connection.
+ // RESPONSE - sends a request, partially reads response and blocks,
+ // to see if server closes the connection.
+
+ static class Worker extends Thread {
+ CountDownLatch latch;
+ Mode mode;
+
+ enum Mode {
+ REQUEST, // block during sending of request
+ RESPONSE, // block during reading of response
+ NORMAL // don't block
+ };
+
+ Worker (CountDownLatch latch, Mode mode) {
+ this.latch = latch;
+ this.mode = mode;
+ }
+
+ void fail(String msg) {
+ System.out.println (msg);
+ failed = true;
+ }
+
+ public void run () {
+ HttpURLConnection urlc;
+ InputStream is = null;
+
+ try {
+ urlc = (HttpURLConnection) url.openConnection();
+ urlc.setReadTimeout (20 * 1000);
+ urlc.setDoOutput(true);
+ } catch (IOException e) {
+ fail("Worker: failed to connect to server");
+ latch.countDown();
+ return;
+ }
+ try {
+ OutputStream os = urlc.getOutputStream();
+ os.write ("foo".getBytes());
+ if (mode == Mode.REQUEST) {
+ Thread.sleep (3000);
+ }
+ os.close();
+ is = urlc.getInputStream();
+ if (mode == Mode.RESPONSE) {
+ Thread.sleep (3000);
+ }
+ if (!checkResponse (is, RESPONSE_BODY)) {
+ fail ("Worker: response");
+ }
+ is.close();
+ return;
+ } catch (InterruptedException e0) {
+ fail("Worker: timedout");
+ } catch (SocketTimeoutException e1) {
+ fail("Worker: timedout");
+ } catch (IOException e2) {
+ switch (mode) {
+ case NORMAL:
+ fail ("Worker: " + e2.getMessage());
+ break;
+ case RESPONSE:
+ if (is == null) {
+ fail ("Worker: " + e2.getMessage());
+ break;
+ }
+ // default: is ok
+ }
+ } finally {
+ latch.countDown();
+ }
+ }
+ }
+
+ static final int NUM = 20;
+
+ static void test3() throws Exception {
+ failed = false;
+ CountDownLatch l = new CountDownLatch (NUM*3);
+ Worker[] workers = new Worker[NUM*3];
+ for (int i=0; i<NUM; i++) {
+ workers[i*3] = new Worker (l, Worker.Mode.NORMAL);
+ workers[i*3+1] = new Worker (l, Worker.Mode.REQUEST);
+ workers[i*3+2] = new Worker (l, Worker.Mode.RESPONSE);
+ workers[i*3].start();
+ workers[i*3+1].start();
+ workers[i*3+2].start();
+ }
+ l.await();
+ for (int i=0; i<NUM*3; i++) {
+ workers[i].join();
+ }
+ if (failed) {
+ throw new RuntimeException ("test3: failed");
+ }
+ System.out.println ("test3: OK");
+ }
+
+ static boolean checkResponse (InputStream is, String resp) {
+ try {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ byte[] buf = new byte [64];
+ int c;
+ while ((c=is.read(buf)) != -1) {
+ bos.write (buf, 0, c);
+ }
+ bos.close();
+ if (!bos.toString().equals(resp)) {
+ System.out.println ("Wrong response: " + bos.toString());
+ return false;
+ }
+ } catch (IOException e) {
+ System.out.println (e);
+ return false;
+ }
+ return true;
+ }
+}
--- a/jdk/test/com/sun/net/httpserver/bugs/B6401598.java Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/test/com/sun/net/httpserver/bugs/B6401598.java Mon Nov 22 10:18:33 2010 -0500
@@ -83,7 +83,7 @@
server = HttpServer.create(new InetSocketAddress(0), 400);
server.createContext("/server/", new MyHandler());
exec = Executors.newFixedThreadPool(3);
- server.setExecutor(null);
+ server.setExecutor(exec);
port = server.getAddress().getPort();
server.start();
--- a/jdk/test/demo/zipfs/ZipFSTester.java Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/test/demo/zipfs/ZipFSTester.java Mon Nov 22 10:18:33 2010 -0500
@@ -64,7 +64,6 @@
fs0.close(); // sync to file
fs = newZipFileSystem(tmpfsPath, new HashMap<String, Object>());
-
try {
// prepare a src
Path src = getTempPath();
@@ -146,13 +145,6 @@
Path fs2Path = getTempPath();
Path fs3Path = getTempPath();
- if (fs1Path.exists())
- fs1Path.delete();
- if (fs2Path.exists())
- fs2Path.delete();
- if (fs3Path.exists())
- fs3Path.delete();
-
// create a new filesystem, copy everything from fs
Map<String, Object> env = new HashMap<String, Object>();
env.put("createNew", true);
@@ -280,7 +272,6 @@
walk(fs4.getPath("/"));
System.out.println("closing: fs4");
fs4.close();
-
System.out.printf("failed=%d%n", failed);
fs1Path.delete();
@@ -426,6 +417,8 @@
}
private static void mkdirs(Path path) throws IOException {
+ if (path.exists())
+ return;
path = path.toAbsolutePath();
Path parent = path.getParent();
if (parent != null) {
--- a/jdk/test/java/nio/Buffer/StringCharBufferSliceTest.java Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/test/java/nio/Buffer/StringCharBufferSliceTest.java Mon Nov 22 10:18:33 2010 -0500
@@ -22,7 +22,7 @@
*/
/* @test
- * @bug 4997655
+ * @bug 4997655 7000913
* @summary (bf) CharBuffer.slice() on wrapped CharSequence results in wrong position
*/
@@ -76,11 +76,26 @@
}
System.out.println(
+ ">>> StringCharBufferSliceTest-main: testing slice with result of slice");
+ buff.position(0);
+ buff.limit(buff.capacity());
+ slice = buff.slice();
+ for (int i=0; i<4; i++) {
+ slice.position(i);
+ CharBuffer nextSlice = slice.slice();
+ if (nextSlice.position() != 0)
+ throw new RuntimeException("New buffer's position should be zero");
+ if (!nextSlice.equals(slice))
+ throw new RuntimeException("New buffer should be equal");
+ slice = nextSlice;
+ }
+
+ System.out.println(
">>> StringCharBufferSliceTest-main: testing toString.");
buff.position(4);
buff.limit(7);
slice = buff.slice();
- if (! slice.toString().equals("tes")) {
+ if (!slice.toString().equals("tes")) {
throw new RuntimeException("bad toString() after slice(): " + slice.toString());
}
@@ -104,6 +119,7 @@
|| dupe.charAt(2) != 's' || dupe.charAt(3) != 't') {
throw new RuntimeException("bad duplicate() after slice(): '" + dupe + "'");
}
+
System.out.println(">>> StringCharBufferSliceTest-main: done!");
}
--- a/jdk/test/java/security/Security/ClassLoaderDeadlock/ClassLoaderDeadlock.sh Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/test/java/security/Security/ClassLoaderDeadlock/ClassLoaderDeadlock.sh Mon Nov 22 10:18:33 2010 -0500
@@ -68,11 +68,10 @@
;;
esac
-# remove old class files
cd ${TESTCLASSES}${FILESEP}
-rm -f ClassLoaderDeadlock.class
-rm -rf provider
-mkdir provider
+if [ ! -d provider ] ; then
+ mkdir provider
+fi
# compile the test program
${TESTJAVA}${FILESEP}bin${FILESEP}javac \
@@ -88,4 +87,11 @@
-classpath "${TESTCLASSES}${PATHSEP}${TESTSRC}${FILESEP}Deadlock.jar" \
ClassLoaderDeadlock
-exit $?
+STATUS=$?
+
+# clean up
+rm -f 'ClassLoaderDeadlock.class' 'ClassLoaderDeadlock$1.class' \
+'ClassLoaderDeadlock$DelayClassLoader.class' \
+provider${FILESEP}HashProvider.class
+
+exit $STATUS
--- a/jdk/test/java/security/Security/ClassLoaderDeadlock/Deadlock2.sh Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/test/java/security/Security/ClassLoaderDeadlock/Deadlock2.sh Mon Nov 22 10:18:33 2010 -0500
@@ -26,7 +26,6 @@
# @test
# @bug 6440846
-# @ignore until 6203816 is dealt with.
# @summary make sure we do not deadlock between ExtClassLoader and AppClassLoader
# @author Valerie Peng
# @run shell/timeout=20 Deadlock2.sh
@@ -71,11 +70,14 @@
# remove old class files
cd ${TESTCLASSES}
-rm -f Deadlock2*.class
if [ -d testlib ] ; then
rm -rf testlib
fi
-cp -r ${TESTJAVA}${FILESEP}lib${FILESEP}ext testlib
+if [ -d ${TESTJAVA}${FILESEP}lib${FILESEP}ext ] ; then
+ cp -r ${TESTJAVA}${FILESEP}lib${FILESEP}ext testlib
+else
+ cp -r ${TESTJAVA}${FILESEP}jre${FILESEP}lib${FILESEP}ext testlib
+fi
# compile and package the test program
${TESTJAVA}${FILESEP}bin${FILESEP}javac \
--- a/jdk/test/java/util/concurrent/Executors/AutoShutdown.java Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/test/java/util/concurrent/Executors/AutoShutdown.java Mon Nov 22 10:18:33 2010 -0500
@@ -32,21 +32,40 @@
import java.util.*;
import java.util.concurrent.*;
import static java.util.concurrent.Executors.*;
+import java.util.concurrent.Phaser;
public class AutoShutdown {
- private static void waitForFinalizersToRun() throws Throwable {
- System.gc(); System.runFinalization(); Thread.sleep(10);
- System.gc(); System.runFinalization(); Thread.sleep(10);
+ private static void waitForFinalizersToRun() {
+ for (int i = 0; i < 2; i++)
+ tryWaitForFinalizersToRun();
+ }
+
+ private static void tryWaitForFinalizersToRun() {
+ System.gc();
+ final CountDownLatch fin = new CountDownLatch(1);
+ new Object() { protected void finalize() { fin.countDown(); }};
+ System.gc();
+ try { fin.await(); }
+ catch (InterruptedException ie) { throw new Error(ie); }
}
private static void realMain(String[] args) throws Throwable {
- Runnable trivialRunnable = new Runnable() { public void run() {}};
+ final Phaser phaser = new Phaser(3);
+ Runnable trivialRunnable = new Runnable() {
+ public void run() {
+ phaser.arriveAndAwaitAdvance();
+ }
+ };
int count0 = Thread.activeCount();
- newSingleThreadExecutor().execute(trivialRunnable);
- newSingleThreadExecutor(defaultThreadFactory()).execute(trivialRunnable);
- Thread.sleep(100);
+ Executor e1 = newSingleThreadExecutor();
+ Executor e2 = newSingleThreadExecutor(defaultThreadFactory());
+ e1.execute(trivialRunnable);
+ e2.execute(trivialRunnable);
+ phaser.arriveAndAwaitAdvance();
equal(Thread.activeCount(), count0 + 2);
- waitForFinalizersToRun();
+ e1 = e2 = null;
+ for (int i = 0; i < 10 && Thread.activeCount() > count0; i++)
+ tryWaitForFinalizersToRun();
equal(Thread.activeCount(), count0);
}
Binary file jdk/test/java/util/jar/JarInputStream/BadSignedJar.jar has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/jar/JarInputStream/TestIndexedJarWithBadSignature.java Mon Nov 22 10:18:33 2010 -0500
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2010, 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 6544278
+ * @summary Confirm the JarInputStream throws the SecurityException when
+ * verifying an indexed jar file with corrupted signature
+ */
+
+import java.io.IOException;
+import java.io.FileInputStream;
+import java.util.jar.JarEntry;
+import java.util.jar.JarInputStream;
+
+public class TestIndexedJarWithBadSignature {
+
+ public static void main(String...args) throws Throwable {
+ try (JarInputStream jis = new JarInputStream(
+ new FileInputStream(System.getProperty("tst.src", ".") +
+ System.getProperty("file.separator") +
+ "BadSignedJar.jar")))
+ {
+ JarEntry je1 = jis.getNextJarEntry();
+ while(je1!=null){
+ System.out.println("Jar Entry1==>"+je1.getName());
+ je1 = jis.getNextJarEntry(); // This should throw Security Exception
+ }
+ throw new RuntimeException(
+ "Test Failed:Security Exception not being thrown");
+ } catch (IOException ie){
+ ie.printStackTrace();
+ } catch (SecurityException e) {
+ System.out.println("Test passed: Security Exception thrown as expected");
+ }
+ }
+}
--- a/jdk/test/sun/nio/cs/CheckHistoricalNames.java Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/test/sun/nio/cs/CheckHistoricalNames.java Mon Nov 22 10:18:33 2010 -0500
@@ -22,7 +22,7 @@
*/
/* @test
- @bug 4513767 4961027
+ @bug 4513767 4961027 6217210
@summary Checks canonical names match between old and (NIO) core charsets
*/
import java.io.InputStreamReader;
@@ -154,6 +154,7 @@
checkHistoricalName("Cp500");
checkHistoricalName("Cp737");
checkHistoricalName("Cp775");
+ checkHistoricalName("Cp833");
checkHistoricalName("Cp838");
checkHistoricalName("Cp850");
checkHistoricalName("Cp852");
@@ -228,6 +229,7 @@
checkMappedName("IBM856", "Cp856");
checkMappedName("IBM857", "Cp857");
checkMappedName("IBM00858", "Cp858");
+ checkMappedName("IBM833", "Cp833");
checkMappedName("IBM860", "Cp860");
checkMappedName("IBM861", "Cp861");
checkMappedName("IBM862", "Cp862");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/krb5/UnknownCCEntry.java Mon Nov 22 10:18:33 2010 -0500
@@ -0,0 +1,219 @@
+/*
+ * Copyright (c) 2010, 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.
+ *
+ * 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.
+ */
+/*
+ * @test
+ * @bug 6979329
+ * @summary CCacheInputStream fails to read ticket cache files from Kerberos 1.8.1
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import sun.security.krb5.internal.ccache.CCacheInputStream;
+import sun.security.krb5.internal.ccache.CredentialsCache;
+
+public class UnknownCCEntry {
+ public static void main(String[] args) throws Exception {
+ // This is a ccache file generated on a test machine:
+ // Default principal: dummy@MAX.LOCAL
+ // Valid starting Expires Service principal
+ // 08/24/10 10:37:28 08/25/10 10:37:28 krbtgt/MAX.LOCAL@MAX.LOCAL
+ // Flags: FI, Etype (skey, tkt): AES-128 CTS mode with 96-bit SHA-1
+ // HMAC, AES-256 CTS mode with 96-bit SHA-1 HMAC
+ byte[] krb5cc = {
+ (byte)0x05, (byte)0x04, (byte)0x00, (byte)0x0C,
+ (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x08,
+ (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFA,
+ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01,
+ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01,
+ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x09,
+ (byte)0x4D, (byte)0x41, (byte)0x58, (byte)0x2E,
+ (byte)0x4C, (byte)0x4F, (byte)0x43, (byte)0x41,
+ (byte)0x4C, (byte)0x00, (byte)0x00, (byte)0x00,
+ (byte)0x05, (byte)0x64, (byte)0x75, (byte)0x6D,
+ (byte)0x6D, (byte)0x79, (byte)0x00, (byte)0x00,
+ (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x00,
+ (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x00,
+ (byte)0x00, (byte)0x09, (byte)0x4D, (byte)0x41,
+ (byte)0x58, (byte)0x2E, (byte)0x4C, (byte)0x4F,
+ (byte)0x43, (byte)0x41, (byte)0x4C, (byte)0x00,
+ (byte)0x00, (byte)0x00, (byte)0x05, (byte)0x64,
+ (byte)0x75, (byte)0x6D, (byte)0x6D, (byte)0x79,
+ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x02,
+ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x09,
+ (byte)0x4D, (byte)0x41, (byte)0x58, (byte)0x2E,
+ (byte)0x4C, (byte)0x4F, (byte)0x43, (byte)0x41,
+ (byte)0x4C, (byte)0x00, (byte)0x00, (byte)0x00,
+ (byte)0x06, (byte)0x6B, (byte)0x72, (byte)0x62,
+ (byte)0x74, (byte)0x67, (byte)0x74, (byte)0x00,
+ (byte)0x00, (byte)0x00, (byte)0x09, (byte)0x4D,
+ (byte)0x41, (byte)0x58, (byte)0x2E, (byte)0x4C,
+ (byte)0x4F, (byte)0x43, (byte)0x41, (byte)0x4C,
+ (byte)0x00, (byte)0x11, (byte)0x00, (byte)0x00,
+ (byte)0x00, (byte)0x10, (byte)0x92, (byte)0x1D,
+ (byte)0x1A, (byte)0x0C, (byte)0x7F, (byte)0xB8,
+ (byte)0x01, (byte)0x2E, (byte)0xC9, (byte)0xF5,
+ (byte)0x7B, (byte)0x92, (byte)0x81, (byte)0xCA,
+ (byte)0x49, (byte)0xC5, (byte)0x4C, (byte)0x73,
+ (byte)0x30, (byte)0x68, (byte)0x4C, (byte)0x73,
+ (byte)0x30, (byte)0x68, (byte)0x4C, (byte)0x74,
+ (byte)0x81, (byte)0xE8, (byte)0x00, (byte)0x00,
+ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x40,
+ (byte)0x41, (byte)0x00, (byte)0x00, (byte)0x00,
+ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+ (byte)0x00, (byte)0x01, (byte)0x29, (byte)0x61,
+ (byte)0x82, (byte)0x01, (byte)0x25, (byte)0x30,
+ (byte)0x82, (byte)0x01, (byte)0x21, (byte)0xA0,
+ (byte)0x03, (byte)0x02, (byte)0x01, (byte)0x05,
+ (byte)0xA1, (byte)0x0B, (byte)0x1B, (byte)0x09,
+ (byte)0x4D, (byte)0x41, (byte)0x58, (byte)0x2E,
+ (byte)0x4C, (byte)0x4F, (byte)0x43, (byte)0x41,
+ (byte)0x4C, (byte)0xA2, (byte)0x1E, (byte)0x30,
+ (byte)0x1C, (byte)0xA0, (byte)0x03, (byte)0x02,
+ (byte)0x01, (byte)0x00, (byte)0xA1, (byte)0x15,
+ (byte)0x30, (byte)0x13, (byte)0x1B, (byte)0x06,
+ (byte)0x6B, (byte)0x72, (byte)0x62, (byte)0x74,
+ (byte)0x67, (byte)0x74, (byte)0x1B, (byte)0x09,
+ (byte)0x4D, (byte)0x41, (byte)0x58, (byte)0x2E,
+ (byte)0x4C, (byte)0x4F, (byte)0x43, (byte)0x41,
+ (byte)0x4C, (byte)0xA3, (byte)0x81, (byte)0xEC,
+ (byte)0x30, (byte)0x81, (byte)0xE9, (byte)0xA0,
+ (byte)0x03, (byte)0x02, (byte)0x01, (byte)0x12,
+ (byte)0xA1, (byte)0x03, (byte)0x02, (byte)0x01,
+ (byte)0x01, (byte)0xA2, (byte)0x81, (byte)0xDC,
+ (byte)0x04, (byte)0x81, (byte)0xD9, (byte)0xFB,
+ (byte)0x4B, (byte)0xD2, (byte)0x55, (byte)0x33,
+ (byte)0xA8, (byte)0x1A, (byte)0xE6, (byte)0xB5,
+ (byte)0x3D, (byte)0x67, (byte)0x46, (byte)0x69,
+ (byte)0x6F, (byte)0x0A, (byte)0x64, (byte)0xE7,
+ (byte)0x3D, (byte)0xEF, (byte)0x22, (byte)0xBE,
+ (byte)0x81, (byte)0x32, (byte)0xF3, (byte)0x72,
+ (byte)0xB4, (byte)0x50, (byte)0xE3, (byte)0xC3,
+ (byte)0xDB, (byte)0xE5, (byte)0x38, (byte)0x3C,
+ (byte)0x60, (byte)0xC8, (byte)0x08, (byte)0x53,
+ (byte)0x44, (byte)0x6F, (byte)0xDF, (byte)0x55,
+ (byte)0x67, (byte)0x32, (byte)0x02, (byte)0xDD,
+ (byte)0x6B, (byte)0xFB, (byte)0x23, (byte)0x1A,
+ (byte)0x88, (byte)0x71, (byte)0xE0, (byte)0xF8,
+ (byte)0xBB, (byte)0x51, (byte)0x1E, (byte)0x76,
+ (byte)0xC9, (byte)0x1F, (byte)0x45, (byte)0x9B,
+ (byte)0xA0, (byte)0xA5, (byte)0x61, (byte)0x45,
+ (byte)0x9E, (byte)0x65, (byte)0xB8, (byte)0xD6,
+ (byte)0x0E, (byte)0x3C, (byte)0xD9, (byte)0x56,
+ (byte)0xD6, (byte)0xA6, (byte)0xDD, (byte)0x36,
+ (byte)0x21, (byte)0x25, (byte)0x0E, (byte)0xE6,
+ (byte)0xAD, (byte)0xA0, (byte)0x3A, (byte)0x9B,
+ (byte)0x21, (byte)0x87, (byte)0xE2, (byte)0xAF,
+ (byte)0x3A, (byte)0xEF, (byte)0x75, (byte)0x85,
+ (byte)0xA8, (byte)0xD7, (byte)0xE5, (byte)0x46,
+ (byte)0xD8, (byte)0x5C, (byte)0x17, (byte)0x4E,
+ (byte)0x64, (byte)0x51, (byte)0xDB, (byte)0x38,
+ (byte)0x8E, (byte)0x6B, (byte)0x02, (byte)0x05,
+ (byte)0x46, (byte)0x77, (byte)0xD0, (byte)0x75,
+ (byte)0x8A, (byte)0xE0, (byte)0x42, (byte)0x5E,
+ (byte)0x8D, (byte)0x49, (byte)0x86, (byte)0xDE,
+ (byte)0x6C, (byte)0xBC, (byte)0xAF, (byte)0x10,
+ (byte)0x9A, (byte)0x97, (byte)0x64, (byte)0xA6,
+ (byte)0xBD, (byte)0xDB, (byte)0x01, (byte)0x40,
+ (byte)0xA9, (byte)0x3D, (byte)0x74, (byte)0x99,
+ (byte)0xDC, (byte)0x63, (byte)0x34, (byte)0x40,
+ (byte)0x31, (byte)0x57, (byte)0xC7, (byte)0x70,
+ (byte)0x9F, (byte)0xCE, (byte)0xC6, (byte)0x7B,
+ (byte)0x00, (byte)0x5B, (byte)0x02, (byte)0x5C,
+ (byte)0xC7, (byte)0x81, (byte)0x40, (byte)0x4D,
+ (byte)0xA7, (byte)0xB1, (byte)0xD2, (byte)0xEA,
+ (byte)0x8E, (byte)0xEC, (byte)0xA0, (byte)0xB3,
+ (byte)0x03, (byte)0x29, (byte)0xB8, (byte)0x44,
+ (byte)0xD7, (byte)0xA1, (byte)0x2B, (byte)0x37,
+ (byte)0x9D, (byte)0x19, (byte)0x11, (byte)0x1D,
+ (byte)0x58, (byte)0xE8, (byte)0x06, (byte)0xE7,
+ (byte)0x06, (byte)0xE3, (byte)0xF7, (byte)0xEF,
+ (byte)0x05, (byte)0xA9, (byte)0x05, (byte)0x93,
+ (byte)0x42, (byte)0x94, (byte)0x5A, (byte)0xD6,
+ (byte)0xA0, (byte)0x24, (byte)0x3A, (byte)0x52,
+ (byte)0x92, (byte)0xA3, (byte)0x79, (byte)0x98,
+ (byte)0x3C, (byte)0x68, (byte)0x55, (byte)0x1B,
+ (byte)0x6A, (byte)0xC5, (byte)0x83, (byte)0x89,
+ (byte)0x5A, (byte)0x79, (byte)0x5C, (byte)0x52,
+ (byte)0xBA, (byte)0xB8, (byte)0xF7, (byte)0x72,
+ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01,
+ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01,
+ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x09,
+ (byte)0x4D, (byte)0x41, (byte)0x58, (byte)0x2E,
+ (byte)0x4C, (byte)0x4F, (byte)0x43, (byte)0x41,
+ (byte)0x4C, (byte)0x00, (byte)0x00, (byte)0x00,
+ (byte)0x05, (byte)0x64, (byte)0x75, (byte)0x6D,
+ (byte)0x6D, (byte)0x79, (byte)0x00, (byte)0x00,
+ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+ (byte)0x00, (byte)0x03, (byte)0x00, (byte)0x00,
+ (byte)0x00, (byte)0x0C, (byte)0x58, (byte)0x2D,
+ (byte)0x43, (byte)0x41, (byte)0x43, (byte)0x48,
+ (byte)0x45, (byte)0x43, (byte)0x4F, (byte)0x4E,
+ (byte)0x46, (byte)0x3A, (byte)0x00, (byte)0x00,
+ (byte)0x00, (byte)0x15, (byte)0x6B, (byte)0x72,
+ (byte)0x62, (byte)0x35, (byte)0x5F, (byte)0x63,
+ (byte)0x63, (byte)0x61, (byte)0x63, (byte)0x68,
+ (byte)0x65, (byte)0x5F, (byte)0x63, (byte)0x6F,
+ (byte)0x6E, (byte)0x66, (byte)0x5F, (byte)0x64,
+ (byte)0x61, (byte)0x74, (byte)0x61, (byte)0x00,
+ (byte)0x00, (byte)0x00, (byte)0x0A, (byte)0x66,
+ (byte)0x61, (byte)0x73, (byte)0x74, (byte)0x5F,
+ (byte)0x61, (byte)0x76, (byte)0x61, (byte)0x69,
+ (byte)0x6C, (byte)0x00, (byte)0x00, (byte)0x00,
+ (byte)0x1A, (byte)0x6B, (byte)0x72, (byte)0x62,
+ (byte)0x74, (byte)0x67, (byte)0x74, (byte)0x2F,
+ (byte)0x4D, (byte)0x41, (byte)0x58, (byte)0x2E,
+ (byte)0x4C, (byte)0x4F, (byte)0x43, (byte)0x41,
+ (byte)0x4C, (byte)0x40, (byte)0x4D, (byte)0x41,
+ (byte)0x58, (byte)0x2E, (byte)0x4C, (byte)0x4F,
+ (byte)0x43, (byte)0x41, (byte)0x4C, (byte)0x00,
+ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+ (byte)0x00, (byte)0x03, (byte)0x79, (byte)0x65,
+ (byte)0x73, (byte)0x00, (byte)0x00, (byte)0x00,
+ (byte)0x00,
+ };
+
+ File f = File.createTempFile("ccache", "cc", new File("."));
+ FileOutputStream fout = new FileOutputStream(f);
+ fout.write(krb5cc);
+ fout.close();
+
+ CredentialsCache cc = CredentialsCache.getInstance(f.getPath());
+ if (!cc.getDefaultCreds().getServicePrincipal().getNameStrings()[0]
+ .equals("krbtgt")) {
+ throw new Exception("No TGT found");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/pkcs11/Cipher/TestPKCS5PaddingError.java Mon Nov 22 10:18:33 2010 -0500
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2010, 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.
+ *
+ * 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.
+ */
+
+/**
+ * @test
+ * @bug 6687725
+ * @summary Test internal PKCS5Padding impl with various error conditions.
+ * @author Valerie Peng
+ * @library ..
+ */
+import java.io.*;
+import java.nio.*;
+import java.util.*;
+
+import java.security.*;
+import java.security.spec.AlgorithmParameterSpec;
+
+import javax.crypto.*;
+import javax.crypto.spec.IvParameterSpec;
+
+public class TestPKCS5PaddingError extends PKCS11Test {
+ private static class CI { // class for holding Cipher Information
+ String transformation;
+ String keyAlgo;
+
+ CI(String transformation, String keyAlgo) {
+ this.transformation = transformation;
+ this.keyAlgo = keyAlgo;
+ }
+ }
+
+ private static final CI[] TEST_LIST = {
+ // algorithms which use the native padding impl
+ new CI("DES/CBC/PKCS5Padding", "DES"),
+ new CI("DESede/CBC/PKCS5Padding", "DESede"),
+ new CI("AES/CBC/PKCS5Padding", "AES"),
+ // algorithms which use SunPKCS11's own padding impl
+ new CI("DES/ECB/PKCS5Padding", "DES"),
+ new CI("DESede/ECB/PKCS5Padding", "DESede"),
+ new CI("AES/ECB/PKCS5Padding", "AES"),
+ };
+
+ private static StringBuffer debugBuf = new StringBuffer();
+
+ public void main(Provider p) throws Exception {
+ boolean status = true;
+ Random random = new Random();
+
+ try {
+ byte[] plainText = new byte[200];
+
+ for (int i = 0; i < TEST_LIST.length; i++) {
+ CI currTest = TEST_LIST[i];
+ System.out.println("===" + currTest.transformation + "===");
+ try {
+ KeyGenerator kg =
+ KeyGenerator.getInstance(currTest.keyAlgo, p);
+ SecretKey key = kg.generateKey();
+ Cipher c1 = Cipher.getInstance(currTest.transformation,
+ "SunJCE");
+ c1.init(Cipher.ENCRYPT_MODE, key);
+ byte[] cipherText = c1.doFinal(plainText);
+ AlgorithmParameters params = c1.getParameters();
+ Cipher c2 = Cipher.getInstance(currTest.transformation, p);
+ c2.init(Cipher.DECRYPT_MODE, key, params);
+
+ // 1st test: wrong output length
+ // NOTE: Skip NSS since it reports CKR_DEVICE_ERROR when
+ // the data passed to its EncryptUpdate/DecryptUpdate is
+ // not multiple of blocks
+ if (!p.getName().equals("SunPKCS11-NSS")) {
+ try {
+ System.out.println("Testing with wrong cipherText length");
+ c2.doFinal(cipherText, 0, cipherText.length - 2);
+ } catch (IllegalBlockSizeException ibe) {
+ // expected
+ } catch (Exception ex) {
+ System.out.println("Error: Unexpected Ex " + ex);
+ ex.printStackTrace();
+ }
+ }
+ // 2nd test: wrong padding value
+ try {
+ System.out.println("Testing with wrong padding bytes");
+ cipherText[cipherText.length - 1]++;
+ c2.doFinal(cipherText);
+ } catch (BadPaddingException bpe) {
+ // expected
+ } catch (Exception ex) {
+ System.out.println("Error: Unexpected Ex " + ex);
+ ex.printStackTrace();
+ }
+ System.out.println("DONE");
+ } catch (NoSuchAlgorithmException nsae) {
+ System.out.println("Skipping unsupported algorithm: " +
+ nsae);
+ }
+ }
+ } catch (Exception ex) {
+ // print out debug info when exception is encountered
+ if (debugBuf != null) {
+ System.out.println(debugBuf.toString());
+ debugBuf = new StringBuffer();
+ }
+ throw ex;
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ main(new TestPKCS5PaddingError());
+ }
+}
--- a/jdk/test/sun/security/pkcs11/KeyGenerator/TestKeyGenerator.java Mon Nov 22 10:16:07 2010 -0500
+++ b/jdk/test/sun/security/pkcs11/KeyGenerator/TestKeyGenerator.java Mon Nov 22 10:18:33 2010 -0500
@@ -23,7 +23,7 @@
/**
* @test
- * @bug 4917233 6461727 6490213
+ * @bug 4917233 6461727 6490213 6720456
* @summary test the KeyGenerator
* @author Andreas Sterbenz
* @library ..
@@ -104,7 +104,7 @@
// Different PKCS11 impls have different ranges
// of supported key sizes for variable-key-length
// algorithms.
- // Solaris> Blowfish: 32-128 bits, RC4: 8-128 bits
+ // Solaris> Blowfish: 32-128 or even 448 bits, RC4: 8-128 bits or as much as 2048 bits
// NSS> Blowfish: n/a, RC4: 8-2048 bits
// However, we explicitly disallowed key sizes less
// than 40-bits.
@@ -114,8 +114,8 @@
test("Blowfish", 32, p, TestResult.FAIL);
test("Blowfish", 40, p, TestResult.PASS);
test("Blowfish", 128, p, TestResult.PASS);
- test("Blowfish", 136, p, TestResult.FAIL);
- test("Blowfish", 448, p, TestResult.FAIL);
+ test("Blowfish", 136, p, TestResult.TBD);
+ test("Blowfish", 448, p, TestResult.TBD);
test("Blowfish", 456, p, TestResult.FAIL);
test("ARCFOUR", 0, p, TestResult.FAIL);
@@ -124,7 +124,7 @@
test("ARCFOUR", 128, p, TestResult.PASS);
if (p.getName().equals("SunPKCS11-Solaris")) {
- test("ARCFOUR", 1024, p, TestResult.FAIL);
+ test("ARCFOUR", 1024, p, TestResult.TBD);
} else if (p.getName().equals("SunPKCS11-NSS")) {
test("ARCFOUR", 1024, p, TestResult.PASS);
test("ARCFOUR", 2048, p, TestResult.PASS);