blob: c4db522d3195cf88f9527e3de5e9fe22f7bfa447 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.commons.jexl3;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Deque;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.apache.commons.jexl3.internal.TemplateDebugger;
import org.apache.commons.jexl3.introspection.JexlSandbox;
import org.apache.commons.logging.Log;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
/**
* Test cases for reported issue between JEXL-200 and JEXL-299.
*/
@SuppressWarnings({"boxing", "UnnecessaryBoxing", "AssertEqualsBetweenInconvertibleTypes"})
public class Issues200Test extends JexlTestCase {
public Issues200Test() {
super("Issues200Test", null);
}
@Before
@Override
public void setUp() throws Exception {
// ensure jul logging is only error to avoid warning in silent mode
java.util.logging.Logger.getLogger(JexlEngine.class.getName()).setLevel(java.util.logging.Level.SEVERE);
}
public static class Eval {
private JexlEngine jexl;
public JexlScript fn(final String src) {
return jexl.createScript(src);
}
void setJexl(final JexlEngine je) {
jexl = je;
}
}
@Test
public void test200() throws Exception {
final JexlContext jc = new MapContext();
final Map<String, Object> funcs = new HashMap<String, Object>();
final Eval eval = new Eval();
funcs.put(null, eval);
final JexlEngine jexl = new JexlBuilder().namespaces(funcs).create();
eval.setJexl(jexl);
final String src = "var f = fn(\'(x)->{x + 42}\'); f(y)";
final JexlScript s200 = jexl.createScript(src, "y");
Assert.assertEquals(142, s200.execute(jc, 100));
Assert.assertEquals(52, s200.execute(jc, 10));
}
@Test
public void test200b() throws Exception {
final JexlContext jc = new MapContext();
final JexlEngine jexl = new JexlBuilder().create();
final JexlScript e = jexl.createScript("var x = 0; var f = (y)->{ x = y; }; f(42); x");
final Object r = e.execute(jc);
Assert.assertEquals(0, r);
}
@Test
public void test209a() throws Exception {
final JexlContext jc = new MapContext();
final JexlEngine jexl = new JexlBuilder().create();
final JexlScript e = jexl.createScript("var x = new('java.util.HashMap'); x.a = ()->{return 1}; x['a']()");
final Object r = e.execute(jc);
Assert.assertEquals(1, r);
}
@Test
public void test209b() throws Exception {
final JexlContext jc = new MapContext();
final JexlEngine jexl = new JexlBuilder().create();
final JexlScript e = jexl.createScript("var x = new('java.util.HashMap'); x['a'] = ()->{return 1}; x.a()");
final Object r = e.execute(jc);
Assert.assertEquals(1, r);
}
public static class T210 {
public void npe() {
throw new NullPointerException("NPE210");
}
}
@Test
public void test210() throws Exception {
final JexlContext jc = new MapContext();
jc.set("v210", new T210());
final JexlEngine jexl = new JexlBuilder().strict(false).silent(false).create();
final JexlScript e = jexl.createScript("v210.npe()");
try {
e.execute(jc);
Assert.fail("should have thrown an exception");
} catch(final JexlException xjexl) {
final Throwable th = xjexl.getCause();
Assert.assertEquals("NPE210", th.getMessage());
}
}
@Test
public void test217() throws Exception {
final JexlEvalContext jc = new JexlEvalContext();
final JexlOptions options = jc.getEngineOptions();
jc.set("foo", new int[]{0, 1, 2, 42});
JexlEngine jexl;
JexlScript e;
Object r;
jexl = new JexlBuilder().strict(false).silent(false).create();
e = jexl.createScript("foo[3]");
r = e.execute(jc);
Assert.assertEquals(42, r);
// cache and fail?
jc.set("foo", new int[]{0, 1});
options.setStrict(true);
Assert.assertTrue(options.isStrict());
try {
r = e.execute(jc);
Assert.fail("should have thrown an exception");
} catch(final JexlException xjexl) {
final Throwable th = xjexl.getCause();
Assert.assertEquals(ArrayIndexOutOfBoundsException.class, th.getClass());
}
//
options.setStrict(false);
r = e.execute(jc);
Assert.assertNull("oob adverted", r);
}
@Test
public void test221() throws Exception {
final JexlEvalContext jc = new JexlEvalContext();
final Map<String, Integer> map = new HashMap<String, Integer>();
map.put("one", 1);
jc.set("map", map);
final JexlEngine jexl = new JexlBuilder().cache(256).create();
final JexlScript e = jexl.createScript("(x)->{ map[x] }");
Object r;
r = e.execute(jc, (Object) null);
Assert.assertNull(r);
r = e.execute(jc, (Object) null);
Assert.assertNull(r);
r = e.execute(jc, "one");
Assert.assertEquals(1, r);
}
public static class JexlArithmetic224 extends JexlArithmetic {
public JexlArithmetic224(final boolean astrict) {
super(astrict);
}
protected Object nth(final Collection<?> c, int i) {
if (c instanceof List) {
// tell engine to use default
return JexlEngine.TRY_FAILED;
}
for (final Object o : c) {
if (i-- == 0) {
return o;
}
}
return null;
}
public Object propertyGet(final Collection<?> c, final Number n) {
return nth(c, n.intValue());
}
public Object arrayGet(final Collection<?> c, final Number n) {
return nth(c, n.intValue());
}
public Object call(final Collection<?> c, final Number n) {
if (c instanceof List) {
return ((List) c).get(n.intValue());
}
return nth(c, n.intValue());
}
}
@Test
public void test224() throws Exception {
final List<String> a0 = Arrays.asList("one", "two");
final Set<String> a1 = new TreeSet<String>(a0);
final JexlContext jc = new MapContext();
final JexlEngine jexl = new JexlBuilder().arithmetic(new JexlArithmetic224(true)).create();
Object r;
JexlScript e = jexl.createScript("(map, x)->{ map[x] }");
r = e.execute(jc, a0, 1);
Assert.assertEquals("two", r);
r = e.execute(jc, a1, 1);
Assert.assertEquals("two", r);
e = jexl.createScript("(map)->{ map.1 }");
r = e.execute(jc, a0);
Assert.assertEquals("two", r);
r = e.execute(jc, a1);
Assert.assertEquals("two", r);
e = jexl.createScript("(map, x)->{ map(x) }");
r = e.execute(jc, a0, 1);
Assert.assertEquals("two", r);
r = e.execute(jc, a1, 1);
Assert.assertEquals("two", r);
}
public static class Context225 extends MapContext {
public String bar(){
return "bar";
}
}
@Test
public void test225() throws Exception {
final Context225 df = new Context225();
final JexlEngine jexl = new JexlBuilder().create();
final JexlExpression expression = jexl.createExpression("bar()");
Assert.assertEquals("bar", expression.evaluate(df));
final ObjectContext<Object> context = new ObjectContext<Object>(jexl, df);
Assert.assertEquals("bar", expression.evaluate(context));
}
private static void handle(final ExecutorService pool, final JexlScript script, final Map<String, Object> payload) {
pool.submit(() -> script.execute(new MapContext(payload)));
}
@Test
public void test241() throws Exception {
ExecutorService pool;
final JexlScript script = new JexlBuilder().create().createScript("`${item}`");
pool = Executors.newFixedThreadPool(4);
final Map<String, Object> m1 = new HashMap<String, Object>();
m1.put("item", "A");
final Map<String, Object> m2 = new HashMap<String, Object>();
m2.put("item", "B");
handle(pool, script, m1);
script.execute(new MapContext(m2));
pool.shutdown();
}
@Test
public void test242() throws Exception {
final Double a = -40.05d;
final Double b = -8.01d;
final Double c = a + b;
final JexlContext context = new MapContext();
context.set("a", a);
context.set("b", b);
final JexlEngine JEXL_ENGINE = new JexlBuilder().strict(true).silent(true).create();
final JexlExpression jsp = JEXL_ENGINE.createExpression("a + b");
final Double e = (Double) jsp.evaluate(context);
Assert.assertEquals(Double.doubleToLongBits(e) + " != " + Double.doubleToLongBits(c), c,
e, 0.0);
Assert.assertEquals(Double.doubleToLongBits(e) + " != " + Double.doubleToLongBits(c), a + b, e, 0.0);
}
@Test
public void test243a() throws Exception {
final JexlEngine jexl = new JexlBuilder().cache(32).create();
final JexlScript script = jexl.createScript("while(true);");
try {
final JexlExpression expr = jexl.createExpression("while(true);");
Assert.fail("should have failed!, expr do not allow 'while' statement");
} catch (final JexlException xparse) {
// ok
}
}
public static class Foo245 {
private Object bar = null;
void setBar(final Object bar) {
this.bar = bar;
}
public Object getBar() {
return bar;
}
}
@Test
public void test245() throws Exception {
final MapContext ctx = new MapContext();
final Foo245 foo245 = new Foo245();
ctx.set("foo", foo245);
final JexlEngine engine = new JexlBuilder().strict(true).safe(false).silent(false).create();
final JexlExpression foobar = engine.createExpression("foo.bar");
final JexlExpression foobaz = engine.createExpression("foo.baz");
final JexlExpression foobarbaz = engine.createExpression("foo.bar.baz");
// add ambiguity with null & not-null
final Object[] args = { null, 245 };
for(final Object arg : args ){
foo245.setBar(arg);
// ok
Assert.assertEquals(foo245.getBar(), foobar.evaluate(ctx));
// fail level 1
try {
foobaz.evaluate(ctx);
Assert.fail("foo.baz is not solvable, exception expected");
} catch(final JexlException xp) {
Assert.assertTrue(xp instanceof JexlException.Property);
}
// fail level 2
try {
foobarbaz.evaluate(ctx);
Assert.fail("foo.bar.baz is not solvable, exception expected");
} catch(final JexlException xp) {
Assert.assertTrue(xp instanceof JexlException.Property);
}
}
}
@Test
public void test256() throws Exception {
final MapContext ctx = new MapContext() {
@Override public void set(final String name, final Object value) {
if ("java".equals(name)) {
throw new JexlException(null, "can not set " + name);
}
super.set(name, value);
}
@Override public Object get(final String name) {
if ("java".equals(name)) {
return null;
}
return super.get(name);
}
@Override public boolean has(final String name) {
if ("java".equals(name)) {
return false;
}
return super.has(name);
}
};
ctx.set("java.version", 10);
final JexlEngine engine = new JexlBuilder().strict(true).silent(false).create();
JexlScript script;
script = engine.createScript("java = 3");
try {
script.execute(ctx);
Assert.fail("should have failed!");
} catch(final JexlException xjexl) {
// expected
}
script = engine.createScript("java.version");
Assert.assertEquals(10, script.execute(ctx));
}
@Test
public void test230() throws Exception {
final JexlEngine jexl = new JexlBuilder().cache(4).create();
final JexlContext ctxt = new MapContext();
final int[] foo = {42};
ctxt.set("fo o", foo);
Object value;
for (int l = 0; l < 2; ++l) {
value = jexl.createExpression("fo\\ o[0]").evaluate(ctxt);
Assert.assertEquals(42, value);
value = jexl.createExpression("fo\\ o[0] = 43").evaluate(ctxt);
Assert.assertEquals(43, value);
value = jexl.createExpression("fo\\ o.0").evaluate(ctxt);
Assert.assertEquals(43, value);
value = jexl.createExpression("fo\\ o.0 = 42").evaluate(ctxt);
Assert.assertEquals(42, value);
}
}
@Test
public void test265() throws Exception {
final JexlEngine jexl = new JexlBuilder().cache(4).create();
final JexlContext ctxt = new MapContext();
ctxt.set("x", 42);
Object result;
JexlScript script;
try {
script = jexl.createScript("(true) ? x : abs(1)");
} catch (final JexlException.Parsing xparse) {
// ambiguous, parsing fails
}
script = jexl.createScript("(true) ? (x) : abs(2)");
result = script.execute(ctxt);
Assert.assertEquals(42, result);
script = jexl.createScript("(true) ? x : (abs(3))");
result = script.execute(ctxt);
Assert.assertEquals(42, result);
script = jexl.createScript("(!true) ? abs(4) : x");
result = script.execute(ctxt);
Assert.assertEquals(42, result);
}
/**
* An iterator that implements Closeable (at least implements a close method).
*/
public static class Iterator266 implements /*Closeable,*/ Iterator<Object> {
private Iterator<Object> iterator;
Iterator266(final Iterator<Object> ator) {
iterator = ator;
}
@Override
protected void finalize() throws Throwable {
close();
super.finalize();
}
//@Override
public void close() {
if (iterator != null) {
Arithmetic266.closeIterator(this);
iterator = null;
}
}
@Override
public boolean hasNext() {
if (iterator == null) {
return false;
}
final boolean n = iterator.hasNext();
if (!n) {
close();
}
return n;
}
@Override
public Object next() {
if (iterator == null) {
throw new NoSuchElementException();
}
return iterator.next();
}
@Override
public void remove() {
if (iterator != null) {
iterator.remove();
}
}
}
public static class Arithmetic266 extends JexlArithmetic {
static final ThreadLocal<Deque<Iterator266>> TLS_FOREACH = new ThreadLocal<Deque<Iterator266>>() {
@Override
public Deque<Iterator266> initialValue() {
return new LinkedList<Iterator266>();
}
};
public Arithmetic266(final boolean strict) {
super(strict);
}
static void closeIterator(final Iterator266 i266) {
final Deque<Iterator266> queue = TLS_FOREACH.get();
if (queue != null) {
queue.remove(i266);
}
}
public Iterator<?> forEach(final Iterable<?> collection) {
final Iterator266 it266 = new Iterator266((Iterator<Object>) collection.iterator());
final Deque<Iterator266> queue = TLS_FOREACH.get();
queue.addFirst(it266);
return it266;
}
public Iterator<?> forEach(final Map<?,?> collection) {
return forEach(collection.values());
}
public void remove() {
final Deque<Iterator266> queue = TLS_FOREACH.get();
final Iterator266 i266 = queue.getFirst();
if (i266 != null) {
i266.remove();
throw new JexlException.Continue(null);
} else {
throw new NoSuchElementException();
}
}
}
@Test
public void test266() throws Exception {
Object result;
JexlScript script;
final JexlEngine jexl = new JexlBuilder().arithmetic(new Arithmetic266(true)).create();
final JexlContext ctxt = new MapContext();
final List<Integer> li = new ArrayList<Integer>(Arrays.asList(1, 2, 3, 4, 5 ,6));
ctxt.set("list", li);
script = jexl.createScript("for (var item : list) { if (item <= 3) remove(); } return size(list)");
result = script.execute(ctxt);
Assert.assertEquals(3, result);
Assert.assertEquals(3, li.size());
final Map<String, Integer> msi = new HashMap<String, Integer>();
msi.put("a", 1);
msi.put("b", 2);
msi.put("c", 3);
msi.put("d", 4);
msi.put("e", 5);
msi.put("f", 6);
ctxt.set("map", msi);
script = jexl.createScript("for (var item : map) { if (item <= 2) remove(); } return size(map)");
result = script.execute(ctxt);
Assert.assertEquals(4, result);
Assert.assertEquals(4, msi.size());
}
@Test
public void test267() throws Exception {
Object result;
JexlScript script;
final JexlEngine jexl = new JexlBuilder().create();
final JexlContext ctxt = new MapContext();
// API declared params
script = jexl.createScript("x + y", "x", "y");
result = script.execute(ctxt, 20, 22);
Assert.assertEquals(42, result);
// script declared params
script = jexl.createScript("(x, y)->{ x + y}");
result = script.execute(ctxt, 22, 20);
Assert.assertEquals(42, result);
// explicitly returning the lambda
script = jexl.createScript("return (x, y)->{ x + y}");
result = script.execute(ctxt);
Assert.assertTrue(result instanceof JexlScript);
}
@Test
public void test274() throws Exception {
JexlEngine jexl = new JexlBuilder().strict(true).safe(true).stackOverflow(5).create();
final JexlContext ctxt = new MapContext();
JexlScript script= jexl.createScript("var f = (x)->{ x > 1? x * f(x - 1) : x }; f(a)", "a");
Object result = script.execute(ctxt, 3);
Assert.assertEquals(6, result);
try {
result = script.execute(ctxt, 32);
Assert.fail("should have overflown");
} catch(final JexlException.StackOverflow xstack) {
// expected
final String sxs = xstack.toString();
Assert.assertTrue(sxs.contains("jexl"));
}
jexl = new JexlBuilder().strict(true).create();
script= jexl.createScript("var f = (x)->{ x * f(x - 1) }; f(a)", "a");
try {
result = script.execute(ctxt, 32);
Assert.fail("should have overflown");
} catch(final JexlException.StackOverflow xstack) {
// expected
final String sxs = xstack.toString();
Assert.assertTrue(sxs.contains("jvm"));
}
}
@Test
public void test275a() throws Exception {
final JexlContext ctxt = new MapContext();
ctxt.set("out", System.out);
final JexlEngine jexl = new JexlBuilder().strict(true).safe(true).create();
final JexlScript e = jexl.createScript("out.println(xyz)");
try {
final Object o = e.execute(ctxt);
Assert.fail("should have thrown");
} catch (final JexlException.Variable xvar) {
Assert.assertEquals("xyz", xvar.getVariable());
}
}
@Test
public void test275b() throws Exception {
final JexlContext ctxt = new MapContext();
//ctxt.set("out", System.out);
final JexlEngine jexl = new JexlBuilder().strict(true).safe(true).create();
final JexlScript e = jexl.createScript("var xyz = xyz");
try {
final Object o = e.execute(ctxt);
Assert.assertNull(o);
} catch (final JexlException.Variable xvar) {
Assert.fail("should not have thrown");
// Assert.assertEquals("xyz", xvar.getVariable());
}
}
@Test
public void test275c() throws Exception {
final JexlContext ctxt = new MapContext();
//ctxt.set("out", System.out);
final JexlEngine jexl = new JexlBuilder().strict(true).safe(true).silent(true).create();
JexlScript e;
Object r;
e = jexl.createScript("(s, v)->{ var x = y ; 42; }");
// wont make an error
try {
r = e.execute(ctxt, false, true);
Assert.assertEquals(42, r);
} catch (final JexlException.Variable xjexl) {
Assert.fail("should not have thrown");
}
}
@Test
public void test275d() throws Exception {
final JexlContext ctxt = new MapContext();
ctxt.set("out", System.out);
final JexlEngine jexl = new JexlBuilder().strict(true).safe(true).create();
final JexlScript e = jexl.createScript("{ var xyz = 42 } out.println(xyz)");
try {
final Object o = e.execute(ctxt);
Assert.assertNull(o);
} catch (final JexlException.Variable xvar) {
Assert.fail("should not have thrown" + xvar);
}
}
@Test
public void test278() throws Exception {
final String[] srcs = new String[]{
"return union x143('arg',5,6) ",
"return union y143('arg',5,6) ;",
"return union\n z143('arg',5,6) ;",
"var f =()->{ return union 143 } foo[0]"
};
final Object[] ctls = new Object[]{
"42","42","42", 42
};
final JexlEngine jexl = new JexlBuilder().cache(4).create();
final JexlContext ctxt = new MapContext();
final int[] foo = {42};
ctxt.set("foo", foo);
ctxt.set("union", "42");
Object value;
JexlScript jc;
for(int i = 0; i < srcs.length; ++i) {
String src = srcs[i];
try {
jc = jexl.createScript(src);
Assert.fail("should have failed, " + (jc != null));
} catch(final JexlException.Ambiguous xa) {
final String str = xa.toString();
Assert.assertTrue(str.contains("143"));
src = xa.tryCleanSource(src);
}
jc = jexl.createScript(src);
value = jc.execute(ctxt);
Assert.assertEquals(src, ctls[i], value);
}
}
public static class Context279 extends MapContext {
public String identity(final String x) {
return x;
}
public Number identity(final Number x) {
return x;
}
public String[] spread(final String str) {
if (str == null) {
return null;
}
final String[] a = new String[str.length()];
for(int i = 0; i < str.length(); ++i) {
a[i] = "" + str.charAt(i);
}
return a;
}
}
@Test
public void test279() throws Exception {
final Log logger = null;//LogFactory.getLog(Issues200Test.class);
Object result;
JexlScript script;
final JexlContext ctxt = new Context279();
final String[] srcs = new String[]{
"var z = null; identity(z[0]);",
"var z = null; z.0;",
"var z = null; z.foo();",
"z['y']['z']",
"z.y.any()",
"identity(z.any())",
"z[0]",
"z.0",
"z.foo()",
"z.y[0]",
"z.y[0].foo()",
"z.y.0",
"z.y.foo()",
"var z = { 'y' : [42] }; z.y[1]",
"var z = { 'y' : [42] }; z.y.1",
"var z = { 'y' : [-42] }; z.y[1].foo()",
"var z = { 'y' : [42] }; z.y.1.foo()",
"var z = { 'y' : [null, null] }; z.y[1].foo()",
"var z = { 'y' : [null, null] }; z.y.1.foo()"
};
for (int i = 0; i < 2; ++i) {
for (final boolean strict : new boolean[]{true, false}) {
final JexlEngine jexl = new JexlBuilder().safe(false).strict(strict).create();
for (final String src : srcs) {
script = jexl.createScript(src);
try {
result = script.execute(ctxt);
if (strict) {
if (logger != null) {
logger.warn(ctxt.has("z") + ": " + src + ": no fail, " + result);
}
Assert.fail("should have failed: " + src);
}
// not reachable
Assert.assertNull("non-null result ?!", result);
} catch (final JexlException.Variable xvar) {
if (logger != null) {
logger.warn(ctxt.has("z") + ": " + src + ": fail, " + xvar);
}
if (!strict) {
Assert.fail(src + ", should not have thrown " + xvar);
} else {
Assert.assertTrue(src + ": " + xvar.toString(), xvar.toString().contains("z"));
}
} catch (final JexlException.Property xprop) {
if (logger != null) {
logger.warn(ctxt.has("z") + ": " + src + ": fail, " + xprop);
}
if (!strict) {
Assert.fail(src + ", should not have thrown " + xprop);
} else {
Assert.assertTrue(src + ": " + xprop.toString(), xprop.toString().contains("1"));
}
}
}
}
ctxt.set("z.y", null);
}
}
@Test
public void test279b() throws Exception {
Object result;
JexlScript script;
final JexlContext ctxt = new Context279();
ctxt.set("ctxt", ctxt);
final String src = "(x)->{ spread(x)[0].toString() }";
final JexlEngine jexl = new JexlBuilder().safe(true).strict(true).create();
script = jexl.createScript(src);
result = script.execute(ctxt, "abc");
Assert.assertEquals("a", result);
result = null;
try {
result = script.execute(ctxt, (Object) null);
} catch(final JexlException xany) {
Assert.assertNotNull(xany.getMessage());
}
Assert.assertNull(result);
}
@Test
public void test285() throws Exception {
final List<String> out = new ArrayList<String>(6);
final JexlContext ctxt = new MapContext();
ctxt.set("$out", out);
final String src = "for(var b: ['g','h','i']) {\n"
+ " var c = b;\n"
+ " $out.add(c);\n"
+ "}\n"
+ " \n"
+ "for(var dc: ['j','k','l']) {\n"
+ " $out.add(dc);\n"
+ "}"
+ " \n"
+ "$out.size()";
final JexlFeatures features = new JexlFeatures();
features.lexical(true);
final JexlEngine jexl = new JexlBuilder()
//.features(features)
.safe(false).strict(true).lexical(true).create();
final JexlScript script = jexl.createScript(src);
final Object result = script.execute(ctxt, (Object) null);
Assert.assertEquals(6, result);
final List<String> ctl = Arrays.asList("g", "h", "i", "j", "k", "l");
Assert.assertEquals(ctl, out);
}
@Test
public void test285a() throws Exception {
final List<String> out = new ArrayList<String>(6);
final JexlContext ctxt = new MapContext();
ctxt.set("$out", out);
final String src =
"for(var b: ['g','h','i']) { $out.add(b); }\n"
+ "for(b: ['j','k','l']) { $out.add(b);}\n"
+ "$out.size()";
final JexlEngine jexl = new JexlBuilder().safe(false).strict(true).lexical(false).create();
final JexlScript script = jexl.createScript(src);
final Object result = script.execute(ctxt, (Object) null);
Assert.assertEquals(6, result);
final List<String> ctl = Arrays.asList("g", "h", "i", "j", "k", "l");
Assert.assertEquals(ctl, out);
}
@Test
public void test285b() throws Exception {
final List<String> out = new ArrayList<String>(6);
final JexlContext ctxt = new MapContext();
ctxt.set("$out", out);
final String src =
"for(b: ['g','h','i']) { $out.add(b); }\n"
+ "for(var b: ['j','k','l']) { $out.add(b);}\n"
+ "$out.size()";
final JexlEngine jexl = new JexlBuilder().safe(false).strict(true).create();
final JexlScript script = jexl.createScript(src);
final Object result = script.execute(ctxt, (Object) null);
Assert.assertEquals(6, result);
final List<String> ctl = Arrays.asList("g", "h", "i", "j", "k", "l");
Assert.assertEquals(ctl, out);
}
@Test
public void test286() {
final String s286 = "var x = 0; for(x : 1..2){}; return x";
final JexlEngine jexl = new JexlBuilder().strict(true).create();
Assert.assertEquals(2, jexl.createScript(s286).execute(null));
}
@Test
public void test287() {
final JexlEvalContext ctxt = new JexlEvalContext();
final JexlOptions options = ctxt.getEngineOptions();
final JexlEngine jexl = new JexlBuilder().strict(true).create();
String src;
JexlScript script;
Object result;
// declared, not defined
src = "x = 1; if (false) var x = 2; x";
script = jexl.createScript(src);
result = script.execute(ctxt);
Assert.assertEquals(1, result);
// declared and defined
src = "x = 1; if (true) var x = 2; x";
script = jexl.createScript(src);
result = script.execute(ctxt);
Assert.assertEquals(2, result);
// definition using shadowed global
src = "x = 1; var x = x + 41; x";
script = jexl.createScript(src);
result = script.execute(ctxt);
Assert.assertEquals(42, result);
// definition using shadowed global
options.setLexical(false);
src = "(x)->{ if (x==1) { var y = 2; } else if (x==2) { var y = 3; }; y }";
script = jexl.createScript(src);
result = script.execute(ctxt, 1);
Assert.assertEquals(2, result);
result = script.execute(ctxt, 2);
Assert.assertEquals(3, result);
options.setStrict(true);
try {
result = script.execute(ctxt, 0);
Assert.fail("should have failed!");
} catch (final JexlException.Variable xvar) {
Assert.assertTrue(xvar.getMessage().contains("y"));
}
options.setStrict(false);
try {
result = script.execute(ctxt, 0);
} catch (final JexlException xvar) {
Assert.fail("should not have failed!");
}
Assert.assertNull(result);
}
@Test
public void test289() {
final JexlContext ctxt = new MapContext();
final JexlEngine jexl = new JexlBuilder().strict(true).create();
String src;
JexlScript script;
Object result;
src = "var x = function(a) { var b; return b}; x(1,2)";
script = jexl.createScript(src);
result = script.execute(ctxt);
Assert.assertNull(result);
}
@Test
public void test290a() throws Exception {
Object result;
JexlScript script;
final String[] srcs = new String[]{
"(x)->{ x.nothing().toString() }",
"(x)->{ x.toString().nothing() }",
"(x)->{ x.nothing().nothing() }",
};
for (final boolean safe : new boolean[]{true, false}) {
final JexlEngine jexl = new JexlBuilder().safe(safe).strict(true).create();
for (final String src : srcs) {
script = jexl.createScript(src);
try {
result = script.execute(null, "abc");
if (!safe) {
Assert.fail("should have failed: " + src);
} else {
Assert.assertNull("non-null result ?!", result);
}
} catch (final JexlException.Method xmethod) {
if (safe) {
Assert.fail(src + ", should not have thrown " + xmethod);
} else {
Assert.assertTrue(src + ": " + xmethod.toString(), xmethod.toString().contains("nothing"));
}
}
}
}
}
@Test
public void test290b() throws Exception {
Object result;
JexlScript script;
final String[] srcs = new String[]{
"(x)->{ x?.nothing()?.toString() }",
"(x)->{ x.toString()?.nothing() }",
"(x)->{ x?.nothing().nothing() }",};
final JexlEngine jexl = new JexlBuilder().strict(true).create();
for (final String src : srcs) {
script = jexl.createScript(src);
result = script.execute(null, "abc");
Assert.assertNull(result);
}
}
@Test
public void test291() throws Exception {
final String str = "{1:'one'}[1]";
final JexlContext ctxt = new MapContext();
final JexlEngine jexl = new JexlBuilder().create();
JexlExpression e = jexl.createExpression(str);
Object value = e.evaluate(ctxt);
Assert.assertEquals("one", value);
final JexlEngine sandboxedJexlEngine = new JexlBuilder().
sandbox(new JexlSandbox(true)). // add a whitebox sandbox
create();
e = sandboxedJexlEngine.createExpression(str);
value = e.evaluate(ctxt);
Assert.assertEquals("one", value);
}
@Test
public void testTemplate6565a() throws Exception {
final JexlEngine jexl = new JexlBuilder().create();
final JxltEngine jexlt = jexl.createJxltEngine();
final String source =
"$$ var res = '';\n" +
"$$ var meta = session.data['METADATA'];\n" +
"$$ if (meta) {\n" +
"$$ var entry = meta['ID'];\n" +
"$$ if (entry) {\n" +
"$$ var value = session.data[entry];\n" +
"$$ res = value?: '';\n" +
"$$ }\n" +
"$$ }\n" +
"${res}\n";
final JxltEngine.Template script = jexlt.createTemplate("$$", new StringReader(source));
Assert.assertNotNull(script);
final TemplateDebugger dbg = new TemplateDebugger();
final String refactored = dbg.debug(script) ? dbg.toString() : "";
Assert.assertNotNull(refactored);
Assert.assertEquals(source, refactored);
}
@Test
public void testTemplate6565b() throws Exception {
final JexlEngine jexl = new JexlBuilder().create();
final JxltEngine jexlt = jexl.createJxltEngine();
final String source =
"$$ var res = '';\n" +
"$$ var meta = session.data['METADATA'];\n" +
"$$ if (meta) {\n" +
"$$ var entry = meta['ID'];\n" +
"$$ if (entry) {\n" +
"$$ var value = session.data[entry];\n" +
"$$ res = value?: '';\n" +
"${res}\n" +
"$$ }\n" +
"$$ }\n";
final JxltEngine.Template script = jexlt.createTemplate("$$", new StringReader(source));
Assert.assertNotNull(script);
final TemplateDebugger dbg = new TemplateDebugger();
final String refactored = dbg.debug(script) ? dbg.toString() : "";
Assert.assertNotNull(refactored);
Assert.assertEquals(source, refactored);
}
public static class Cls298 {
int sz = 42;
public int size() {
return sz;
}
public int size(final int x) {
return sz + x;
}
public boolean isEmpty() {
return sz <= 0;
}
}
@Test
public void test298() throws Exception {
final Cls298 c298 = new Cls298();
final JexlContext ctxt = new MapContext();
final JexlEngine jexl = new JexlBuilder().create();
String str = "c.size()";
JexlScript e = jexl.createScript(str, "c");
Object value = e.execute(ctxt, c298);
Assert.assertEquals(str, 42, value);
str = "size c";
e = jexl.createScript(str, "c");
value = e.execute(ctxt, c298);
Assert.assertEquals(str, 42, value);
str = "c.size(127)";
e = jexl.createScript(str, "c");
value = e.execute(ctxt, c298);
Assert.assertEquals(str, 169, value);
}
}