1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.jexl3;
18
19 import static org.junit.jupiter.api.Assertions.assertEquals;
20 import static org.junit.jupiter.api.Assertions.assertFalse;
21 import static org.junit.jupiter.api.Assertions.assertThrows;
22 import static org.junit.jupiter.api.Assertions.assertTrue;
23
24 import java.util.Collections;
25 import java.util.concurrent.atomic.AtomicInteger;
26
27 import org.apache.commons.jexl3.annotations.NoJexl;
28 import org.junit.jupiter.api.Test;
29
30
31
32
33
34 class NamespaceInstantiationTest extends JexlTestCase {
35
36 public NamespaceInstantiationTest() {
37 super("NamespaceInstantiationTest");
38 }
39
40
41 static final AtomicInteger CTOR = new AtomicInteger();
42
43
44 public static class InstanceNs {
45 private final int base;
46 public InstanceNs(final JexlContext ctxt) {
47 CTOR.incrementAndGet();
48 final Object n = ctxt.get("BASE");
49 base = n instanceof Number ? ((Number) n).intValue() : 0;
50 }
51 public int callIt(final int n) {
52 return n + base;
53 }
54 }
55
56
57 public static class StaticNs {
58 private StaticNs() { }
59 public static int callIt(final int n) {
60 return n + 19;
61 }
62 }
63
64
65 @NoJexl
66 public static class HiddenNs {
67 public static int callIt(final int n) {
68 return n + 1;
69 }
70 }
71
72 @Test
73 void testFeatureDefaultsOn() {
74 assertTrue(new JexlFeatures().supportsNamespaceInstantiation());
75 assertTrue(new JexlFeatures().namespaceInstantiation(false).namespaceInstantiation(true)
76 .supportsNamespaceInstantiation());
77 assertFalse(new JexlFeatures().namespaceInstantiation(false).supportsNamespaceInstantiation());
78 }
79
80 @Test
81 void testInstantiationEnabled() {
82 CTOR.set(0);
83 final JexlContext ctxt = new MapContext();
84 ctxt.set("BASE", 19);
85
86 final JexlEngine jexl = new JexlBuilder().strict(true).silent(false)
87 .features(new JexlFeatures().namespaceInstantiation(true))
88 .namespaces(Collections.singletonMap("nsns", InstanceNs.class)).create();
89 final JexlScript s = jexl.createScript("x -> { nsns:callIt(x); }");
90 assertEquals(42, s.execute(ctxt, 23));
91 assertEquals(1, CTOR.get());
92 }
93
94 @Test
95 void testInstantiationDisabledBlocksInstanceNs() {
96 CTOR.set(0);
97 final JexlContext ctxt = new MapContext();
98 ctxt.set("BASE", 19);
99 final JexlEngine jexl = new JexlBuilder().strict(true).silent(false)
100 .features(new JexlFeatures().namespaceInstantiation(false))
101 .namespaces(Collections.singletonMap("nsns", InstanceNs.class)).create();
102 final JexlScript s = jexl.createScript("x -> { nsns:callIt(x); }");
103
104
105 assertThrows(JexlException.class, () -> s.execute(ctxt, 23));
106 assertEquals(0, CTOR.get());
107 }
108
109 @Test
110 void testInstantiationDisabledKeepsStaticNs() {
111 final JexlEngine jexl = new JexlBuilder().strict(true).silent(false)
112 .features(new JexlFeatures().namespaceInstantiation(false))
113 .namespaces(Collections.singletonMap("sns", StaticNs.class)).create();
114 final JexlScript s = jexl.createScript("x -> { sns:callIt(x); }");
115 assertEquals(42, s.execute(new MapContext(), 23));
116 }
117
118 @Test
119 void testInstantiationDisabledKeepsStaticNsByName() {
120 final JexlEngine jexl = new JexlBuilder().strict(true).silent(false)
121 .features(new JexlFeatures().namespaceInstantiation(false))
122 .namespaces(Collections.singletonMap("sns", StaticNs.class.getName())).create();
123 final JexlScript s = jexl.createScript("x -> { sns:callIt(x); }");
124 assertEquals(42, s.execute(new MapContext(), 23));
125 }
126
127 @Test
128 void testStringNamespaceDeniedClass() {
129
130
131 final JexlEngine jexl = new JexlBuilder().strict(true).silent(false)
132 .namespaces(Collections.singletonMap("h", HiddenNs.class.getName())).create();
133 final JexlScript script = jexl.createScript("h:callIt(41)");
134 final JexlException xany = assertThrows(JexlException.class, () -> script.execute(new MapContext()));
135 assertTrue(xany.getMessage().contains("class namespace") || xany.getMessage().contains("HiddenNs"),
136 xany.getMessage());
137 }
138 }