changeset 4928:a2a7730dff8a

8009554: Improve SerialJavaObject.getFields Reviewed-by: alanb, skoivu
author lancea
date Fri, 22 Mar 2013 15:40:16 -0400
parents 777c7be511a7
children ccc9d6467f7a
files src/share/classes/javax/sql/rowset/serial/SerialJavaObject.java
diffstat 1 files changed, 38 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/javax/sql/rowset/serial/SerialJavaObject.java	Wed Jun 12 15:16:26 2013 +0100
+++ b/src/share/classes/javax/sql/rowset/serial/SerialJavaObject.java	Fri Mar 22 15:40:16 2013 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2011, 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
@@ -28,6 +28,7 @@
 import java.io.*;
 import java.lang.reflect.*;
 import javax.sql.rowset.RowSetWarning;
+import sun.reflect.Reflection;
 
 /**
  * A serializable mapping in the Java programming language of an SQL
@@ -120,10 +121,12 @@
      * @return an array of <code>Field</code> objects
      * @throws SerialException if an error is encountered accessing
      * the serialized object
+     * @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" +
@@ -153,4 +156,38 @@
         }
         chain.add(e);
     }
+
+    /*
+     * 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;
+    }
 }