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

papegaaij pushed a commit to branch wicket-8.x
in repository https://gitbox.apache.org/repos/asf/wicket.git

commit 7f53ba4dff2f0041cc3c433c4b96cc4c4cfdf2e3
Author: Emond Papegaaij <[email protected]>
AuthorDate: Wed Aug 19 22:24:56 2026 +0200

    Escape the attribute values of a MetaDataHeaderItem as markup
    
    generateString escaped attribute names with Strings.escapeMarkup but ran the
    values through Strings.replaceAll(value, "\"", "\\\""). A backslash before a
    double quote means nothing in HTML, so a value holding a double quote ended 
its
    own attribute and whatever followed was read as further attributes. Values 
may
    come from an IModel, so they are not necessarily literals. WICKET-6178 set 
out to
    escape these values and this is what it left behind.
    
    They now go through Strings.escapeMarkup, like the names beside them and 
like
    every attribute ComponentTag writes.
    
    Two tests asserted the old output. testEscapeOnlyDoubleQuotes was named 
after the
    behaviour that was the problem and is renamed. HtmlImportHeaderItemTest 
expects
    an escaped ampersand in the href of a link tag, which is what a url holding 
two
    parameters has to carry, and is what ComponentTag writes for every other
    attribute.
    
    Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
---
 .../wicket/markup/head/MetaDataHeaderItem.java     |  2 +-
 .../markup/head/HtmlImportHeaderItemTest.java      |  7 +++--
 .../wicket/markup/head/MetaDataHeaderItemTest.java | 35 ++++++++++++++++++++--
 3 files changed, 39 insertions(+), 5 deletions(-)

diff --git 
a/wicket-core/src/main/java/org/apache/wicket/markup/head/MetaDataHeaderItem.java
 
b/wicket-core/src/main/java/org/apache/wicket/markup/head/MetaDataHeaderItem.java
index 77fce4bea1..09d1d8c444 100644
--- 
a/wicket-core/src/main/java/org/apache/wicket/markup/head/MetaDataHeaderItem.java
+++ 
b/wicket-core/src/main/java/org/apache/wicket/markup/head/MetaDataHeaderItem.java
@@ -131,7 +131,7 @@ public class MetaDataHeaderItem extends HeaderItem
                        {
                                buffer.append('=')
                                        .append('"')
-                                       
.append(Strings.replaceAll(value.toString(), "\"", "\\\""))
+                                       
.append(Strings.escapeMarkup(value.toString()))
                                        .append('"');
                        }
                }
diff --git 
a/wicket-core/src/test/java/org/apache/wicket/markup/head/HtmlImportHeaderItemTest.java
 
b/wicket-core/src/test/java/org/apache/wicket/markup/head/HtmlImportHeaderItemTest.java
index 79244b6f5e..b629da4c84 100644
--- 
a/wicket-core/src/test/java/org/apache/wicket/markup/head/HtmlImportHeaderItemTest.java
+++ 
b/wicket-core/src/test/java/org/apache/wicket/markup/head/HtmlImportHeaderItemTest.java
@@ -20,6 +20,7 @@ import static org.junit.Assert.assertEquals;
 
 import org.apache.wicket.markup.html.basic.SimplePage;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
+import org.apache.wicket.util.string.Strings;
 import org.apache.wicket.util.tester.WicketTester;
 import org.junit.Test;
 
@@ -53,7 +54,9 @@ public class HtmlImportHeaderItemTest
                MetaDataHeaderItem importLink = HtmlImportHeaderItem
                        .forImportLinkTag(SimplePage.class, parameters, 
"monitor", true);
                
-               assertEquals("<link rel=\"import\" href=\"" + pageUrl + "\" 
media=\"monitor\" async />\n", 
-                       importLink.generateString());
+               // the href is escaped as markup, like every other attribute 
Wicket writes. The url holds
+               // a literal & between its two parameters, which has to be 
written as an entity
+               assertEquals("<link rel=\"import\" href=\"" + 
Strings.escapeMarkup(pageUrl)
+                       + "\" media=\"monitor\" async />\n", 
importLink.generateString());
        }
 }
diff --git 
a/wicket-core/src/test/java/org/apache/wicket/markup/head/MetaDataHeaderItemTest.java
 
b/wicket-core/src/test/java/org/apache/wicket/markup/head/MetaDataHeaderItemTest.java
index 6cff0a5ab6..c8b5ea1699 100644
--- 
a/wicket-core/src/test/java/org/apache/wicket/markup/head/MetaDataHeaderItemTest.java
+++ 
b/wicket-core/src/test/java/org/apache/wicket/markup/head/MetaDataHeaderItemTest.java
@@ -43,12 +43,43 @@ public class MetaDataHeaderItemTest
                assertEquals(expectedString, metaTag.generateString());
        }
        
+       /**
+        * Attribute values are escaped as markup. A backslash before a double 
quote means nothing in
+        * HTML, so escaping that way left the value able to close its own 
attribute.
+        */
        @Test
-       public void testEscapeOnlyDoubleQuotes() throws Exception
+       public void testEscapesAttributeValuesAsMarkup() throws Exception
        {
-               String expectedString = "<link rel=\"single quote \' double 
quotes\\\"\" href=\"\" />\n";
+               String expectedString = "<link rel=\"single quote &#039; double 
quotes&quot;\" href=\"\" />\n";
                MetaDataHeaderItem metaTag = 
MetaDataHeaderItem.forLinkTag("single quote \' double quotes\"", "");
                
                assertEquals(expectedString, metaTag.generateString());
        }
+
+       /**
+        * A value cannot end its attribute and add another one.
+        */
+       @Test
+       public void testAttributeValueCannotInjectAnotherAttribute() throws 
Exception
+       {
+               MetaDataHeaderItem metaTag = 
MetaDataHeaderItem.forMetaTag("description",
+                       "x\" onload=\"x=1");
+
+               assertEquals("<meta name=\"description\" content=\"x&quot; 
onload=&quot;x=1\" />\n",
+                       metaTag.generateString());
+       }
+
+       /**
+        * The same for a value taken from a model.
+        */
+       @Test
+       public void testAttributeValueFromModelIsEscaped() throws Exception
+       {
+               MetaDataHeaderItem metaTag = 
MetaDataHeaderItem.forLinkTag("stylesheet", "");
+               metaTag.addTagAttribute("title", 
Model.of("<script>x=1</script>"));
+
+               assertEquals(
+                       "<link rel=\"stylesheet\" href=\"\" 
title=\"&lt;script&gt;x=1&lt;/script&gt;\" />\n",
+                       metaTag.generateString());
+       }
 }

Reply via email to