From 035f86ed254ae02570c7dbc72acfa5cfb19b128c Mon Sep 17 00:00:00 2001 From: Jumper Chen Date: Wed, 20 Dec 2023 15:32:29 +0800 Subject: [PATCH] 1. ZK-5182: Prevent XSS issue in component attributes 2. ZK-5162: emptyMessage is not escaped with HTML characters --- .../org/zkoss/zhtml/impl/AbstractTag.java | 5 +- zhtml/src/main/resources/web/js/zhtml/Text.ts | 6 +- .../org/zkoss/zk/ui/AbstractComponent.java | 10 ++- .../org/zkoss/zk/ui/HtmlNativeComponent.java | 4 +- .../java/org/zkoss/zk/ui/SafeHtmlValue.java | 78 +++++++++++++++++++ .../ui/sys/JSCumulativeContentRenderer.java | 3 +- .../zkoss/zk/ui/sys/JsContentRenderer.java | 3 +- zk/src/main/resources/web/js/zk/widget.ts | 2 +- zkdoc/release-note | 6 ++ zktest/src/main/webapp/test2/B100-ZK-5162.zul | 24 ++++++ .../zktest/zats/test2/B100_ZK_5162Test.java | 38 +++++++++ .../main/java/org/zkoss/zul/Comboitem.java | 47 +++++++---- zul/src/main/java/org/zkoss/zul/Html.java | 21 +++-- zul/src/main/java/org/zkoss/zul/Menu.java | 41 +++++++++- .../resources/web/js/zul/inp/InputWidget.ts | 4 +- .../web/js/zul/layout/LayoutRegion.ts | 2 +- .../main/resources/web/js/zul/menu/Menu.ts | 2 +- .../resources/web/js/zul/menu/Menuitem.ts | 2 +- .../resources/web/js/zul/sel/ItemWidget.ts | 2 +- .../main/resources/web/js/zul/sel/Listcell.ts | 2 +- .../resources/web/js/zul/sel/Listfooter.ts | 2 +- .../resources/web/js/zul/sel/Listheader.ts | 2 +- .../main/resources/web/js/zul/sel/Option.ts | 2 +- .../resources/web/js/zul/sel/SelectWidget.ts | 2 +- .../main/resources/web/js/zul/sel/Treecell.ts | 2 +- .../main/resources/web/js/zul/sel/Treecol.ts | 2 +- .../resources/web/js/zul/sel/Treefooter.ts | 2 +- zul/src/main/resources/web/js/zul/tab/Tab.ts | 2 +- zul/src/main/resources/web/js/zul/wgt/A.ts | 2 +- .../main/resources/web/js/zul/wgt/Button.ts | 2 +- .../main/resources/web/js/zul/wgt/Caption.ts | 1 - .../resources/web/js/zul/wgt/Combobutton.ts | 2 +- .../main/resources/web/js/zul/wgt/Label.ts | 8 +- .../resources/web/js/zul/wgt/Notification.ts | 2 +- .../resources/web/js/zul/wgt/Toolbarbutton.ts | 2 +- .../resources/web/js/zul/wgt/mold/label.js | 2 +- 36 files changed, 277 insertions(+), 62 deletions(-) create mode 100644 zk/src/main/java/org/zkoss/zk/ui/SafeHtmlValue.java create mode 100644 zktest/src/main/webapp/test2/B100-ZK-5162.zul create mode 100644 zktest/src/test/java/org/zkoss/zktest/zats/test2/B100_ZK_5162Test.java diff --git a/zhtml/src/main/java/org/zkoss/zhtml/impl/AbstractTag.java b/zhtml/src/main/java/org/zkoss/zhtml/impl/AbstractTag.java index d51863999df..245a2694fca 100644 --- a/zhtml/src/main/java/org/zkoss/zhtml/impl/AbstractTag.java +++ b/zhtml/src/main/java/org/zkoss/zhtml/impl/AbstractTag.java @@ -32,6 +32,7 @@ import org.zkoss.zk.ui.Desktop; import org.zkoss.zk.ui.Execution; import org.zkoss.zk.ui.Executions; +import org.zkoss.zk.ui.SafeHtmlValue; import org.zkoss.zk.ui.UiException; import org.zkoss.zk.ui.WrongValueException; import org.zkoss.zk.ui.event.Events; @@ -520,8 +521,8 @@ protected void redrawChildrenDirectly(TagRenderContext rc, Execution exec, java. protected void renderProperties(org.zkoss.zk.ui.sys.ContentRenderer renderer) throws java.io.IOException { super.renderProperties(renderer); - render(renderer, "prolog", getPrologHalf(false)); - render(renderer, "epilog", getEpilogHalf()); + render(renderer, "prolog", SafeHtmlValue.valueOf(getPrologHalf(false))); + render(renderer, "epilog", SafeHtmlValue.valueOf(getEpilogHalf())); } /** diff --git a/zhtml/src/main/resources/web/js/zhtml/Text.ts b/zhtml/src/main/resources/web/js/zhtml/Text.ts index 4b95c6a6c58..ab63f58f4e1 100644 --- a/zhtml/src/main/resources/web/js/zhtml/Text.ts +++ b/zhtml/src/main/resources/web/js/zhtml/Text.ts @@ -43,7 +43,7 @@ export class Text extends zhtml.Widget { var n = this.$n(); if (n) { var val = this._value; - n.innerHTML = this._encode ? zUtl.encodeXML(val) : val; + n.innerHTML = this._encode ? val : zUtl.decodeXML(val); // See Bug 2871080 and ZK-294 } } @@ -71,7 +71,7 @@ export class Text extends zhtml.Widget { var n = this.$n(); if (n) { var val = this._value; - n.innerHTML = this._encode ? zUtl.encodeXML(val) : val; + n.innerHTML = this._encode ? val : zUtl.decodeXML(val); // See Bug 2871080 and ZK-294 } } @@ -99,7 +99,7 @@ export class Text extends zhtml.Widget { span = attrs || (this.idRequired && this._checkContentRequired(val)); // Bug 3245960: enclosed text was wrapped with if (span) out.push(''); - out.push(this._encode ? zUtl.encodeXML(val) : val); + out.push(this._encode ? val : zUtl.decodeXML(val)); // See Bug 2871080 and ZK-294 if (span) out.push(''); } diff --git a/zk/src/main/java/org/zkoss/zk/ui/AbstractComponent.java b/zk/src/main/java/org/zkoss/zk/ui/AbstractComponent.java index 78ba76dc625..31709d1f6eb 100644 --- a/zk/src/main/java/org/zkoss/zk/ui/AbstractComponent.java +++ b/zk/src/main/java/org/zkoss/zk/ui/AbstractComponent.java @@ -49,6 +49,7 @@ import org.zkoss.lang.Strings; import org.zkoss.util.CollectionsX; import org.zkoss.util.Converter; +import org.zkoss.xml.XMLs; import org.zkoss.zk.au.AuRequest; import org.zkoss.zk.au.AuResponse; import org.zkoss.zk.au.AuService; @@ -1853,6 +1854,8 @@ protected void smartUpdate(String attr, Object value) { * and wgt.setAttr("value2") will be invoked at the client * accordingly. * + *

Note: the String type value will be escaped by {@link Strings#escapeJavaScript} and {@link XMLs#escapeXML}. + * To allow the safe HTML, use {@link org.zkoss.zk.ui.SafeHtmlValue} to wrap the value. (since 10.0.0) * @param append whether to append the updates of properties with the same * name. If false, only the last value of the same property will be sent * to the client. @@ -1860,8 +1863,13 @@ protected void smartUpdate(String attr, Object value) { * @see #smartUpdate(String, Object) */ protected void smartUpdate(String attr, Object value, boolean append) { - if (_page != null) + if (_page != null) { + if (value instanceof String) { + // no need to use Strings.escapeJavaScript() here. + value = XMLs.escapeXML((String) value); + } getAttachedUiEngine().addSmartUpdate(this, attr, value, append); + } } /** A special smart update to update a value in int. diff --git a/zk/src/main/java/org/zkoss/zk/ui/HtmlNativeComponent.java b/zk/src/main/java/org/zkoss/zk/ui/HtmlNativeComponent.java index ba5144661a2..ca3156b795f 100644 --- a/zk/src/main/java/org/zkoss/zk/ui/HtmlNativeComponent.java +++ b/zk/src/main/java/org/zkoss/zk/ui/HtmlNativeComponent.java @@ -294,8 +294,8 @@ private static boolean startsWith(StringBuffer sb, String tag, int start) { protected void renderProperties(org.zkoss.zk.ui.sys.ContentRenderer renderer) throws java.io.IOException { super.renderProperties(renderer); - render(renderer, "prolog", getPrologHalf()); - render(renderer, "epilog", getEpilogHalf()); + render(renderer, "prolog", SafeHtmlValue.valueOf(getPrologHalf())); + render(renderer, "epilog", SafeHtmlValue.valueOf(getEpilogHalf())); } private String getPrologHalf() { diff --git a/zk/src/main/java/org/zkoss/zk/ui/SafeHtmlValue.java b/zk/src/main/java/org/zkoss/zk/ui/SafeHtmlValue.java new file mode 100644 index 00000000000..c0a4a3077a2 --- /dev/null +++ b/zk/src/main/java/org/zkoss/zk/ui/SafeHtmlValue.java @@ -0,0 +1,78 @@ +/* SafeHtmlValue.java + + Purpose: + + Description: + + History: + 2:39 PM 2023/12/20, Created by jumperchen + +Copyright (C) 2023 Potix Corporation. All Rights Reserved. +*/ +package org.zkoss.zk.ui; + +import java.util.Objects; + +import org.zkoss.json.JSONValue; + +/** + * A string-like value that is safe to be used as HTML content. + * @author jumperchen + * @since 10.0.0 + */ +public class SafeHtmlValue implements org.zkoss.json.JSONAware, java.io.Serializable { + private static final long serialVersionUID = 202312201440L; + private final String _value; + + /** An empty SafeHtmlValue instance. */ + public static final SafeHtmlValue EMPTY = new SafeHtmlValue(""); + + /** + * Constructor. + * @param value the value to be wrapped. + */ + public SafeHtmlValue(String value) { + _value = value; + } + + /** + * Returns the wrapped value. + */ + public String getValue() { + return _value; + } + + @Override + public String toString() { + return toJSONString(); + } + + @Override + public String toJSONString() { + return JSONValue.toJSONString(_value); + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + SafeHtmlValue that = (SafeHtmlValue) o; + return Objects.equals(_value, that._value); + } + + @Override + public int hashCode() { + return Objects.hash(_value); + } + + /** + * Returns a SafeHtmlValue instance for the specified value. + * @param value the value to be wrapped. + * @since 10.0.0 + */ + public static SafeHtmlValue valueOf(String value) { + return new SafeHtmlValue(value); + } +} diff --git a/zk/src/main/java/org/zkoss/zk/ui/sys/JSCumulativeContentRenderer.java b/zk/src/main/java/org/zkoss/zk/ui/sys/JSCumulativeContentRenderer.java index 615233dceaa..7a858246dc5 100644 --- a/zk/src/main/java/org/zkoss/zk/ui/sys/JSCumulativeContentRenderer.java +++ b/zk/src/main/java/org/zkoss/zk/ui/sys/JSCumulativeContentRenderer.java @@ -23,6 +23,7 @@ import org.zkoss.json.JSONs; import org.zkoss.lang.Generics; import org.zkoss.lang.Strings; +import org.zkoss.xml.XMLs; import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.UiException; @@ -95,7 +96,7 @@ private String renderValue(String value) { if (value == null) return null; else { - return Strings.escapeJavaScript(value); + return Strings.escapeJavaScript(XMLs.escapeXML(value)); } } diff --git a/zk/src/main/java/org/zkoss/zk/ui/sys/JsContentRenderer.java b/zk/src/main/java/org/zkoss/zk/ui/sys/JsContentRenderer.java index 873a75c461e..1784ec5b948 100644 --- a/zk/src/main/java/org/zkoss/zk/ui/sys/JsContentRenderer.java +++ b/zk/src/main/java/org/zkoss/zk/ui/sys/JsContentRenderer.java @@ -25,6 +25,7 @@ import org.zkoss.json.JSONAware; import org.zkoss.json.JSONs; import org.zkoss.lang.Strings; +import org.zkoss.xml.XMLs; import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.UiException; @@ -153,7 +154,7 @@ private void renderValue(String value) { _buf.append((String) null); else { _buf.append('\''); - _buf.append(Strings.escapeJavaScript(value)); + _buf.append(Strings.escapeJavaScript(XMLs.escapeXML(value))); _buf.append('\''); } } diff --git a/zk/src/main/resources/web/js/zk/widget.ts b/zk/src/main/resources/web/js/zk/widget.ts index 1aa5a68cced..7e11bc1b2af 100755 --- a/zk/src/main/resources/web/js/zk/widget.ts +++ b/zk/src/main/resources/web/js/zk/widget.ts @@ -3160,7 +3160,7 @@ new zul.wnd.Window({ if ((s = this.domClass_(no))) out += ' class="' + s + '"'; if ((s = this.domTooltiptext_())) - out += ' title="' + zUtl.encodeXML(s) + '"'; // ZK-676 + out += ' title="' + s + '"'; // ZK-676 if ((tabIndex = this.getTabindex()) != undefined) out += ' tabindex="' + tabIndex + '"'; } else { diff --git a/zkdoc/release-note b/zkdoc/release-note index 0f2ab30ae37..94f94f70575 100644 --- a/zkdoc/release-note +++ b/zkdoc/release-note @@ -7,6 +7,7 @@ ZK 10.0.0 ZK-5048: MVVM DebuggerFactory should log via SLF4J ZK-5595: Upgrade Servlet version from 2.4 to 3.1 aligned with Java EE 7 ZK-5596: Simplify the JavaScript url when enable embedded mode + ZK-5182: Prevent XSS issue in component attributes * Bugs ZK-5393: Update ZK jars to jakarta-friendly uploads @@ -20,6 +21,7 @@ ZK 10.0.0 ZK-5569: Radiogroup onCheck event type mismatch ZK-5161: page directive's attributes are not encoded before rendering into HTML ZK-5598: CKEditor requests ExecutionImpl.encodeURL with null value, causes NPE in embedded mode + ZK-5162: emptyMessage is not escaped with HTML characters * Upgrade Notes + Upgrade commons-fileupload to commons-fileupload2-javax 2.0.0-M1 and commons-io to 2.13.0 to support jakarta-friendly uploads @@ -29,6 +31,10 @@ ZK 10.0.0 + Remove all deprecated Java APIs and the legacy module "zkplus-legacy". + Use /zkEmbedded url (or specify yourself) to simply include embedded.js, instead of specify the real path to embedded.js, simplifying the source to enable embedded mode. + + To prevent XSS issue in component attributes, all component attributes will be + encoded before rendering into HTML. If you want to render HTML in component attributes, + please use the corresponding SafeHtmlValue object APIs instead of using HTML characters. + Such as Comboitem, Menu, Navitem, and HTML components. -------- ZK 10.0.0-Beta diff --git a/zktest/src/main/webapp/test2/B100-ZK-5162.zul b/zktest/src/main/webapp/test2/B100-ZK-5162.zul new file mode 100644 index 00000000000..d32f40f8196 --- /dev/null +++ b/zktest/src/main/webapp/test2/B100-ZK-5162.zul @@ -0,0 +1,24 @@ + + + + + "; //might read from an external source +String script = ""; + ]]> + + + + \ No newline at end of file diff --git a/zktest/src/test/java/org/zkoss/zktest/zats/test2/B100_ZK_5162Test.java b/zktest/src/test/java/org/zkoss/zktest/zats/test2/B100_ZK_5162Test.java new file mode 100644 index 00000000000..18c0674b738 --- /dev/null +++ b/zktest/src/test/java/org/zkoss/zktest/zats/test2/B100_ZK_5162Test.java @@ -0,0 +1,38 @@ +/* B100_ZK_5162Test.java + + Purpose: + + Description: + + History: + 11:57 AM 2023/12/20, Created by jumperchen + +Copyright (C) 2023 Potix Corporation. All Rights Reserved. +*/ +package org.zkoss.zktest.zats.test2; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.fail; + +import org.junit.jupiter.api.Test; +import org.openqa.selenium.NoAlertPresentException; + +import org.zkoss.test.webdriver.WebDriverTestCase; + +/** + * @author jumperchen + */ +public class B100_ZK_5162Test extends WebDriverTestCase { + @Test + public void test() { + connect(); + try { + driver.switchTo().alert(); + fail("Should not be here"); + } catch (NoAlertPresentException ex) { + // ignore + } + assertEquals("", jq(".z-grid-emptybody-content").text()); + assertEquals("", jq(".z-listbox-emptybody-content").text()); + } +} diff --git a/zul/src/main/java/org/zkoss/zul/Comboitem.java b/zul/src/main/java/org/zkoss/zul/Comboitem.java index 6236c342fb4..7fcc479c964 100644 --- a/zul/src/main/java/org/zkoss/zul/Comboitem.java +++ b/zul/src/main/java/org/zkoss/zul/Comboitem.java @@ -19,7 +19,10 @@ import java.io.Serializable; import org.zkoss.lang.Objects; +import org.zkoss.lang.Strings; +import org.zkoss.xml.XMLs; import org.zkoss.zk.ui.Component; +import org.zkoss.zk.ui.SafeHtmlValue; import org.zkoss.zk.ui.UiException; import org.zkoss.zul.impl.LabelImageElement; @@ -36,7 +39,7 @@ public class Comboitem extends LabelImageElement implements org.zkoss.zk.ui.ext.Disable { private String _desc = ""; private transient Object _value; - private String _content = ""; + private SafeHtmlValue _content = SafeHtmlValue.EMPTY; private boolean _disabled; private transient int _index; @@ -101,34 +104,50 @@ public void setDescription(String desc) { * @since 3.0.0 */ public String getContent() { - return _content; + return _content.toString(); } - /** Sets the embedded content (i.e., HTML tags) that is + /** Returns the embedded content (i.e., HTML tags) that is * shown as part of the description. * *

It is useful to show the description in more versatile way. * - *

Default: empty (""). - * - *

Deriving class can override it to return whatever it wants - * other than null. + * @see #getDescription + * @since 10.0.0 + */ + public SafeHtmlValue getRawContent() { + return _content; + } + + /** Sets the embedded content that is + * shown as part of the description. * *

Security Note

- *

Unlike other methods, the content assigned to this method - * is generated directly to the browser without escaping. - * Thus, it is better not to have something input by the user to avoid - * any XSS - * attach. + *

Since 10.0.0, the content assigned to this method will be escaped by default. + * To avoid escaping, use {@link #setContent(SafeHtmlValue)} instead. * @see #setDescription * @since 3.0.0 */ public void setContent(String content) { if (content == null) content = ""; + content = Strings.escapeJavaScript(XMLs.escapeXML(content)); + if (!Objects.equals(_content, SafeHtmlValue.valueOf(content))) { + _content = SafeHtmlValue.valueOf(content); + smartUpdate("content", getRawContent()); + } + } + + /** Sets the embedded content (i.e., HTML tags) that is + * shown as part of the description. + * @since 10.0.0 + */ + public void setContent(SafeHtmlValue content) { + if (content == null) + content = SafeHtmlValue.EMPTY; if (!Objects.equals(_content, content)) { _content = content; - smartUpdate("content", getContent()); //allow overriding getContent() + smartUpdate("content", getRawContent()); } } @@ -203,7 +222,7 @@ protected void renderProperties(org.zkoss.zk.ui.sys.ContentRenderer renderer) th render(renderer, "disabled", _disabled); render(renderer, "description", getDescription()); //allow overriding getDescription() - render(renderer, "content", getContent()); //allow overriding getContent() + render(renderer, "content", getRawContent()); //allow overriding getContent() if (_value instanceof String) { render(renderer, "value", _value); diff --git a/zul/src/main/java/org/zkoss/zul/Html.java b/zul/src/main/java/org/zkoss/zul/Html.java index 1b88e765940..2e422537185 100644 --- a/zul/src/main/java/org/zkoss/zul/Html.java +++ b/zul/src/main/java/org/zkoss/zul/Html.java @@ -20,6 +20,7 @@ import org.zkoss.json.JavaScriptValue; import org.zkoss.lang.Objects; +import org.zkoss.zk.ui.SafeHtmlValue; import org.zkoss.zk.ui.sys.HtmlPageRenders; import org.zkoss.zul.impl.XulElement; @@ -72,7 +73,7 @@ * @author tomyeh */ public class Html extends XulElement { - private String _content = ""; + private SafeHtmlValue _content = SafeHtmlValue.EMPTY; /** Constructs a {@link Html} component to embed HTML tags. */ @@ -83,12 +84,19 @@ public Html() { * with the specified content. */ public Html(String content) { - _content = content != null ? content : ""; + _content = SafeHtmlValue.valueOf(content != null ? content : ""); } /** Returns the embedded content (i.e., HTML tags). */ public String getContent() { + return _content.toString(); + } + + /** Returns the embedded content (i.e., HTML tags). + * @since 10.0.0 + */ + public SafeHtmlValue getRawContent() { return _content; } @@ -107,10 +115,9 @@ public String getContent() { public void setContent(String content) { if (content == null) content = ""; - if (!Objects.equals(_content, content)) { - _content = content; - smartUpdate("content", getContent()); - //allow deriving to override getContent() + if (!Objects.equals(_content, SafeHtmlValue.valueOf(content))) { + _content = SafeHtmlValue.valueOf(content); + smartUpdate("content", getRawContent()); } } @@ -135,7 +142,7 @@ protected void renderProperties(org.zkoss.zk.ui.sys.ContentRenderer renderer) th if (cnt == null) renderer.render("content", new JavaScriptValue("zk('" + getUuid() + "').detachChildren()")); else - render(renderer, "content", cnt); + render(renderer, "content", getRawContent()); } } diff --git a/zul/src/main/java/org/zkoss/zul/Menu.java b/zul/src/main/java/org/zkoss/zul/Menu.java index c4d5ff401b0..7353267ea89 100644 --- a/zul/src/main/java/org/zkoss/zul/Menu.java +++ b/zul/src/main/java/org/zkoss/zul/Menu.java @@ -20,9 +20,12 @@ import java.util.Map; import org.zkoss.lang.Objects; +import org.zkoss.lang.Strings; +import org.zkoss.xml.XMLs; import org.zkoss.zk.au.AuRequest; import org.zkoss.zk.au.out.AuInvoke; import org.zkoss.zk.ui.Component; +import org.zkoss.zk.ui.SafeHtmlValue; import org.zkoss.zk.ui.UiException; import org.zkoss.zk.ui.event.Events; import org.zkoss.zk.ui.event.InputEvent; @@ -41,7 +44,7 @@ */ public class Menu extends LabelImageElement implements org.zkoss.zk.ui.ext.Disable { private Menupopup _popup; - private String _content = ""; + private SafeHtmlValue _content = SafeHtmlValue.EMPTY; private boolean _disabled = false; static { @@ -83,10 +86,22 @@ public Menupopup getMenupopup() { * @since 5.0.0 */ public String getContent() { + return _content.toString(); + } + + /** Returns the embedded content (i.e., HTML tags) that is + * shown as part of the description. + * + *

It is useful to show the description in more versatile way. + * + * @since 10.0.0 + */ + public SafeHtmlValue getRawContent() { return _content; } - /** Sets the embedded content (i.e., HTML tags) that is + + /** Sets the embedded content that is * shown as part of the description. * *

It is useful to show the description in more versatile way. @@ -94,14 +109,32 @@ public String getContent() { *

There is a way to create Colorbox automatically by using * #color=#RRGGBB, usage example setContent("#color=#FFFFFF") * + *

Security Note

+ *

Since 10.0.0, the content assigned to this method will be escaped by default. + * To avoid escaping, use {@link #setContent(SafeHtmlValue)} instead. * @since 5.0.0 */ public void setContent(String content) { if (content == null) content = ""; + content = Strings.escapeJavaScript(XMLs.escapeXML(content)); + if (!Objects.equals(_content, SafeHtmlValue.valueOf(content))) { + _content = SafeHtmlValue.valueOf(content); + smartUpdate("content", getRawContent()); + } + } + + + /** Sets the embedded content (i.e., HTML tags) that is + * shown as part of the description. + * @since 10.0.0 + */ + public void setContent(SafeHtmlValue content) { + if (content == null) + content = SafeHtmlValue.EMPTY; if (!Objects.equals(_content, content)) { _content = content; - smartUpdate("content", content); + smartUpdate("content", getRawContent()); } } @@ -141,7 +174,7 @@ public String getZclass() { protected void renderProperties(ContentRenderer renderer) throws IOException { super.renderProperties(renderer); - render(renderer, "content", _content); + render(renderer, "content", getRawContent()); render(renderer, "disabled", _disabled); } diff --git a/zul/src/main/resources/web/js/zul/inp/InputWidget.ts b/zul/src/main/resources/web/js/zul/inp/InputWidget.ts index 6a58e49b321..bb5019a7c91 100644 --- a/zul/src/main/resources/web/js/zul/inp/InputWidget.ts +++ b/zul/src/main/resources/web/js/zul/inp/InputWidget.ts @@ -629,7 +629,7 @@ export class InputWidget extends zul.Widget extends zul.Widget'); } - out.push(zUtl.encodeXML(this._title), ''); + out.push(this._title, ''); } } diff --git a/zul/src/main/resources/web/js/zul/menu/Menu.ts b/zul/src/main/resources/web/js/zul/menu/Menu.ts index a096c5b9f86..94563225ab7 100644 --- a/zul/src/main/resources/web/js/zul/menu/Menu.ts +++ b/zul/src/main/resources/web/js/zul/menu/Menu.ts @@ -213,7 +213,7 @@ export class Menu extends zul.LabelImageWidget implements zul.LabelImageWidgetWi /** @internal */ override domContent_(): string { var label = '' - + (zUtl.encodeXML(this.getLabel())) + '', + + this.getLabel() + '', img = this.getImage(), icon = '', diff --git a/zul/src/main/resources/web/js/zul/menu/Menuitem.ts b/zul/src/main/resources/web/js/zul/menu/Menuitem.ts index ab8764bab11..9ecfb903812 100644 --- a/zul/src/main/resources/web/js/zul/menu/Menuitem.ts +++ b/zul/src/main/resources/web/js/zul/menu/Menuitem.ts @@ -360,7 +360,7 @@ export class Menuitem extends zul.LabelImageWidget implements zul.LabelImageWidg /** @internal */ override domContent_(): string { var label = '' - + (zUtl.encodeXML(this.getLabel())) + '', + + this.getLabel() + '', icon = '', img = this.getImage(), iconSclass = this.domIcon_(); diff --git a/zul/src/main/resources/web/js/zul/sel/ItemWidget.ts b/zul/src/main/resources/web/js/zul/sel/ItemWidget.ts index bcc7f7ef91b..e3f3a6ea91a 100644 --- a/zul/src/main/resources/web/js/zul/sel/ItemWidget.ts +++ b/zul/src/main/resources/web/js/zul/sel/ItemWidget.ts @@ -313,7 +313,7 @@ export class ItemWidget extends zul.Widget implements zul.m const iterator = this.getMeshWidget()!.itemIterator(); let cnt = 2, msg: string | undefined; - if (!this.isSelected()) return zUtl.encodeXML(this.getLabel()!); + if (!this.isSelected()) return this.getLabel(); while (iterator.hasNext()) { const item = iterator.next()!; if (item.isSelected()) { diff --git a/zul/src/main/resources/web/js/zul/sel/Listcell.ts b/zul/src/main/resources/web/js/zul/sel/Listcell.ts index bc47439b42d..3fb77f8cf01 100644 --- a/zul/src/main/resources/web/js/zul/sel/Listcell.ts +++ b/zul/src/main/resources/web/js/zul/sel/Listcell.ts @@ -127,7 +127,7 @@ export class Listcell extends zul.LabelImageWidget { /** @internal */ override domLabel_(): string { - return zUtl.encodeXML(this.getLabel(), { maxlength: this.getMaxlength() }); + return this.getLabel(); } /** @internal */ diff --git a/zul/src/main/resources/web/js/zul/sel/Listfooter.ts b/zul/src/main/resources/web/js/zul/sel/Listfooter.ts index 7f4922aa003..59fdfb4a4f9 100644 --- a/zul/src/main/resources/web/js/zul/sel/Listfooter.ts +++ b/zul/src/main/resources/web/js/zul/sel/Listfooter.ts @@ -54,6 +54,6 @@ export class Listfooter extends zul.mesh.FooterWidget { /** @internal */ override domLabel_(): string { - return zUtl.encodeXML(this.getLabel(), {maxlength: this.getMaxlength()}); + return this.getLabel(); } } \ No newline at end of file diff --git a/zul/src/main/resources/web/js/zul/sel/Listheader.ts b/zul/src/main/resources/web/js/zul/sel/Listheader.ts index 32811e4ac64..331e3b1f989 100644 --- a/zul/src/main/resources/web/js/zul/sel/Listheader.ts +++ b/zul/src/main/resources/web/js/zul/sel/Listheader.ts @@ -344,7 +344,7 @@ export class Listheader extends zul.mesh.SortWidget { /** @internal */ override domLabel_(): string { - return zUtl.encodeXML(this.getLabel(), {maxlength: this._maxlength}); + return this.getLabel(); } /** @internal */ diff --git a/zul/src/main/resources/web/js/zul/sel/Option.ts b/zul/src/main/resources/web/js/zul/sel/Option.ts index a3d3bd1bf97..4d7a67f3c4c 100644 --- a/zul/src/main/resources/web/js/zul/sel/Option.ts +++ b/zul/src/main/resources/web/js/zul/sel/Option.ts @@ -213,7 +213,7 @@ export class Option extends zul.Widget { /** @internal */ domLabel_(): string { - return zUtl.encodeXML(this.getLabel()!, {maxlength: this.getMaxlength()!}); + return this.getLabel()!; } /** @internal */ diff --git a/zul/src/main/resources/web/js/zul/sel/SelectWidget.ts b/zul/src/main/resources/web/js/zul/sel/SelectWidget.ts index 8cd61f74e03..342008037ce 100644 --- a/zul/src/main/resources/web/js/zul/sel/SelectWidget.ts +++ b/zul/src/main/resources/web/js/zul/sel/SelectWidget.ts @@ -350,7 +350,7 @@ export abstract class SelectWidget extends zul.mesh.MeshWidget { // don't use jq.newHidden() in this case, because the performance is not good. var data = '', - tmp = ''; diff --git a/zul/src/main/resources/web/js/zul/sel/Treecell.ts b/zul/src/main/resources/web/js/zul/sel/Treecell.ts index 480adeafd7e..fe9d5174d91 100644 --- a/zul/src/main/resources/web/js/zul/sel/Treecell.ts +++ b/zul/src/main/resources/web/js/zul/sel/Treecell.ts @@ -114,7 +114,7 @@ export class Treecell extends zul.LabelImageWidget { /** @internal */ override domLabel_(): string { - return zUtl.encodeXML(this.getLabel(), {maxlength: this.getMaxlength()}); + return this.getLabel(); } override getTextNode(): HTMLElement | undefined { diff --git a/zul/src/main/resources/web/js/zul/sel/Treecol.ts b/zul/src/main/resources/web/js/zul/sel/Treecol.ts index 873dd4ecd62..d69614a8951 100644 --- a/zul/src/main/resources/web/js/zul/sel/Treecol.ts +++ b/zul/src/main/resources/web/js/zul/sel/Treecol.ts @@ -209,7 +209,7 @@ export class Treecol extends zul.mesh.SortWidget { /** @internal */ override domLabel_(): string { - return zUtl.encodeXML(this.getLabel(), {maxlength: this._maxlength}); + return this.getLabel(); } /** @internal */ diff --git a/zul/src/main/resources/web/js/zul/sel/Treefooter.ts b/zul/src/main/resources/web/js/zul/sel/Treefooter.ts index 75866659c43..41518326da0 100644 --- a/zul/src/main/resources/web/js/zul/sel/Treefooter.ts +++ b/zul/src/main/resources/web/js/zul/sel/Treefooter.ts @@ -53,6 +53,6 @@ export class Treefooter extends zul.mesh.FooterWidget { /** @internal */ override domLabel_(): string { - return zUtl.encodeXML(this.getLabel(), {maxlength: this.getMaxlength()}); + return this.getLabel(); } } \ No newline at end of file diff --git a/zul/src/main/resources/web/js/zul/tab/Tab.ts b/zul/src/main/resources/web/js/zul/tab/Tab.ts index 1108092b521..202f51d4dc1 100644 --- a/zul/src/main/resources/web/js/zul/tab/Tab.ts +++ b/zul/src/main/resources/web/js/zul/tab/Tab.ts @@ -268,7 +268,7 @@ export class Tab extends zul.LabelImageWidget implements zul.LabelImageWidgetWit /** @internal */ override domContent_(): string { - let label = zUtl.encodeXML(this.getLabel()), + let label = this.getLabel(), img = this.getImage(); const iconSclass = this.domIcon_(); diff --git a/zul/src/main/resources/web/js/zul/wgt/A.ts b/zul/src/main/resources/web/js/zul/wgt/A.ts index 08e79ebe739..1fd28dcbf30 100644 --- a/zul/src/main/resources/web/js/zul/wgt/A.ts +++ b/zul/src/main/resources/web/js/zul/wgt/A.ts @@ -235,7 +235,7 @@ export class A extends zul.LabelImageWidget implements zul.La /** @internal */ override domContent_(): string { - var label = zUtl.encodeXML(this.getLabel()), + var label = this.getLabel(), img = this.domImage_(), iconSclass = this.domIcon_(); if (!img && !iconSclass) diff --git a/zul/src/main/resources/web/js/zul/wgt/Button.ts b/zul/src/main/resources/web/js/zul/wgt/Button.ts index db637ddef2a..034ff3e9ebe 100644 --- a/zul/src/main/resources/web/js/zul/wgt/Button.ts +++ b/zul/src/main/resources/web/js/zul/wgt/Button.ts @@ -368,7 +368,7 @@ export class Button extends zul.LabelImageWidget implements z /** @internal */ override domContent_(): string { - var label = zUtl.encodeXML(this.getLabel()), + var label = this.getLabel(), img = this.getImage(), iconSclass = this.domIcon_(); if (!img && !iconSclass) return label; diff --git a/zul/src/main/resources/web/js/zul/wgt/Caption.ts b/zul/src/main/resources/web/js/zul/wgt/Caption.ts index 81475ab2689..19227f61b5b 100644 --- a/zul/src/main/resources/web/js/zul/wgt/Caption.ts +++ b/zul/src/main/resources/web/js/zul/wgt/Caption.ts @@ -41,7 +41,6 @@ export class Caption extends zul.LabelImageWidget { title = this.parent ? this.parent._title : '', iconSclass = this.domIcon_(); if (title) label = label ? title + ' - ' + label : title; - label = zUtl.encodeXML(label); if (!img && !iconSclass) return label; if (!img) img = iconSclass; diff --git a/zul/src/main/resources/web/js/zul/wgt/Combobutton.ts b/zul/src/main/resources/web/js/zul/wgt/Combobutton.ts index 304c30682c4..1b3e7239b32 100644 --- a/zul/src/main/resources/web/js/zul/wgt/Combobutton.ts +++ b/zul/src/main/resources/web/js/zul/wgt/Combobutton.ts @@ -141,7 +141,7 @@ export class Combobutton extends zul.wgt.Button { /** @internal */ override domContent_(): string { var label = '' - + zUtl.encodeXML(this.getLabel()) + '', + + this.getLabel() + '', img = this.domImage_(), iconSclass = this.domIcon_(); if (!img && !iconSclass) return label; diff --git a/zul/src/main/resources/web/js/zul/wgt/Label.ts b/zul/src/main/resources/web/js/zul/wgt/Label.ts index 1d3b340382f..9affca1a5ae 100644 --- a/zul/src/main/resources/web/js/zul/wgt/Label.ts +++ b/zul/src/main/resources/web/js/zul/wgt/Label.ts @@ -48,7 +48,7 @@ export class Label extends zul.Widget { if (o !== value || opts?.force) { var n = this.$n(); - if (n) n.innerHTML = this.getEncodedText(); + if (n) n.innerHTML = this._value; } return this; @@ -72,7 +72,7 @@ export class Label extends zul.Widget { if (o !== multiline || opts?.force) { var n = this.$n(); - if (n) n.innerHTML = this.getEncodedText(); + if (n) n.innerHTML = this._value; } return this; @@ -103,7 +103,7 @@ export class Label extends zul.Widget { if (o !== pre || opts?.force) { var n = this.$n(); - if (n) n.innerHTML = this.getEncodedText(); + if (n) n.innerHTML = this._value; } return this; @@ -126,7 +126,7 @@ export class Label extends zul.Widget { if (o !== maxlength || opts?.force) { var n = this.$n(); - if (n) n.innerHTML = this.getEncodedText(); + if (n) n.innerHTML = this._value; } return this; diff --git a/zul/src/main/resources/web/js/zul/wgt/Notification.ts b/zul/src/main/resources/web/js/zul/wgt/Notification.ts index 50e5b98a066..fee2220545d 100644 --- a/zul/src/main/resources/web/js/zul/wgt/Notification.ts +++ b/zul/src/main/resources/web/js/zul/wgt/Notification.ts @@ -86,7 +86,7 @@ export class Notification extends zul.wgt.Popup { var type = this._type, s = super.domClass_(no); if (type) - s += ' ' + this.$s(zUtl.encodeXML(type)); + s += ' ' + this.$s(type); return s; } diff --git a/zul/src/main/resources/web/js/zul/wgt/Toolbarbutton.ts b/zul/src/main/resources/web/js/zul/wgt/Toolbarbutton.ts index a0ffe5c5e3c..95623a5f2c7 100644 --- a/zul/src/main/resources/web/js/zul/wgt/Toolbarbutton.ts +++ b/zul/src/main/resources/web/js/zul/wgt/Toolbarbutton.ts @@ -385,7 +385,7 @@ export class Toolbarbutton extends zul.LabelImageWidget implements zul.LabelImag /** @internal */ override domContent_(): string { - var label = zUtl.encodeXML(this.getLabel()), img = this.domImage_(), + var label = this.getLabel(), img = this.domImage_(), iconSclass = this.domIcon_(); if (!img && !iconSclass) return label; diff --git a/zul/src/main/resources/web/js/zul/wgt/mold/label.js b/zul/src/main/resources/web/js/zul/wgt/mold/label.js index 61e72fec092..35f9dc3b491 100644 --- a/zul/src/main/resources/web/js/zul/wgt/mold/label.js +++ b/zul/src/main/resources/web/js/zul/wgt/mold/label.js @@ -13,5 +13,5 @@ Copyright (C) 2008 Potix Corporation. All Rights Reserved. it will be useful, but WITHOUT ANY WARRANTY. */ function label$mold$(out) { - out.push('', this.getEncodedText(), ''); + out.push('', this._value, ''); } \ No newline at end of file