From 479a9d86ed3b37db10c8322045887be293f14cd6 Mon Sep 17 00:00:00 2001 From: Lukasz Lenart Date: Wed, 31 Jul 2024 16:53:01 +0200 Subject: [PATCH] WW-5451 Fixes NPE when iterator starts with null --- .../struts2/components/IteratorComponent.java | 5 ++- .../components/IteratorComponentTest.java | 36 +++++++++++++++++++ .../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 7ff83bd458..1659e6c6e9 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 boolean start(Writer writer) { 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 7f08ef64ea..077510a71e 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 List getItems() { assertEquals("1, 2, , 4, ", out.getBuffer().toString()); } + public void testIteratorWithNullsOnly() { + // given + stack.push(new FooAction() { + private final List items = Arrays.asList(null, null, null); + + public List 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 fd3fc9587e..acb4fa053d 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 @@ 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 void testCounterWithList() throws JspException { 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"});