测试html代码如下,里面带有中文的字体:隶书。

<span style="font-family:'隶书' , 'simli';font-size:'14px';" width="100px">测试测试测试</span>

        原代码如下:

private String sanitizeHtml(String html) {
        PolicyFactory policy = new HtmlPolicyBuilder()
                .allowCommonBlockElements()
                .allowCommonInlineFormattingElements()
                .allowElements("iframe", "table", "tbody", "tr", "td", "img", "a", "video", "style")
                .allowStyling()
                .allowAttributes("src", "width", "height", "alt")
                .onElements("img")
                .allowAttributes("src", "width", "height", "frameborder", "allowfullscreen")
                .onElements("iframe")
                .allowAttributes("width", "height", "valign")
                .onElements("td")
                .toFactory();
        return policy.sanitize(html);
    }

        经过以上代码处理后变成了以下的html字符串,隶书被清除了,其中&#39;是单引号

<span style="font-family:, &#39;simli&#39;">测试测试测试</span>
&#39;是单引号,实际是:
<span style="font-family:, 'simli'">测试测试测试</span>

        这是由于 owasp-java-html-sanitizer在处理带有单引号的样式属性时,会把它当做STRING的类型去处理,而且是不允许带有中文的,处理的时候会把中文清除。

        解决办法是在处理标签的属性时,把单引号去掉,这时就不会把样式的中文去掉了。

PolicyFactory policy = new HtmlPolicyBuilder()
                .allowCommonBlockElements()
                .allowCommonInlineFormattingElements()
                .allowElements("iframe", "table", "tbody", "tr", "td", "img", "a", "video", "style")
                .allowStyling()
                .allowAttributes("src", "width", "height", "alt")
                .onElements("img")
                .allowAttributes("src", "width", "height", "frameborder", "allowfullscreen")
                .onElements("iframe")
                .allowAttributes("width", "height", "valign")
                .onElements("td")
                //withPreprocessor里的方法是为了把属性的单引号都去掉,否则中文字体会被清除。
                .withPreprocessor(new HtmlStreamEventProcessor() {
                    @Override
                    public HtmlStreamEventReceiver wrap(HtmlStreamEventReceiver sink) {
                        return new HtmlStreamEventReceiverWrapper(sink) {
                            @Override
                            public void openTag(String elementName, List<String> attrs) {
                                List<String> newAttrs;
                                if (!CollectionUtils.isEmpty(attrs)) {
                                    newAttrs = new ArrayList<>();
                                    for (String attr : attrs) {
                                        if (StringUtils.isBlank(attr)) {
                                            newAttrs.add(attr);
                                        } else {
                                            newAttrs.add(attr.replace("'", ""));
                                        }
                                    }
                                } else {
                                    newAttrs = attrs;
                                }
                                this.underlying.openTag(elementName, newAttrs);
                            }
                        };
                    }
                })
                .toFactory();
        return policy.sanitize(html);

        经过处理后html如下,隶书被保留了下来:

<span style="font-family:&#39;隶书&#39; , &#39;simli&#39;;font-size:14px">测试测试测试</span>
其中&#39;是单引号,实际如下:
<span style="font-family:'隶书', 'simli';font-size:14px">测试测试测试</span>
处理后的html还是有单引号,实际是owasp-java-html-sanitizer给补的。

        跟踪代码是StylingPolicy去处理样式的

        类型是STRING时会进入这个方法:

        把单引号去掉就不会判断是STRING类型,就不会进入quotedString方法,就不会清除中文。

Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐