8280409: JarFile::getInputStream can fail with NPE accessing ze.getName()

Reviewed-by: mullan, alanb
This commit is contained in:
Lance Andersen 2022-02-23 16:56:50 +00:00
parent 99b8ed9dbf
commit a020b6ba8f
3 changed files with 1103 additions and 32 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2022, 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
@ -826,7 +826,8 @@ public class JarFile extends ZipFile {
* zip file entry.
* @param ze the zip file entry
* @return an input stream for reading the contents of the specified
* zip file entry
* zip file entry or null if the zip file entry does not exist
* within the jar file
* @throws ZipException if a zip file format error has occurred
* @throws IOException if an I/O error has occurred
* @throws SecurityException if any of the jar file entries
@ -837,6 +838,8 @@ public class JarFile extends ZipFile {
public synchronized InputStream getInputStream(ZipEntry ze)
throws IOException
{
Objects.requireNonNull(ze, "ze");
maybeInstantiateVerifier();
if (jv == null) {
return super.getInputStream(ze);
@ -850,21 +853,33 @@ public class JarFile extends ZipFile {
if (jv == null)
return super.getInputStream(ze);
}
// Return null InputStream when the specified entry is not found in the
// Jar
var je = verifiableEntry(ze);
if (je == null) {
return null;
}
// wrap a verifier stream around the real stream
return new JarVerifier.VerifierStream(
getManifestFromReference(),
verifiableEntry(ze),
super.getInputStream(ze),
jv);
getManifestFromReference(),
je,
super.getInputStream(ze),
jv);
}
private JarEntry verifiableEntry(ZipEntry ze) {
private JarEntry verifiableEntry(ZipEntry ze) throws ZipException {
if (ze instanceof JarFileEntry) {
// assure the name and entry match for verification
return ((JarFileEntry)ze).realEntry();
}
ze = getJarEntry(ze.getName());
// ZipEntry::getName should not return null, if it does, return null
var entryName = ze.getName();
if (entryName != null) {
ze = getJarEntry(entryName);
} else {
return null;
}
if (ze instanceof JarFileEntry) {
return ((JarFileEntry)ze).realEntry();
}

View File

@ -345,7 +345,8 @@ public class ZipFile implements ZipConstants, Closeable {
*
* @param entry the zip file entry
* @return the input stream for reading the contents of the specified
* zip file entry.
* zip file entry or null if the zip file entry does not exist
* within the zip file.
* @throws ZipException if a ZIP format error has occurred
* @throws IOException if an I/O error has occurred
* @throws IllegalStateException if the zip file has been closed
@ -368,28 +369,28 @@ public class ZipFile implements ZipConstants, Closeable {
}
in = new ZipFileInputStream(zsrc.cen, pos);
switch (CENHOW(zsrc.cen, pos)) {
case STORED:
synchronized (istreams) {
istreams.add(in);
}
return in;
case DEFLATED:
// Inflater likes a bit of slack
// MORE: Compute good size for inflater stream:
long size = CENLEN(zsrc.cen, pos) + 2;
if (size > 65536) {
size = 8192;
}
if (size <= 0) {
size = 4096;
}
InputStream is = new ZipFileInflaterInputStream(in, res, (int)size);
synchronized (istreams) {
istreams.add(is);
}
return is;
default:
throw new ZipException("invalid compression method");
case STORED:
synchronized (istreams) {
istreams.add(in);
}
return in;
case DEFLATED:
// Inflater likes a bit of slack
// MORE: Compute good size for inflater stream:
long size = CENLEN(zsrc.cen, pos) + 2;
if (size > 65536) {
size = 8192;
}
if (size <= 0) {
size = 4096;
}
InputStream is = new ZipFileInflaterInputStream(in, res, (int) size);
synchronized (istreams) {
istreams.add(is);
}
return is;
default:
throw new ZipException("invalid compression method");
}
}
}

File diff suppressed because it is too large Load Diff