Adding recursive call to the getResolvedClassInfo() method: look into the parent...
authorRahmadi Trimananda <rtrimana@uci.edu>
Fri, 28 Jun 2019 01:18:50 +0000 (18:18 -0700)
committerRahmadi Trimananda <rtrimana@uci.edu>
Fri, 28 Jun 2019 01:19:17 +0000 (18:19 -0700)
examples/Reflection.java
src/classes/java/lang/Class.java
src/classes/java/security/AllPermission.java [new file with mode: 0644]
src/classes/java/security/ProtectionDomain.java [new file with mode: 0644]
src/classes/sun/reflect/generics/reflectiveObjects/GenericArrayTypeImpl.java
src/classes/sun/reflect/generics/reflectiveObjects/ParameterizedTypeImpl.java
src/classes/sun/reflect/generics/reflectiveObjects/TypeVariableImpl.java
src/classes/sun/reflect/generics/reflectiveObjects/WildcardTypeImpl.java
src/main/gov/nasa/jpf/vm/ClassLoaderInfo.java
src/peers/gov/nasa/jpf/vm/JPF_java_lang_Class.java
src/peers/gov/nasa/jpf/vm/JPF_java_lang_ClassLoader.java

index cc13e07..9502a04 100644 (file)
@@ -9,6 +9,7 @@ import java.util.ArrayList;
 import java.util.Arrays;
 
 import java.math.BigInteger;
+import java.security.ProtectionDomain;
 
 public class Reflection {
 
@@ -79,8 +80,9 @@ public class Reflection {
       Type returnType = method.getGenericReturnType();
          Class.class.getSimpleName();*/
       //System.out.println(returnType);
-      BigInteger bi = new BigInteger("-1");
-         System.out.println(bi);
+         
+      //BigInteger bi = new BigInteger("-1");
+         //System.out.println(bi);
          
         /* TODO: This is an excerpt of the BigInteger library
                int radix = 10;
@@ -178,7 +180,7 @@ public class Reflection {
       System.out.println(returnType);*/
       
       /* TODO: Enumerate all methods in Class.class */
-      Method[] methods = Class.class.getMethods();
+      /*Method[] methods = Class.class.getMethods();
       for(Method mth : methods) {
                  System.out.println("===========================");
          System.out.println("Method: " + mth.getName());
@@ -189,7 +191,7 @@ public class Reflection {
                  System.out.println();
                  Type returnType = mth.getGenericReturnType();
                  System.out.println(returnType + "\n");
-      }
+      }*/
 
       /*Class[] parameterTypes = methods[0].getParameterTypes();
       for(Class parameterType: parameterTypes){
@@ -210,6 +212,9 @@ public class Reflection {
           System.out.println(bound);
       }
       System.out.println();*/
+         
+         ProtectionDomain pd = Class.class.getProtectionDomain();
+      System.out.println(pd);
    }
 }
 
index 3d21d02..7dd3947 100644 (file)
@@ -330,10 +330,12 @@ public final class Class<T> implements Serializable, GenericDeclaration, Type, A
   public Class<?>[] getDeclaredClasses() throws SecurityException {
     throw new UnsupportedOperationException();
   }
-  
-  public java.security.ProtectionDomain getProtectionDomain() {
+
+  // TODO: Fix for Groovy's model-checking
+  public native java.security.ProtectionDomain getProtectionDomain();
+  /*public java.security.ProtectionDomain getProtectionDomain() {
     throw new UnsupportedOperationException();
-  }
+  }*/
 
   void setProtectionDomain0(java.security.ProtectionDomain pd) {
     pd = null;  // Get rid of IDE warning 
diff --git a/src/classes/java/security/AllPermission.java b/src/classes/java/security/AllPermission.java
new file mode 100644 (file)
index 0000000..658c063
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2014, United States Government, as represented by the
+ * Administrator of the National Aeronautics and Space Administration.
+ * All rights reserved.
+ *
+ * The Java Pathfinder core (jpf-core) platform is licensed under the
+ * Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package java.security;
+
+import java.util.Enumeration;
+import sun.security.util.SecurityConstants;
+
+// TODO: Fix for Groovy's model-checking
+/**
+ * MJI model class for java.security.AllPermission library abstraction
+ */
+public final class AllPermission extends Permission {
+
+    private static final long serialVersionUID = -2916474571451318075L;
+
+    public AllPermission() {
+        super("<all permissions>");
+    }
+
+    public boolean implies(Permission p) {
+        return true;
+    }
+
+    public boolean equals(Object obj) {
+        return (obj instanceof AllPermission);
+    }
+
+    public int hashCode() {
+        return 1;
+    }
+
+    public String getActions() {
+        return "<all actions>";
+    }
+
+    public PermissionCollection newPermissionCollection() {
+        return new AllPermissionCollection();
+    }
+
+}
+
+
+final class AllPermissionCollection
+        extends PermissionCollection
+        implements java.io.Serializable
+{
+
+    // use serialVersionUID from JDK 1.2.2 for interoperability
+    private static final long serialVersionUID = -4023755556366636806L;
+
+    private boolean all_allowed; // true if any all permissions have been added
+
+    public AllPermissionCollection() {
+        all_allowed = false;
+    }
+
+    public void add(Permission permission) {
+        if (! (permission instanceof AllPermission))
+            throw new IllegalArgumentException("invalid permission: "+
+                    permission);
+        if (isReadOnly())
+            throw new SecurityException("attempt to add a Permission to a readonly PermissionCollection");
+
+        all_allowed = true; // No sync; staleness OK
+    }
+
+    public boolean implies(Permission permission) {
+        return all_allowed; // No sync; staleness OK
+    }
+
+    public Enumeration<Permission> elements() {
+        return new Enumeration<Permission>() {
+            private boolean hasMore = all_allowed;
+
+            public boolean hasMoreElements() {
+                return hasMore;
+            }
+
+            public Permission nextElement() {
+                hasMore = false;
+                return SecurityConstants.ALL_PERMISSION;
+            }
+        };
+    }
+}
diff --git a/src/classes/java/security/ProtectionDomain.java b/src/classes/java/security/ProtectionDomain.java
new file mode 100644 (file)
index 0000000..09650ab
--- /dev/null
@@ -0,0 +1,265 @@
+/*
+ * Copyright (C) 2014, United States Government, as represented by the
+ * Administrator of the National Aeronautics and Space Administration.
+ * All rights reserved.
+ *
+ * The Java Pathfinder core (jpf-core) platform is licensed under the
+ * Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package java.security;
+
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import sun.security.util.Debug;
+import sun.security.util.SecurityConstants;
+
+// TODO: Fix for Groovy's model-checking
+/**
+ * MJI model class for java.security.ProtectionDomain library abstraction
+ */
+public class ProtectionDomain {
+
+    private CodeSource codesource ;
+
+    private ClassLoader classloader;
+
+    private Principal[] principals;
+
+    private PermissionCollection permissions;
+
+    private boolean hasAllPerm = false;
+
+    private boolean staticPermissions;
+
+    final Key key = new Key();
+
+    private Debug debug = Debug.getInstance("domain");
+
+    public ProtectionDomain(CodeSource codesource,
+                            PermissionCollection permissions) {
+        this.codesource = codesource;
+        if (permissions != null) {
+            this.permissions = permissions;
+            this.permissions.setReadOnly();
+            if (permissions instanceof Permissions &&
+                    ((Permissions)permissions).allPermission != null) {
+                hasAllPerm = true;
+            }
+        }
+        this.classloader = null;
+        this.principals = new Principal[0];
+        staticPermissions = true;
+    }
+
+    public ProtectionDomain(CodeSource codesource,
+                            PermissionCollection permissions,
+                            ClassLoader classloader,
+                            Principal[] principals) {
+        this.codesource = codesource;
+        if (permissions != null) {
+            this.permissions = permissions;
+            this.permissions.setReadOnly();
+            if (permissions instanceof Permissions &&
+                    ((Permissions)permissions).allPermission != null) {
+                hasAllPerm = true;
+            }
+        }
+        this.classloader = classloader;
+        this.principals = (principals != null ? principals.clone():
+                new Principal[0]);
+        staticPermissions = false;
+    }
+
+    public final CodeSource getCodeSource() {
+        return this.codesource;
+    }
+
+    public final ClassLoader getClassLoader() {
+        return this.classloader;
+    }
+
+    public final Principal[] getPrincipals() {
+        return this.principals.clone();
+    }
+
+    public final PermissionCollection getPermissions() {
+        return permissions;
+    }
+
+    public boolean implies(Permission permission) {
+
+        if (hasAllPerm) {
+            // internal permission collection already has AllPermission -
+            // no need to go to policy
+            return true;
+        }
+
+        if (!staticPermissions &&
+                Policy.getPolicyNoCheck().implies(this, permission))
+            return true;
+        if (permissions != null)
+            return permissions.implies(permission);
+
+        return false;
+    }
+
+    boolean impliesCreateAccessControlContext() {
+        return implies(SecurityConstants.CREATE_ACC_PERMISSION);
+    }
+
+    @Override public String toString() {
+        String pals = "<no principals>";
+        if (principals != null && principals.length > 0) {
+            StringBuilder palBuf = new StringBuilder("(principals ");
+
+            for (int i = 0; i < principals.length; i++) {
+                palBuf.append(principals[i].getClass().getName() +
+                        " \"" + principals[i].getName() +
+                        "\"");
+                if (i < principals.length-1)
+                    palBuf.append(",\n");
+                else
+                    palBuf.append(")\n");
+            }
+            pals = palBuf.toString();
+        }
+
+        // Check if policy is set; we don't want to load
+        // the policy prematurely here
+        PermissionCollection pc = Policy.isSet() && seeAllp() ?
+                mergePermissions():
+                getPermissions();
+
+        return "ProtectionDomain "+
+                " "+codesource+"\n"+
+                " "+classloader+"\n"+
+                " "+pals+"\n"+
+                " "+pc+"\n";
+    }
+
+    private boolean seeAllp() {
+        SecurityManager sm = System.getSecurityManager();
+
+        if (sm == null) {
+            return true;
+        } else {
+            if (debug != null) {
+                if (sm.getClass().getClassLoader() == null &&
+                        Policy.getPolicyNoCheck().getClass().getClassLoader()
+                                == null) {
+                    return true;
+                }
+            } else {
+                try {
+                    sm.checkPermission(SecurityConstants.GET_POLICY_PERMISSION);
+                    return true;
+                } catch (SecurityException se) {
+                    // fall thru and return false
+                }
+            }
+        }
+
+        return false;
+    }
+
+    private PermissionCollection mergePermissions() {
+        if (staticPermissions)
+            return permissions;
+
+        PermissionCollection perms =
+                java.security.AccessController.doPrivileged
+                        (new java.security.PrivilegedAction<PermissionCollection>() {
+                            public PermissionCollection run() {
+                                Policy p = Policy.getPolicyNoCheck();
+                                return p.getPermissions(ProtectionDomain.this);
+                            }
+                        });
+
+        Permissions mergedPerms = new Permissions();
+        int swag = 32;
+        int vcap = 8;
+        Enumeration<Permission> e;
+        List<Permission> pdVector = new ArrayList<>(vcap);
+        List<Permission> plVector = new ArrayList<>(swag);
+
+        //
+        // Build a vector of domain permissions for subsequent merge
+        if (permissions != null) {
+            synchronized (permissions) {
+                e = permissions.elements();
+                while (e.hasMoreElements()) {
+                    pdVector.add(e.nextElement());
+                }
+            }
+        }
+
+        //
+        // Build a vector of Policy permissions for subsequent merge
+        if (perms != null) {
+            synchronized (perms) {
+                e = perms.elements();
+                while (e.hasMoreElements()) {
+                    plVector.add(e.nextElement());
+                    vcap++;
+                }
+            }
+        }
+
+        if (perms != null && permissions != null) {
+            //
+            // Weed out the duplicates from the policy. Unless a refresh
+            // has occurred since the pd was consed this should result in
+            // an empty vector.
+            synchronized (permissions) {
+                e = permissions.elements();   // domain vs policy
+                while (e.hasMoreElements()) {
+                    Permission pdp = e.nextElement();
+                    Class<?> pdpClass = pdp.getClass();
+                    String pdpActions = pdp.getActions();
+                    String pdpName = pdp.getName();
+                    for (int i = 0; i < plVector.size(); i++) {
+                        Permission pp = plVector.get(i);
+                        if (pdpClass.isInstance(pp)) {
+                            // The equals() method on some permissions
+                            // have some side effects so this manual
+                            // comparison is sufficient.
+                            if (pdpName.equals(pp.getName()) &&
+                                    pdpActions.equals(pp.getActions())) {
+                                plVector.remove(i);
+                                break;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        if (perms !=null) {
+            // the order of adding to merged perms and permissions
+            // needs to preserve the bugfix 4301064
+
+            for (int i = plVector.size()-1; i >= 0; i--) {
+                mergedPerms.add(plVector.get(i));
+            }
+        }
+        if (permissions != null) {
+            for (int i = pdVector.size()-1; i >= 0; i--) {
+                mergedPerms.add(pdVector.get(i));
+            }
+        }
+
+        return mergedPerms;
+    }
+
+    final class Key {}
+}
\ No newline at end of file
index ad0bca9..ac627a0 100644 (file)
@@ -1,3 +1,20 @@
+/*
+ * Copyright (C) 2014, United States Government, as represented by the
+ * Administrator of the National Aeronautics and Space Administration.
+ * All rights reserved.
+ *
+ * The Java Pathfinder core (jpf-core) platform is licensed under the
+ * Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 package sun.reflect.generics.reflectiveObjects;
 
 import java.lang.reflect.GenericArrayType;
index 809dbf4..48c30d2 100644 (file)
@@ -1,3 +1,20 @@
+/*
+ * Copyright (C) 2014, United States Government, as represented by the
+ * Administrator of the National Aeronautics and Space Administration.
+ * All rights reserved.
+ *
+ * The Java Pathfinder core (jpf-core) platform is licensed under the
+ * Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 package sun.reflect.generics.reflectiveObjects;
 
 import sun.reflect.generics.tree.FieldTypeSignature;
index a10eb87..ebe6114 100644 (file)
@@ -1,3 +1,20 @@
+/*
+ * Copyright (C) 2014, United States Government, as represented by the
+ * Administrator of the National Aeronautics and Space Administration.
+ * All rights reserved.
+ *
+ * The Java Pathfinder core (jpf-core) platform is licensed under the
+ * Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 package sun.reflect.generics.reflectiveObjects;
 
 import java.lang.annotation.*;
index 5a4fdaf..4a2933c 100644 (file)
@@ -1,6 +1,22 @@
+/*
+ * Copyright (C) 2014, United States Government, as represented by the
+ * Administrator of the National Aeronautics and Space Administration.
+ * All rights reserved.
+ *
+ * The Java Pathfinder core (jpf-core) platform is licensed under the
+ * Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 package sun.reflect.generics.reflectiveObjects;
 
-
 import java.lang.reflect.Type;
 import java.lang.reflect.WildcardType;
 import sun.reflect.generics.factory.GenericsFactory;
index dec2423..63c3c88 100644 (file)
@@ -351,16 +351,22 @@ public class ClassLoaderInfo
             try {
               log.info("loading class ", typeName, " from ",  url);
               ci = match.createClassInfo(this);
-              
+
             } catch (ClassParseException cpx){
               throw new ClassInfoException( "error parsing class", this, "java.lang.NoClassDefFoundError", typeName, cpx);
             }
-            
+
             loadedClasses.put( url, ci);
           }
-          
+
         } else { // no match found
-          throw new ClassInfoException("class not found: " + typeName, this, "java.lang.ClassNotFoundException", typeName);
+          // TODO: Fix for Groovy's model-checking
+          // TODO: May need to do a recursive lookup
+          if (parent != null) {
+            return parent.getResolvedClassInfo(typeName);
+          } else {
+            throw new ClassInfoException("class not found: " + typeName, this, "java.lang.ClassNotFoundException", typeName);
+          }
         }
       }
       
index 2c769f2..20c59e8 100644 (file)
@@ -161,6 +161,7 @@ public class JPF_java_lang_Class extends NativePeer {
     return typeVarRef;
   }
 
+  // TODO: Fix for Groovy's model-checking
   @MJI
   public int getGenericSuperclass____Ljava_lang_reflect_Type_2 (MJIEnv env, int robj){
     ClassInfo ci = env.getReferredClassInfo( robj);
@@ -242,6 +243,32 @@ public class JPF_java_lang_Class extends NativePeer {
 
     return aRef;
   }
+
+  @MJI
+  public int getProtectionDomain____Ljava_security_ProtectionDomain_2 (MJIEnv env, int robj) {
+    // Now create a ProtectionDomain object
+    ClassLoaderInfo cli = env.getSystemClassLoaderInfo();
+    ClassInfo pdci = cli.getResolvedClassInfo("java.security.ProtectionDomain");
+
+    int proDomRef = MJIEnv.NULL;
+    /* TODO: Defer the following to future implementations
+    int proDomRef = env.newObject(pdci);
+    ElementInfo ei = env.getModifiableElementInfo(proDomRef);
+    ei.setReferenceField("codesource", MJIEnv.NULL);
+    ei.setReferenceField("classloader", MJIEnv.NULL);
+    ei.setBooleanField("hasAllPerm", true);
+    ei.setBooleanField("staticPermissions", true);
+
+    // Load the Permission (AllPermission class)
+    ClassInfo pci = cli.getResolvedClassInfo("java.security.AllPermission");
+    int permRef = env.newObject(pci);
+    ElementInfo pei = env.getModifiableElementInfo(permRef);
+    pei.setReferenceField("name", env.newString("<all permissions>"));
+    ei.setReferenceField("permissions", permRef);*/
+
+    return proDomRef;
+  }
+  // TODO: Fix for Groovy's model-checking
   
   @MJI
   public int getAnnotation__Ljava_lang_Class_2__Ljava_lang_annotation_Annotation_2 (MJIEnv env, int robj,
index 136c12e..98a8dd4 100644 (file)
@@ -144,7 +144,6 @@ public class JPF_java_lang_ClassLoader extends NativePeer {
     byte[] buffer = env.getByteArrayObject(bufferRef);
     
     try {
-
       ClassInfo ci = cl.getResolvedClassInfo( cname, buffer, offset, length);
 
       // Note: if the representation is not of a supported major or minor version, loading