This is an automated email from the ASF dual-hosted git repository.
lukaszlenart pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/struts.git
The following commit(s) were added to refs/heads/main by this push:
new 54d3dd114 WW-5824 fix(core): escape the radio name attribute like
every other tag
54d3dd114 is described below
commit 54d3dd114ef26c7f42305b7aec9b7b6af2f0fd7e
Author: Lukasz Lenart <[email protected]>
AuthorDate: Sat Oct 31 10:12:36 2026 +0100
WW-5824 fix(core): escape the radio name attribute like every other tag
The radio template was the only bundled form template writing the name
attribute with ?no_esc. The exception dates from the original template,
which never carried the per-parameter ?html the checkbox template had,
and WW-4972 preserved that output when the templates moved to built-in
auto-escaping. Drop the opt-out in the simple and html5 templates and pin
the escaped name in RadioTest; Radio-6.txt now carries the apostrophes
of its name as ', as the combobox fixtures already do.
Co-Authored-By: Claude Mythos 5.1 <[email protected]>
---
.../src/main/resources/template/html5/radiomap.ftl | 2 +-
.../main/resources/template/simple/radiomap.ftl | 2 +-
.../org/apache/struts2/views/jsp/ui/RadioTest.java | 30 ++++++++++++++++++++++
.../org/apache/struts2/views/jsp/ui/Radio-14.txt | 2 ++
.../org/apache/struts2/views/jsp/ui/Radio-15.txt | 2 ++
.../org/apache/struts2/views/jsp/ui/Radio-6.txt | 6 ++---
6 files changed, 39 insertions(+), 5 deletions(-)
diff --git a/core/src/main/resources/template/html5/radiomap.ftl
b/core/src/main/resources/template/html5/radiomap.ftl
index 55fd97c95..c9d62a4c3 100644
--- a/core/src/main/resources/template/html5/radiomap.ftl
+++ b/core/src/main/resources/template/html5/radiomap.ftl
@@ -64,7 +64,7 @@ file for it's localized value. This is then used as a label
-->
</#if>
<input type="radio"<#rt/>
<#if attributes.name?has_content>
- name="${attributes.name?no_esc}"<#rt/>
+ name="${attributes.name}"<#rt/>
</#if>
id="${attributes.id}${itemKeyStr?replace(".", "_")}"<#rt/>
<#if tag.contains(attributes.nameValue!'', itemKey)>
diff --git a/core/src/main/resources/template/simple/radiomap.ftl
b/core/src/main/resources/template/simple/radiomap.ftl
index a091d25a7..5d47adcf3 100644
--- a/core/src/main/resources/template/simple/radiomap.ftl
+++ b/core/src/main/resources/template/simple/radiomap.ftl
@@ -63,7 +63,7 @@
</#if>
<input type="radio"<#rt/>
<#if attributes.name?has_content>
- name="${attributes.name?no_esc}"<#rt/>
+ name="${attributes.name}"<#rt/>
</#if>
id="${attributes.id}${itemKeyStr?replace(".", "_")}"<#rt/>
<#if tag.contains(attributes.nameValue!'', itemKey)>
diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/RadioTest.java
b/core/src/test/java/org/apache/struts2/views/jsp/ui/RadioTest.java
index ba7913b8a..05819af8c 100644
--- a/core/src/test/java/org/apache/struts2/views/jsp/ui/RadioTest.java
+++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/RadioTest.java
@@ -726,6 +726,36 @@ public class RadioTest extends AbstractUITagTest {
strutsBodyTagsAreReflectionEqual(tag, freshTag));
}
+ public void testNameIsEscaped() throws Exception {
+ RadioTag tag = createTagWithQuoteInName("simple");
+ tag.doStartTag();
+ tag.doEndTag();
+
+ verify(RadioTag.class.getResource("Radio-14.txt"));
+ }
+
+ public void testNameIsEscapedHtml5() throws Exception {
+ RadioTag tag = createTagWithQuoteInName("html5");
+ tag.doStartTag();
+ tag.doEndTag();
+
+ verify(RadioTag.class.getResource("Radio-15.txt"));
+ }
+
+ private RadioTag createTagWithQuoteInName(String theme) {
+ TestAction testAction = (TestAction) action;
+ Map<String, String> map = new LinkedHashMap<>();
+ map.put("a", "A");
+ testAction.setMap(map);
+
+ RadioTag tag = new RadioTag();
+ tag.setTheme(theme);
+ tag.setPageContext(pageContext);
+ tag.setName("myname\" onfocus=\"alert(1)");
+ tag.setList("map");
+ return tag;
+ }
+
private void prepareTagGeneric(RadioTag tag) {
TestAction testAction = (TestAction) action;
testAction.setFoo("bar");
diff --git
a/core/src/test/resources/org/apache/struts2/views/jsp/ui/Radio-14.txt
b/core/src/test/resources/org/apache/struts2/views/jsp/ui/Radio-14.txt
new file mode 100644
index 000000000..dfc29161f
--- /dev/null
+++ b/core/src/test/resources/org/apache/struts2/views/jsp/ui/Radio-14.txt
@@ -0,0 +1,2 @@
+<input type="radio" name="myname" onfocus="alert(1)"
id="myname__onfocus__alert_1_a" value="a"/>
+<label for="myname__onfocus__alert_1_a">A</label>
diff --git
a/core/src/test/resources/org/apache/struts2/views/jsp/ui/Radio-15.txt
b/core/src/test/resources/org/apache/struts2/views/jsp/ui/Radio-15.txt
new file mode 100644
index 000000000..dfc29161f
--- /dev/null
+++ b/core/src/test/resources/org/apache/struts2/views/jsp/ui/Radio-15.txt
@@ -0,0 +1,2 @@
+<input type="radio" name="myname" onfocus="alert(1)"
id="myname__onfocus__alert_1_a" value="a"/>
+<label for="myname__onfocus__alert_1_a">A</label>
diff --git
a/core/src/test/resources/org/apache/struts2/views/jsp/ui/Radio-6.txt
b/core/src/test/resources/org/apache/struts2/views/jsp/ui/Radio-6.txt
index 8c7f20bad..11f619c2a 100644
--- a/core/src/test/resources/org/apache/struts2/views/jsp/ui/Radio-6.txt
+++ b/core/src/test/resources/org/apache/struts2/views/jsp/ui/Radio-6.txt
@@ -1,11 +1,11 @@
<tr>
<td class="tdLabel"></td>
<td class="tdInput">
- <input type="radio" name="myMap['name']" id="myMap__name__"value=""/>
+ <input type="radio" name="myMap['name']"
id="myMap__name__"value=""/>
<label for="myMap__name__">N/A</label>
- <input type="radio" name="myMap['name']" id="myMap__name__Opt_"
value="Opt."/>
+ <input type="radio" name="myMap['name']"
id="myMap__name__Opt_" value="Opt."/>
<label for="myMap__name__Opt_">Opt.</label>
- <input type="radio" name="myMap['name']" id="myMap__name__Std_"
checked="checked" value="Std."/>
+ <input type="radio" name="myMap['name']"
id="myMap__name__Std_" checked="checked" value="Std."/>
<label for="myMap__name__Std_">Std.</label>
</td>
</tr>