[RFC][icedtea-web] Fixes for PluginAppletSecurityContext

Adam Domurad adomurad at redhat.com
Fri Aug 10 12:07:12 PDT 2012


On Fri, 2012-08-10 at 08:11 +0200, Thomas Meyer wrote:
> Hi,
> 
> several fixes and clean ups for PluginAppletSecurityContext.
> 
> with kind regards
> thomas

Good stuff! Comments inline.


> # HG changeset patch
> # Parent caefdb0bc90aa0894e1781f3e105ad8277e1983b
> 
> diff -r caefdb0bc90a
> plugin/icedteanp/java/sun/applet/PluginAppletSecurityContext.java
> ---
> a/plugin/icedteanp/java/sun/applet/PluginAppletSecurityContext.java Thu Aug 09 20:14:53 2012 +0200
> +++
> b/plugin/icedteanp/java/sun/applet/PluginAppletSecurityContext.java Thu Aug 09 20:57:20 2012 +0200
> @@ -49,213 +49,56 @@
>  import java.security.AllPermission;
>  import java.security.BasicPermission;
>  import java.security.CodeSource;
> +import java.security.Permission;
>  import java.security.Permissions;
>  import java.security.PrivilegedAction;
>  import java.security.ProtectionDomain;
>  import java.util.ArrayList;
> +import java.util.HashMap;
>  import java.util.Hashtable;
>  import java.util.List;
>  import java.util.Map;
> +import java.util.logging.StreamHandler;
Eclipse says this import is unused ?
>  
>  import net.sourceforge.jnlp.runtime.JNLPRuntime;
>  import net.sourceforge.jnlp.DefaultLaunchHandler;
>  import netscape.javascript.JSObjectCreatePermission;
>  
> -class Signature {
> -    private String signature;
> -    private int currentIndex;
> -    private List<Class> typeList;
> -    private static final char ARRAY = '[';
> -    private static final char OBJECT = 'L';
> -    private static final char SIGNATURE_ENDCLASS = ';';
> -    private static final char SIGNATURE_FUNC = '(';
> -    private static final char SIGNATURE_ENDFUNC = ')';
> -    private static final char VOID = 'V';
> -    private static final char BOOLEAN = 'Z';
> -    private static final char BYTE = 'B';
> -    private static final char CHARACTER = 'C';
> -    private static final char SHORT = 'S';
> -    private static final char INTEGER = 'I';
> -    private static final char LONG = 'J';
> -    private static final char FLOAT = 'F';
> -    private static final char DOUBLE = 'D';
> -
> -    private String nextTypeName() {
> -        char key = signature.charAt(currentIndex++);
> -
> -        switch (key) {
> -            case ARRAY:
> -                return nextTypeName() + "[]";
> -
> -            case OBJECT:
> -                int endClass = signature.indexOf(SIGNATURE_ENDCLASS,
> currentIndex);
> -                String retVal = signature.substring(currentIndex,
> endClass);
> -                retVal = retVal.replace('/', '.');
> -                currentIndex = endClass + 1;
> -                return retVal;
> -
> -                // FIXME: generated bytecode with classes named after
> -                // primitives will not work in this scheme -- those
> -                // classes will be incorrectly treated as primitive
> -                // types.
> -            case VOID:
> -                return "void";
> -            case BOOLEAN:
> -                return "boolean";
> -            case BYTE:
> -                return "byte";
> -            case CHARACTER:
> -                return "char";
> -            case SHORT:
> -                return "short";
> -            case INTEGER:
> -                return "int";
> -            case LONG:
> -                return "long";
> -            case FLOAT:
> -                return "float";
> -            case DOUBLE:
> -                return "double";
> -
> -            case SIGNATURE_ENDFUNC:
> -                return null;
> -
> -            case SIGNATURE_FUNC:
> -                return nextTypeName();
> -
> -            default:
> -                throw new IllegalArgumentException(
> -                                        "Invalid JNI signature
> character '" + key + "'");
> -        }
> -    }
> -
> -    public Signature(String signature, ClassLoader cl) {
> -        this.signature = signature;
> -        currentIndex = 0;
> -        typeList = new ArrayList<Class>(10);
> -
> -        String elem;
> -        while (currentIndex < signature.length()) {
> -            elem = nextTypeName();
> -
> -            if (elem == null) // end of signature
> -                continue;
> -
> -            Class primitive = primitiveNameToType(elem);
> -            if (primitive != null)
> -                typeList.add(primitive);
> -            else {
> -                int dimsize = 0;
> -                int n = elem.indexOf('[');
> -                if (n != -1) {
> -                    String arrayType = elem.substring(0, n);
> -                    dimsize++;
> -                    n = elem.indexOf('[', n + 1);
> -                    while (n != -1) {
> -                        dimsize++;
> -                        n = elem.indexOf('[', n + 1);
> -                    }
> -                    int[] dims = new int[dimsize];
> -                    primitive = primitiveNameToType(arrayType);
> -                    if (primitive != null) {
> -                        typeList.add(Array.newInstance(primitive,
> dims)
> -                                                                .getClass());
> -                    } else
> -                        typeList.add(Array.newInstance(
> -
> getClass(arrayType, cl), dims).getClass());
> -                } else {
> -                    typeList.add(getClass(elem, cl));
> -                }
> -            }
> -        }
> -        if (signature.length() < 2) {
> -            throw new IllegalArgumentException("Invalid JNI signature
> '"
> -                                        + signature + "'");
> -        }
> -    }
> -
> -    public static Class getClass(String name, ClassLoader cl) {
> -
> -        Class c = null;
> -
> -        try {
> -            c = Class.forName(name);
> -        } catch (ClassNotFoundException cnfe) {
> -
> -            PluginDebug.debug("Class ", name, " not found in
> primordial loader. Looking in ", cl);
> -            try {
> -                c = cl.loadClass(name);
> -            } catch (ClassNotFoundException e) {
> -                throw (new RuntimeException(new
> ClassNotFoundException("Unable to find class " + name)));
> -            }
> -        }
> -
> -        return c;
> -    }
> -
> -    public static Class primitiveNameToType(String name) {
> -        if (name.equals("void"))
> -            return Void.TYPE;
> -        else if (name.equals("boolean"))
> -            return Boolean.TYPE;
> -        else if (name.equals("byte"))
> -            return Byte.TYPE;
> -        else if (name.equals("char"))
> -            return Character.TYPE;
> -        else if (name.equals("short"))
> -            return Short.TYPE;
> -        else if (name.equals("int"))
> -            return Integer.TYPE;
> -        else if (name.equals("long"))
> -            return Long.TYPE;
> -        else if (name.equals("float"))
> -            return Float.TYPE;
> -        else if (name.equals("double"))
> -            return Double.TYPE;
> -        else
> -            return null;
> -    }
> -
> -    public Class[] getClassArray() {
> -        return typeList.subList(0, typeList.size()).toArray(new
> Class[] {});
> -    }
> -}
> -
>  public class PluginAppletSecurityContext {
>  
> -    private static Hashtable<ClassLoader, URL> classLoaders = new
> Hashtable<ClassLoader, URL>();
> -    private static Hashtable<Integer, ClassLoader>
> instanceClassLoaders = new Hashtable<Integer, ClassLoader>();
> +    private final static Map<ClassLoader, URL> classLoaders = new
> Hashtable<ClassLoader, URL>();
> +    private final static Map<Integer, ClassLoader>
> instanceClassLoaders = new Hashtable<Integer, ClassLoader>();
>  
> -    private PluginObjectStore store =
> PluginObjectStore.getInstance();
> -    private Throwable throwable = null;
> -    private ClassLoader liveconnectLoader =
> ClassLoader.getSystemClassLoader();
> -    int identifier = 0;
> +    private final PluginObjectStore store =
> PluginObjectStore.getInstance();
> +    private final ClassLoader liveconnectLoader =
> ClassLoader.getSystemClassLoader();
> +    private final int identifier;
> +    private final PluginStreamHandler streamhandler;
>  
> -    public static PluginStreamHandler streamhandler;
> +    private Throwable throwable;
> +    private long startTime;
>  
> -    long startTime = 0;
> -
> -    public PluginAppletSecurityContext(int identifier) {
> +    public PluginAppletSecurityContext(int identifier,
> PluginStreamHandler streamhandler) {
>          this.identifier = identifier;
> +        this.streamhandler = streamhandler;
Definitely an improvement, not sure why it was static to begin with.
>  
>          // We need a security manager.. and since there is a good
> chance that
>          // an applet will be loaded at some point, we should make it
> the SM
>          // that JNLPRuntime will try to install
>          if (System.getSecurityManager() == null) {
> -            JNLPRuntime.initialize(/* isApplication */false);
> +            JNLPRuntime.initialize( /* isApplication */ false);
>              JNLPRuntime.setDefaultLaunchHandler(new
> DefaultLaunchHandler(System.err));
>          }
>  
>          JNLPRuntime.disableExit();
>  
> -        URL u = null;
>          try {
> -            u = new URL("file://");
> -        } catch (Exception e) {
> +            URL u = new URL("file://");
> +
> PluginAppletSecurityContext.classLoaders.put(liveconnectLoader, u);
> +        } catch (MalformedURLException e) {
>              e.printStackTrace();
>          }
>  
> -        this.classLoaders.put(liveconnectLoader, u);
This changes functionality somewhat - from what I can see, getLoaderInfo
iterates the keySet of classLoaders, so it will be affected by the
placement change. OTOH this method seems to be only used for printing
the classloader information, so I'm not sure what to make of it.

> +        prePopulateLCClasses();
>      }
>  
>      private static <V> V parseCall(String s, ClassLoader cl, Class<V>
> c) {
> @@ -269,7 +112,7 @@
>              throw new RuntimeException("Unexpected call value.");
>      }
>  
> -    private Object parseArgs(String s, Class c) {
> +    private Object parseArgs(String s, Class<?> c) {
>          if (c == Boolean.TYPE || c == Boolean.class)
>              return new Boolean(s);
>          else if (c == Byte.TYPE || c == Byte.class)
> @@ -296,20 +139,16 @@
>  
>      public void associateSrc(ClassLoader cl, URL src) {
>          PluginDebug.debug("Associating ", cl, " with ", src);
> -        this.classLoaders.put(cl, src);
> +        PluginAppletSecurityContext.classLoaders.put(cl, src);
Java needs a This keyword :). Improvement over using 'this', though.
>      }
>  
>      public void associateInstance(Integer i, ClassLoader cl) {
>          PluginDebug.debug("Associating ", cl, " with instance ", i);
> -        this.instanceClassLoaders.put(i, cl);
> -    }
> -
> -    public static void setStreamhandler(PluginStreamHandler sh) {
> -        streamhandler = sh;
This static setter was awkward, agreed here.
> +        PluginAppletSecurityContext.instanceClassLoaders.put(i, cl);
>      }
>  
>      public static Map<String, String> getLoaderInfo() {
> -        Hashtable<String, String> map = new Hashtable<String,
> String>();
> +        Map<String, String> map = new HashMap<String, String>();
>  
>          for (ClassLoader loader :
> PluginAppletSecurityContext.classLoaders.keySet()) {
>              map.put(loader.getClass().getName(),
> classLoaders.get(loader).toString());
> @@ -325,7 +164,7 @@
>          try {
>              if (message.startsWith("FindClass")) {
>                  ClassLoader cl = null;
> -                Class c = null;
> +                Class<?> c = null;
>                  cl = liveconnectLoader;
>                  String[] args = message.split(" ");
>                  Integer instance = new Integer(args[1]);
> @@ -338,7 +177,7 @@
>                      write(reference, "FindClass " +
> store.getIdentifier(c));
>                  } catch (ClassNotFoundException cnfe) {
>  
> -                    cl = this.instanceClassLoaders.get(instance);
> +                    cl =
> PluginAppletSecurityContext.instanceClassLoaders.get(instance);
>                      PluginDebug.debug("Not found. Looking in ", cl);
>  
>                      if (instance != 0 && cl != null) {
> @@ -359,8 +198,8 @@
>                  String[] args = message.split(" ");
>                  Integer classID = parseCall(args[1], null,
> Integer.class);
>                  String methodName = parseCall(args[2], null,
> String.class);
> -                Signature signature = parseCall(args[3], ((Class)
> store.getObject(classID)).getClassLoader(), Signature.class);
> -                Object[] a = signature.getClassArray();
> +                Signature signature = parseCall(args[3], ((Class<?>)
> store.getObject(classID)).getClassLoader(), Signature.class);
> +//                Object[] a = signature.getClassArray();
I'd rather just remove this if its really unneeded rather than keep it
as a comment.
>                  Class<?> c;
>  
> @@ -372,7 +211,7 @@
>                      c = store.getObject(classID).getClass();
>  
>                  Method m = null;
> -                Constructor cs = null;
> +                Constructor<?> cs = null;
>                  Object o = null;
>                  if (methodName.equals("<init>")
>                                                  ||
> methodName.equals("<clinit>")) {
> @@ -403,7 +242,7 @@
>                  write(reference, "GetStaticFieldID " +
> store.getIdentifier(f));
>              } else if (message.startsWith("GetStaticField")) {
>                  String[] args = message.split(" ");
> -                String type = parseCall(args[1], null, String.class);
> +//                String type = parseCall(args[1], null,
> String.class);
Same here
>                  Integer classID = parseCall(args[1], null,
> Integer.class);
>                  Integer fieldID = parseCall(args[2], null,
> Integer.class);
>  
> @@ -490,7 +329,7 @@
>  
>                  AccessControlContext acc = callContext != null ?
> callContext : getClosedAccessControlContext();
>                  checkPermission(src,
> -
> message.startsWith("SetStaticField") ? (Class) o : o.getClass(),
> +
> message.startsWith("SetStaticField") ? (Class<?>) o : o.getClass(),
>                                                  acc);
>  
>                  Object ret = AccessController.doPrivileged(new
> PrivilegedAction<Object>() {
> @@ -515,7 +354,7 @@
>                  Integer index = parseCall(args[2], null,
> Integer.class);
>  
>                  Object ret = Array.get(store.getObject(arrayID),
> index);
> -                Class retClass =
> store.getObject(arrayID).getClass().getComponentType(); // prevent
> auto-boxing influence
> +                Class<?> retClass =
> store.getObject(arrayID).getClass().getComponentType(); // prevent
> auto-boxing influence
>  
>                  if (ret == null) {
>                      write(reference, "GetObjectArrayElement
> literalreturn null");
> @@ -555,13 +394,12 @@
>                  Integer arrayID = parseCall(args[1], null,
> Integer.class);
>  
>                  Object o = store.getObject(arrayID);
> -                int len = 0;
> -                len = Array.getLength(o);
> +//                int len = Array.getLength(o);
Same
>  
>                  write(reference, "GetArrayLength " +
> Array.getLength(o));
>              } else if (message.startsWith("GetField")) {
>                  String[] args = message.split(" ");
> -                String type = parseCall(args[1], null, String.class);
> +//                String type = parseCall(args[1], null,
> String.class);
Same
>                  Integer objectID = parseCall(args[1], null,
> Integer.class);
>                  Integer fieldID = parseCall(args[2], null,
> Integer.class);
>  
> @@ -715,7 +553,7 @@
>                  Class<?> c = null;
>                  Class<?> ret = null;
>  
> -                c = (Class) store.getObject(classID);
> +                c = (Class<?>) store.getObject(classID);
>                  ret = c.getSuperclass();
>                  store.reference(ret);
>  
> @@ -749,9 +587,9 @@
>                  Integer stringID = parseCall(args[1], null,
> Integer.class);
>  
>                  String o = null;
> -                byte[] b = null;
> +//                byte[] b = null;
Same
>                  o = (String) store.getObject(stringID);
> -                b = o.getBytes("UTF-8");
> +//                b = o.getBytes("UTF-8");
Same
>  
>                  write(reference, "GetStringUTFLength " + o.length());
>              } else if (message.startsWith("GetStringLength")) {
> @@ -759,9 +597,9 @@
>                  Integer stringID = parseCall(args[1], null,
> Integer.class);
>  
>                  String o = null;
> -                byte[] b = null;
> +//                byte[] b = null;
Same
>                  o = (String) store.getObject(stringID);
> -                b = o.getBytes("UTF-16LE");
> +//                b = o.getBytes("UTF-16LE");
Same
>  
>                  write(reference, "GetStringLength " + o.length());
>              } else if (message.startsWith("GetStringUTFChars")) {
> @@ -776,10 +614,7 @@
>                  buf = new StringBuffer(b.length * 2);
>                  buf.append(b.length);
>                  for (int i = 0; i < b.length; i++)
> -                    buf
> -                                                        .append(" "
> -
> + Integer
> -                                                                                        .toString(((int) b[i]) & 0x0ff, 16));
> +                    buf.append(" " + Integer.toString(((int) b[i]) &
> 0x0ff, 16));
Better :)
>  
>                  write(reference, "GetStringUTFChars " + buf);
>              } else if (message.startsWith("GetStringChars")) {
> @@ -795,10 +630,7 @@
>                  buf = new StringBuffer(b.length * 2);
>                  buf.append(b.length);
>                  for (int i = 0; i < b.length; i++)
> -                    buf
> -                                                        .append(" "
> -
> + Integer
> -                                                                                        .toString(((int) b[i]) & 0x0ff, 16));
> +                    buf.append(" " + Integer.toString(((int) b[i]) &
> 0x0ff, 16));
>  
>                  PluginDebug.debug("Java: GetStringChars: ", o);
>                  PluginDebug.debug("  String BYTES: ", buf);
> @@ -815,10 +647,7 @@
>                  buf = new StringBuffer(b.length * 2);
>                  buf.append(b.length);
>                  for (int i = 0; i < b.length; i++)
> -                    buf
> -                            .append(" "
> -                                    + Integer
> -                                            .toString(((int) b[i]) &
> 0x0ff, 16));
> +                    buf.append(" " + Integer.toString(((int) b[i]) &
> 0x0ff, 16));
>  
>                  write(reference, "GetToStringValue " + buf);
>              } else if (message.startsWith("NewArray")) {
> @@ -828,7 +657,7 @@
>  
>                  Object newArray = null;
>  
> -                Class c;
> +                Class<?> c;
>                  if (type.equals("bool")) {
>                      c = Boolean.class;
>                  } else if (type.equals("double")) {
> @@ -855,7 +684,7 @@
>                  Integer classNameID = parseCall(args[1], null,
> Integer.class);
>                  Integer methodNameID = parseCall(args[2], null,
> Integer.class);
>  
> -                Class c = (Class<?>) store.getObject(classNameID);
> +                Class<?> c = (Class<?>) store.getObject(classNameID);
>                  String methodName = (String)
> store.getObject(methodNameID);
>  
>                  Method method = null;
> @@ -872,7 +701,7 @@
>                  write(reference, "HasMethod " + hasMethod);
>              } else if (message.startsWith("HasPackage")) {
>                  String[] args = message.split(" ");
> -                Integer instance = parseCall(args[1], null,
> Integer.class);
> +//                Integer instance = parseCall(args[1], null,
> Integer.class);
Same
>                  Integer nameID = parseCall(args[2], null,
> Integer.class);
>                  String pkgName = (String) store.getObject(nameID);
>  
> @@ -886,7 +715,7 @@
>                  Integer classNameID = parseCall(args[1], null,
> Integer.class);
>                  Integer fieldNameID = parseCall(args[2], null,
> Integer.class);
>  
> -                Class c = (Class) store.getObject(classNameID);
> +                Class<?> c = (Class<?>) store.getObject(classNameID);
>                  String fieldName = (String)
> store.getObject(fieldNameID);
>  
>                  Field field = null;
> @@ -908,7 +737,7 @@
>                  Integer objectID = parseCall(args[3], null,
> Integer.class);
>  
>                  Object newArray = null;
> -                newArray = Array.newInstance((Class)
> store.getObject(classID),
> +                newArray = Array.newInstance((Class<?>)
> store.getObject(classID),
>                                                  length);
>  
>                  Object[] array = (Object[]) newArray;
> @@ -923,8 +752,8 @@
>                  Integer classID = parseCall(args[1], null,
> Integer.class);
>                  Integer methodID = parseCall(args[2], null,
> Integer.class);
>  
> -                final Constructor m = (Constructor)
> store.getObject(methodID);
> -                Class[] argTypes = m.getParameterTypes();
> +                final Constructor<?> m = (Constructor<?>)
> store.getObject(methodID);
> +                Class<?>[] argTypes = m.getParameterTypes();
>  
>                  Object[] arguments = new Object[argTypes.length];
>                  for (int i = 0; i < argTypes.length; i++) {
> @@ -934,7 +763,7 @@
>                  final Object[] fArguments = arguments;
>                  AccessControlContext acc = callContext != null ?
> callContext : getClosedAccessControlContext();
>  
> -                Class c = (Class) store.getObject(classID);
> +                Class<?> c = (Class<?>) store.getObject(classID);
>                  checkPermission(src, c, acc);
>  
>                  Object ret = AccessController.doPrivileged(new
> PrivilegedAction<Object>() {
> @@ -957,8 +786,8 @@
>              } else if (message.startsWith("NewObject")) {
>                  String[] args = message.split(" ");
>                  Integer classID = parseCall(args[1], null,
> Integer.class);
> -                Class c = (Class) store.getObject(classID);
> -                final Constructor cons;
> +                Class<?> c = (Class<?>) store.getObject(classID);
> +                final Constructor<?> cons;
>                  final Object[] fArguments;
>  
>                  Object[] arguments = new Object[args.length - 1];
> @@ -983,7 +812,7 @@
>                      castedArgs[i] = matchingConstructorAndArgs[i +
> 1];
>                  }
>  
> -                cons = (Constructor) matchingConstructorAndArgs[0];
> +                cons = (Constructor<?>)
> matchingConstructorAndArgs[0];
>                  fArguments = castedArgs;
>  
>                  String collapsedArgs = "";
> @@ -1126,7 +955,7 @@
>       * @param acc AccessControlContext for this execution
>       * @throws AccessControlException If the script has insufficient
> permissions
>       */
> -    public void checkPermission(String jsSrc, Class target,
> AccessControlContext acc) throws AccessControlException {
> +    public void checkPermission(String jsSrc, Class<?> target,
> AccessControlContext acc) throws AccessControlException {
>          // NPRuntime does not allow cross-site calling. We therefore
> always
>          // allow this, for the time being
>          return;
> @@ -1138,7 +967,7 @@
>                                  + " " + message);
>      }
>  
> -    public void prePopulateLCClasses() {
> +    private void prePopulateLCClasses() {
>  
>          int classID;
>  
> @@ -1209,7 +1038,7 @@
>      private int prepopulateClass(String name) {
>          name = name.replace('/', '.');
>          ClassLoader cl = liveconnectLoader;
> -        Class c = null;
> +        Class<?> c = null;
>  
>          try {
>              c = cl.loadClass(name);
> @@ -1223,12 +1052,12 @@
>      }
>  
>      private int prepopulateMethod(int classID, String methodName,
> String signatureStr) {
> -        Signature signature = parseCall(signatureStr, ((Class)
> store.getObject(classID)).getClassLoader(), Signature.class);
> -        Object[] a = signature.getClassArray();
> +        Signature signature = parseCall(signatureStr, ((Class<?>)
> store.getObject(classID)).getClassLoader(), Signature.class);
> +//        Object[] a = signature.getClassArray();
Same
>  
>          Class<?> c = (Class<?>) store.getObject(classID);
>          Method m = null;
> -        Constructor cs = null;
> +        Constructor<?> cs = null;
>  
>          try {
>              if (methodName.equals("<init>")
> @@ -1297,7 +1126,7 @@
>  
>          for (String privilege : nsPrivilegeList) {
>              if (privilege.equals("UniversalBrowserRead")) {
> -                BrowserReadPermission bp = new
> BrowserReadPermission();
> +                Permission bp = new BrowserReadPermission();
>                  grantedPermissions.add(bp);
>              } else if (privilege.equals("UniversalJavaPermission")) {
>                  AllPermission ap = new AllPermission();
May as well make this 'Permission ap = ' for consistency. Or possibly
make them both Permission p = ...;
> @@ -1324,7 +1153,7 @@
>  
>          ProtectionDomain pd = new ProtectionDomain(cs,
> grantedPermissions, null, null);
>  
> -        // Add to hashmap
> +        // Add to map
>          return new AccessControlContext(new ProtectionDomain[]
> { pd });
>      }
>  
> @@ -1335,14 +1164,148 @@
>          try {
>              Integer.parseInt((String) o);
>              isInt = true;
> -        } catch (Exception e) {
> +        } catch (NumberFormatException e) {
>              // don't care
>          }
>  
>          return isInt;
>      }
>  
> -    class BrowserReadPermission extends BasicPermission {
> +    private static class Signature {
Good change. Multiple classes per file at top level is a rather obscure
java feature.
> +        private final String signature;
> +        private final List<Class<?>> typeList;
> +
> +        private static final char ARRAY = '[';
> +        private static final char SIGNATURE_ENDCLASS = ';';
> +        private static final char SIGNATURE_FUNC = '(';
> +        private static final char SIGNATURE_ENDFUNC = ')';
> +        private static final char OBJECT = 'L';
> +        private static final char VOID = 'V';
> +        private static final char BOOLEAN = 'Z';
> +        private static final char BYTE = 'B';
> +        private static final char CHARACTER = 'C';
> +        private static final char SHORT = 'S';
> +        private static final char INTEGER = 'I';
> +        private static final char LONG = 'J';
> +        private static final char FLOAT = 'F';
> +        private static final char DOUBLE = 'D';
> +
> +        public Signature(String signature, ClassLoader cl) {
> +
> +            if (signature.length() < 2) {
> +                throw new IllegalArgumentException("Invalid JNI
> signature '"
> +                                            + signature + "'");
> +            }
> +
> +            this.signature = signature;
> +            this.typeList = new ArrayList<Class<?>>(10);
> +
> +            fillParameterTypeList(cl);
> +        }
> +
> +        void fillParameterTypeList(ClassLoader cl) {
> +
> +//         For example, the Java method:
> +//                long f (int n, String s, int[] arr);
> +//         has the following type signature:
> +//                (ILjava/lang/String;[I)J
> +
> +            for(int i = 0, n = signature.length(); i < n; i++) {
> +                char typeChar = signature.charAt(i);
> +                int dimsize = 0;
> +                Class<?> currentClass = null;
> +
> +                switch (typeChar) {
> +                case ARRAY:
> +                    for(; (typeChar = signature.charAt(i)) == ARRAY
> && i < n; i++)
> +                        dimsize++;
> +                }
> +
> +                switch (typeChar) {
> +                    case OBJECT:
> +                        int endClass =
> signature.indexOf(SIGNATURE_ENDCLASS, ++i);
> +                        String className = signature.substring(i,
> endClass);
> +                        className = className.replace('/', '.');
> +                        i = endClass;
> +                        currentClass = getClass(className, cl);
> +                        break;
> +
> +                // primitive types
> +                    case VOID:
> +                        currentClass = Void.TYPE;
> +                        break;
> +                    case BOOLEAN:
> +                        currentClass = Boolean.TYPE;
> +                        break;
> +                    case BYTE:
> +                        currentClass = Byte.TYPE;
> +                        break;
> +                    case CHARACTER:
> +                        currentClass = Character.TYPE;
> +                        break;
> +                    case SHORT:
> +                        currentClass = Short.TYPE;
> +                        break;
> +                    case INTEGER:
> +                        currentClass = Integer.TYPE;
> +                        break;
> +                    case LONG:
> +                        currentClass = Long.TYPE;
> +                        break;
> +                    case FLOAT:
> +                        currentClass = Float.TYPE;
> +                        break;
> +                    case DOUBLE:
> +                        currentClass = Double.TYPE;
> +                        break;
> +
> +                    case SIGNATURE_ENDFUNC:
> +                        n = i; // exit loop - don't add return type
> to typelist
> +                        break;
> +
> +                    case SIGNATURE_FUNC:
> +                        break;
> +
> +                    default:
> +                        throw new IllegalArgumentException(
> +                                                "Invalid JNI
> signature character '" + typeChar + "'");
> +                }
> +
> +                if(currentClass != null) {
> +                    if(dimsize > 0) {
> +                        int[] dims = new int[dimsize];
> +                        currentClass =
> Array.newInstance(currentClass, dims).getClass();
> +                    }
> +                    typeList.add(currentClass);
> +                }
> +            }
> +        }
> +
> +        private static Class<?> getClass(String name, ClassLoader cl)
> {
> +
> +            Class<?> c = null;
> +
> +            try {
> +                c = Class.forName(name);
> +            } catch (ClassNotFoundException cnfe) {
> +
> +                PluginDebug.debug("Class ", name, " not found in
> primordial loader. Looking in ", cl);
> +                try {
> +                    c = cl.loadClass(name);
> +                } catch (ClassNotFoundException e) {
> +                    throw (new RuntimeException(new
> ClassNotFoundException("Unable to find class " + name)));
> +                }
> +            }
> +
> +            return c;
> +        }
> +
> +        public Class<?>[] getClassArray() {
> +            return typeList.subList(0, typeList.size()).toArray(new
> Class<?>[] {});
> +        }
> +    }
I'm going to have to take your word that this class is identical to what
it was before ? I skimmed it and it looked OK.

> +    private static class BrowserReadPermission extends
> BasicPermission {
>          public BrowserReadPermission() {
>              super("browserRead");
>          }
> diff -r caefdb0bc90a plugin/icedteanp/java/sun/applet/PluginMain.java
> --- a/plugin/icedteanp/java/sun/applet/PluginMain.java  Thu Aug 09
> 20:14:53 2012 +0200
> +++ b/plugin/icedteanp/java/sun/applet/PluginMain.java  Thu Aug 09
> 20:57:20 2012 +0200
> @@ -106,9 +106,7 @@
>              // must be called before JNLPRuntime.initialize()
>              JNLPRuntime.setRedirectStreams(redirectStreams);
>  
> -            PluginAppletSecurityContext sc = new
> PluginAppletSecurityContext(0);
> -            sc.prePopulateLCClasses();
> -
> PluginAppletSecurityContext.setStreamhandler(streamHandler);
> +            PluginAppletSecurityContext sc = new
> PluginAppletSecurityContext(0, streamHandler);
>              AppletSecurityContextManager.addContext(0, sc);
>  
>              PluginAppletViewer.setStreamhandler(streamHandler);
> 

Overall looks good! Definitely worth having. I very much like changes
like this. In addition to my nits, needs a ChangeLog before being
push-ready, though.




More information about the distro-pkg-dev mailing list