From: Henri Sara
+ * The default implementation of InvalidValueException does not support HTML
+ * in error messages. To enable HTML support, override
+ * {@link #getHtmlMessage()} and use the subclass in validators.
+ *
+ * The default implementation of AbstractValidator does not support HTML in + * error messages. To enable HTML support, override + * {@link InvalidValueException#getHtmlMessage()} and throw such exceptions from + * {@link #validate(Object)}. + *
* * @author IT Mill Ltd. * @version diff --git a/src/com/vaadin/terminal/SystemError.java b/src/com/vaadin/terminal/SystemError.java index 8b721c07f5..fb1de0c494 100644 --- a/src/com/vaadin/terminal/SystemError.java +++ b/src/com/vaadin/terminal/SystemError.java @@ -7,12 +7,18 @@ package com.vaadin.terminal; import java.io.PrintWriter; import java.io.StringWriter; +import com.vaadin.terminal.gwt.server.AbstractApplicationServlet; + /** *SystemError
is a runtime exception caused by error in system.
* The system error can be shown to the user as it implements
* ErrorMessage
interface, but contains technical information such
* as stack trace and exception.
*
+ * SystemError does not support HTML in error messages or stack traces. If HTML
+ * messages are required, use {@link UserError} or a custom implementation of
+ * {@link ErrorMessage}.
+ *
* @author IT Mill Ltd.
* @version
* @VERSION@
@@ -75,11 +81,26 @@ public class SystemError extends RuntimeException implements ErrorMessage {
target.startTag("error");
target.addAttribute("level", "system");
+ String message = getHtmlMessage();
+
+ target.addXMLSection("div", message,
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd");
+
+ target.endTag("error");
+
+ }
+
+ /**
+ * Returns the message of the error in HTML.
+ *
+ * Note that this API may change in future versions.
+ */
+ protected String getHtmlMessage() {
StringBuilder sb = new StringBuilder();
final String message = getLocalizedMessage();
if (message != null) {
sb.append(""); - sb.append(buffer.toString()); + sb.append(AbstractApplicationServlet.safeEscapeForHtml(buffer + .toString())); sb.append(""); } - - target.addXMLSection("div", sb.toString(), - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"); - - target.endTag("error"); - + return sb.toString(); } /** diff --git a/src/com/vaadin/terminal/UserError.java b/src/com/vaadin/terminal/UserError.java index bcce0ed283..d33c02d144 100644 --- a/src/com/vaadin/terminal/UserError.java +++ b/src/com/vaadin/terminal/UserError.java @@ -4,6 +4,8 @@ package com.vaadin.terminal; +import com.vaadin.terminal.gwt.server.AbstractApplicationServlet; + /** *
UserError
is a controlled error occurred in application. User
* errors are occur in normal usage of the application and guide the user.
@@ -32,6 +34,11 @@ public class UserError implements ErrorMessage {
*/
public static final int CONTENT_UIDL = 2;
+ /**
+ * Content mode, where the error contains XHTML.
+ */
+ public static final int CONTENT_XHTML = 3;
+
/**
* Content mode.
*/
@@ -80,24 +87,24 @@ public class UserError implements ErrorMessage {
level = errorLevel;
}
- /* Documenten in interface */
+ /* Documented in interface */
public int getErrorLevel() {
return level;
}
- /* Documenten in interface */
+ /* Documented in interface */
public void addListener(RepaintRequestListener listener) {
}
- /* Documenten in interface */
+ /* Documented in interface */
public void removeListener(RepaintRequestListener listener) {
}
- /* Documenten in interface */
+ /* Documented in interface */
public void requestRepaint() {
}
- /* Documenten in interface */
+ /* Documented in interface */
public void paint(PaintTarget target) throws PaintException {
target.startTag("error");
@@ -118,21 +125,25 @@ public class UserError implements ErrorMessage {
// Paint the message
switch (mode) {
case CONTENT_TEXT:
- target.addText(msg);
+ target.addText(AbstractApplicationServlet.safeEscapeForHtml(msg));
break;
case CONTENT_UIDL:
target.addUIDL(msg);
break;
case CONTENT_PREFORMATTED:
- target.startTag("pre");
+ target.addText("" + + AbstractApplicationServlet.safeEscapeForHtml(msg) + + ""); + break; + case CONTENT_XHTML: target.addText(msg); - target.endTag("pre"); + break; } target.endTag("error"); } - /* Documenten in interface */ + /* Documented in interface */ public void requestRepaintRequests() { } diff --git a/src/com/vaadin/ui/AbstractComponent.java b/src/com/vaadin/ui/AbstractComponent.java index 784ecb262b..da55aa7fa0 100644 --- a/src/com/vaadin/ui/AbstractComponent.java +++ b/src/com/vaadin/ui/AbstractComponent.java @@ -449,9 +449,10 @@ public abstract class AbstractComponent implements Component, MethodEventSource /** *
- * Gets the component's description. The description can be used to briefly - * describe the state of the component to the user. The description string - * may contain certain XML tags: + * Gets the component's description, used in tooltips and can be displayed + * directly in certain other components such as forms. The description can + * be used to briefly describe the state of the component to the user. The + * description string may contain certain XML tags: *
* *@@ -513,6 +514,10 @@ public abstract class AbstractComponent implements Component, MethodEventSource * {@link com.vaadin.terminal.Paintable.RepaintRequestEvent * RepaintRequestEvent}. * + * The description is displayed as HTML/XHTML in tooltips or directly in + * certain components so care should be taken to avoid creating the + * possibility for HTML injection and possibly XSS vulnerabilities. + * * @param description * the new description string for the component. */ diff --git a/src/com/vaadin/ui/Panel.java b/src/com/vaadin/ui/Panel.java index 73140fd79a..877171232e 100644 --- a/src/com/vaadin/ui/Panel.java +++ b/src/com/vaadin/ui/Panel.java @@ -105,7 +105,7 @@ public class Panel extends AbstractComponentContainer implements Scrollable, * Creates a new empty panel with caption. Default layout is used. * * @param caption - * the caption used in the panel. + * the caption used in the panel (HTML/XHTML). */ public Panel(String caption) { this(caption, null); @@ -115,7 +115,7 @@ public class Panel extends AbstractComponentContainer implements Scrollable, * Creates a new empty panel with the given caption and content. * * @param caption - * the caption of the panel. + * the caption of the panel (HTML/XHTML). * @param content * the content used in the panel. */ @@ -124,6 +124,20 @@ public class Panel extends AbstractComponentContainer implements Scrollable, setCaption(caption); } + /** + * Sets the caption of the panel. + * + * Note that the caption is interpreted as HTML/XHTML and therefore care + * should be taken not to enable HTML injection and XSS attacks using panel + * captions. This behavior may change in future versions. + * + * @see AbstractComponent#setCaption(String) + */ + @Override + public void setCaption(String caption) { + super.setCaption(caption); + } + /** * Gets the current layout of the panel. *