8009554: Improve SerialJavaObject.getFields
authorlancea
Thu, 28 Mar 2013 06:55:42 -0400
changeset 18211 74aeb4741e3d
parent 18210 662eb8b3dfb5
child 18212 22f8c33b0690
8009554: Improve SerialJavaObject.getFields Reviewed-by: alanb, skoivu, mchung
jdk/src/share/classes/javax/sql/rowset/serial/SerialJavaObject.java
--- a/jdk/src/share/classes/javax/sql/rowset/serial/SerialJavaObject.java	Wed Mar 27 15:58:39 2013 -0700
+++ b/jdk/src/share/classes/javax/sql/rowset/serial/SerialJavaObject.java	Thu Mar 28 06:55:42 2013 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, 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
@@ -30,6 +30,7 @@
 import java.util.Arrays;
 import java.util.Vector;
 import javax.sql.rowset.RowSetWarning;
+import sun.reflect.Reflection;
 
 /**
  * A serializable mapping in the Java programming language of an SQL
@@ -119,10 +120,19 @@
      * @return an array of <code>Field</code> objects
      * @throws SerialException if an error is encountered accessing
      * the serialized object
+     * @throws  SecurityException  If a security manager, <i>s</i>, is present
+     * and the caller's class loader is not the same as or an
+     * ancestor of the class loader for the class of the
+     * {@linkplain #getObject object} being serialized
+     * and invocation of {@link SecurityManager#checkPackageAccess
+     * s.checkPackageAccess()} denies access to the package
+     * of that class.
+     * @see Class#getFields
      */
     public Field[] getFields() throws SerialException {
         if (fields != null) {
             Class<?> c = this.obj.getClass();
+            checkPackageAccess(c);
             return c.getFields();
         } else {
             throw new SerialException("SerialJavaObject does not contain" +
@@ -254,4 +264,38 @@
         }
         return false;
     }
+
+    /*
+     * Check if the caller is allowed to access the specified class's package.  If access is denied,
+     * throw a SecurityException.
+     *
+     */
+    private void checkPackageAccess(Class<?> clz) {
+        SecurityManager s = System.getSecurityManager();
+        if (s != null) {
+            if (sun.reflect.misc.ReflectUtil.needsPackageAccessCheck(
+                    getCallerClassLoader(), clz.getClassLoader())) {
+                String name = clz.getName();
+                int i = name.lastIndexOf('.');
+                if (i != -1) {
+                    s.checkPackageAccess(name.substring(0, i));
+                }
+            }
+        }
+    }
+
+    /* Internal method used to get the caller's caller class loader.
+     * Caution is required if you attempt to make changes as this method assumes
+     * the following stack frame count:
+     * 0: Reflection
+     * 1: getCallerClassLoader
+     * 2: checkPackageAccess
+     * 3: getFields
+     * 4: caller of getFields
+     */
+    private static ClassLoader getCallerClassLoader() {
+        Class<?> cc = Reflection.getCallerClass(4);
+        ClassLoader cl = (cc != null) ? cc.getClassLoader() : null;
+        return cl;
+    }
 }