You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by pa...@apache.org on 2021/06/10 20:41:29 UTC
[felix-dev] 01/01: FELIX-6430: fix usage of unsave
This is an automated email from the ASF dual-hosted git repository.
pauls pushed a commit to branch FELIX-6430
in repository https://gitbox.apache.org/repos/asf/felix-dev.git
commit 3486e2410cd3f0054c1be3f7ac26b26fdaa0cb83
Author: Karl Pauls <ka...@gmail.com>
AuthorDate: Thu Jun 10 22:41:05 2021 +0200
FELIX-6430: fix usage of unsave
---
.../apache/felix/framework/util/SecureAction.java | 59 ++++++++++++++++++----
1 file changed, 48 insertions(+), 11 deletions(-)
diff --git a/framework/src/main/java/org/apache/felix/framework/util/SecureAction.java b/framework/src/main/java/org/apache/felix/framework/util/SecureAction.java
index 1e8024e..1ed8e54 100644
--- a/framework/src/main/java/org/apache/felix/framework/util/SecureAction.java
+++ b/framework/src/main/java/org/apache/felix/framework/util/SecureAction.java
@@ -18,14 +18,38 @@
*/
package org.apache.felix.framework.util;
-import java.io.*;
-import java.lang.reflect.*;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.invoke.MethodHandles;
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Array;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Executable;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;
-import java.net.*;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.net.URLConnection;
+import java.net.URLStreamHandler;
import java.nio.channels.FileChannel;
import java.nio.file.Files;
import java.nio.file.StandardOpenOption;
-import java.security.*;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.Policy;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
import java.util.Collection;
import java.util.HashMap;
import java.util.Hashtable;
@@ -1130,13 +1154,26 @@ public class SecureAction
// NOTE: deep reflection is allowed on sun.misc package for java 9.
theUnsafe.setAccessible(true);
Object unsafe = theUnsafe.get(null);
- // using defineAnonymousClass here because it seems more simple to get what we need
- Method defineAnonymousClass = unsafeClass.getMethod("defineAnonymousClass", Class.class, byte[].class, Object[].class); //$NON-NLS-1$
- // The bytes stored in a resource to avoid real loading of it (see accessible.src for source).
-
- Class<Consumer<AccessibleObject[]>> result =
- (Class<Consumer<AccessibleObject[]>>)
- defineAnonymousClass.invoke(unsafe, URL.class, accessor , null);
+ Class<Consumer<AccessibleObject[]>> result;
+ try {
+ Method defineAnonymousClass = unsafeClass.getMethod("defineAnonymousClass", Class.class, byte[].class, Object[].class); //$NON-NLS-1$
+ result = (Class<Consumer<AccessibleObject[]>>) defineAnonymousClass.invoke(unsafe, URL.class, accessor , null);;
+ }
+ catch (NoSuchMethodException ex)
+ {
+ long offset = (long) unsafeClass.getMethod("staticFieldOffset", Field.class)
+ .invoke(unsafe, MethodHandles.Lookup.class.getDeclaredField("IMPL_LOOKUP"));
+
+ MethodHandles.Lookup lookup = (MethodHandles.Lookup) unsafeClass.getMethod("getObject", Object.class, long.class)
+ .invoke(unsafe, MethodHandles.Lookup.class, offset);
+ lookup = lookup.in(URL.class);
+ Class<?> classOption = Class.forName("java.lang.invoke.MethodHandles$Lookup$ClassOption"); //$NON-NLS-1$
+ Object classOptions = Array.newInstance(classOption, 0);
+ Method defineHiddenClass = MethodHandles.Lookup.class.getMethod("defineHiddenClass", byte[].class, boolean.class, //$NON-NLS-1$
+ classOptions.getClass());
+ lookup = (MethodHandles.Lookup) defineHiddenClass.invoke(lookup, accessor, Boolean.FALSE, classOptions);
+ result = (Class<Consumer<AccessibleObject[]>>) lookup.lookupClass();
+ }
m_accessorCache = result.getConstructor().newInstance();
}
catch (Throwable t)