import java.io.InputStream;\r
import java.io.PushbackInputStream;\r
import java.lang.reflect.Field;\r
+import java.security.AccessController;\r
+import java.security.PrivilegedAction;\r
import java.util.zip.InflaterInputStream;\r
import java.util.zip.ZipEntry;\r
import java.util.zip.ZipException;\r
\r
import org.apache.poi.util.POILogFactory;\r
import org.apache.poi.util.POILogger;\r
+import org.apache.poi.util.SuppressForbidden;\r
\r
/**\r
* This class wraps a {@link ZipFile} in order to check the\r
return addThreshold(zipIS);\r
}\r
\r
- @SuppressWarnings("resource")\r
- public static ThresholdInputStream addThreshold(InputStream zipIS) throws IOException {\r
+ public static ThresholdInputStream addThreshold(final InputStream zipIS) throws IOException {\r
ThresholdInputStream newInner;\r
if (zipIS instanceof InflaterInputStream) {\r
- try {\r
- Field f = FilterInputStream.class.getDeclaredField("in");\r
- f.setAccessible(true);\r
- InputStream oldInner = (InputStream)f.get(zipIS);\r
- newInner = new ThresholdInputStream(oldInner, null);\r
- f.set(zipIS, newInner);\r
- } catch (Exception ex) {\r
- logger.log(POILogger.WARN, "SecurityManager doesn't allow manipulation via reflection for zipbomb detection - continue with original input stream", ex);\r
- newInner = null;\r
- }\r
+ newInner = AccessController.doPrivileged(new PrivilegedAction<ThresholdInputStream>() {\r
+ @SuppressForbidden("TODO: Fix this to not use reflection (it will break in Java 9)! " +\r
+ "Better would be to wrap *before* instead of tyring to insert wrapper afterwards.")\r
+ public ThresholdInputStream run() {\r
+ ThresholdInputStream newInner = null;\r
+ try {\r
+ Field f = FilterInputStream.class.getDeclaredField("in");\r
+ f.setAccessible(true);\r
+ InputStream oldInner = (InputStream)f.get(zipIS);\r
+ newInner = new ThresholdInputStream(oldInner, null);\r
+ f.set(zipIS, newInner);\r
+ } catch (Exception ex) {\r
+ logger.log(POILogger.WARN, "SecurityManager doesn't allow manipulation via reflection for zipbomb detection - continue with original input stream", ex);\r
+ newInner = null;\r
+ }\r
+ return newInner;\r
+ }\r
+ });\r
} else {\r
// the inner stream is a ZipFileInputStream, i.e. the data wasn't compressed\r
newInner = null;\r
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URL;
+import java.security.AccessController;
import java.security.CodeSource;
+import java.security.PrivilegedAction;
import java.security.ProtectionDomain;
import java.util.ArrayList;
import java.util.Enumeration;
* @author Yegor Kozlov
*/
public final class OOXMLLite {
- private static Field _classes;
/**
* Destination directory to copy filtered classes
// make the field accessible, we defer this from static initialization to here to
// allow JDKs which do not have this field (e.g. IBM JDK) to at least load the class
// without failing, see https://issues.apache.org/bugzilla/show_bug.cgi?id=56550
- try {
- _classes = ClassLoader.class.getDeclaredField("classes");
- _classes.setAccessible(true);
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
+ final Field _classes = AccessController.doPrivileged(new PrivilegedAction<Field>() {
+ @SuppressForbidden("TODO: Reflection works until Java 8 on Oracle/Sun JDKs, but breaks afterwards (different classloader types, access checks)")
+ public Field run() {
+ try {
+ Field fld = ClassLoader.class.getDeclaredField("classes");
+ fld.setAccessible(true);
+ return fld;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+
+ }
+ });
ClassLoader appLoader = ClassLoader.getSystemClassLoader();
try {