Skip to content
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

diffenent result when call varargs method of compiled expression twice #335

Open
scmod opened this issue Jul 13, 2023 · 0 comments
Open

Comments

@scmod
Copy link

scmod commented Jul 13, 2023

it's a rare case when someone override the method with parameter of varargs by an array type and vice versa.
for example

public class Mvel {
	public static void main(String[] args) throws Exception {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("args1", new VarArgs());
		map.put("args2", new Array());
		{
			String script = "args1.method(\"abc\", \"bcd\")";
			Serializable compiled = MVEL.compileExpression(script);
			MVEL.executeExpression(compiled, map);
			MVEL.executeExpression(compiled, map);
		}
		{
			String script = "args2.method({\"abc\", \"bcd\"})";
			Serializable compiled = MVEL.compileExpression(script);
			MVEL.executeExpression(compiled, map);
			MVEL.executeExpression(compiled, map);
		}
	}
	public static class ArrayBase {
		public void method(String[] strs) {
			System.out.println(Arrays.toString(strs));
		}
	}
	public static class VarArgsBase {
		public void method(String... strs) {
			System.out.println(Arrays.toString(strs));
		}
	}
	public static class VarArgs extends ArrayBase {
		@Override
		public void method(String... strs) {
			System.out.println(Arrays.toString(strs));
		}	
	}
	public static class Array extends VarArgsBase {
		@Override
		public void method(String[] strs) {
			super.method(strs);
		}
	}	
}

the console shows

[abc, bcd]
[abc]
[abc, bcd]
[[Ljava.lang.Object;@85ede7b]

The reason is when we get a widenedTarget, the getExactMatch method doesn't check the method varargs type, but override a method like this maybe not recommended. So should we make a change of ParseTools like this,

  public static Method getExactMatch(String name, Class[] args, Class returnType, Class cls, boolean varArgs) {
	outer:
	for (Method meth : cls.getMethods()) {
		if (name.equals(meth.getName()) && returnType == meth.getReturnType() && varArgs == meth.isVarArgs()) {
        Class[] parameterTypes = meth.getParameterTypes();
        if (parameterTypes.length != args.length) continue;

        for (int i = 0; i < parameterTypes.length; i++) {
          if (parameterTypes[i] != args[i]) continue outer;
        }
        return meth;
      }
    }
    return null;
  }

to make this rare case result same

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant