This is an automated email from the ASF dual-hosted git repository.

henrib pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-jexl.git


The following commit(s) were added to refs/heads/master by this push:
     new 1d41aecf JEXL : release notes; - fixing unsafe JSR233 configuration;
1d41aecf is described below

commit 1d41aecf9eaba2f0d6f3f9a7909aa886c00cfc0f
Author: Henrib <[email protected]>
AuthorDate: Fri Jun 19 19:06:33 2026 +0200

    JEXL : release notes;
    - fixing unsafe JSR233 configuration;
---
 .../commons/jexl3/scripting/JexlScriptEngine.java  |  62 +++++------
 .../jexl3/scripting/JexlScriptEngineFactory.java   |  61 ++++++++++-
 src/site/xdoc/relnotes.xml                         | 116 +++++++++++++++++++--
 .../jexl3/scripting/JexlScriptEngineTest.java      |  10 +-
 4 files changed, 199 insertions(+), 50 deletions(-)

diff --git 
a/src/main/java/org/apache/commons/jexl3/scripting/JexlScriptEngine.java 
b/src/main/java/org/apache/commons/jexl3/scripting/JexlScriptEngine.java
index 652d3419..3d9bb458 100644
--- a/src/main/java/org/apache/commons/jexl3/scripting/JexlScriptEngine.java
+++ b/src/main/java/org/apache/commons/jexl3/scripting/JexlScriptEngine.java
@@ -36,7 +36,6 @@ import javax.script.ScriptEngineFactory;
 import javax.script.ScriptException;
 import javax.script.SimpleBindings;
 
-import org.apache.commons.jexl3.JexlBuilder;
 import org.apache.commons.jexl3.JexlContext;
 import org.apache.commons.jexl3.JexlEngine;
 import org.apache.commons.jexl3.JexlException;
@@ -265,12 +264,7 @@ public class JexlScriptEngine extends AbstractScriptEngine 
implements Compilable
      * The shared engine instance.
      * <p>A single soft-reference JEXL engine and JexlUberspect is shared by 
all instances of JexlScriptEngine.</p>
      */
-    private static Reference<JexlEngine> ENGINE;
-
-    /**
-     * The permissions used to create the script engine.
-     */
-    private static JexlPermissions PERMISSIONS;
+    private static Reference<JexlEngine> engineReference;
 
     /** The logger. */
     static final Log LOG = LogFactory.getLog(JexlScriptEngine.class);
@@ -284,27 +278,26 @@ public class JexlScriptEngine extends 
AbstractScriptEngine implements Compilable
     /** Reserved key for JexlScriptObject. */
     public static final String JEXL_OBJECT_KEY = "JEXL";
 
+    /** Reserved key for script. */
+    private static final String SCRIPT = "script";
+
     /**
      * @return the shared JexlEngine instance, create it if necessary
      */
-    private static JexlEngine getEngine() {
-        JexlEngine engine = ENGINE != null ? ENGINE.get() : null;
+    private static JexlEngine getEngine(ScriptEngineFactory 
scriptEngineFactory) {
+        Reference<JexlEngine> ref = engineReference;
+        JexlEngine engine = ref != null ? ref.get() : null;
         if (engine == null) {
             synchronized (JexlScriptEngineFactory.class) {
-                engine = ENGINE != null ? ENGINE.get() : null;
+                ref = engineReference;
+                engine = ref != null ? ref.get() : null;
                 if (engine == null) {
-                    final JexlBuilder builder = new JexlBuilder()
-                            .strict(true)
-                            .safe(false)
-                            .logger(JexlScriptEngine.LOG)
-                            .cache(JexlScriptEngine.CACHE_SIZE);
-                    // ensure the script object class is always allowed for 
all permissions set
-                    JexlPermissions permissions = new 
JexlPermissions.ClassPermissions(
-                        PERMISSIONS == null ? JexlPermissions.RESTRICTED : 
PERMISSIONS,
-                            JexlScriptObject.class);
-                        builder.permissions(permissions);
-                    engine = builder.create();
-                    ENGINE = new SoftReference<>(engine);
+                    if (!(scriptEngineFactory instanceof 
JexlScriptEngineFactory)) {
+                        throw new 
IllegalArgumentException("ScriptEngineFactory is not JexlScriptEngineFactory");
+                    }
+                    JexlScriptEngineFactory factory = 
(JexlScriptEngineFactory) scriptEngineFactory;
+                    engine = factory.createJexlEngine();
+                    engineReference = new SoftReference<>(engine);
                 }
             }
         }
@@ -367,23 +360,18 @@ public class JexlScriptEngine extends 
AbstractScriptEngine implements Compilable
      * @since 3.3
      */
     public static void setInstance(final JexlEngine engine) {
-        ENGINE = new SoftReference<>(engine);
+        engineReference = new SoftReference<>(engine);
     }
 
     /**
      * Sets the permissions instance used to create the script engine.
-     * <p>Calling this method will force engine instance re-creation.</p>
-     * <p>To restore 3.2 script behavior:</p>
-     * {@code
-     *         JexlScriptEngine.setPermissions(JexlPermissions.UNRESTRICTED);
-     * }
-     *
-     * @param permissions the permissions instance to use or null to use the 
{@link JexlBuilder} default
-     * @since 3.3
+     * <p>This method has been considered unsafe and is no longer 
supported.</p>
+     * @deprecated 3.6.3
+     * @param permissions unused, method will throw
      */
+    @Deprecated
     public static void setPermissions(final JexlPermissions permissions) {
-        PERMISSIONS = permissions;
-        ENGINE = null; // will force recreation
+        throw new 
UnsupportedOperationException("JexlScriptEngine.setPermissions is unsafe and no 
longer supported");
     }
 
     /** The JexlScriptObject instance. */
@@ -414,21 +402,21 @@ public class JexlScriptEngine extends 
AbstractScriptEngine implements Compilable
     public JexlScriptEngine(final ScriptEngineFactory scriptEngineFactory) {
         Objects.requireNonNull(scriptEngineFactory, "scriptEngineFactory");
         parentFactory = scriptEngineFactory;
-        jexlEngine = getEngine();
+        jexlEngine = getEngine(scriptEngineFactory);
         jexlObject = new JexlScriptObject();
     }
 
     @Override
     public CompiledScript compile(final Reader script) throws ScriptException {
         // This is mandated by JSR-223
-        Objects.requireNonNull(script, "script");
+        Objects.requireNonNull(script, SCRIPT);
         return compile(readerToString(script));
     }
 
     @Override
     public CompiledScript compile(final String script) throws ScriptException {
         // This is mandated by JSR-223
-        Objects.requireNonNull(script, "script");
+        Objects.requireNonNull(script, SCRIPT);
         try {
             final JexlScript jexlScript = jexlEngine.createScript(script);
             return new JexlCompiledScript(jexlScript);
@@ -453,7 +441,7 @@ public class JexlScriptEngine extends AbstractScriptEngine 
implements Compilable
     @Override
     public Object eval(final String script, final ScriptContext context) 
throws ScriptException {
         // This is mandated by JSR-223 (see SCR.5.5.2   Methods)
-        Objects.requireNonNull(script, "script");
+        Objects.requireNonNull(script, SCRIPT);
         Objects.requireNonNull(context, CONTEXT_KEY);
         // This is mandated by JSR-223 (end of section SCR.4.3.4.1.2 - 
JexlScript Execution)
         context.setAttribute(CONTEXT_KEY, context, ScriptContext.ENGINE_SCOPE);
diff --git 
a/src/main/java/org/apache/commons/jexl3/scripting/JexlScriptEngineFactory.java 
b/src/main/java/org/apache/commons/jexl3/scripting/JexlScriptEngineFactory.java
index 1f0b5f7c..7862b36e 100644
--- 
a/src/main/java/org/apache/commons/jexl3/scripting/JexlScriptEngineFactory.java
+++ 
b/src/main/java/org/apache/commons/jexl3/scripting/JexlScriptEngineFactory.java
@@ -24,6 +24,9 @@ import java.util.List;
 import javax.script.ScriptEngine;
 import javax.script.ScriptEngineFactory;
 
+import org.apache.commons.jexl3.JexlBuilder;
+import org.apache.commons.jexl3.JexlEngine;
+import org.apache.commons.jexl3.introspection.JexlPermissions;
 import org.apache.commons.jexl3.parser.StringParser;
 
 /**
@@ -44,9 +47,65 @@ import org.apache.commons.jexl3.parser.StringParser;
  * @since 2.0
  */
 public class JexlScriptEngineFactory implements ScriptEngineFactory {
+    /**
+     * The default factory permissions.
+     */
+    private static JexlPermissions defaultPermissions = null;
+
+    /**
+     * The engine permissions.
+     */
+    private final JexlPermissions permissions;
 
     /** Default constructor */
-    public JexlScriptEngineFactory() {} // Keep Javadoc happy
+    public JexlScriptEngineFactory() { this(null); } // Keep Javadoc happy
+
+    /**
+     * Constructor with permissions.
+     * <p>Meant to reduce dependency to JEXL for extraordinary case of JSR233 
</p>
+     * @param jexlPermissions the permissions instance to use or null to use 
the {@link JexlScriptEngineFactory} default
+     */
+    public JexlScriptEngineFactory(JexlPermissions jexlPermissions) {
+        permissions = jexlPermissions != null ? jexlPermissions : 
defaultPermissions;
+    }
+
+    /**
+     * @return a new JexlEngine instance
+     */
+    JexlEngine createJexlEngine() {
+        JexlBuilder builder = new JexlBuilder()
+          .strict(true)
+          .safe(false)
+          .logger(JexlScriptEngine.LOG)
+          .cache(JexlScriptEngine.CACHE_SIZE);
+        JexlPermissions p = permissions;
+        if (p == null) {
+            p = defaultPermissions;
+            if (p == null) {
+                p = builder.permissions();
+                if (p == null) {
+                    p = JexlPermissions.RESTRICTED;
+                }
+            }
+        }
+        JexlPermissions required = new JexlPermissions.ClassPermissions(p, 
JexlScriptEngine.JexlScriptObject.class);
+        builder.permissions(required);
+        return builder.create();
+    }
+
+    /**
+     * Sets the permissions instance used to create the script engine.
+     * <p>To restore 3.2 <em>unsafe</em> script behavior:</p>
+     * {@code
+     *         
JexlScriptEngineFactory.setDefaultPermissions(JexlPermissions.UNRESTRICTED);
+     * }
+     *
+     * @param permissions the permissions instance to use or null to use the 
{@link JexlBuilder} default
+     * @since 3.6.3
+     */
+    public static void setDefaultPermissions(final JexlPermissions 
permissions) {
+        defaultPermissions = permissions;
+    }
 
     @Override
     public String getEngineName() {
diff --git a/src/site/xdoc/relnotes.xml b/src/site/xdoc/relnotes.xml
index 893503d6..99b53562 100644
--- a/src/site/xdoc/relnotes.xml
+++ b/src/site/xdoc/relnotes.xml
@@ -59,6 +59,30 @@
     <section name="Bugs fixed in 3.6.3:">
       <p>
         <table>
+          <tr>
+            <td>
+              <a 
href="https://issues.apache.org/jira/browse/JEXL-461";>JEXL-461:</a>
+            </td>
+            <td>Updates/improvements to the site documentation for JEXL 
Syntax.</td>
+          </tr>
+          <tr>
+            <td>
+              <a 
href="https://issues.apache.org/jira/browse/JEXL-459";>JEXL-459:</a>
+            </td>
+            <td>Empty/size functions swallow all exceptions with no trace.</td>
+          </tr>
+          <tr>
+            <td>
+              <a 
href="https://issues.apache.org/jira/browse/JEXL-458";>JEXL-458:</a>
+            </td>
+            <td>Improve permissions expressivity.</td>
+          </tr>
+          <tr>
+            <td>
+              <a 
href="https://issues.apache.org/jira/browse/JEXL-457";>JEXL-457:</a>
+            </td>
+            <td>Reduce default exposure for RESTRICTED JexlPermissions.</td>
+          </tr>
           <tr>
             <td>
               <a 
href="https://issues.apache.org/jira/browse/JEXL-456";>JEXL-456:</a>
@@ -68,6 +92,28 @@
         </table>
       </p>
     </section>
+    <section name="Changes in 3.6.3:">
+      <p>
+        <table>
+          <tr>
+            <td></td>
+            <td>Fix the @return tags in the Javadoc for 
JexlArithmetic.toBigInteger() overloads.</td>
+          </tr>
+          <tr>
+            <td></td>
+            <td>Bump org.apache.commons:commons-parent from 96 to 102.</td>
+          </tr>
+          <tr>
+            <td></td>
+            <td>Bump commons-logging:commons-logging from 1.3.5 to 1.4.0.</td>
+          </tr>
+          <tr>
+            <td></td>
+            <td>Bump com.google.code.gson:gson from 2.13.2 to 2.14.0.</td>
+          </tr>
+        </table>
+      </p>
+    </section>
 
     <section name="What was new in 3.6.2:">
       <p>
@@ -100,6 +146,17 @@
       </p>
     </section>
 
+    <section name="Changes in 3.6.2:">
+      <p>
+        <table>
+          <tr>
+            <td></td>
+            <td>Bump org.apache.commons:commons-parent from 93 to 96.</td>
+          </tr>
+        </table>
+      </p>
+    </section>
+
     <section name="What was new in 3.6.1:">
       <p>
         JEXL 3.6.1 was a minor release that fixed some bugs.
@@ -137,6 +194,21 @@
       </p>
     </section>
 
+    <section name="Changes in 3.6.1:">
+      <p>
+        <table>
+          <tr>
+            <td></td>
+            <td>Bump org.apache.commons:commons-parent from 91 to 93.</td>
+          </tr>
+          <tr>
+            <td></td>
+            <td>Bump org.apache.commons:commons-lang3 from 3.17.0 to 
3.20.0.</td>
+          </tr>
+        </table>
+      </p>
+    </section>
+
     <section name="What was new in 3.6.0:">
       <p>
         JEXL 3.6.0 introduced a switch statement and expressions (JEXL-440).
@@ -160,21 +232,27 @@
         <table>
           <tr>
             <td>
-              <a 
href="https://issues.apache.org/jira/browse/JEXL-437";>JEXL-447:</a>
+              <a 
href="https://issues.apache.org/jira/browse/JEXL-448";>JEXL-448:</a>
             </td>
-            <td>Regression in script-defined functions</td>
+            <td>Engines caching misses local variables handling and global 
eviction capability.</td>
+          </tr>
+          <tr>
+            <td>
+              <a 
href="https://issues.apache.org/jira/browse/JEXL-447";>JEXL-447:</a>
+            </td>
+            <td>Regression in script-defined functions.</td>
           </tr>
           <tr>
             <td>
               <a 
href="https://issues.apache.org/jira/browse/JEXL-446";>JEXL-446:</a>
             </td>
-            <td>ClassTool module inspection is too strict</td>
+            <td>ClassTool module inspection is too strict.</td>
           </tr>
           <tr>
             <td>
               <a 
href="https://issues.apache.org/jira/browse/JEXL-442";>JEXL-442:</a>
             </td>
-            <td>Local variables are not resolved in interpolation string 
expression</td>
+            <td>Local variables are not resolved in interpolation string 
expression.</td>
           </tr>
           <tr>
             <td>
@@ -186,13 +264,39 @@
             <td>
               <a 
href="https://issues.apache.org/jira/browse/JEXL-439";>JEXL-439:</a>
             </td>
-            <td>When using reference capture, incorrect scoping when local 
variable redefines a captured symbol</td>
+            <td>When using reference capture, incorrect scoping when local 
variable redefines a captured symbol.</td>
           </tr>
           <tr>
             <td>
               <a 
href="https://issues.apache.org/jira/browse/JEXL-437";>JEXL-437:</a>
             </td>
-            <td>Semicolons actually not optional between function calls on 
separate lines</td>
+            <td>Semicolons not actually optional between function calls on 
separate lines.</td>
+          </tr>
+          <tr>
+            <td></td>
+            <td>AbstractExecutor.initMarker throws IllegalArgumentException 
instead of Exception.</td>
+          </tr>
+          <tr>
+            <td></td>
+            <td>Reuse BigInteger constants instead of creating new instances 
in JexlArithmetic.toBigInteger(Object).</td>
+          </tr>
+        </table>
+      </p>
+    </section>
+    <section name="Changes in 3.6.0:">
+      <p>
+        <table>
+          <tr>
+            <td></td>
+            <td>Bump org.apache.commons:commons-parent from 81 to 91.</td>
+          </tr>
+          <tr>
+            <td></td>
+            <td>Bump org.apache.commons:commons-lang3 from 3.17.0 to 
3.19.0.</td>
+          </tr>
+          <tr>
+            <td></td>
+            <td>Bump com.google.code.gson:gson from 2.13.1 to 2.13.2.</td>
           </tr>
         </table>
       </p>
diff --git 
a/src/test/java/org/apache/commons/jexl3/scripting/JexlScriptEngineTest.java 
b/src/test/java/org/apache/commons/jexl3/scripting/JexlScriptEngineTest.java
index 0cac1093..5b60b3ac 100644
--- a/src/test/java/org/apache/commons/jexl3/scripting/JexlScriptEngineTest.java
+++ b/src/test/java/org/apache/commons/jexl3/scripting/JexlScriptEngineTest.java
@@ -45,7 +45,6 @@ import javax.script.ScriptEngine;
 import javax.script.ScriptEngineManager;
 import javax.script.ScriptException;
 
-import org.apache.commons.jexl3.JexlBuilder;
 import org.apache.commons.jexl3.JexlException;
 import org.apache.commons.jexl3.LoggingPermissions;
 import org.apache.commons.jexl3.introspection.JexlPermissions;
@@ -81,9 +80,8 @@ class JexlScriptEngineTest {
 
     @AfterEach
     void tearDown() {
-        JexlBuilder.setDefaultPermissions(null);
         JexlScriptEngine.setInstance(null);
-        JexlScriptEngine.setPermissions(null);
+        JexlScriptEngineFactory.setDefaultPermissions(null);
     }
 
     @Test
@@ -148,7 +146,7 @@ class JexlScriptEngineTest {
     @Test
     void testErrors() throws Exception {
         JexlPermissions permissions = new 
JexlPermissions.ClassPermissions(Errors.class);
-        JexlScriptEngine.setPermissions(permissions);
+        JexlScriptEngineFactory.setDefaultPermissions(permissions);
         final ScriptEngineManager manager = new ScriptEngineManager();
         final JexlScriptEngine engine = (JexlScriptEngine) 
manager.getEngineByName("JEXL");
         engine.put("errors", new Errors());
@@ -257,7 +255,7 @@ class JexlScriptEngineTest {
     }
     @Test
     void testScriptingInstance0() throws Exception {
-        JexlScriptEngine.setPermissions(JexlPermissions.UNRESTRICTED);
+        
JexlScriptEngineFactory.setDefaultPermissions(JexlPermissions.UNRESTRICTED);
         final ScriptEngineManager manager = new ScriptEngineManager();
         final ScriptEngine engine = manager.getEngineByName("jexl3");
         final Long time2 = (Long) engine.eval(
@@ -269,7 +267,7 @@ class JexlScriptEngineTest {
     @Test
     void testScriptingPermissions1() throws Exception {
         // shows what is required to access System.currentTimeMillis()
-        JexlScriptEngine.setPermissions(new LoggingPermissions(
+        JexlScriptEngineFactory.setDefaultPermissions(new LoggingPermissions(
             JexlPermissions.RESTRICTED.compose(
                 "javax.script { +SimpleScriptContext { getClass(); } }"
                     + "java.lang { "

Reply via email to