Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

hexo-renderer-marked 中的新功能 DOMPurify 与部分标签外挂语法发生冲突 #205

Closed
3 tasks done
cxplay opened this issue Aug 25, 2021 · 8 comments · Fixed by hexojs/hexo#4771
Closed
3 tasks done

Comments

@cxplay
Copy link

cxplay commented Aug 25, 2021

I want to create a Bug report

Butterfly Information

Butterfly Version:

v3.8.3

Platform:

版本: Windows 10 专业版
版本号: 21H1
安装日期: ‎2021/‎8/‎22
操作系统内部版本: 19043.1165
体验: Windows Feature Experience Pack 120.2212.3530.0

Browser:

Microsoft Edge
版本 94.0.982.2 (官方内部版本) dev (64 位)

Expected behavior

当启用使用 v4.1 版本的 DOMPurify 时应当能够完整显示标签外挂语法中的 Gallery 相册 或者 InlineImg.

Actual behavior

当在配置文件中开启 hexo-renderer-marked 的 DOMPurify 功能后InlineImg 语法渲染失效, 页面中无法生成对应区域.

Steps to reproduce the behavior

  1. 为 Hexo 更新新版 hexo-renderer-marked 的 v4.1 版本: https://github.com/hexojs/hexo-renderer-marked/releases/tag/v4.1.0
  2. _config.yml 中定义 dompurifytrue. (参见 https://github.com/hexojs/hexo-renderer-marked#options)
  3. 使用 InlineImg 语法写入 Markdown 源文件中后生成到站点中.
  4. 查看对应包含 InlineImg 的文章或页面.
  5. 无法观察到对应 InlineImg 应当表现的 HTML 形式.

Screenshots

此为开启 DOMPurify 后 clean 并生成的新文章中的 "InlineImg" 标签外挂:

image

此为关闭 DOMPurify 后 clean 并生成的新文章中的 "InlineImg" 标签外挂:

image

Website

(目前我的站点已关闭 DOMPurify)
https://www.cxplay.org/works/markdown_test.html#Markdown-语法支持测试-v1-2

Describe the bug

不仅 InlineImg 会出现问题, 在撰写文章的时候发现 Gallery 相册 同样也会出现相同的渲染失效的问题,

由于在更新 hexo-renderer-marked v4.1 后在配置文件中只启用了这个新功能, 因此在开关 DOMPurify 后呈现出渲染成功与失败完全不同的效果, 因此得出 hexo-renderer-marked 中的新功能 DOMPurify 与部分标签外挂语法发生冲突 的结论.

@tomap
Copy link
Contributor

tomap commented Aug 27, 2021

Hello,

I'm sorry, I'm not fluent in chinese :(

However, I did managed to reproduce the issue!

It comes from the fact that DOMPurify is removing all the HTML comments

(It is also impacting myself)

If you check here: https://github.com/hexojs/hexo/blob/9e3360a9af3c7842636519cb82a8c773ca7dd526/lib/hexo/post.js#L22

You'll see that hexo is interpreting the tags {% whatever %} after the markdown, and temporarily replaces your tag with an HTML comment: <!--swig 1-->

I did managed to find a workaround:

1/ change hexo to use replace tags with a new HTML tag:

https://github.com/hexojs/hexo/blob/9e3360a9af3c7842636519cb82a8c773ca7dd526/lib/hexo/post.js#L22

L22:  const _escapeContent = (cache, flag, str) => `<${flag}>${cache.push(str) - 1}</${flag}>`;

2/ Change DOMPurify initialization to allow this new swig tag:

let param = {ADD_TAGS: ['swig']};
if (dompurify !== true) {
  param =  Object.assign(param, dompurify);
}

This seems to be a lot of changes + it might break other plugins

A better way seems to be to use https://github.com/hexojs/hexo-renderer-markdown-it
which seems to be safe by default: https://github.com/markdown-it/markdown-it/blob/master/docs/security.md
instead of forcing DOMPurify into this plugin...

cc @yoshinorin @hexojs/core what do you think?

@cxplay
Copy link
Author

cxplay commented Aug 27, 2021

对不起我的英文很差, 我只能用尽可能适用于谷歌翻译的方式让你能在翻译后看明白.


但这个问题的确是存在的, 你可以尝试全新部署一个 "Hexo" 然后使用 "hexo-renderer-marked" 的最新版本:

这里是我为这个全新的 "Hexo" 的 "_config.yml" 添加的配置项目:

marked:
  gfm: true
  pedantic: false
  breaks: true
  smartLists: true
  smartypants: true
  quotes: '“”‘’'
  modifyAnchors: 0
  anchorAlias: false
  autolink: true
  mangle: true
  sanitizeUrl: false
  dompurify: true
  headerIds: true
  lazyload: false
  prependRoot: false
  postAsset: false
  external_link:
    enable: false
    exclude: []
    nofollow: false
  disableNunjucks: false
  descriptionLists: true

之后我在 "_post" 文件夹中的新文章写入了以下 Markdown 内容:

---
title: test
date: 2021-08-28 06:20:01
tags:
---

# test

{% codeblock %}
alert('Hello World!');
{% endcodeblock %}

## test

这是它在本地服务器中呈现的网页效果:

image


但是如果我将配置文件中的 "dompurify" 定义为 "false" 时, 重新 "hexo clean" 后生成页面, 它的页面的表现就是这样的:

image


这里是我的 Markdown 源文件:
test.md

这里是两次生成的网页的离线副本:

[dompurify-false]test _ Hexo.zip

[dompurify-true]test _ Hexo.zip

@tomap
Copy link
Contributor

tomap commented Aug 28, 2021

@cxplay I understand, and I saw the same issue as you did.

Any tag (codeblock, inlineimg, ...) will be broken by DOMPurify!

Thus my fix explained above. But I believe this fix will cause too many issues. So, what I would like to suggest is to:

cc @hexojs/core Please tell me what you think :)

@cxplay
Copy link
Author

cxplay commented Aug 28, 2021

好吧, 确实切换到 "hexo-renderer-markdown-it" 是一个不错的选择, 我准备尝试.

不过我更希望 "Hexo" 一开始就使用 "hexo-renderer-markdown-it"...😂

@yoshinorin
Copy link
Member

@tomap
I agree with the below two suggestions:

  • document the issue in the readme
  • NOT enable DOMPurify by default

But, I don't know other two suggestions:

Personally, I use hexo-renderer-markdown-it, but I'm not sure which is better for the default markdown renderer for hexo.
IMHO the best way is ask to the user "Which renderer do you want to use?" when hexo init. But, we can't it soon.

Anyway, we should do the below tasks first:

  • document the issue in the readme
  • NOT enable DOMPurify by default

@cxplay
Copy link
Author

cxplay commented Sep 1, 2021

@yoshinorin (I have to try to use English.😂)


In fact both renderers are provided by Hexo, and I would like them to be merged into one so that they inherit "markdown-it" The advantages of scalability.
I don't think giving users the freedom to choose between the two is the best approach, as providing both renderers also doubles the development time and doubles the uncertainty.

@stevenjoezhang
Copy link
Member

How about making hexo-starter a Yeoman plugin, e.g. https://www.npmjs.com/package/generator-hexo
Users can choose the appropriate renderer plugin for markdown (marked / markdown-it), css (stylus / sass) and html (ejs / njk)

@tomap
Copy link
Contributor

tomap commented Sep 4, 2021

For the choice of marked vs mardown-it, it's a great idea.

For the other choices, it entirely depends on the theme. If the theme uses es vs njk, it is not really a chose to give to the use but rather something we should detect via the cli or if the theme is a package, declare it as a peer dependency in the theme's package.json?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants