1/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package tests.security.permissions;
18
19import dalvik.annotation.AndroidOnly;
20import dalvik.annotation.TestTargets;
21import dalvik.annotation.TestLevel;
22import dalvik.annotation.TestTargetNew;
23import dalvik.annotation.TestTargetClass;
24import dalvik.system.DexFile;
25
26import junit.framework.TestCase;
27
28import java.io.File;
29import java.io.IOException;
30import java.io.InputStream;
31import java.net.URL;
32import java.security.Permission;
33
34import tests.support.Support_ClassLoader;
35import tests.support.resource.Support_Resources;
36
37/*
38 * This class tests the security permissions which are documented in
39 * http://java.sun.com/j2se/1.5.0/docs/guide/security/permissions.html#PermsAndMethods
40 * for class java.lang.ClassLoader
41 */
42@TestTargetClass(java.lang.ClassLoader.class)
43public class JavaLangClassLoaderTest extends TestCase {
44
45    SecurityManager old;
46
47    @Override
48    protected void setUp() throws Exception {
49        old = System.getSecurityManager();
50        super.setUp();
51    }
52
53    @Override
54    protected void tearDown() throws Exception {
55        System.setSecurityManager(old);
56        super.tearDown();
57    }
58
59    @TestTargets({
60        @TestTargetNew(
61            level = TestLevel.PARTIAL,
62            notes = "Verifies that ClassLoader constructor calls checkCreateClassLoader on security manager.",
63            method = "ClassLoader",
64            args = {}
65        ),
66        @TestTargetNew(
67            level = TestLevel.PARTIAL,
68            notes = "Verifies that ClassLoader constructor calls checkCreateClassLoader on security manager.",
69            method = "ClassLoader",
70            args = {java.lang.ClassLoader.class}
71        )
72    })
73    public void test_ClassLoaderCtor () {
74        class TestSecurityManager extends SecurityManager {
75            boolean called;
76            void reset(){
77                called = false;
78            }
79            @Override
80            public void checkCreateClassLoader(){
81                called = true;
82            }
83            @Override
84            public void checkPermission(Permission p) {
85
86            }
87        }
88
89        // class MyClassLoader defined package visible constructors
90        class MyClassLoader extends ClassLoader {
91            MyClassLoader(){super();}
92            MyClassLoader(ClassLoader parent){super(parent);}
93        }
94
95        TestSecurityManager s = new TestSecurityManager();
96        System.setSecurityManager(s);
97
98        s.reset();
99        ClassLoader c1 = new MyClassLoader();
100        assertTrue("ClassLoader ctor must call checkCreateClassLoader on security manager", s.called);
101
102        s.reset();
103        ClassLoader c2 = new MyClassLoader(c1);
104        assertTrue("ClassLoader ctor must call checkCreateClassLoader on security manager", s.called);
105    }
106
107    @TestTargets({
108        @TestTargetNew(
109            level = TestLevel.PARTIAL,
110            notes = "Verifies that ClassLoader.getSystemClassLoader() calls checkPermission on security manager.",
111            method = "getSystemClassLoader",
112            args = {}
113        ),
114        @TestTargetNew(
115            level = TestLevel.PARTIAL,
116            notes = "Verifies that ClassLoader.getParent() calls checkPermission on security manager.",
117            method = "getParent",
118            args = {}
119        )
120    })
121    @AndroidOnly("uses DexFile")
122    public void test_getSystemClassLoader () throws IOException,
123            IllegalAccessException, InstantiationException {
124        class TestSecurityManager extends SecurityManager {
125            boolean called;
126            void reset(){
127                called = false;
128            }
129            @Override
130            public void checkPermission(Permission permission){
131                if(permission instanceof RuntimePermission &&
132                        "getClassLoader".equals(permission.getName())){
133                    called = true;
134                }
135            }
136        }
137
138        TestSecurityManager s = new TestSecurityManager();
139        System.setSecurityManager(s);
140
141        File tempFile = Support_Resources.createTempFile(".jar");
142        tempFile.delete();
143        tempFile.deleteOnExit();
144        File tempCache = Support_Resources.createTempFile(".dex");
145        tempCache.delete();
146        tempCache.deleteOnExit();
147
148        /*
149         * The testdex.jar contains the following two classes:
150         *
151         * package tests.security.permissions.resources;
152         *
153         * public class TestClass1 {
154         *
155         *      public TestClass1() {
156         *          ClassLoader.getSystemClassLoader();
157         *      }
158         *  }
159         *
160         * package tests.security.permissions.resources;
161         *
162         *  public class TestClass2 {
163         *
164         *      public TestClass2 () {
165         *          getClass().getClassLoader().getParent();
166         *      }
167         *  }
168         */
169
170        InputStream is = Support_Resources.getResourceStream("testdex.jar");
171        Support_Resources.copyLocalFileto(tempFile, is);
172        DexFile dexfile = DexFile.loadDex(tempFile.getAbsolutePath(),
173                tempCache.getAbsolutePath(), 0);
174        ClassLoader pcl = Support_ClassLoader.getInstance(
175                new URL(Support_Resources.getResourceURL("testdex.jar")),
176                ClassLoader.getSystemClassLoader());
177
178        Class<?> testClass = dexfile.loadClass(
179                "tests/security/permissions/resources/TestClass1", pcl);
180
181        assertNotNull("failed to load TestlClass1", testClass);
182
183        s.reset();
184        testClass.newInstance();
185
186        assertTrue("ClassLoader.getSystemClassLoader() must call "
187                + "checkPermission on security manager", s.called);
188
189        testClass = dexfile.loadClass(
190                "tests/security/permissions/resources/TestClass2", pcl);
191
192        assertNotNull("failed to load TestClass2", testClass);
193        s.reset();
194
195        testClass.newInstance();
196
197        assertTrue("Method getParent on a class loader must call "
198                + "checkPermission on security manager", s.called);
199    }
200}
201
202