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

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

commit 7498e109ffb33a071386c17fd1089e424af0f970
Author: Emond Papegaaij <[email protected]>
AuthorDate: Thu Aug 20 12:32:01 2026 +0200

    Say in the javadoc which methods have their value written to the markup as 
is
    
    Escaping in the render path is a convention among callers rather than 
something
    the path itself guarantees. replaceComponentTagBody and Response#write 
write what
    they are handed, and Label is safe only because it hands them
    getDefaultModelObjectAsString(). Where an overridable method's value 
reaches one
    of those writes, an implementation has to know that, and until now it had 
to work
    it out by reading the caller.
    
    Twenty-six methods now say so and name the escaping to apply: the body of an
    option points at escapeOptionHtml, everything else at Strings#escapeMarkup. 
The
    wording follows what the method does with the value. A getter returns it, a
    setter is handed it, appendOptionHtml and setOptionAttributes append it to 
the
    option buffer, the renderer methods write it to a Response, and escapeHtml
    decides whether the output of a template is escaped at all.
    
    Where the framework calls the method and the default implementation escapes
    correctly, the note says so and addresses the override instead, since 
relying on
    the default is not what puts anything at risk. That covers the three hooks 
of
    AbstractChoice: renderValue escapes the body of the option, 
setOptionAttributes
    escapes the id it writes, and getDefaultChoice returns no choice at all 
unless a
    subclass builds one.
    
    Methods whose caller escapes for them are left alone, since telling an
    implementation to escape there would have it encode twice: the display value
    methods of AbstractSingleSelectChoice, defaultNullLabel of the editable 
labels,
    the additional attributes of RadioChoice and CheckBoxMultipleChoice, and 
those of
    the palette.
    
    Include is left alone as well. What its method returns is the least of what 
that
    component does with the value it is given, and it is being looked at on its 
own.
    
    Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
---
 .../wicket/markup/html/form/AbstractChoice.java    | 28 +++++++++++++++++
 .../markup/html/form/CheckBoxMultipleChoice.java   | 36 ++++++++++++++++++++++
 .../wicket/markup/html/form/RadioChoice.java       | 36 ++++++++++++++++++++++
 .../html/navigation/paging/PagingNavigation.java   | 12 ++++++++
 .../wicket/markup/transformer/ITransformer.java    |  6 ++++
 .../autocomplete/AbstractAutoCompleteRenderer.java |  6 ++++
 .../html/autocomplete/IAutoCompleteRenderer.java   | 18 +++++++++++
 .../extensions/breadcrumb/BreadCrumbBar.java       |  6 ++++
 .../wicket/velocity/VelocityContributor.java       |  6 ++++
 .../wicket/velocity/markup/html/VelocityPanel.java |  6 ++++
 10 files changed, 160 insertions(+)

diff --git 
a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/AbstractChoice.java
 
b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/AbstractChoice.java
index afab72549e..a3b5e85898 100644
--- 
a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/AbstractChoice.java
+++ 
b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/AbstractChoice.java
@@ -386,6 +386,14 @@ public abstract class AbstractChoice<T, E> extends 
FormComponent<T>
        /**
         * Get a default choice to be rendered additionally to the choices 
available in the model.
         * 
+        * <p>
+        * <b>The return value of an override is written to the markup as is, 
without escaping.</b>
+        * This implementation returns no choice at all, and the override in
+        * {@link AbstractSingleSelectChoice} escapes the body of the option it 
builds. An override
+        * that builds an option itself must escape the option body with
+        * {@link Strings#escapeMarkup(CharSequence)}.
+        * </p>
+        *
         * @param selectedValue
         *            The currently selected value
         * @return Any default choice, such as "Choose One", depending on the 
subclass
@@ -456,6 +464,13 @@ public abstract class AbstractChoice<T, E> extends 
FormComponent<T>
        /**
         * Generates and appends html for a single choice into the provided 
buffer
         * 
+        * <p>
+        * <b>Whatever an override appends reaches the markup as is, without 
escaping.</b> This
+        * implementation escapes the body of the option it appends, according 
to
+        * {@link #getEscapeModelStrings()}. An override that assembles an 
option itself must do
+        * the same for whatever it puts there, with {@link 
Strings#escapeMarkup(CharSequence)}.
+        * </p>
+        *
         * @param buffer
         *            Appending string buffer that will have the generated html 
appended
         * @param choice
@@ -513,6 +528,13 @@ public abstract class AbstractChoice<T, E> extends 
FormComponent<T>
        /**
         * Sets the attributes of a single choice into the provided buffer.
         *
+        * <p>
+        * <b>Whatever an override appends reaches the markup as is, without 
escaping.</b> This
+        * implementation escapes the value of the id attribute it writes. An 
override that adds
+        * attributes of its own must escape their values with
+        * {@link Strings#escapeMarkup(CharSequence)}.
+        * </p>
+        *
         * @param buffer
         *            Appending string buffer that will have the generated html 
appended
         * @param choice
@@ -542,6 +564,12 @@ public abstract class AbstractChoice<T, E> extends 
FormComponent<T>
        /**
         * Method to override if you want special escaping of the options html.
         * 
+        * <p>
+        * <b>The return value is written to the body of the option as is, 
without escaping.</b> An
+        * override that returns the display value without escaping it puts 
user input and other
+        * dynamic content into the page as markup.
+        * </p>
+        *
         * @param displayValue
         * @return The escaped display value
         */
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/CheckBoxMultipleChoice.java
 
b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/CheckBoxMultipleChoice.java
index 4ba0fad523..840a7f69f6 100644
--- 
a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/CheckBoxMultipleChoice.java
+++ 
b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/CheckBoxMultipleChoice.java
@@ -232,6 +232,12 @@ public class CheckBoxMultipleChoice<T> extends 
ListMultipleChoice<T>
        }
 
        /**
+        * <p>
+        * <b>The return value is written to the markup as is, without 
escaping.</b> Any part of
+        * it that comes from user input or other dynamic content must be 
escaped with
+        * {@link Strings#escapeMarkup(CharSequence)}.
+        * </p>
+        *
         * @return Prefix to use before choice
         */
        public String getPrefix()
@@ -240,6 +246,12 @@ public class CheckBoxMultipleChoice<T> extends 
ListMultipleChoice<T>
        }
 
        /**
+        * <p>
+        * <b>The return value is written to the markup as is, without 
escaping.</b> Any part of
+        * it that comes from user input or other dynamic content must be 
escaped with
+        * {@link Strings#escapeMarkup(CharSequence)}.
+        * </p>
+        *
         * @param index
         *            index of the choice
         * @param choice
@@ -253,6 +265,12 @@ public class CheckBoxMultipleChoice<T> extends 
ListMultipleChoice<T>
        }
 
        /**
+        * <p>
+        * <b>The return value is written to the markup as is, without 
escaping.</b> Any part of
+        * it that comes from user input or other dynamic content must be 
escaped with
+        * {@link Strings#escapeMarkup(CharSequence)}.
+        * </p>
+        *
         * @param index
         *            index of the choice
         * @param choice
@@ -266,6 +284,12 @@ public class CheckBoxMultipleChoice<T> extends 
ListMultipleChoice<T>
        }
 
        /**
+        * <p>
+        * <b>The value passed here is written to the markup as is, without 
escaping.</b> Any
+        * part of it that comes from user input or other dynamic content must 
be escaped with
+        * {@link Strings#escapeMarkup(CharSequence)}.
+        * </p>
+        *
         * @param prefix
         *            Prefix to use before choice
         * @return this
@@ -284,6 +308,12 @@ public class CheckBoxMultipleChoice<T> extends 
ListMultipleChoice<T>
        }
 
        /**
+        * <p>
+        * <b>The return value is written to the markup as is, without 
escaping.</b> Any part of
+        * it that comes from user input or other dynamic content must be 
escaped with
+        * {@link Strings#escapeMarkup(CharSequence)}.
+        * </p>
+        *
         * @return Separator to use between radio options
         */
        public String getSuffix()
@@ -292,6 +322,12 @@ public class CheckBoxMultipleChoice<T> extends 
ListMultipleChoice<T>
        }
 
        /**
+        * <p>
+        * <b>The value passed here is written to the markup as is, without 
escaping.</b> Any
+        * part of it that comes from user input or other dynamic content must 
be escaped with
+        * {@link Strings#escapeMarkup(CharSequence)}.
+        * </p>
+        *
         * @param suffix
         *            Separator to use between radio options
         * @return this
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/RadioChoice.java 
b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/RadioChoice.java
index 60b6b27c67..079244ddaa 100644
--- 
a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/RadioChoice.java
+++ 
b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/RadioChoice.java
@@ -237,6 +237,12 @@ public class RadioChoice<T> extends 
AbstractSingleSelectChoice<T>
        }
 
        /**
+        * <p>
+        * <b>The return value is written to the markup as is, without 
escaping.</b> Any part of
+        * it that comes from user input or other dynamic content must be 
escaped with
+        * {@link Strings#escapeMarkup(CharSequence)}.
+        * </p>
+        *
         * @return Prefix to use before choice
         */
        public String getPrefix()
@@ -245,6 +251,12 @@ public class RadioChoice<T> extends 
AbstractSingleSelectChoice<T>
        }
 
        /**
+        * <p>
+        * <b>The return value is written to the markup as is, without 
escaping.</b> Any part of
+        * it that comes from user input or other dynamic content must be 
escaped with
+        * {@link Strings#escapeMarkup(CharSequence)}.
+        * </p>
+        *
         * @param index
         *            index of the choice
         * @param choice
@@ -258,6 +270,12 @@ public class RadioChoice<T> extends 
AbstractSingleSelectChoice<T>
        }
 
        /**
+        * <p>
+        * <b>The return value is written to the markup as is, without 
escaping.</b> Any part of
+        * it that comes from user input or other dynamic content must be 
escaped with
+        * {@link Strings#escapeMarkup(CharSequence)}.
+        * </p>
+        *
         * @param index
         *            index of the choice
         * @param choice
@@ -271,6 +289,12 @@ public class RadioChoice<T> extends 
AbstractSingleSelectChoice<T>
        }
 
        /**
+        * <p>
+        * <b>The value passed here is written to the markup as is, without 
escaping.</b> Any
+        * part of it that comes from user input or other dynamic content must 
be escaped with
+        * {@link Strings#escapeMarkup(CharSequence)}.
+        * </p>
+        *
         * @param prefix
         *            Prefix to use before choice
         * @return this
@@ -284,6 +308,12 @@ public class RadioChoice<T> extends 
AbstractSingleSelectChoice<T>
        }
 
        /**
+        * <p>
+        * <b>The return value is written to the markup as is, without 
escaping.</b> Any part of
+        * it that comes from user input or other dynamic content must be 
escaped with
+        * {@link Strings#escapeMarkup(CharSequence)}.
+        * </p>
+        *
         * @return Separator to use between radio options
         */
        public String getSuffix()
@@ -292,6 +322,12 @@ public class RadioChoice<T> extends 
AbstractSingleSelectChoice<T>
        }
 
        /**
+        * <p>
+        * <b>The value passed here is written to the markup as is, without 
escaping.</b> Any
+        * part of it that comes from user input or other dynamic content must 
be escaped with
+        * {@link Strings#escapeMarkup(CharSequence)}.
+        * </p>
+        *
         * @param suffix
         *            Separator to use between radio options
         * @return this
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/markup/html/navigation/paging/PagingNavigation.java
 
b/wicket-core/src/main/java/org/apache/wicket/markup/html/navigation/paging/PagingNavigation.java
index 5abd724ee7..3980d8e914 100644
--- 
a/wicket-core/src/main/java/org/apache/wicket/markup/html/navigation/paging/PagingNavigation.java
+++ 
b/wicket-core/src/main/java/org/apache/wicket/markup/html/navigation/paging/PagingNavigation.java
@@ -187,6 +187,12 @@ public class PagingNavigation extends Loop
        /**
         * Gets the seperator.
         *
+        * <p>
+        * <b>The return value is written to the markup as is, without 
escaping.</b> Any part of
+        * it that comes from user input or other dynamic content must be 
escaped with
+        * {@link 
org.apache.wicket.util.string.Strings#escapeMarkup(CharSequence) 
Strings#escapeMarkup(CharSequence)}.
+        * </p>
+        *
         * @return the seperator
         */
        public String getSeparator()
@@ -228,6 +234,12 @@ public class PagingNavigation extends Loop
        /**
         * Sets the seperator. Null meaning, no separator at all.
         *
+        * <p>
+        * <b>The value passed here is written to the markup as is, without 
escaping.</b> Any
+        * part of it that comes from user input or other dynamic content must 
be escaped with
+        * {@link 
org.apache.wicket.util.string.Strings#escapeMarkup(CharSequence) 
Strings#escapeMarkup(CharSequence)}.
+        * </p>
+        *
         * @param separator
         *            the seperator
         */
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/markup/transformer/ITransformer.java
 
b/wicket-core/src/main/java/org/apache/wicket/markup/transformer/ITransformer.java
index b883e83516..e03a449150 100644
--- 
a/wicket-core/src/main/java/org/apache/wicket/markup/transformer/ITransformer.java
+++ 
b/wicket-core/src/main/java/org/apache/wicket/markup/transformer/ITransformer.java
@@ -32,6 +32,12 @@ public interface ITransformer
         * Will be invoked after all child components have been processed to 
allow for transforming the
         * markup generated.
         * 
+        * <p>
+        * <b>The return value is written to the markup as is, without 
escaping.</b> Any part of
+        * it that comes from user input or other dynamic content must be 
escaped with
+        * {@link 
org.apache.wicket.util.string.Strings#escapeMarkup(CharSequence) 
Strings#escapeMarkup(CharSequence)}.
+        * </p>
+        *
         * @param component
         *            The associated Wicket component
         * @param output
diff --git 
a/wicket-extensions/src/main/java/org/apache/wicket/extensions/ajax/markup/html/autocomplete/AbstractAutoCompleteRenderer.java
 
b/wicket-extensions/src/main/java/org/apache/wicket/extensions/ajax/markup/html/autocomplete/AbstractAutoCompleteRenderer.java
index 1c0d3d0a5a..94afe108fa 100644
--- 
a/wicket-extensions/src/main/java/org/apache/wicket/extensions/ajax/markup/html/autocomplete/AbstractAutoCompleteRenderer.java
+++ 
b/wicket-extensions/src/main/java/org/apache/wicket/extensions/ajax/markup/html/autocomplete/AbstractAutoCompleteRenderer.java
@@ -74,6 +74,12 @@ public abstract class AbstractAutoCompleteRenderer<T> 
implements IAutoCompleteRe
         * Render the visual portion of the assist. Usually the html 
representing the assist choice
         * object is written out to the response use {@link 
Response#write(CharSequence)}
         * 
+        * <p>
+        * <b>Whatever is written to the response reaches the markup as is, 
without escaping.</b>
+        * Any part of it that comes from user input or other dynamic content 
must be escaped
+        * before it is written, with {@link 
Strings#escapeMarkup(CharSequence)}.
+        * </p>
+        *
         * @param object
         *            current assist choice
         * @param response
diff --git 
a/wicket-extensions/src/main/java/org/apache/wicket/extensions/ajax/markup/html/autocomplete/IAutoCompleteRenderer.java
 
b/wicket-extensions/src/main/java/org/apache/wicket/extensions/ajax/markup/html/autocomplete/IAutoCompleteRenderer.java
index 3958a0a3fd..0e76791e5f 100644
--- 
a/wicket-extensions/src/main/java/org/apache/wicket/extensions/ajax/markup/html/autocomplete/IAutoCompleteRenderer.java
+++ 
b/wicket-extensions/src/main/java/org/apache/wicket/extensions/ajax/markup/html/autocomplete/IAutoCompleteRenderer.java
@@ -66,6 +66,12 @@ public interface IAutoCompleteRenderer<T> extends IDetachable
         * Render the html fragment for the given completion object. Usually 
the html is written out by
         * calling {@link Response#write(CharSequence)}.
         * 
+        * <p>
+        * <b>Whatever is written to the response reaches the markup as is, 
without escaping.</b>
+        * Any part of it that comes from user input or other dynamic content 
must be escaped
+        * before it is written, with {@link 
org.apache.wicket.util.string.Strings#escapeMarkup(CharSequence) 
Strings#escapeMarkup(CharSequence)}.
+        * </p>
+        *
         * @param object
         *            completion choice object
         * @param response
@@ -80,6 +86,12 @@ public interface IAutoCompleteRenderer<T> extends IDetachable
         * Render the html header fragment for the completion. Usually the html 
is written out by
         * calling {@link Response#write(CharSequence)}.
         * 
+        * <p>
+        * <b>Whatever is written to the response reaches the markup as is, 
without escaping.</b>
+        * Any part of it that comes from user input or other dynamic content 
must be escaped
+        * before it is written, with {@link 
org.apache.wicket.util.string.Strings#escapeMarkup(CharSequence) 
Strings#escapeMarkup(CharSequence)}.
+        * </p>
+        *
         * @param response
         */
        void renderHeader(Response response);
@@ -88,6 +100,12 @@ public interface IAutoCompleteRenderer<T> extends 
IDetachable
         * Render the html footer fragment for the completion. Usually the html 
is written out by
         * calling {@link Response#write(CharSequence)}.
         * 
+        * <p>
+        * <b>Whatever is written to the response reaches the markup as is, 
without escaping.</b>
+        * Any part of it that comes from user input or other dynamic content 
must be escaped
+        * before it is written, with {@link 
org.apache.wicket.util.string.Strings#escapeMarkup(CharSequence) 
Strings#escapeMarkup(CharSequence)}.
+        * </p>
+        *
         * @param response
         * @param count
         *            The number of choices rendered
diff --git 
a/wicket-extensions/src/main/java/org/apache/wicket/extensions/breadcrumb/BreadCrumbBar.java
 
b/wicket-extensions/src/main/java/org/apache/wicket/extensions/breadcrumb/BreadCrumbBar.java
index ec85ec0e20..e48f1aa560 100644
--- 
a/wicket-extensions/src/main/java/org/apache/wicket/extensions/breadcrumb/BreadCrumbBar.java
+++ 
b/wicket-extensions/src/main/java/org/apache/wicket/extensions/breadcrumb/BreadCrumbBar.java
@@ -245,6 +245,12 @@ public class BreadCrumbBar extends Panel implements 
IBreadCrumbModel
        }
 
        /**
+        * <p>
+        * <b>The return value is written to the markup as is, without 
escaping.</b> Any part of
+        * it that comes from user input or other dynamic content must be 
escaped with
+        * {@link 
org.apache.wicket.util.string.Strings#escapeMarkup(CharSequence) 
Strings#escapeMarkup(CharSequence)}.
+        * </p>
+        *
         * @return markup used as a separator between breadcrumbs. By default 
<code>/</code> is used,
         *         but <code>&gt;&gt;</code> is also a popular choice.
         */
diff --git 
a/wicket-velocity/src/main/java/org/apache/wicket/velocity/VelocityContributor.java
 
b/wicket-velocity/src/main/java/org/apache/wicket/velocity/VelocityContributor.java
index 64bf10c997..81d78fcd98 100644
--- 
a/wicket-velocity/src/main/java/org/apache/wicket/velocity/VelocityContributor.java
+++ 
b/wicket-velocity/src/main/java/org/apache/wicket/velocity/VelocityContributor.java
@@ -104,6 +104,12 @@ public class VelocityContributor extends Behavior
        }
 
        /**
+        * <p>
+        * <b>While this returns false, the output of the template is written 
to the markup as
+        * is, without escaping.</b> A template that interpolates user input or 
other dynamic
+        * content then puts it in the page unescaped.
+        * </p>
+        *
         * @return whether to escape HTML characters. The default value is false
         */
        protected boolean escapeHtml()
diff --git 
a/wicket-velocity/src/main/java/org/apache/wicket/velocity/markup/html/VelocityPanel.java
 
b/wicket-velocity/src/main/java/org/apache/wicket/velocity/markup/html/VelocityPanel.java
index 4ab790f3f2..986b6ef86a 100644
--- 
a/wicket-velocity/src/main/java/org/apache/wicket/velocity/markup/html/VelocityPanel.java
+++ 
b/wicket-velocity/src/main/java/org/apache/wicket/velocity/markup/html/VelocityPanel.java
@@ -186,6 +186,12 @@ public abstract class VelocityPanel extends Panel
        /**
         * Gets whether to escape HTML characters.
         * 
+        * <p>
+        * <b>While this returns false, the output of the template is written 
to the markup as
+        * is, without escaping.</b> A template that interpolates user input or 
other dynamic
+        * content then puts it in the page unescaped.
+        * </p>
+        *
         * @return whether to escape HTML characters. The default value is 
false.
         */
        protected boolean escapeHtml()

Reply via email to