changeset 1732:fe83e4b18082

8181432: Better processing of unresolved permissions Reviewed-by: mullan
author igerasim
date Thu, 06 Jul 2017 17:08:18 -0700
parents 1419e995bc69
children c7bda8ea6e0b
files src/share/classes/java/security/CodeSource.java src/share/classes/java/security/UnresolvedPermission.java src/share/classes/sun/misc/IOUtils.java
diffstat 3 files changed, 40 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/java/security/CodeSource.java	Wed Jul 12 11:21:55 2017 -0700
+++ b/src/share/classes/java/security/CodeSource.java	Thu Jul 06 17:08:18 2017 -0700
@@ -34,6 +34,7 @@
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.security.cert.*;
+import sun.misc.IOUtils;
 
 /**
  *
@@ -540,6 +541,8 @@
             // could all be present in the stream at the same time
             cfs = new Hashtable<String, CertificateFactory>(3);
             certList = new ArrayList(size > 20 ? 20 : size);
+        } else if (size < 0) {
+            throw new IOException("size cannot be negative");
         }
 
         for (int i = 0; i < size; i++) {
@@ -561,13 +564,7 @@
                 cfs.put(certType, cf);
             }
             // parse the certificate
-            byte[] encoded = null;
-            try {
-                encoded = new byte[ois.readInt()];
-            } catch (OutOfMemoryError oome) {
-                throw new IOException("Certificate too big");
-            }
-            ois.readFully(encoded);
+            byte[] encoded = IOUtils.readNBytes(ois, ois.readInt());
             ByteArrayInputStream bais = new ByteArrayInputStream(encoded);
             try {
                 certList.add(cf.generateCertificate(bais));
--- a/src/share/classes/java/security/UnresolvedPermission.java	Wed Jul 12 11:21:55 2017 -0700
+++ b/src/share/classes/java/security/UnresolvedPermission.java	Thu Jul 06 17:08:18 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -25,12 +25,16 @@
 
 package java.security;
 
+import sun.misc.IOUtils;
+
 import java.io.IOException;
 import java.io.ByteArrayInputStream;
+import java.security.cert.Certificate;
 import java.util.ArrayList;
 import java.util.Hashtable;
 import java.lang.reflect.*;
 import java.security.cert.*;
+import java.util.List;
 
 /**
  * The UnresolvedPermission class is used to hold Permissions that
@@ -549,6 +553,7 @@
     {
         CertificateFactory cf;
         Hashtable<String, CertificateFactory> cfs = null;
+        List<Certificate> certList = null;
 
         ois.defaultReadObject();
 
@@ -561,7 +566,9 @@
             // we know of 3 different cert types: X.509, PGP, SDSI, which
             // could all be present in the stream at the same time
             cfs = new Hashtable<String, CertificateFactory>(3);
-            this.certs = new java.security.cert.Certificate[size];
+            certList = new ArrayList<Certificate>(size > 20 ? 20 : size);
+        } else if (size < 0) {
+            throw new IOException("size cannot be negative");
         }
 
         for (int i=0; i<size; i++) {
@@ -583,20 +590,18 @@
                 cfs.put(certType, cf);
             }
             // parse the certificate
-            byte[] encoded=null;
-            try {
-                encoded = new byte[ois.readInt()];
-            } catch (OutOfMemoryError oome) {
-                throw new IOException("Certificate too big");
-            }
-            ois.readFully(encoded);
+            byte[] encoded = IOUtils.readNBytes(ois, ois.readInt());
             ByteArrayInputStream bais = new ByteArrayInputStream(encoded);
             try {
-                this.certs[i] = cf.generateCertificate(bais);
+                certList.add(cf.generateCertificate(bais));
             } catch (CertificateException ce) {
                 throw new IOException(ce.getMessage());
             }
             bais.close();
         }
+        if (certList != null) {
+            this.certs = certList.toArray(
+                    new java.security.cert.Certificate[size]);
+        }
     }
 }
--- a/src/share/classes/sun/misc/IOUtils.java	Wed Jul 12 11:21:55 2017 -0700
+++ b/src/share/classes/sun/misc/IOUtils.java	Thu Jul 06 17:08:18 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2017, 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
@@ -38,9 +38,9 @@
 public class IOUtils {
 
     /**
-     * Read up to <code>length</code> of bytes from <code>in</code>
+     * Read up to {@code length} of bytes from {@code in}
      * until EOF is detected.
-     * @param in input stream, must not be null
+     * @param is input stream, must not be null
      * @param length number of bytes to read, -1 or Integer.MAX_VALUE means
      *        read as much as possible
      * @param readAll if true, an EOFException will be thrown if not enough
@@ -78,6 +78,24 @@
         }
         return output;
     }
+
+    /**
+     * Read {@code length} of bytes from {@code in}. An exception is
+     * thrown if there are not enough bytes in the stream.
+     *
+     * @param is input stream, must not be null
+     * @param length number of bytes to read, must not be negative
+     * @return bytes read
+     * @throws IOException if any IO error or a premature EOF is detected, or
+     *      if {@code length} is negative since this length is usually also
+     *      read from {@code is}.
+     */
+    public static byte[] readNBytes(InputStream is, int length) throws IOException {
+        if (length < 0) {
+            throw new IOException("length cannot be negative: " + length);
+        }
+        return readFully(is, length, true);
+    }
     
     /*
      * <p> Creates a new empty file in the specified directory, using the