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

lukaszlenart pushed a commit to branch feature/WW-5451-null-iterator
in repository https://gitbox.apache.org/repos/asf/struts.git

commit 479a9d86ed3b37db10c8322045887be293f14cd6
Author: Lukasz Lenart <lukaszlen...@apache.org>
AuthorDate: Wed Jul 31 16:53:01 2024 +0200

    WW-5451 Fixes NPE when iterator starts with null
---
 .../struts2/components/IteratorComponent.java      |  5 ++-
 .../struts2/components/IteratorComponentTest.java  | 36 ++++++++++++++++++++++
 .../apache/struts2/views/jsp/IteratorTagTest.java  | 36 +++++++++++++++++++++-
 3 files changed, 75 insertions(+), 2 deletions(-)

diff --git 
a/core/src/main/java/org/apache/struts2/components/IteratorComponent.java 
b/core/src/main/java/org/apache/struts2/components/IteratorComponent.java
index 7ff83bd45..1659e6c6e 100644
--- a/core/src/main/java/org/apache/struts2/components/IteratorComponent.java
+++ b/core/src/main/java/org/apache/struts2/components/IteratorComponent.java
@@ -306,7 +306,10 @@ public class IteratorComponent extends ContextBean {
         if ((iterator != null) && iterator.hasNext()) {
             Object currentValue = iterator.next();
             stack.push(currentValue);
-            threadAllowlist.allowClass(currentValue.getClass());
+
+            if (currentValue != null) {
+                threadAllowlist.allowClass(currentValue.getClass());
+            }
 
             String var = getVar();
 
diff --git 
a/core/src/test/java/org/apache/struts2/components/IteratorComponentTest.java 
b/core/src/test/java/org/apache/struts2/components/IteratorComponentTest.java
index 7f08ef64e..077510a71 100644
--- 
a/core/src/test/java/org/apache/struts2/components/IteratorComponentTest.java
+++ 
b/core/src/test/java/org/apache/struts2/components/IteratorComponentTest.java
@@ -184,6 +184,42 @@ public class IteratorComponentTest extends 
StrutsInternalTestCase {
         assertEquals("1, 2, , 4, ", out.getBuffer().toString());
     }
 
+    public void testIteratorWithNullsOnly() {
+        // given
+        stack.push(new FooAction() {
+            private final List<String> items = Arrays.asList(null, null, null);
+
+            public List<String> getItems() {
+                return items;
+            }
+        });
+
+        StringWriter out = new StringWriter();
+
+        ic.setValue("items");
+        ic.setVar("val");
+        Property prop = new Property(stack);
+
+        ic.getComponentStack().push(prop);
+        ic.getComponentStack().push(prop);
+        ic.getComponentStack().push(prop);
+        ic.getComponentStack().push(prop);
+
+        String body = ", ";
+
+        // when
+        assertTrue(ic.start(out));
+
+        for (int i = 0; i < 3; i++) {
+            prop.start(out);
+            prop.end(out, body);
+            ic.end(out, null);
+        }
+
+        // then
+        assertEquals(", , , ", out.getBuffer().toString());
+    }
+
     public void testIteratorWithDifferentLocale() {
         // given
         ActionContext.getContext().withLocale(new Locale("fa_IR"));
diff --git 
a/core/src/test/java/org/apache/struts2/views/jsp/IteratorTagTest.java 
b/core/src/test/java/org/apache/struts2/views/jsp/IteratorTagTest.java
index fd3fc9587..acb4fa053 100644
--- a/core/src/test/java/org/apache/struts2/views/jsp/IteratorTagTest.java
+++ b/core/src/test/java/org/apache/struts2/views/jsp/IteratorTagTest.java
@@ -20,7 +20,6 @@ package org.apache.struts2.views.jsp;
 
 import com.mockobjects.servlet.MockBodyContent;
 import com.mockobjects.servlet.MockJspWriter;
-import com.opensymphony.xwork2.ActionContext;
 import org.apache.commons.collections.ListUtils;
 
 import javax.servlet.jsp.JspException;
@@ -722,6 +721,41 @@ public class IteratorTagTest extends AbstractUITagTest {
         validateCounter(new String[]{"a", "b", "c"});
     }
 
+    public void testNullElements() throws JspException {
+        Foo foo = new Foo();
+        foo.setArray(new String[3]);
+
+        stack.push(foo);
+        tag.setValue("array");
+        tag.setVar("anId");
+
+        // one
+        int result = tag.doStartTag();
+        assertEquals(TagSupport.EVAL_BODY_INCLUDE, result);
+        assertNull(stack.peek());
+        assertNull(stack.getContext().get("anId"));
+
+        tag.doInitBody();
+
+        // two
+        result = tag.doAfterBody();
+        assertEquals(TagSupport.EVAL_BODY_AGAIN, result);
+        assertNull(stack.peek());
+        assertNull(stack.getContext().get("anId"));
+
+        // three
+        result = tag.doAfterBody();
+        assertEquals(TagSupport.EVAL_BODY_AGAIN, result);
+        assertNull(stack.peek());
+        assertNull(stack.getContext().get("anId"));
+
+        result = tag.doAfterBody();
+        assertEquals(TagSupport.SKIP_BODY, result);
+
+        result = tag.doEndTag();
+        assertEquals(TagSupport.EVAL_PAGE, result);
+    }
+
     public void testCounterWithArray() throws JspException {
         Foo foo = new Foo();
         foo.setArray(new String[]{"a", "b", "c", "d"});

Reply via email to