-
Notifications
You must be signed in to change notification settings - Fork 16
Fix Java Class objects being wrapped as NativeJavaObject #66
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
When Java Class objects get passed from JS to Java they are incorrectly wrapped in NativeJavaObject instead of NativeJavaClass. This PR fixes that.
|
Well I think this is intentional, wrapping any |
Yeah it's definitely not a solution to just wrap every class as NJC, it would likely have to go through the class filter somehow (but iirc that is implemented on KubeJS' side?) |
|
The behavior on the JS side doesn't change at all. All loadable Java classes are already accessible by design, like this: let $ListTag = Java.loadClass("net.minecraft.nbt.ListTag")
const listTagClass = $ListTag.__javaObject__
console.log(listTagClass)You can see all the Class methods if you do: console.log(JSON.stringify(listTagClass, null, 2))You can call most Class methods on it, but importantly, you can't call any caller sensitive methods, which are the methods that do the actual potentially security-breaking reflection. So basically you can just call I actually found this NativeJavaClass bug while making a mod to allow for reflection in kube: https://github.com/lonevox/KubeJS-Reflected Also you cannot ever get a usable reference to banned classes from Java. The class filter doesn't allow banned classes to be sent from Java to JS. It doesn't matter if it's wrapped as a NativeJavaObject or a NativeJavaClass. My mod has to circumvent the class filter to make reflection work. |
I believe there's no such issue. Class<?> clazz;
if (jsObj instanceof NativeJavaClass njc) {
clazz = ...;
}I would recommend: Class<?> clazz;
if (jsObj instanceof Wrapper wrapper && wrapper.unwrap() instanceof Class c) {
clazz = c;
}
// or alternatively:
if (Wrapper.unwrapped(jsObj) instanceof Class c) {
clazz = c;
}Also I'm curious, JS objects will be automatically unwrapped and transformed when accessing Java method/field, why would you need to unwrap it manually? |
Because specifically private void expectsClass(Class<?> clazz) {
System.out.println(clazz.isArray());
}I'm unsure if the above is even possible without circumventing the class filter though, so I admit this is a very specific issue that probably only I will even run into. So if it's worth merging, idk, I currently fix it myself with a mixin so I'm not that bothered. Just thought I might as well contribute the fix. |
When Java Class objects get passed from JS to Java they are incorrectly wrapped in NativeJavaObject instead of NativeJavaClass. This PR fixes that.