src/jdk/nashorn/internal/runtime/NashornLoader.java

Tue, 12 Mar 2013 18:12:42 +0530

author
sundar
date
Tue, 12 Mar 2013 18:12:42 +0530
changeset 136
c54e218333be
parent 108
a971adb68f38
child 468
dc54df348a58
permissions
-rw-r--r--

8009757: Package access clean up and refactoring
Reviewed-by: jlaskey, lagergren, attila

     1 /*
     2  * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Oracle in the LICENSE file that accompanied this code.
    10  *
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    14  * version 2 for more details (a copy is included in the LICENSE file that
    15  * accompanied this code).
    16  *
    17  * You should have received a copy of the GNU General Public License version
    18  * 2 along with this work; if not, write to the Free Software Foundation,
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    20  *
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    24  */
    26 package jdk.nashorn.internal.runtime;
    28 import java.io.File;
    29 import java.io.IOException;
    30 import java.net.MalformedURLException;
    31 import java.net.URL;
    32 import java.net.URLClassLoader;
    33 import java.security.CodeSource;
    34 import java.security.Permission;
    35 import java.security.PermissionCollection;
    36 import java.security.Permissions;
    37 import java.security.SecureClassLoader;
    38 import jdk.nashorn.tools.Shell;
    40 /**
    41  * Superclass for Nashorn class loader classes. This stores Context
    42  * instance as an instance field. The current context can be
    43  * efficiently accessed from a given Class via it's ClassLoader.
    44  *
    45  */
    46 abstract class NashornLoader extends SecureClassLoader {
    47     private static final String OBJECTS_PKG = "jdk.nashorn.internal.objects";
    48     private static final String RUNTIME_PKG = "jdk.nashorn.internal.runtime";
    49     private static final String RUNTIME_LINKER_PKG = "jdk.nashorn.internal.runtime.linker";
    50     private static final String SCRIPTS_PKG = "jdk.nashorn.internal.scripts";
    52     private static final Permission[] SCRIPT_PERMISSIONS;
    53     static {
    54         SCRIPT_PERMISSIONS = new Permission[4];
    56         /*
    57          * Generated classes get access to runtime, runtime.linker, objects, scripts packages.
    58          * Note that the actual scripts can not access these because Java.type, Packages
    59          * prevent these restricted packages. And Java reflection and JSR292 access is prevented
    60          * for scripts. In other words, nashorn generated portions of script classes can access
    61          * clases in these implementation packages.
    62          */
    63         SCRIPT_PERMISSIONS[0] = new RuntimePermission("accessClassInPackage." + RUNTIME_PKG);
    64         SCRIPT_PERMISSIONS[1] = new RuntimePermission("accessClassInPackage." + RUNTIME_LINKER_PKG);
    65         SCRIPT_PERMISSIONS[2] = new RuntimePermission("accessClassInPackage." + OBJECTS_PKG);
    66         SCRIPT_PERMISSIONS[3] = new RuntimePermission("accessClassInPackage." + SCRIPTS_PKG);
    67     }
    69     private final Context context;
    71     final Context getContext() {
    72         return context;
    73     }
    75     NashornLoader(final ClassLoader parent, final Context context) {
    76         super(parent);
    77         this.context = context;
    78     }
    81     /**
    82      * Called by subclass after package access check is done
    83      * @param name name of the class to be loaded
    84      * @param resolve whether the class should be resolved or not
    85      * @return Class object
    86      * @throws ClassNotFoundException if class cannot be loaded
    87      */
    88     protected final Class<?> loadClassTrusted(final String name, final boolean resolve) throws ClassNotFoundException {
    89         return super.loadClass(name, resolve);
    90     }
    92     protected static void checkPackageAccess(final String name) {
    93         final int i = name.lastIndexOf('.');
    94         if (i != -1) {
    95             final SecurityManager sm = System.getSecurityManager();
    96             if (sm != null) {
    97                 final String pkgName = name.substring(0, i);
    98                 switch (pkgName) {
    99                     case RUNTIME_PKG:
   100                     case RUNTIME_LINKER_PKG:
   101                     case OBJECTS_PKG:
   102                     case SCRIPTS_PKG:
   103                         // allow it.
   104                         break;
   105                     default:
   106                         sm.checkPackageAccess(pkgName);
   107                 }
   108             }
   109         }
   110     }
   112     @Override
   113     protected PermissionCollection getPermissions(CodeSource codesource) {
   114         final Permissions permCollection = new Permissions();
   115         for (final Permission perm : SCRIPT_PERMISSIONS) {
   116             permCollection.add(perm);
   117         }
   118         return permCollection;
   119     }
   121     /**
   122      * Create a secure URL class loader for the given classpath
   123      * @param classPath classpath for the loader to search from
   124      * @return the class loader
   125      */
   126     static ClassLoader createClassLoader(final String classPath) {
   127         final ClassLoader parent = Shell.class.getClassLoader();
   128         final URL[] urls = pathToURLs(classPath);
   129         return URLClassLoader.newInstance(urls, parent);
   130     }
   132     /*
   133      * Utility method for converting a search path string to an array
   134      * of directory and JAR file URLs.
   135      *
   136      * @param path the search path string
   137      * @return the resulting array of directory and JAR file URLs
   138      */
   139     private static URL[] pathToURLs(final String path) {
   140         final String[] components = path.split(File.pathSeparator);
   141         URL[] urls = new URL[components.length];
   142         int count = 0;
   143         while(count < components.length) {
   144             final URL url = fileToURL(new File(components[count]));
   145             if (url != null) {
   146                 urls[count++] = url;
   147             }
   148         }
   149         if (urls.length != count) {
   150             final URL[] tmp = new URL[count];
   151             System.arraycopy(urls, 0, tmp, 0, count);
   152             urls = tmp;
   153         }
   154         return urls;
   155     }
   157     /*
   158      * Returns the directory or JAR file URL corresponding to the specified
   159      * local file name.
   160      *
   161      * @param file the File object
   162      * @return the resulting directory or JAR file URL, or null if unknown
   163      */
   164     private static URL fileToURL(final File file) {
   165         String name;
   166         try {
   167             name = file.getCanonicalPath();
   168         } catch (final IOException e) {
   169             name = file.getAbsolutePath();
   170         }
   171         name = name.replace(File.separatorChar, '/');
   172         if (!name.startsWith("/")) {
   173             name = "/" + name;
   174         }
   175         // If the file does not exist, then assume that it's a directory
   176         if (!file.isFile()) {
   177             name = name + "/";
   178         }
   179         try {
   180             return new URL("file", "", name);
   181         } catch (final MalformedURLException e) {
   182             throw new IllegalArgumentException("file");
   183         }
   184     }
   185 }

mercurial