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

ddekany pushed a commit to branch 2.3-gae
in repository https://gitbox.apache.org/repos/asf/freemarker.git


The following commit(s) were added to refs/heads/2.3-gae by this push:
     new ebb38fff FREEMARKER-227: Fixed bug, where if classic_compatible mode 
was true (rarely used), then sequence built-ins, like seq?seq_contains(value), 
has failed with NullPointerException if values of incompatible types had to be 
compared. The intended behavior is to convert the values to string, and then 
compare them (to mimic the behavior of FreeMarker 1.x).
ebb38fff is described below

commit ebb38fffb7cf8afd1e29f62c7ef646551be9f203
Author: ddekany <[email protected]>
AuthorDate: Mon Jul 8 23:58:42 2024 +0200

    FREEMARKER-227: Fixed bug, where if classic_compatible mode was true 
(rarely used), then sequence built-ins, like seq?seq_contains(value), has 
failed with NullPointerException if values of incompatible types had to be 
compared. The intended behavior is to convert the values to string, and then 
compare them (to mimic the behavior of FreeMarker 1.x).
---
 .../src/main/java/freemarker/core/EvalUtil.java    | 12 +++--
 .../freemarker/core/ClassicCompatibleBugsTest.java | 59 ++++++++++++++++++++++
 freemarker-manual/src/main/docgen/en_US/book.xml   | 24 +++++++--
 3 files changed, 87 insertions(+), 8 deletions(-)

diff --git a/freemarker-core/src/main/java/freemarker/core/EvalUtil.java 
b/freemarker-core/src/main/java/freemarker/core/EvalUtil.java
index f7025646..03755368 100644
--- a/freemarker-core/src/main/java/freemarker/core/EvalUtil.java
+++ b/freemarker-core/src/main/java/freemarker/core/EvalUtil.java
@@ -293,9 +293,13 @@ class EvalUtil {
             boolean rightBool = ((TemplateBooleanModel) 
rightValue).getAsBoolean();
             cmpResult = (leftBool ? 1 : 0) - (rightBool ? 1 : 0);
         } else if (env.isClassicCompatible()) {
-            String leftSting = leftExp.evalAndCoerceToPlainText(env);
-            String rightString = rightExp.evalAndCoerceToPlainText(env);
-            cmpResult = env.getCollator().compare(leftSting, rightString);
+            String leftString = leftExp != null
+                    ? leftExp.evalAndCoerceToPlainText(env)
+                    : EvalUtil.coerceModelToPlainText(leftValue, null, null, 
env);
+            String rightString = rightExp != null
+                    ? rightExp.evalAndCoerceToPlainText(env)
+                    : EvalUtil.coerceModelToPlainText(rightValue, null, null, 
env);;
+            cmpResult = env.getCollator().compare(leftString, rightString);
         } else {
             if (typeMismatchMeansNotEqual) {
                 if (operator == CMP_OP_EQUALS) {
@@ -446,7 +450,7 @@ class EvalUtil {
      * 
      * @param seqTip
      *            Tip to display if the value type is not coercable, but it's 
sequence or collection.
-     * @param exp {@code null} is allowed, but may results in less helpful 
error messages
+     * @param exp {@code null} is allowed, but may result in less helpful 
error messages
      *
      * @return Never {@code null}
      */
diff --git 
a/freemarker-core/src/test/java/freemarker/core/ClassicCompatibleBugsTest.java 
b/freemarker-core/src/test/java/freemarker/core/ClassicCompatibleBugsTest.java
new file mode 100644
index 00000000..610c9959
--- /dev/null
+++ 
b/freemarker-core/src/test/java/freemarker/core/ClassicCompatibleBugsTest.java
@@ -0,0 +1,59 @@
+/*
+ * 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 freemarker.core;
+
+import java.io.IOException;
+import java.util.List;
+
+import org.junit.Test;
+
+import freemarker.template.Configuration;
+import freemarker.template.TemplateException;
+import freemarker.test.TemplateTest;
+
+public class ClassicCompatibleBugsTest extends TemplateTest {
+    @Override
+    protected Configuration createConfiguration() {
+        Configuration conf = new Configuration(Configuration.VERSION_2_3_33);
+        conf.setClassicCompatible(true);
+        conf.setBooleanFormat("c");
+        return conf;
+    }
+
+    /**
+     * FREEMARKER-227
+     */
+    @Test
+    public void testLenientValueComparisonInSeqBuiltIns() throws 
TemplateException, IOException {
+        addToDataModel("seq", List.of(1, "2", 3.0));
+
+        assertOutput("${seq?seq_contains(1)?string}", "true");
+        assertOutput("${seq?seq_contains('1')?string}", "true");
+
+        assertOutput("${seq?seq_contains(2)?string}", "true");
+        assertOutput("${seq?seq_contains('2')?string}", "true");
+
+        assertOutput("${seq?seq_contains(3)?string}", "true");
+        assertOutput("${seq?seq_contains('3')?string}", "true");
+
+        assertOutput("${seq?seq_contains(4)?string}", "false");
+        assertOutput("${seq?seq_contains('4')?string}", "false");
+    }
+}
diff --git a/freemarker-manual/src/main/docgen/en_US/book.xml 
b/freemarker-manual/src/main/docgen/en_US/book.xml
index f01481a3..5813d09c 100644
--- a/freemarker-manual/src/main/docgen/en_US/book.xml
+++ b/freemarker-manual/src/main/docgen/en_US/book.xml
@@ -20,10 +20,7 @@
 <book conformance="docgen" version="5.0" xml:lang="en"
       xmlns="http://docbook.org/ns/docbook";
       xmlns:xlink="http://www.w3.org/1999/xlink";
-      xmlns:ns5="http://www.w3.org/1999/xhtml";
-      xmlns:ns4="http://www.w3.org/1998/Math/MathML";
-      xmlns:ns3="http://www.w3.org/2000/svg";
-      xmlns:ns="http://docbook.org/ns/docbook";>
+>
   <info>
     <title>Apache FreeMarker Manual</title>
 
@@ -30119,6 +30116,25 @@ TemplateModel x = env.getVariable("x");  // get 
variable x</programlisting>
 
         <para>Release date: TODO</para>
 
+        <section>
+          <title>Changes on the FTL side</title>
+
+          <itemizedlist>
+            <listitem>
+              <para><link
+              
xlink:href="https://issues.apache.org/jira/browse/FREEMARKER-227";>FREEMARKER-227</link>:
+              Fixed bug, where if <literal>classic_compatible</literal> mode
+              was <literal>true</literal> (rarely used), then sequence
+              built-ins, like
+              
<literal><replaceable>seq</replaceable>?seq_contains(<replaceable>value</replaceable>)</literal>,
+              has failed with <literal>NullPointerException</literal> if
+              values of incompatible types had to be compared. The intended
+              behavior is to convert the values to string, and then compare
+              them (to mimic the behavior of FreeMarker 1.x).</para>
+            </listitem>
+          </itemizedlist>
+        </section>
+
         <section>
           <title>Changes on the Java side</title>
 

Reply via email to