提交 fa7b30b0 编写于 作者: M michaelm

Merge

...@@ -42,3 +42,10 @@ DEMO_DESTDIR = $(DEMODIR)/nio/$(DEMONAME) ...@@ -42,3 +42,10 @@ DEMO_DESTDIR = $(DEMODIR)/nio/$(DEMONAME)
# #
include $(BUILDDIR)/common/Demo.gmk include $(BUILDDIR)/common/Demo.gmk
#EXTJAR = $(EXTDIR)/$(DEMONAME).jar
#
#all : build $(EXTJAR)
#
#$(EXTJAR) : $(DEMO_JAR)
# $(prep-target)
# $(CP) $(DEMO_JAR) $(EXTJAR)
...@@ -44,11 +44,11 @@ public interface Readable { ...@@ -44,11 +44,11 @@ public interface Readable {
* rewinding of the buffer is performed. * rewinding of the buffer is performed.
* *
* @param cb the buffer to read characters into * @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 * or -1 if this source of characters is at its end
* @throws IOException if an I/O error occurs * @throws IOException if an I/O error occurs
* @throws NullPointerException if cb is null * @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; public int read(java.nio.CharBuffer cb) throws IOException;
......
...@@ -126,10 +126,8 @@ public class LinkedBlockingDeque<E> ...@@ -126,10 +126,8 @@ public class LinkedBlockingDeque<E>
*/ */
Node<E> next; Node<E> next;
Node(E x, Node<E> p, Node<E> n) { Node(E x) {
item = x; item = x;
prev = p;
next = n;
} }
} }
...@@ -199,7 +197,7 @@ public class LinkedBlockingDeque<E> ...@@ -199,7 +197,7 @@ public class LinkedBlockingDeque<E>
for (E e : c) { for (E e : c) {
if (e == null) if (e == null)
throw new NullPointerException(); throw new NullPointerException();
if (!linkLast(e)) if (!linkLast(new Node<E>(e)))
throw new IllegalStateException("Deque full"); throw new IllegalStateException("Deque full");
} }
} finally { } finally {
...@@ -211,38 +209,38 @@ public class LinkedBlockingDeque<E> ...@@ -211,38 +209,38 @@ public class LinkedBlockingDeque<E>
// Basic linking and unlinking operations, called only while holding lock // Basic linking and unlinking operations, called only while holding lock
/** /**
* Links e as first element, or returns false if full. * Links node as first element, or returns false if full.
*/ */
private boolean linkFirst(E e) { private boolean linkFirst(Node<E> node) {
// assert lock.isHeldByCurrentThread(); // assert lock.isHeldByCurrentThread();
if (count >= capacity) if (count >= capacity)
return false; return false;
Node<E> f = first; Node<E> f = first;
Node<E> x = new Node<E>(e, null, f); node.next = f;
first = x; first = node;
if (last == null) if (last == null)
last = x; last = node;
else else
f.prev = x; f.prev = node;
++count; ++count;
notEmpty.signal(); notEmpty.signal();
return true; return true;
} }
/** /**
* Links e as last element, or returns false if full. * Links node as last element, or returns false if full.
*/ */
private boolean linkLast(E e) { private boolean linkLast(Node<E> node) {
// assert lock.isHeldByCurrentThread(); // assert lock.isHeldByCurrentThread();
if (count >= capacity) if (count >= capacity)
return false; return false;
Node<E> l = last; Node<E> l = last;
Node<E> x = new Node<E>(e, l, null); node.prev = l;
last = x; last = node;
if (first == null) if (first == null)
first = x; first = node;
else else
l.next = x; l.next = node;
++count; ++count;
notEmpty.signal(); notEmpty.signal();
return true; return true;
...@@ -339,10 +337,11 @@ public class LinkedBlockingDeque<E> ...@@ -339,10 +337,11 @@ public class LinkedBlockingDeque<E>
*/ */
public boolean offerFirst(E e) { public boolean offerFirst(E e) {
if (e == null) throw new NullPointerException(); if (e == null) throw new NullPointerException();
Node<E> node = new Node<E>(e);
final ReentrantLock lock = this.lock; final ReentrantLock lock = this.lock;
lock.lock(); lock.lock();
try { try {
return linkFirst(e); return linkFirst(node);
} finally { } finally {
lock.unlock(); lock.unlock();
} }
...@@ -353,10 +352,11 @@ public class LinkedBlockingDeque<E> ...@@ -353,10 +352,11 @@ public class LinkedBlockingDeque<E>
*/ */
public boolean offerLast(E e) { public boolean offerLast(E e) {
if (e == null) throw new NullPointerException(); if (e == null) throw new NullPointerException();
Node<E> node = new Node<E>(e);
final ReentrantLock lock = this.lock; final ReentrantLock lock = this.lock;
lock.lock(); lock.lock();
try { try {
return linkLast(e); return linkLast(node);
} finally { } finally {
lock.unlock(); lock.unlock();
} }
...@@ -368,10 +368,11 @@ public class LinkedBlockingDeque<E> ...@@ -368,10 +368,11 @@ public class LinkedBlockingDeque<E>
*/ */
public void putFirst(E e) throws InterruptedException { public void putFirst(E e) throws InterruptedException {
if (e == null) throw new NullPointerException(); if (e == null) throw new NullPointerException();
Node<E> node = new Node<E>(e);
final ReentrantLock lock = this.lock; final ReentrantLock lock = this.lock;
lock.lock(); lock.lock();
try { try {
while (!linkFirst(e)) while (!linkFirst(node))
notFull.await(); notFull.await();
} finally { } finally {
lock.unlock(); lock.unlock();
...@@ -384,10 +385,11 @@ public class LinkedBlockingDeque<E> ...@@ -384,10 +385,11 @@ public class LinkedBlockingDeque<E>
*/ */
public void putLast(E e) throws InterruptedException { public void putLast(E e) throws InterruptedException {
if (e == null) throw new NullPointerException(); if (e == null) throw new NullPointerException();
Node<E> node = new Node<E>(e);
final ReentrantLock lock = this.lock; final ReentrantLock lock = this.lock;
lock.lock(); lock.lock();
try { try {
while (!linkLast(e)) while (!linkLast(node))
notFull.await(); notFull.await();
} finally { } finally {
lock.unlock(); lock.unlock();
...@@ -401,11 +403,12 @@ public class LinkedBlockingDeque<E> ...@@ -401,11 +403,12 @@ public class LinkedBlockingDeque<E>
public boolean offerFirst(E e, long timeout, TimeUnit unit) public boolean offerFirst(E e, long timeout, TimeUnit unit)
throws InterruptedException { throws InterruptedException {
if (e == null) throw new NullPointerException(); if (e == null) throw new NullPointerException();
Node<E> node = new Node<E>(e);
long nanos = unit.toNanos(timeout); long nanos = unit.toNanos(timeout);
final ReentrantLock lock = this.lock; final ReentrantLock lock = this.lock;
lock.lockInterruptibly(); lock.lockInterruptibly();
try { try {
while (!linkFirst(e)) { while (!linkFirst(node)) {
if (nanos <= 0) if (nanos <= 0)
return false; return false;
nanos = notFull.awaitNanos(nanos); nanos = notFull.awaitNanos(nanos);
...@@ -423,11 +426,12 @@ public class LinkedBlockingDeque<E> ...@@ -423,11 +426,12 @@ public class LinkedBlockingDeque<E>
public boolean offerLast(E e, long timeout, TimeUnit unit) public boolean offerLast(E e, long timeout, TimeUnit unit)
throws InterruptedException { throws InterruptedException {
if (e == null) throw new NullPointerException(); if (e == null) throw new NullPointerException();
Node<E> node = new Node<E>(e);
long nanos = unit.toNanos(timeout); long nanos = unit.toNanos(timeout);
final ReentrantLock lock = this.lock; final ReentrantLock lock = this.lock;
lock.lockInterruptibly(); lock.lockInterruptibly();
try { try {
while (!linkLast(e)) { while (!linkLast(node)) {
if (nanos <= 0) if (nanos <= 0)
return false; return false;
nanos = notFull.awaitNanos(nanos); nanos = notFull.awaitNanos(nanos);
...@@ -955,7 +959,20 @@ public class LinkedBlockingDeque<E> ...@@ -955,7 +959,20 @@ public class LinkedBlockingDeque<E>
final ReentrantLock lock = this.lock; final ReentrantLock lock = this.lock;
lock.lock(); lock.lock();
try { try {
return super.toString(); Node<E> p = first;
if (p == null)
return "[]";
StringBuilder sb = new StringBuilder();
sb.append('[');
for (;;) {
E e = p.item;
sb.append(e == this ? "(this Collection)" : e);
p = p.next;
if (p == null)
return sb.append(']').toString();
sb.append(',').append(' ');
}
} finally { } finally {
lock.unlock(); lock.unlock();
} }
...@@ -1053,6 +1070,26 @@ public class LinkedBlockingDeque<E> ...@@ -1053,6 +1070,26 @@ public class LinkedBlockingDeque<E>
} }
} }
/**
* Returns the successor node of the given non-null, but
* possibly previously deleted, node.
*/
private Node<E> succ(Node<E> n) {
// Chains of deleted nodes ending in null or self-links
// are possible if multiple interior nodes are removed.
for (;;) {
Node<E> s = nextNode(n);
if (s == null)
return null;
else if (s.item != null)
return s;
else if (s == n)
return firstNode();
else
n = s;
}
}
/** /**
* Advances next. * Advances next.
*/ */
...@@ -1061,16 +1098,7 @@ public class LinkedBlockingDeque<E> ...@@ -1061,16 +1098,7 @@ public class LinkedBlockingDeque<E>
lock.lock(); lock.lock();
try { try {
// assert next != null; // assert next != null;
Node<E> s = nextNode(next); next = succ(next);
if (s == next) {
next = firstNode();
} else {
// Skip over removed nodes.
// May be necessary if multiple interior Nodes are removed.
while (s != null && s.item == null)
s = nextNode(s);
next = s;
}
nextItem = (next == null) ? null : next.item; nextItem = (next == null) ? null : next.item;
} finally { } finally {
lock.unlock(); lock.unlock();
......
...@@ -28,6 +28,7 @@ package java.util.jar; ...@@ -28,6 +28,7 @@ package java.util.jar;
import java.util.zip.*; import java.util.zip.*;
import java.io.*; import java.io.*;
import sun.security.util.ManifestEntryVerifier; import sun.security.util.ManifestEntryVerifier;
import sun.misc.JarIndex;
/** /**
* The <code>JarInputStream</code> class is used to read the contents of * The <code>JarInputStream</code> class is used to read the contents of
...@@ -47,7 +48,8 @@ class JarInputStream extends ZipInputStream { ...@@ -47,7 +48,8 @@ class JarInputStream extends ZipInputStream {
private JarEntry first; private JarEntry first;
private JarVerifier jv; private JarVerifier jv;
private ManifestEntryVerifier mev; private ManifestEntryVerifier mev;
private final boolean doVerify;
private boolean tryManifest;
/** /**
* Creates a new <code>JarInputStream</code> and reads the optional * Creates a new <code>JarInputStream</code> and reads the optional
...@@ -72,25 +74,33 @@ class JarInputStream extends ZipInputStream { ...@@ -72,25 +74,33 @@ class JarInputStream extends ZipInputStream {
*/ */
public JarInputStream(InputStream in, boolean verify) throws IOException { public JarInputStream(InputStream in, boolean verify) throws IOException {
super(in); super(in);
JarEntry e = (JarEntry)super.getNextEntry(); 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/")) if (e != null && e.getName().equalsIgnoreCase("META-INF/"))
e = (JarEntry)super.getNextEntry(); e = (JarEntry)super.getNextEntry();
first = checkManifest(e);
}
private JarEntry checkManifest(JarEntry e)
throws IOException
{
if (e != null && JarFile.MANIFEST_NAME.equalsIgnoreCase(e.getName())) { if (e != null && JarFile.MANIFEST_NAME.equalsIgnoreCase(e.getName())) {
man = new Manifest(); man = new Manifest();
byte bytes[] = getBytes(new BufferedInputStream(this)); byte bytes[] = getBytes(new BufferedInputStream(this));
man.read(new ByteArrayInputStream(bytes)); man.read(new ByteArrayInputStream(bytes));
//man.read(new BufferedInputStream(this));
closeEntry(); closeEntry();
if (verify) { if (doVerify) {
jv = new JarVerifier(bytes); jv = new JarVerifier(bytes);
mev = new ManifestEntryVerifier(man); mev = new ManifestEntryVerifier(man);
} }
first = getNextJarEntry(); return (JarEntry)super.getNextEntry();
} else {
first = e;
} }
return e;
} }
private byte[] getBytes(InputStream is) private byte[] getBytes(InputStream is)
...@@ -98,10 +108,7 @@ class JarInputStream extends ZipInputStream { ...@@ -98,10 +108,7 @@ class JarInputStream extends ZipInputStream {
{ {
byte[] buffer = new byte[8192]; byte[] buffer = new byte[8192];
ByteArrayOutputStream baos = new ByteArrayOutputStream(2048); ByteArrayOutputStream baos = new ByteArrayOutputStream(2048);
int n; int n;
baos.reset();
while ((n = is.read(buffer, 0, buffer.length)) != -1) { while ((n = is.read(buffer, 0, buffer.length)) != -1) {
baos.write(buffer, 0, n); baos.write(buffer, 0, n);
} }
...@@ -133,8 +140,14 @@ class JarInputStream extends ZipInputStream { ...@@ -133,8 +140,14 @@ class JarInputStream extends ZipInputStream {
JarEntry e; JarEntry e;
if (first == null) { if (first == null) {
e = (JarEntry)super.getNextEntry(); e = (JarEntry)super.getNextEntry();
if (tryManifest) {
e = checkManifest(e);
tryManifest = false;
}
} else { } else {
e = first; e = first;
if (first.getName().equalsIgnoreCase(JarIndex.INDEX_NAME))
tryManifest = true;
first = null; first = null;
} }
if (jv != null && e != null) { if (jv != null && e != null) {
......
...@@ -74,7 +74,7 @@ final class P11Cipher extends CipherSpi { ...@@ -74,7 +74,7 @@ final class P11Cipher extends CipherSpi {
// DEC: return the length of trailing padding bytes given the specified // DEC: return the length of trailing padding bytes given the specified
// padded data // padded data
int unpad(byte[] paddedData, int len) int unpad(byte[] paddedData, int len)
throws BadPaddingException; throws BadPaddingException, IllegalBlockSizeException;
} }
private static class PKCS5Padding implements Padding { private static class PKCS5Padding implements Padding {
...@@ -96,9 +96,10 @@ final class P11Cipher extends CipherSpi { ...@@ -96,9 +96,10 @@ final class P11Cipher extends CipherSpi {
} }
public int unpad(byte[] paddedData, int len) public int unpad(byte[] paddedData, int len)
throws BadPaddingException { throws BadPaddingException, IllegalBlockSizeException {
if (len < 1 || len > paddedData.length) { if ((len < 1) || (len % blockSize != 0)) {
throw new BadPaddingException("Invalid pad array length!"); throw new IllegalBlockSizeException
("Input length must be multiples of " + blockSize);
} }
byte padValue = paddedData[len - 1]; byte padValue = paddedData[len - 1];
if (padValue < 1 || padValue > blockSize) { if (padValue < 1 || padValue > blockSize) {
......
...@@ -75,9 +75,15 @@ public class Demo { ...@@ -75,9 +75,15 @@ public class Demo {
// copy an external src file into zipfile // copy an external src file into zipfile
// as entry dst // 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> copyout, // <java Demo copyout zipfile src dst>
// copy zipfile entry src" out to file 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> zzmove, // <java Demo zzmove zfsrc zfdst path>
// move entry path/dir from zfsrc to zfdst // move entry path/dir from zfsrc to zfdst
...@@ -94,6 +100,9 @@ public class Demo { ...@@ -94,6 +100,9 @@ public class Demo {
setmtime, // <java Demo setmtime zipfile "MM/dd/yy-HH:mm:ss" path...> setmtime, // <java Demo setmtime zipfile "MM/dd/yy-HH:mm:ss" path...>
// set the lastModifiedTime of entry 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> lsdir, // <java Demo lsdir zipfile dir>
// list dir's direct child files/dirs // list dir's direct child files/dirs
...@@ -135,12 +144,14 @@ public class Demo { ...@@ -135,12 +144,14 @@ public class Demo {
attrs2, // <java Demo attrs2 zipfile file [...]> attrs2, // <java Demo attrs2 zipfile file [...]>
// test different ways to print attrs // test different ways to print attrs
prof,
} }
public static void main(String[] args) throws Throwable { public static void main(String[] args) throws Throwable {
Action action = Action.valueOf(args[0]);; Action action = Action.valueOf(args[0]);
Map<String, Object> env = env = new HashMap<String, Object>(); Map<String, Object> env = env = new HashMap<>();
if (action == Action.create) if (action == Action.create)
env.put("createNew", true); env.put("createNew", true);
if (action == Action.tlist || action == Action.twalk) if (action == Action.tlist || action == Action.twalk)
...@@ -185,6 +196,16 @@ public class Demo { ...@@ -185,6 +196,16 @@ public class Demo {
dst = fs.getPath(args[3]); dst = fs.getPath(args[3]);
src.copyTo(dst); src.copyTo(dst);
break; 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: case zzmove:
fs2 = FileSystems.newFileSystem( fs2 = FileSystems.newFileSystem(
URI.create("zip" + Paths.get(args[2]).toUri().toString().substring(4)), URI.create("zip" + Paths.get(args[2]).toUri().toString().substring(4)),
...@@ -206,6 +227,7 @@ public class Demo { ...@@ -206,6 +227,7 @@ public class Demo {
case attrs: case attrs:
for (int i = 2; i < args.length; i++) { for (int i = 2; i < args.length; i++) {
path = fs.getPath(args[i]); path = fs.getPath(args[i]);
System.out.println(path);
System.out.println( System.out.println(
Attributes.readBasicFileAttributes(path).toString()); Attributes.readBasicFileAttributes(path).toString());
} }
...@@ -221,6 +243,28 @@ public class Demo { ...@@ -221,6 +243,28 @@ public class Demo {
Attributes.readBasicFileAttributes(path).toString()); Attributes.readBasicFileAttributes(path).toString());
} }
break; 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: case attrsspace:
path = fs.getPath("/"); path = fs.getPath("/");
FileStore fstore = path.getFileStore(); FileStore fstore = path.getFileStore();
...@@ -293,6 +337,7 @@ public class Demo { ...@@ -293,6 +337,7 @@ public class Demo {
case attrs2: case attrs2:
for (int i = 2; i < args.length; i++) { for (int i = 2; i < args.length; i++) {
path = fs.getPath(args[i]); path = fs.getPath(args[i]);
System.out.printf("%n%s%n", path);
System.out.println("-------(1)---------"); System.out.println("-------(1)---------");
System.out.println( System.out.println(
Attributes.readBasicFileAttributes(path).toString()); Attributes.readBasicFileAttributes(path).toString());
...@@ -308,6 +353,13 @@ public class Demo { ...@@ -308,6 +353,13 @@ public class Demo {
} }
} }
break; break;
case prof:
list(fs.getPath("/"), false);
while (true) {
Thread.sleep(10000);
//list(fs.getPath("/"), true);
System.out.println("sleeping...");
}
} }
} catch (Exception x) { } catch (Exception x) {
x.printStackTrace(); x.printStackTrace();
...@@ -501,10 +553,11 @@ public class Demo { ...@@ -501,10 +553,11 @@ public class Demo {
} }
private static void list(Path path, boolean verbose ) throws IOException { private static void list(Path path, boolean verbose ) throws IOException {
if (verbose) if (!"/".equals(path.toString())) {
System.out.println(Attributes.readBasicFileAttributes(path).toString()); System.out.printf(" %s%n", path.toString());
else if (verbose)
System.out.printf(" %s%n", path.toString()); System.out.println(Attributes.readBasicFileAttributes(path).toString());
}
if (path.notExists()) if (path.notExists())
return; return;
if (Attributes.readBasicFileAttributes(path).isDirectory()) { if (Attributes.readBasicFileAttributes(path).isDirectory()) {
......
...@@ -2,7 +2,7 @@ ZipFileSystem is a file system provider that treats the contents of a zip or ...@@ -2,7 +2,7 @@ ZipFileSystem is a file system provider that treats the contents of a zip or
JAR file as a java.nio.file.FileSystem. JAR file as a java.nio.file.FileSystem.
To deploy the provider you must copy zipfs.jar into your extensions 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. to your class path.
The factory methods defined by the java.nio.file.FileSystems class can be The factory methods defined by the java.nio.file.FileSystems class can be
...@@ -10,8 +10,8 @@ used to create a FileSystem, eg: ...@@ -10,8 +10,8 @@ used to create a FileSystem, eg:
// use file type detection // use file type detection
Map<String,?> env = Collections.emptyMap(); Map<String,?> env = Collections.emptyMap();
Path jarfile = Path.get("foo.jar"); Path jarfile = Paths.get("foo.jar");
FileSystem fs = FileSystems.newFileSystem(jarfile, env); FileSystem fs = FileSystems.newFileSystem(jarfile, env, null);
-or -or
......
...@@ -68,4 +68,21 @@ public class JarFileSystemProvider extends ZipFileSystemProvider ...@@ -68,4 +68,21 @@ public class JarFileSystemProvider extends ZipFileSystemProvider
throw new AssertionError(e); //never thrown 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");
}
} }
...@@ -31,7 +31,6 @@ ...@@ -31,7 +31,6 @@
package com.sun.nio.zipfs; package com.sun.nio.zipfs;
import java.nio.ByteBuffer;
/** /**
* *
...@@ -48,6 +47,7 @@ class ZipConstants { ...@@ -48,6 +47,7 @@ class ZipConstants {
static final int METHOD_BZIP2 = 12; static final int METHOD_BZIP2 = 12;
static final int METHOD_LZMA = 14; static final int METHOD_LZMA = 14;
static final int METHOD_LZ77 = 19; static final int METHOD_LZ77 = 19;
static final int METHOD_AES = 99;
/* /*
* General purpose big flag * General purpose big flag
...@@ -168,7 +168,8 @@ class ZipConstants { ...@@ -168,7 +168,8 @@ class ZipConstants {
static final int EXTID_ZIP64 = 0x0001; // ZIP64 static final int EXTID_ZIP64 = 0x0001; // ZIP64
static final int EXTID_NTFS = 0x000a; // NTFS static final int EXTID_NTFS = 0x000a; // NTFS
static final int EXTID_UNIX = 0x000d; // UNIX 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 * fields access methods
...@@ -226,34 +227,23 @@ class ZipConstants { ...@@ -226,34 +227,23 @@ class ZipConstants {
static final long ZIP64_ENDOFF(byte[] b) { return LL(b, 48);} // central directory offset 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 long ZIP64_LOCOFF(byte[] b) { return LL(b, 8);} // zip64 end offset
////////////////////////////////////////// // central directory header (CEN) fields
static final int CH(ByteBuffer b, int pos) { static final long CENSIG(byte[] b, int pos) { return LG(b, pos + 0); }
return b.get(pos) & 0xff; 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 SH(ByteBuffer b, int pos) { static final int CENFLG(byte[] b, int pos) { return SH(b, pos + 8); }
return b.getShort(pos) & 0xffff; 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 LG(ByteBuffer b, int pos) { static final long CENCRC(byte[] b, int pos) { return LG(b, pos + 16);}
return b.getInt(pos) & 0xffffffffL; 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);}
// central directory header (END) fields static final int CENEXT(byte[] b, int pos) { return SH(b, pos + 30);}
static final long CENSIG(ByteBuffer b, int pos) { return LG(b, pos + 0); } static final int CENCOM(byte[] b, int pos) { return SH(b, pos + 32);}
static final int CENVEM(ByteBuffer b, int pos) { return SH(b, pos + 4); } static final int CENDSK(byte[] b, int pos) { return SH(b, pos + 34);}
static final int CENVER(ByteBuffer b, int pos) { return SH(b, pos + 6); } static final int CENATT(byte[] b, int pos) { return SH(b, pos + 36);}
static final int CENFLG(ByteBuffer b, int pos) { return SH(b, pos + 8); } static final long CENATX(byte[] b, int pos) { return LG(b, pos + 38);}
static final int CENHOW(ByteBuffer b, int pos) { return SH(b, pos + 10);} static final long CENOFF(byte[] b, int pos) { return LG(b, pos + 42);}
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);}
/* The END header is followed by a variable length comment of size < 64k. */ /* The END header is followed by a variable length comment of size < 64k. */
static final long END_MAXLEN = 0xFFFF + ENDHDR; static final long END_MAXLEN = 0xFFFF + ENDHDR;
......
...@@ -38,7 +38,6 @@ import java.nio.file.Path; ...@@ -38,7 +38,6 @@ import java.nio.file.Path;
import java.util.Iterator; import java.util.Iterator;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.io.IOException; import java.io.IOException;
import static com.sun.nio.zipfs.ZipUtils.*;
/** /**
* *
...@@ -77,7 +76,7 @@ public class ZipDirectoryStream implements DirectoryStream<Path> { ...@@ -77,7 +76,7 @@ public class ZipDirectoryStream implements DirectoryStream<Path> {
} catch (IOException e) { } catch (IOException e) {
throw new IllegalStateException(e); throw new IllegalStateException(e);
} }
return new Iterator<Path>() { return new Iterator<>() {
private Path next; private Path next;
@Override @Override
public boolean hasNext() { public boolean hasNext() {
......
...@@ -32,7 +32,6 @@ ...@@ -32,7 +32,6 @@
package com.sun.nio.zipfs; package com.sun.nio.zipfs;
import java.nio.file.ReadOnlyFileSystemException;
import java.nio.file.attribute.BasicFileAttributeView; import java.nio.file.attribute.BasicFileAttributeView;
import java.nio.file.attribute.FileAttributeView; import java.nio.file.attribute.FileAttributeView;
import java.nio.file.attribute.FileTime; import java.nio.file.attribute.FileTime;
...@@ -113,6 +112,10 @@ public class ZipFileAttributeView implements BasicFileAttributeView ...@@ -113,6 +112,10 @@ public class ZipFileAttributeView implements BasicFileAttributeView
try { try {
if (AttrID.valueOf(attribute) == AttrID.lastModifiedTime) if (AttrID.valueOf(attribute) == AttrID.lastModifiedTime)
setTimes ((FileTime)value, null, null); 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; return;
} catch (IllegalArgumentException x) {} } catch (IllegalArgumentException x) {}
throw new UnsupportedOperationException("'" + attribute + throw new UnsupportedOperationException("'" + attribute +
......
...@@ -56,7 +56,7 @@ public class ZipFileAttributes implements BasicFileAttributes ...@@ -56,7 +56,7 @@ public class ZipFileAttributes implements BasicFileAttributes
@Override @Override
public FileTime creationTime() { public FileTime creationTime() {
if (e.ctime != -1) if (e.ctime != -1)
return FileTime.fromMillis(dosToJavaTime(e.ctime)); return FileTime.fromMillis(e.ctime);
return null; return null;
} }
...@@ -78,13 +78,13 @@ public class ZipFileAttributes implements BasicFileAttributes ...@@ -78,13 +78,13 @@ public class ZipFileAttributes implements BasicFileAttributes
@Override @Override
public FileTime lastAccessTime() { public FileTime lastAccessTime() {
if (e.atime != -1) if (e.atime != -1)
return FileTime.fromMillis(dosToJavaTime(e.atime)); return FileTime.fromMillis(e.atime);
return null; return null;
} }
@Override @Override
public FileTime lastModifiedTime() { public FileTime lastModifiedTime() {
return FileTime.fromMillis(dosToJavaTime(e.mtime)); return FileTime.fromMillis(e.mtime);
} }
@Override @Override
...@@ -103,10 +103,6 @@ public class ZipFileAttributes implements BasicFileAttributes ...@@ -103,10 +103,6 @@ public class ZipFileAttributes implements BasicFileAttributes
} }
///////// zip entry attributes /////////// ///////// zip entry attributes ///////////
public byte[] name() {
return Arrays.copyOf(e.name, e.name.length);
}
public long compressedSize() { public long compressedSize() {
return e.csize; return e.csize;
} }
...@@ -132,10 +128,13 @@ public class ZipFileAttributes implements BasicFileAttributes ...@@ -132,10 +128,13 @@ public class ZipFileAttributes implements BasicFileAttributes
} }
public String toString() { public String toString() {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder(1024);
Formatter fm = new Formatter(sb); Formatter fm = new Formatter(sb);
fm.format("[/%s]%n", new String(e.name)); // TBD encoding if (creationTime() != null)
fm.format(" creationTime : %s%n", creationTime()); fm.format(" creationTime : %tc%n", creationTime().toMillis());
else
fm.format(" creationTime : null%n");
if (lastAccessTime() != null) if (lastAccessTime() != null)
fm.format(" lastAccessTime : %tc%n", lastAccessTime().toMillis()); fm.format(" lastAccessTime : %tc%n", lastAccessTime().toMillis());
else else
......
...@@ -55,6 +55,8 @@ import java.util.Set; ...@@ -55,6 +55,8 @@ import java.util.Set;
*/ */
public class ZipFileSystemProvider extends FileSystemProvider { public class ZipFileSystemProvider extends FileSystemProvider {
private final Map<Path, ZipFileSystem> filesystems = new HashMap<>(); private final Map<Path, ZipFileSystem> filesystems = new HashMap<>();
public ZipFileSystemProvider() {} public ZipFileSystemProvider() {}
...@@ -101,10 +103,16 @@ public class ZipFileSystemProvider extends FileSystemProvider { ...@@ -101,10 +103,16 @@ public class ZipFileSystemProvider extends FileSystemProvider {
throws IOException throws IOException
{ {
synchronized(filesystems) { synchronized(filesystems) {
if (filesystems.containsKey(path)) Path realPath = null;
throw new FileSystemAlreadyExistsException(); if (path.exists()) {
realPath = path.toRealPath(true);
if (filesystems.containsKey(realPath))
throw new FileSystemAlreadyExistsException();
}
ZipFileSystem zipfs = new ZipFileSystem(this, path, env); ZipFileSystem zipfs = new ZipFileSystem(this, path, env);
filesystems.put(path, zipfs); if (realPath == null)
realPath = path.toRealPath(true);
filesystems.put(realPath, zipfs);
return zipfs; return zipfs;
} }
} }
...@@ -137,16 +145,21 @@ public class ZipFileSystemProvider extends FileSystemProvider { ...@@ -137,16 +145,21 @@ public class ZipFileSystemProvider extends FileSystemProvider {
@Override @Override
public FileSystem getFileSystem(URI uri) { public FileSystem getFileSystem(URI uri) {
synchronized (filesystems) { 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) if (zipfs == null)
throw new FileSystemNotFoundException(); throw new FileSystemNotFoundException();
return zipfs; return zipfs;
} }
} }
void removeFileSystem(Path zfpath) { void removeFileSystem(Path zfpath) throws IOException {
synchronized (filesystems) { synchronized (filesystems) {
filesystems.remove(zfpath); filesystems.remove(zfpath.toRealPath(true));
} }
} }
} }
...@@ -31,7 +31,6 @@ ...@@ -31,7 +31,6 @@
package com.sun.nio.zipfs; package com.sun.nio.zipfs;
import java.io.PrintStream;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.Collections; import java.util.Collections;
import java.util.Iterator; import java.util.Iterator;
...@@ -41,7 +40,7 @@ import static com.sun.nio.zipfs.ZipConstants.*; ...@@ -41,7 +40,7 @@ import static com.sun.nio.zipfs.ZipConstants.*;
import static com.sun.nio.zipfs.ZipUtils.*; 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 * @author Xueming Shen
*/ */
...@@ -49,34 +48,38 @@ import static com.sun.nio.zipfs.ZipUtils.*; ...@@ -49,34 +48,38 @@ import static com.sun.nio.zipfs.ZipUtils.*;
public class ZipInfo { public class ZipInfo {
public static void main(String[] args) throws Throwable { public static void main(String[] args) throws Throwable {
if (args.length < 2) { if (args.length < 1) {
print("Usage: java ZipInfo [cen|loc] zfname"); print("Usage: java ZipInfo zfname");
} else { } else {
Map<String, ?> env = Collections.emptyMap(); Map<String, ?> env = Collections.emptyMap();
ZipFileSystem zfs = (ZipFileSystem)(new ZipFileSystemProvider() ZipFileSystem zfs = (ZipFileSystem)(new ZipFileSystemProvider()
.newFileSystem(Paths.get(args[1]), env)); .newFileSystem(Paths.get(args[0]), env));
byte[] cen = zfs.cen;
long pos = 0; 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])) { // use size CENHDR as the extra bytes to read, just in case the
print("[Local File Header]%n"); // loc.extra is bigger than the cen.extra, try to avoid to read
byte[] buf = new byte[1024]; // twice
for (int i = 0; i < zfs.getEntryNames().length; i++) { long len = LOCHDR + CENNAM(cen, pos) + CENEXT(cen, pos) + CENHDR;
Entry loc = Entry.readLOC(zfs, pos, buf); if (zfs.readFullyAt(buf, 0, len, locoff(cen, pos)) != len)
print("--------loc[%x]--------%n", pos); zfs.zerror("read loc header failed");
printLOC(loc); if (LOCEXT(buf) > CENEXT(cen, pos) + CENHDR) {
pos = loc.endPos; // have to read the second time;
} len = LOCHDR + LOCNAM(buf) + LOCEXT(buf);
} if ("cen".equals(args[0])) { if (zfs.readFullyAt(buf, 0, len, locoff(cen, pos)) != len)
int i = 0; zfs.zerror("read loc header failed");
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(); zfs.close();
} }
...@@ -86,47 +89,135 @@ public class ZipInfo { ...@@ -86,47 +89,135 @@ public class ZipInfo {
System.out.printf(fmt, objs); System.out.printf(fmt, objs);
} }
static void printLOC(Entry loc) { static void printLOC(byte[] loc) {
print(" [%x, %x]%n", loc.startPos, loc.endPos); print("%n");
print(" Signature : %8x%n", LOCSIG); print("[Local File Header]%n");
print(" Version : %4x [%d.%d]%n", print(" Signature : %#010x%n", LOCSIG(loc));
loc.version, loc. version/10, loc. version%10); if (LOCSIG(loc) != LOCSIG) {
print(" Flag : %4x%n", loc.flag); print(" Wrong signature!");
print(" Method : %4x%n", loc. method); return;
print(" LastMTime : %8x [%tc]%n", }
loc.mtime, dosToJavaTime(loc.mtime)); print(" Version : %#6x [%d.%d]%n",
print(" CRC : %8x%n", loc.crc); LOCVER(loc), LOCVER(loc) / 10, LOCVER(loc) % 10);
print(" CSize : %8x%n", loc.csize); print(" Flag : %#6x%n", LOCFLG(loc));
print(" Size : %8x%n", loc.size); print(" Method : %#6x%n", LOCHOW(loc));
print(" NameLength : %4x [%s]%n", print(" LastMTime : %#10x [%tc]%n",
loc.nlen, new String(loc.name)); LOCTIM(loc), dosToJavaTime(LOCTIM(loc)));
print(" ExtraLength : %4x%n", loc.elen); print(" CRC : %#10x%n", LOCCRC(loc));
if (loc.hasZip64) print(" CSize : %#10x%n", LOCSIZ(loc));
print(" *ZIP64*%n"); 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 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 printCEN(Entry cen) { static void printExtra(byte[] extra, int off, int len) {
print(" Signature : %08x%n", CENSIG); int end = off + len;
print(" VerMadeby : %4x [%d.%d]%n", while (off + 4 < end) {
cen.versionMade, cen.versionMade/10, cen.versionMade%10); int tag = SH(extra, off);
print(" VerExtract : %4x [%d.%d]%n", int sz = SH(extra, off + 2);
cen.version, cen.version/10, cen.version%10); print(" [tag=0x%04x, sz=%d, data= ", tag, sz);
print(" Flag : %4x%n", cen.flag); if (off + sz > end) {
print(" Method : %4x%n", cen.method); print(" Error: Invalid extra data, beyond extra length");
print(" LastMTime : %8x [%tc]%n", break;
cen.mtime, dosToJavaTime(cen.mtime)); }
print(" CRC : %8x%n", cen.crc); off += 4;
print(" CSize : %8x%n", cen.csize); for (int i = 0; i < sz; i++)
print(" Size : %8x%n", cen.size); print("%02x ", extra[off + i]);
print(" NameLen : %4x [%s]%n", print("]%n");
cen.nlen, new String(cen.name)); switch (tag) {
print(" ExtraLen : %4x%n", cen.elen); case EXTID_ZIP64 :
print(" CommentLen : %4x%n", cen.clen); print(" ->ZIP64: ");
print(" DiskStart : %4x%n", cen.disk); int pos = off;
print(" Attrs : %4x%n", cen.attrs); while (pos + 8 <= off + sz) {
print(" AttrsEx : %8x%n", cen.attrsEx); print(" *0x%x ", LL(extra, pos));
print(" LocOff : %8x%n", cen.locoff); pos += 8;
if (cen.hasZip64) }
print(" *ZIP64*%n"); 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;
}
} }
} }
...@@ -32,24 +32,19 @@ ...@@ -32,24 +32,19 @@
package com.sun.nio.zipfs; package com.sun.nio.zipfs;
import java.io.File; import java.io.File;
import java.io.FilterInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.net.URI; import java.net.URI;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel; import java.nio.channels.FileChannel;
import java.nio.channels.SeekableByteChannel; import java.nio.channels.SeekableByteChannel;
import java.nio.file.*; import java.nio.file.*;
import java.nio.file.DirectoryStream.Filter; import java.nio.file.DirectoryStream.Filter;
import java.nio.file.spi.FileSystemProvider;
import java.nio.file.attribute.BasicFileAttributeView; import java.nio.file.attribute.BasicFileAttributeView;
import java.nio.file.attribute.FileAttribute; import java.nio.file.attribute.FileAttribute;
import java.nio.file.attribute.FileAttributeView; import java.nio.file.attribute.FileAttributeView;
import java.nio.file.attribute.FileTime; import java.nio.file.attribute.FileTime;
import java.util.*; import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static java.nio.file.StandardOpenOption.*; import static java.nio.file.StandardOpenOption.*;
import static java.nio.file.StandardCopyOption.*; import static java.nio.file.StandardCopyOption.*;
...@@ -599,7 +594,7 @@ public class ZipPath extends Path { ...@@ -599,7 +594,7 @@ public class ZipPath extends Path {
} }
private static final DirectoryStream.Filter<Path> acceptAllFilter = private static final DirectoryStream.Filter<Path> acceptAllFilter =
new DirectoryStream.Filter<Path>() { new DirectoryStream.Filter<>() {
@Override public boolean accept(Path entry) { return true; } @Override public boolean accept(Path entry) { return true; }
}; };
...@@ -625,7 +620,7 @@ public class ZipPath extends Path { ...@@ -625,7 +620,7 @@ public class ZipPath extends Path {
// create a matcher and return a filter that uses it. // create a matcher and return a filter that uses it.
final PathMatcher matcher = getFileSystem().getPathMatcher("glob:" + glob); final PathMatcher matcher = getFileSystem().getPathMatcher("glob:" + glob);
DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>() { DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<>() {
@Override @Override
public boolean accept(Path entry) { public boolean accept(Path entry) {
return matcher.matches(entry.getName()); return matcher.matches(entry.getName());
...@@ -758,7 +753,7 @@ public class ZipPath extends Path { ...@@ -758,7 +753,7 @@ public class ZipPath extends Path {
@Override @Override
public Iterator<Path> iterator() { public Iterator<Path> iterator() {
return new Iterator<Path>() { return new Iterator<>() {
private int i = 0; private int i = 0;
@Override @Override
...@@ -803,7 +798,7 @@ public class ZipPath extends Path { ...@@ -803,7 +798,7 @@ public class ZipPath extends Path {
@Override @Override
public SeekableByteChannel newByteChannel(OpenOption... options) public SeekableByteChannel newByteChannel(OpenOption... options)
throws IOException { throws IOException {
Set<OpenOption> set = new HashSet<OpenOption>(options.length); Set<OpenOption> set = new HashSet<>(options.length);
Collections.addAll(set, options); Collections.addAll(set, options);
return newByteChannel(set); return newByteChannel(set);
} }
...@@ -908,7 +903,7 @@ public class ZipPath extends Path { ...@@ -908,7 +903,7 @@ public class ZipPath extends Path {
if (opt == REPLACE_EXISTING) if (opt == REPLACE_EXISTING)
replaceExisting = true; replaceExisting = true;
else if (opt == COPY_ATTRIBUTES) else if (opt == COPY_ATTRIBUTES)
copyAttrs = false; copyAttrs = true;
} }
// attributes of source file // attributes of source file
ZipFileAttributes zfas = getAttributes(); ZipFileAttributes zfas = getAttributes();
...@@ -951,7 +946,9 @@ public class ZipPath extends Path { ...@@ -951,7 +946,9 @@ public class ZipPath extends Path {
BasicFileAttributeView view = BasicFileAttributeView view =
target.getFileAttributeView(BasicFileAttributeView.class); target.getFileAttributeView(BasicFileAttributeView.class);
try { try {
view.setTimes(zfas.lastModifiedTime(), null, null); view.setTimes(zfas.lastModifiedTime(),
zfas.lastAccessTime(),
zfas.creationTime());
} catch (IOException x) { } catch (IOException x) {
// rollback? // rollback?
try { try {
......
...@@ -36,6 +36,7 @@ import java.io.OutputStream; ...@@ -36,6 +36,7 @@ import java.io.OutputStream;
import java.util.Arrays; import java.util.Arrays;
import java.util.Date; import java.util.Date;
import java.util.regex.PatternSyntaxException; import java.util.regex.PatternSyntaxException;
import java.util.concurrent.TimeUnit;
/** /**
* *
...@@ -48,7 +49,7 @@ class ZipUtils { ...@@ -48,7 +49,7 @@ class ZipUtils {
* Writes a 16-bit short to the output stream in little-endian byte order. * Writes a 16-bit short to the output stream in little-endian byte order.
*/ */
public static void writeShort(OutputStream os, int v) throws IOException { public static void writeShort(OutputStream os, int v) throws IOException {
os.write((v >>> 0) & 0xff); os.write(v & 0xff);
os.write((v >>> 8) & 0xff); os.write((v >>> 8) & 0xff);
} }
...@@ -56,7 +57,7 @@ class ZipUtils { ...@@ -56,7 +57,7 @@ class ZipUtils {
* Writes a 32-bit int to the output stream in little-endian byte order. * Writes a 32-bit int to the output stream in little-endian byte order.
*/ */
public static void writeInt(OutputStream os, long v) throws IOException { 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 >>> 8) & 0xff));
os.write((int)((v >>> 16) & 0xff)); os.write((int)((v >>> 16) & 0xff));
os.write((int)((v >>> 24) & 0xff)); os.write((int)((v >>> 24) & 0xff));
...@@ -66,7 +67,7 @@ class ZipUtils { ...@@ -66,7 +67,7 @@ class ZipUtils {
* Writes a 64-bit int to the output stream in little-endian byte order. * Writes a 64-bit int to the output stream in little-endian byte order.
*/ */
public static void writeLong(OutputStream os, long v) throws IOException { 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 >>> 8) & 0xff));
os.write((int)((v >>> 16) & 0xff)); os.write((int)((v >>> 16) & 0xff));
os.write((int)((v >>> 24) & 0xff)); os.write((int)((v >>> 24) & 0xff));
...@@ -132,6 +133,27 @@ class ZipUtils { ...@@ -132,6 +133,27 @@ class ZipUtils {
d.getSeconds() >> 1; 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 regexMetaChars = ".^$+{[]|()";
private static final String globMetaChars = "\\*?[{"; private static final String globMetaChars = "\\*?[{";
private static boolean isRegexMeta(char c) { private static boolean isRegexMeta(char c) {
......
...@@ -31,5 +31,9 @@ disabledMechanisms = { ...@@ -31,5 +31,9 @@ disabledMechanisms = {
CKM_SHA256_RSA_PKCS CKM_SHA256_RSA_PKCS
CKM_SHA384_RSA_PKCS CKM_SHA384_RSA_PKCS
CKM_SHA512_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
} }
...@@ -64,7 +64,6 @@ public class ZipFSTester { ...@@ -64,7 +64,6 @@ public class ZipFSTester {
fs0.close(); // sync to file fs0.close(); // sync to file
fs = newZipFileSystem(tmpfsPath, new HashMap<String, Object>()); fs = newZipFileSystem(tmpfsPath, new HashMap<String, Object>());
try { try {
// prepare a src // prepare a src
Path src = getTempPath(); Path src = getTempPath();
...@@ -146,13 +145,6 @@ public class ZipFSTester { ...@@ -146,13 +145,6 @@ public class ZipFSTester {
Path fs2Path = getTempPath(); Path fs2Path = getTempPath();
Path fs3Path = 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 // create a new filesystem, copy everything from fs
Map<String, Object> env = new HashMap<String, Object>(); Map<String, Object> env = new HashMap<String, Object>();
env.put("createNew", true); env.put("createNew", true);
...@@ -280,7 +272,6 @@ public class ZipFSTester { ...@@ -280,7 +272,6 @@ public class ZipFSTester {
walk(fs4.getPath("/")); walk(fs4.getPath("/"));
System.out.println("closing: fs4"); System.out.println("closing: fs4");
fs4.close(); fs4.close();
System.out.printf("failed=%d%n", failed); System.out.printf("failed=%d%n", failed);
fs1Path.delete(); fs1Path.delete();
...@@ -426,6 +417,8 @@ public class ZipFSTester { ...@@ -426,6 +417,8 @@ public class ZipFSTester {
} }
private static void mkdirs(Path path) throws IOException { private static void mkdirs(Path path) throws IOException {
if (path.exists())
return;
path = path.toAbsolutePath(); path = path.toAbsolutePath();
Path parent = path.getParent(); Path parent = path.getParent();
if (parent != null) { if (parent != null) {
......
...@@ -22,15 +22,19 @@ ...@@ -22,15 +22,19 @@
*/ */
/* @test /* @test
* @bug 4607272 * @bug 4607272 6999915
* @summary Unit test for AsynchronousSocketChannel * @summary Unit test for AsynchronousSocketChannel
* @run main/othervm -XX:+DisableExplicitGC -mx64m Leaky * @run main/othervm -XX:+DisableExplicitGC -XX:MaxDirectMemorySize=64m Leaky
*/ */
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.BufferPoolMXBean;
import java.nio.channels.*; import java.nio.channels.*;
import java.net.*; import java.net.*;
import java.util.List;
import java.util.concurrent.Future; import java.util.concurrent.Future;
import java.util.concurrent.ThreadFactory;
import java.lang.management.ManagementFactory;
/** /**
* Heap buffers must be substituted with direct buffers when doing I/O. This * Heap buffers must be substituted with direct buffers when doing I/O. This
...@@ -49,13 +53,13 @@ public class Leaky { ...@@ -49,13 +53,13 @@ public class Leaky {
private final ByteBuffer dst; private final ByteBuffer dst;
private Future<Integer> readResult; private Future<Integer> readResult;
Connection() throws Exception { Connection(AsynchronousChannelGroup group) throws Exception {
ServerSocketChannel ssc = ServerSocketChannel ssc =
ServerSocketChannel.open().bind(new InetSocketAddress(0)); ServerSocketChannel.open().bind(new InetSocketAddress(0));
InetAddress lh = InetAddress.getLocalHost(); InetAddress lh = InetAddress.getLocalHost();
int port = ((InetSocketAddress)(ssc.getLocalAddress())).getPort(); int port = ((InetSocketAddress)(ssc.getLocalAddress())).getPort();
SocketAddress remote = new InetSocketAddress(lh, port); SocketAddress remote = new InetSocketAddress(lh, port);
client = AsynchronousSocketChannel.open(); client = AsynchronousSocketChannel.open(group);
client.connect(remote).get(); client.connect(remote).get();
peer = ssc.accept(); peer = ssc.accept();
ssc.close(); ssc.close();
...@@ -77,11 +81,21 @@ public class Leaky { ...@@ -77,11 +81,21 @@ public class Leaky {
} }
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
ThreadFactory threadFactory = new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setDaemon(true);
return t;
}
};
AsynchronousChannelGroup group =
AsynchronousChannelGroup.withFixedThreadPool(4, threadFactory);
final int CONNECTION_COUNT = 10; final int CONNECTION_COUNT = 10;
Connection[] connections = new Connection[CONNECTION_COUNT]; Connection[] connections = new Connection[CONNECTION_COUNT];
for (int i=0; i<CONNECTION_COUNT; i++) { for (int i=0; i<CONNECTION_COUNT; i++) {
connections[i] = new Connection(); connections[i] = new Connection(group);
} }
for (int i=0; i<1024; i++) { for (int i=0; i<1024; i++) {
...@@ -100,5 +114,20 @@ public class Leaky { ...@@ -100,5 +114,20 @@ public class Leaky {
conn.finishRead(); conn.finishRead();
} }
} }
// print summary of buffer pool usage
List<BufferPoolMXBean> pools =
ManagementFactory.getPlatformMXBeans(BufferPoolMXBean.class);
for (BufferPoolMXBean pool: pools)
System.out.format(" %8s ", pool.getName());
System.out.println();
for (int i=0; i<pools.size(); i++)
System.out.format("%6s %10s %10s ", "Count", "Capacity", "Memory");
System.out.println();
for (BufferPoolMXBean pool: pools) {
System.out.format("%6d %10d %10d ",
pool.getCount(), pool.getTotalCapacity(), pool.getMemoryUsed());
}
System.out.println();
} }
} }
...@@ -56,23 +56,44 @@ public class IteratorWeakConsistency { ...@@ -56,23 +56,44 @@ public class IteratorWeakConsistency {
// test(new ArrayBlockingQueue(20)); // test(new ArrayBlockingQueue(20));
} }
void test(Queue q) throws Throwable { void test(Queue q) {
// TODO: make this more general // TODO: make this more general
for (int i = 0; i < 10; i++) try {
q.add(i); for (int i = 0; i < 10; i++)
Iterator it = q.iterator(); q.add(i);
q.poll(); Iterator it = q.iterator();
q.poll(); q.poll();
q.poll(); q.poll();
q.remove(7); q.poll();
List list = new ArrayList(); q.remove(7);
while (it.hasNext()) List list = new ArrayList();
list.add(it.next()); while (it.hasNext())
equal(list, Arrays.asList(0, 3, 4, 5, 6, 8, 9)); list.add(it.next());
check(! list.contains(null)); equal(list, Arrays.asList(0, 3, 4, 5, 6, 8, 9));
System.out.printf("%s: %s%n", check(! list.contains(null));
q.getClass().getSimpleName(), System.out.printf("%s: %s%n",
list); q.getClass().getSimpleName(),
list);
} catch (Throwable t) { unexpected(t); }
try {
q.clear();
q.add(1);
q.add(2);
q.add(3);
q.add(4);
Iterator it = q.iterator();
it.next();
q.remove(2);
q.remove(1);
q.remove(3);
boolean found4 = false;
while (it.hasNext()) {
found4 |= it.next().equals(4);
}
check(found4);
} catch (Throwable t) { unexpected(t); }
} }
//--------------------- Infrastructure --------------------------- //--------------------- Infrastructure ---------------------------
...@@ -85,7 +106,6 @@ public class IteratorWeakConsistency { ...@@ -85,7 +106,6 @@ public class IteratorWeakConsistency {
void equal(Object x, Object y) { void equal(Object x, Object y) {
if (x == null ? y == null : x.equals(y)) pass(); if (x == null ? y == null : x.equals(y)) pass();
else fail(x + " not equal to " + y);} else fail(x + " not equal to " + y);}
static Class<?> thisClass = new Object(){}.getClass().getEnclosingClass();
public static void main(String[] args) throws Throwable { public static void main(String[] args) throws Throwable {
new IteratorWeakConsistency().instanceMain(args);} new IteratorWeakConsistency().instanceMain(args);}
public void instanceMain(String[] args) throws Throwable { public void instanceMain(String[] args) throws Throwable {
......
/*
* 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");
}
}
}
/*
* 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());
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册