From deaa53f205ed6ca79faac42e0d33a7080909ad4b Mon Sep 17 00:00:00 2001 From: Mark Kevin Baldemor Date: Mon, 28 Dec 2020 10:00:35 +0800 Subject: [PATCH 1/4] Fixed XSS Vulnerability. --- .../design/client/base/AbstractButton.java | 19 ++++- .../client/base/AbstractValueWidget.java | 3 - .../client/base/DefaultHtmlSanitizer.java | 35 +++++++++ .../design/client/base/HasSafeText.java | 32 ++++++++ .../design/client/base/TextWidget.java | 34 +++++++-- .../client/base/mixin/AbstractMixin.java | 6 +- .../design/client/base/mixin/HTMLMixin.java | 3 +- .../design/client/base/mixin/TextMixin.java | 51 ++++++++++++- .../design/client/ui/MaterialBadge.java | 11 --- .../design/client/ui/MaterialCardTitle.java | 22 +++++- .../design/client/ui/MaterialChip.java | 23 +++++- .../design/client/ui/MaterialHelpBlock.java | 20 ++++- .../design/client/ui/MaterialLabel.java | 20 ++++- .../design/client/ui/MaterialValueBox.java | 2 +- .../design/client/ui/html/Heading.java | 20 ++++- .../material/design/client/ui/html/Label.java | 36 ++++++++- .../design/client/ui/html/Paragraph.java | 22 +++++- .../material/design/client/ui/html/Span.java | 20 ++++- .../design/client/MixinTestSuite.java | 34 +++++++++ .../client/mixin/AbstractMixinTest.java | 41 ++++++++++ .../design/client/mixin/TextMixinTest.java | 75 +++++++++++++++++++ .../client/ui/sanitizer/CustomSanitizer.java | 43 +++++++++++ 22 files changed, 531 insertions(+), 41 deletions(-) create mode 100644 gwt-material/src/main/java/gwt/material/design/client/base/DefaultHtmlSanitizer.java create mode 100644 gwt-material/src/main/java/gwt/material/design/client/base/HasSafeText.java create mode 100644 gwt-material/src/test/java/gwt/material/design/client/MixinTestSuite.java create mode 100644 gwt-material/src/test/java/gwt/material/design/client/mixin/AbstractMixinTest.java create mode 100644 gwt-material/src/test/java/gwt/material/design/client/mixin/TextMixinTest.java create mode 100644 gwt-material/src/test/java/gwt/material/design/client/ui/sanitizer/CustomSanitizer.java diff --git a/gwt-material/src/main/java/gwt/material/design/client/base/AbstractButton.java b/gwt-material/src/main/java/gwt/material/design/client/base/AbstractButton.java index 43232cd9c..dcb05b45c 100644 --- a/gwt-material/src/main/java/gwt/material/design/client/base/AbstractButton.java +++ b/gwt-material/src/main/java/gwt/material/design/client/base/AbstractButton.java @@ -24,6 +24,8 @@ import com.google.gwt.event.logical.shared.ValueChangeEvent; import com.google.gwt.event.logical.shared.ValueChangeHandler; import com.google.gwt.event.shared.HandlerRegistration; +import com.google.gwt.safehtml.shared.HtmlSanitizer; +import com.google.gwt.safehtml.shared.SafeHtml; import com.google.gwt.user.client.History; import com.google.gwt.user.client.ui.HasValue; import gwt.material.design.client.base.mixin.ActivatesMixin; @@ -36,7 +38,7 @@ * @author Ben Dol */ public abstract class AbstractButton extends MaterialWidget implements HasHref, HasGrid, HasActivates, - HasTargetHistoryToken, HasType, HasValue { + HasTargetHistoryToken, HasType, HasValue, HasSafeText { private String targetHistoryToken; private Span span = new Span(); @@ -169,6 +171,21 @@ public void setText(String text) { } } + @Override + public void setHtml(SafeHtml html) { + span.setHtml(html); + } + + @Override + public void setSanitizer(HtmlSanitizer sanitizer) { + span.setSanitizer(sanitizer); + } + + @Override + public HtmlSanitizer getSanitizer() { + return span.getSanitizer(); + } + /** * Set the target history token for the widget. Note, that you should use either * {@link #setTargetHistoryToken(String)} or {@link #setHref(String)}, but not both as diff --git a/gwt-material/src/main/java/gwt/material/design/client/base/AbstractValueWidget.java b/gwt-material/src/main/java/gwt/material/design/client/base/AbstractValueWidget.java index 3019f1984..674e1f3b7 100644 --- a/gwt-material/src/main/java/gwt/material/design/client/base/AbstractValueWidget.java +++ b/gwt-material/src/main/java/gwt/material/design/client/base/AbstractValueWidget.java @@ -86,9 +86,6 @@ public void setValue(V value, boolean fireEvents, boolean reload) { } } - //TODO: - //setSanitizer(); - @Override public void setErrorText(String errorText) { getStatusTextMixin().setErrorText(errorText); diff --git a/gwt-material/src/main/java/gwt/material/design/client/base/DefaultHtmlSanitizer.java b/gwt-material/src/main/java/gwt/material/design/client/base/DefaultHtmlSanitizer.java new file mode 100644 index 000000000..c550e9ad5 --- /dev/null +++ b/gwt-material/src/main/java/gwt/material/design/client/base/DefaultHtmlSanitizer.java @@ -0,0 +1,35 @@ +/* + * #%L + * GwtMaterial + * %% + * Copyright (C) 2015 - 2020 GwtMaterialDesign + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ +package gwt.material.design.client.base; + +import com.google.gwt.safehtml.shared.HtmlSanitizer; +import com.google.gwt.safehtml.shared.SafeHtml; +import com.google.gwt.safehtml.shared.SafeHtmlUtils; + +/** + * HTML-escapes its argument and returns the result wrapped as a SafeHtml. + */ +public class DefaultHtmlSanitizer implements HtmlSanitizer { + + @Override + public SafeHtml sanitize(String html) { + return SafeHtmlUtils.fromString(html); + } +} diff --git a/gwt-material/src/main/java/gwt/material/design/client/base/HasSafeText.java b/gwt-material/src/main/java/gwt/material/design/client/base/HasSafeText.java new file mode 100644 index 000000000..c47c6b2ff --- /dev/null +++ b/gwt-material/src/main/java/gwt/material/design/client/base/HasSafeText.java @@ -0,0 +1,32 @@ +/* + * #%L + * GwtMaterial + * %% + * Copyright (C) 2015 - 2020 GwtMaterialDesign + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ +package gwt.material.design.client.base; + +import com.google.gwt.safehtml.shared.HtmlSanitizer; +import com.google.gwt.safehtml.shared.SafeHtml; + +public interface HasSafeText { + + void setHtml(SafeHtml html); + + void setSanitizer(HtmlSanitizer sanitizer); + + HtmlSanitizer getSanitizer(); +} diff --git a/gwt-material/src/main/java/gwt/material/design/client/base/TextWidget.java b/gwt-material/src/main/java/gwt/material/design/client/base/TextWidget.java index 5ca72853d..83d568eb4 100644 --- a/gwt-material/src/main/java/gwt/material/design/client/base/TextWidget.java +++ b/gwt-material/src/main/java/gwt/material/design/client/base/TextWidget.java @@ -20,13 +20,15 @@ package gwt.material.design.client.base; import com.google.gwt.dom.client.Element; +import com.google.gwt.safehtml.shared.HtmlSanitizer; +import com.google.gwt.safehtml.shared.SafeHtml; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.ui.HasText; import gwt.material.design.client.base.mixin.TextMixin; -public class TextWidget extends MaterialWidget implements HasText { +public class TextWidget extends MaterialWidget implements HasSafeText, HasText { - private final TextMixin textMixin = new TextMixin<>(this); + private TextMixin textMixin; public TextWidget() { super(DOM.createDiv()); @@ -42,11 +44,33 @@ public TextWidget(Element element, String... initialClass) { @Override public String getText() { - return textMixin.getText(); + return getTextMixin().getText(); } @Override public void setText(String text) { - textMixin.setText(text); + getTextMixin().setText(text); } -} \ No newline at end of file + + @Override + public void setHtml(SafeHtml html) { + getTextMixin().setHtml(html); + } + + @Override + public void setSanitizer(HtmlSanitizer sanitizer) { + getTextMixin().setSanitizer(sanitizer); + } + + @Override + public HtmlSanitizer getSanitizer() { + return getTextMixin().getSanitizer(); + } + + public TextMixin getTextMixin() { + if (textMixin == null) { + textMixin = new TextMixin<>(this); + } + return textMixin; + } +} diff --git a/gwt-material/src/main/java/gwt/material/design/client/base/mixin/AbstractMixin.java b/gwt-material/src/main/java/gwt/material/design/client/base/mixin/AbstractMixin.java index 9d62d7fda..32a0bbcf5 100644 --- a/gwt-material/src/main/java/gwt/material/design/client/base/mixin/AbstractMixin.java +++ b/gwt-material/src/main/java/gwt/material/design/client/base/mixin/AbstractMixin.java @@ -26,7 +26,7 @@ /** * @author Sven Jacobs */ -abstract class AbstractMixin { +public abstract class AbstractMixin { T uiObject; @@ -37,4 +37,8 @@ abstract class AbstractMixin { public void setUiObject(T uiObject) { this.uiObject = uiObject; } + + public T getUiObject() { + return uiObject; + } } diff --git a/gwt-material/src/main/java/gwt/material/design/client/base/mixin/HTMLMixin.java b/gwt-material/src/main/java/gwt/material/design/client/base/mixin/HTMLMixin.java index 1363cc936..b14ed8580 100644 --- a/gwt-material/src/main/java/gwt/material/design/client/base/mixin/HTMLMixin.java +++ b/gwt-material/src/main/java/gwt/material/design/client/base/mixin/HTMLMixin.java @@ -23,13 +23,14 @@ import com.google.gwt.dom.client.Element; import com.google.gwt.user.client.ui.HasHTML; import com.google.gwt.user.client.ui.UIObject; +import gwt.material.design.client.base.HasSafeText; import static gwt.material.design.jquery.client.api.JQuery.$; /** * @author Grant Slender */ -public class HTMLMixin extends TextMixin implements HasHTML { +public class HTMLMixin extends TextMixin implements HasHTML { public HTMLMixin(final T uiObject) { super(uiObject); diff --git a/gwt-material/src/main/java/gwt/material/design/client/base/mixin/TextMixin.java b/gwt-material/src/main/java/gwt/material/design/client/base/mixin/TextMixin.java index 4cc68b9b9..ce18b3f7e 100644 --- a/gwt-material/src/main/java/gwt/material/design/client/base/mixin/TextMixin.java +++ b/gwt-material/src/main/java/gwt/material/design/client/base/mixin/TextMixin.java @@ -20,23 +20,68 @@ * #L% */ +import com.google.gwt.safehtml.shared.HtmlSanitizer; +import com.google.gwt.safehtml.shared.SafeHtml; import com.google.gwt.safehtml.shared.SafeHtmlUtils; import com.google.gwt.user.client.ui.UIObject; +import gwt.material.design.client.base.DefaultHtmlSanitizer; +import gwt.material.design.client.base.HasSafeText; /** + * @author Mark Kevin * @author Ben Dol */ -public class TextMixin extends AbstractMixin { +public class TextMixin extends AbstractMixin implements HasSafeText { + + protected static HtmlSanitizer DEFAULT_SANITIZER = new DefaultHtmlSanitizer(); + protected HtmlSanitizer _sanitizer; + protected SafeHtml safeHtml; public TextMixin(final T uiObject) { super(uiObject); } public String getText() { - return uiObject.getElement().getInnerText(); + return safeHtml != null ? uiObject.getElement().getInnerText() : null; } public void setText(final String text) { - uiObject.getElement().setInnerText(text); + setHtml(toSafeHtml(text)); + } + + protected SafeHtml toSafeHtml(String text) { + SafeHtml safeHtml = null; + if (text != null) { + if (_sanitizer == null) { + safeHtml = DEFAULT_SANITIZER.sanitize(text); + } else { + safeHtml = _sanitizer.sanitize(text); + } + } + return safeHtml; + } + + @Override + public void setHtml(SafeHtml safeHtml) { + this.safeHtml = safeHtml; + uiObject.getElement().setInnerSafeHtml(safeHtml != null ? safeHtml : SafeHtmlUtils.fromString("")); + } + + public static void setDefaultSanitizer(HtmlSanitizer defaultSanitizer) { + DEFAULT_SANITIZER = defaultSanitizer; + } + + public static HtmlSanitizer getDefaultSanitizer() { + return DEFAULT_SANITIZER; + } + + @Override + public void setSanitizer(HtmlSanitizer sanitizer) { + _sanitizer = sanitizer; + } + + @Override + public HtmlSanitizer getSanitizer() { + return _sanitizer; } } diff --git a/gwt-material/src/main/java/gwt/material/design/client/ui/MaterialBadge.java b/gwt-material/src/main/java/gwt/material/design/client/ui/MaterialBadge.java index 04e9b8662..29af757e3 100644 --- a/gwt-material/src/main/java/gwt/material/design/client/ui/MaterialBadge.java +++ b/gwt-material/src/main/java/gwt/material/design/client/ui/MaterialBadge.java @@ -20,7 +20,6 @@ package gwt.material.design.client.ui; import com.google.gwt.dom.client.Document; -import com.google.gwt.safehtml.shared.SafeHtmlUtils; import gwt.material.design.client.constants.Color; import gwt.material.design.client.constants.CssName; import gwt.material.design.client.ui.html.Span; @@ -81,14 +80,4 @@ public MaterialBadge(String text, Color textColor, Color bgColor) { setTextColor(textColor); setBackgroundColor(bgColor); } - - @Override - public String getText() { - return SafeHtmlUtils.fromString(getElement().getInnerText()).asString(); - } - - @Override - public void setText(String text) { - getElement().setInnerSafeHtml(SafeHtmlUtils.fromString(text)); - } } diff --git a/gwt-material/src/main/java/gwt/material/design/client/ui/MaterialCardTitle.java b/gwt-material/src/main/java/gwt/material/design/client/ui/MaterialCardTitle.java index 30947e07d..c57b08644 100644 --- a/gwt-material/src/main/java/gwt/material/design/client/ui/MaterialCardTitle.java +++ b/gwt-material/src/main/java/gwt/material/design/client/ui/MaterialCardTitle.java @@ -21,8 +21,11 @@ import com.google.gwt.dom.client.Document; import com.google.gwt.dom.client.Style; +import com.google.gwt.safehtml.shared.HtmlSanitizer; +import com.google.gwt.safehtml.shared.SafeHtml; import com.google.gwt.user.client.ui.HasText; import gwt.material.design.client.base.HasIcon; +import gwt.material.design.client.base.HasSafeText; import gwt.material.design.client.base.MaterialWidget; import gwt.material.design.client.constants.*; import gwt.material.design.client.ui.html.Span; @@ -38,7 +41,7 @@ * @see Material Design Specification */ //@formatter:on -public class MaterialCardTitle extends MaterialWidget implements HasIcon, HasText { +public class MaterialCardTitle extends MaterialWidget implements HasIcon, HasSafeText, HasText { private MaterialIcon icon = new MaterialIcon(); private Span titleLabel = new Span(); @@ -56,11 +59,26 @@ public String getText() { public void setText(String text) { titleLabel.setText(text); - if(!titleLabel.isAttached()) { + if (!titleLabel.isAttached()) { add(titleLabel); } } + @Override + public void setHtml(SafeHtml html) { + titleLabel.setHtml(html); + } + + @Override + public void setSanitizer(HtmlSanitizer sanitizer) { + titleLabel.setSanitizer(sanitizer); + } + + @Override + public HtmlSanitizer getSanitizer() { + return titleLabel.getSanitizer(); + } + @Override public MaterialIcon getIcon() { return icon; diff --git a/gwt-material/src/main/java/gwt/material/design/client/ui/MaterialChip.java b/gwt-material/src/main/java/gwt/material/design/client/ui/MaterialChip.java index bdec35e6f..9006fa944 100644 --- a/gwt-material/src/main/java/gwt/material/design/client/ui/MaterialChip.java +++ b/gwt-material/src/main/java/gwt/material/design/client/ui/MaterialChip.java @@ -26,7 +26,9 @@ import com.google.gwt.event.logical.shared.HasCloseHandlers; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.resources.client.ImageResource; -import com.google.gwt.safehtml.shared.SafeHtmlUtils; +import com.google.gwt.safehtml.shared.HtmlSanitizer; +import com.google.gwt.safehtml.shared.SafeHtml; +import com.google.gwt.user.client.ui.HasText; import com.google.gwt.user.client.ui.HasValue; import gwt.material.design.client.base.*; import gwt.material.design.client.base.mixin.ActiveMixin; @@ -62,7 +64,7 @@ */ //@formatter:on public class MaterialChip extends AbstractValueWidget implements HasImage, HasIcon, HasLetter, - HasValue, HasCloseHandlers, HasType, HasActive { + HasValue, HasCloseHandlers, HasType, HasActive, HasSafeText, HasText { private MaterialIcon icon = new MaterialIcon(IconType.CLOSE); private Span chipLabel = new Span(); @@ -126,6 +128,21 @@ public String getText() { return getValue(); } + @Override + public void setHtml(SafeHtml html) { + chipLabel.setHtml(html); + } + + @Override + public void setSanitizer(HtmlSanitizer sanitizer) { + chipLabel.setSanitizer(sanitizer); + } + + @Override + public HtmlSanitizer getSanitizer() { + return chipLabel.getSanitizer(); + } + @Override public void setValue(String value, boolean fireEvents) { chipLabel.setText(value); @@ -134,7 +151,7 @@ public void setValue(String value, boolean fireEvents) { @Override public String getValue() { - return SafeHtmlUtils.fromString(chipLabel.getElement().getInnerText()).asString(); + return chipLabel.getText(); } @Override diff --git a/gwt-material/src/main/java/gwt/material/design/client/ui/MaterialHelpBlock.java b/gwt-material/src/main/java/gwt/material/design/client/ui/MaterialHelpBlock.java index fe5b3f5cd..93e305bbc 100644 --- a/gwt-material/src/main/java/gwt/material/design/client/ui/MaterialHelpBlock.java +++ b/gwt-material/src/main/java/gwt/material/design/client/ui/MaterialHelpBlock.java @@ -20,8 +20,11 @@ package gwt.material.design.client.ui; import com.google.gwt.dom.client.Style.Unit; +import com.google.gwt.safehtml.shared.HtmlSanitizer; +import com.google.gwt.safehtml.shared.SafeHtml; import com.google.gwt.user.client.ui.HasText; import gwt.material.design.client.base.HasIcon; +import gwt.material.design.client.base.HasSafeText; import gwt.material.design.client.base.mixin.TextMixin; import gwt.material.design.client.constants.Color; import gwt.material.design.client.constants.IconPosition; @@ -29,7 +32,7 @@ import gwt.material.design.client.constants.IconType; import gwt.material.design.client.ui.html.Div; -public class MaterialHelpBlock extends Div implements HasText, HasIcon { +public class MaterialHelpBlock extends Div implements HasSafeText, HasText, HasIcon { private MaterialIcon icon = new MaterialIcon(); private TextMixin textMixin; @@ -48,6 +51,21 @@ public void setText(String text) { getTextMixin().setText(text); } + @Override + public void setHtml(SafeHtml html) { + getTextMixin().setHtml(html); + } + + @Override + public void setSanitizer(HtmlSanitizer sanitizer) { + getTextMixin().setSanitizer(sanitizer); + } + + @Override + public HtmlSanitizer getSanitizer() { + return getTextMixin().getSanitizer(); + } + @Override public MaterialIcon getIcon() { return icon; diff --git a/gwt-material/src/main/java/gwt/material/design/client/ui/MaterialLabel.java b/gwt-material/src/main/java/gwt/material/design/client/ui/MaterialLabel.java index 893dd452d..549cb50d6 100644 --- a/gwt-material/src/main/java/gwt/material/design/client/ui/MaterialLabel.java +++ b/gwt-material/src/main/java/gwt/material/design/client/ui/MaterialLabel.java @@ -20,8 +20,11 @@ package gwt.material.design.client.ui; import com.google.gwt.dom.client.Document; +import com.google.gwt.safehtml.shared.HtmlSanitizer; +import com.google.gwt.safehtml.shared.SafeHtml; import com.google.gwt.user.client.ui.HasText; import gwt.material.design.client.base.AbstractValueWidget; +import gwt.material.design.client.base.HasSafeText; import gwt.material.design.client.base.mixin.TextMixin; import gwt.material.design.client.base.mixin.ToggleStyleMixin; import gwt.material.design.client.constants.Color; @@ -42,7 +45,7 @@ * @see Material Design Specification */ //@formatter:on -public class MaterialLabel extends AbstractValueWidget implements HasText { +public class MaterialLabel extends AbstractValueWidget implements HasSafeText, HasText { private boolean secondary; private TextMixin textMixin; @@ -79,6 +82,21 @@ public void setText(String text) { setValue(text, true); } + @Override + public void setHtml(SafeHtml html) { + getTextMixin().setHtml(html); + } + + @Override + public void setSanitizer(HtmlSanitizer sanitizer) { + getTextMixin().setSanitizer(sanitizer); + } + + @Override + public HtmlSanitizer getSanitizer() { + return getTextMixin().getSanitizer(); + } + @Override public void setValue(String value, boolean fireEvents) { getTextMixin().setText(value); diff --git a/gwt-material/src/main/java/gwt/material/design/client/ui/MaterialValueBox.java b/gwt-material/src/main/java/gwt/material/design/client/ui/MaterialValueBox.java index b6affda9b..cba44d13b 100644 --- a/gwt-material/src/main/java/gwt/material/design/client/ui/MaterialValueBox.java +++ b/gwt-material/src/main/java/gwt/material/design/client/ui/MaterialValueBox.java @@ -235,7 +235,7 @@ public String getPlaceholder() { public void setPlaceholder(String placeholder) { valueBoxBase.getElement().setAttribute("placeholder", placeholder); - if (!label.getText().isEmpty()) { + if (label.getText() != null && !label.getText().isEmpty()) { label.setStyleName(CssName.ACTIVE); } } diff --git a/gwt-material/src/main/java/gwt/material/design/client/ui/html/Heading.java b/gwt-material/src/main/java/gwt/material/design/client/ui/html/Heading.java index bbdb06f38..d7317545d 100644 --- a/gwt-material/src/main/java/gwt/material/design/client/ui/html/Heading.java +++ b/gwt-material/src/main/java/gwt/material/design/client/ui/html/Heading.java @@ -20,13 +20,16 @@ package gwt.material.design.client.ui.html; import com.google.gwt.dom.client.Document; +import com.google.gwt.safehtml.shared.HtmlSanitizer; +import com.google.gwt.safehtml.shared.SafeHtml; import com.google.gwt.uibinder.client.UiConstructor; import com.google.gwt.user.client.ui.HasText; +import gwt.material.design.client.base.HasSafeText; import gwt.material.design.client.base.MaterialWidget; import gwt.material.design.client.base.mixin.TextMixin; import gwt.material.design.client.constants.HeadingSize; -public class Heading extends MaterialWidget implements HasText { +public class Heading extends MaterialWidget implements HasSafeText, HasText { private TextMixin textMixin; @@ -49,6 +52,21 @@ public void setText(String text) { getTextMixin().setText(text); } + @Override + public void setHtml(SafeHtml html) { + getTextMixin().setHtml(html); + } + + @Override + public void setSanitizer(HtmlSanitizer sanitizer) { + getTextMixin().setSanitizer(sanitizer); + } + + @Override + public HtmlSanitizer getSanitizer() { + return getTextMixin().getSanitizer(); + } + public TextMixin getTextMixin() { if (textMixin == null) { textMixin = new TextMixin<>(this); diff --git a/gwt-material/src/main/java/gwt/material/design/client/ui/html/Label.java b/gwt-material/src/main/java/gwt/material/design/client/ui/html/Label.java index 4609bbae2..7bcf77ba7 100644 --- a/gwt-material/src/main/java/gwt/material/design/client/ui/html/Label.java +++ b/gwt-material/src/main/java/gwt/material/design/client/ui/html/Label.java @@ -19,10 +19,16 @@ */ package gwt.material.design.client.ui.html; +import com.google.gwt.safehtml.shared.HtmlSanitizer; +import com.google.gwt.safehtml.shared.SafeHtml; import com.google.gwt.user.client.DOM; +import gwt.material.design.client.base.HasSafeText; import gwt.material.design.client.base.MaterialWidget; +import gwt.material.design.client.base.mixin.TextMixin; -public class Label extends MaterialWidget { +public class Label extends MaterialWidget implements HasSafeText { + + private TextMixin