Skip to content

Commit defd113

Browse files
committed
chore: tweaks
1 parent ec00835 commit defd113

File tree

8 files changed

+124
-28
lines changed

8 files changed

+124
-28
lines changed

docs/plugins/markdown/markdown-chart/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,4 +135,4 @@ export default {
135135

136136
- Type: `string[] | '*'`
137137
- Default: `[]`
138-
- Details: A list of sources files that script execution is enabled. Use `'*'` to allow all source files.
138+
- Details: Only effective when `DANGEROUS_ALLOW_SCRIPT_EXECUTION` is enabled. A list of file paths allowed to execute chart scripts. Use `'*'` to allow all files.

docs/zh/plugins/markdown/markdown-chart/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,4 +135,4 @@ export default {
135135

136136
- 类型:`string[] | '*'`
137137
- 默认:`[]`
138-
- 详情:当启用脚本执行时,允许脚本运行的源文件列表。使用 `'*'` 允许所有源文件
138+
- 详情:当启用脚本执行时,允许执行图表脚本的文件路径列表。使用 `'*'` 允许所有文件

plugins/markdown/plugin-markdown-chart/src/client/components/ECharts.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { LoadingIcon, decodeData } from '@vuepress/helper/client'
22
import { useDebounceFn, useEventListener } from '@vueuse/core'
33
import type { EChartsOption, EChartsType } from 'echarts'
4-
import type * as Echarts from 'echarts'
4+
import type * as ECharts from 'echarts'
55
import type { PropType, VNode } from 'vue'
66
import {
77
defineComponent,
@@ -30,7 +30,7 @@ const AsyncFunction = (async (): Promise<void> => {}).constructor
3030
const parseEChartsConfig = (
3131
config: string,
3232
type: 'js' | 'json',
33-
echarts: typeof Echarts,
33+
echarts: typeof ECharts,
3434
instance: EChartsType,
3535
): Promise<EChartsConfig> => {
3636
if (type === 'js') {
@@ -102,12 +102,12 @@ export default defineComponent({
102102
}, 100),
103103
)
104104

105-
const destroyEcharts = (): void => {
105+
const destroyECharts = (): void => {
106106
instance?.dispose()
107107
instance = null
108108
}
109109

110-
const renderEcharts = async (): Promise<void> => {
110+
const renderECharts = async (): Promise<void> => {
111111
if (__VUEPRESS_SSR__) return
112112

113113
const echarts = await import(/* webpackChunkName: "echarts" */ 'echarts')
@@ -129,7 +129,7 @@ export default defineComponent({
129129

130130
onContentUpdated(async (reason) => {
131131
if (reason === 'mounted') {
132-
await renderEcharts()
132+
await renderECharts()
133133
loaded.value = true
134134
}
135135
})
@@ -141,15 +141,15 @@ export default defineComponent({
141141
watch(
142142
() => props.config,
143143
async () => {
144-
destroyEcharts()
144+
destroyECharts()
145145
await nextTick()
146-
await renderEcharts()
146+
await renderECharts()
147147
},
148148
{ flush: 'post' },
149149
)
150150
})
151151

152-
onUnmounted(destroyEcharts)
152+
onUnmounted(destroyECharts)
153153

154154
return (): (VNode | null)[] => [
155155
props.title

plugins/markdown/plugin-markdown-chart/src/node/markdown-it-plugins/chartjs.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ export const chartjs: PluginWithOptions<ChartJSPluginOptions> = (
3636
md,
3737
options,
3838
) => {
39-
const { allowScripts, allowAll, allowList = new Set() } = options!
39+
const { allowScripts, allowAll, allowList = new Set() } = options ?? {}
4040

4141
container(md, {
4242
name: 'chartjs',
@@ -62,8 +62,8 @@ export const chartjs: PluginWithOptions<ChartJSPluginOptions> = (
6262
// eslint-disable-next-line no-console
6363
console.warn(
6464
`\
65-
${colors.magenta('chartjs')}: JavaScript in echarts block is found in ${colors.cyan(filePathRelative)}, ${colors.red("it's ignored for security reasons")}.
66-
To enable the chart, you must manually add it to allowlist, see https://vuepress.vuejs.org/plugin/markdown/markdown-charts/echarts.html for details.
65+
${colors.magenta('chartjs')}: JavaScript in Chart.js block is found in ${colors.cyan(filePathRelative)}, ${colors.red('it is ignored for security reasons')}.
66+
To enable the chart, you must manually add it to allowlist, see https://vuepress.vuejs.org/plugin/markdown/markdown-charts/chartjs.html for details.
6767
`,
6868
)
6969
tokens[i].hidden = true
@@ -94,8 +94,8 @@ To enable the chart, you must manually add it to allowlist, see https://vuepress
9494
return ''
9595
}
9696

97-
return `<ChartJS config="${config}" ${
98-
title ? `title="${encodeURIComponent(title)}" ` : ''
97+
return `<ChartJS config="${config}"${
98+
title ? ` title="${encodeURIComponent(title)}"` : ''
9999
}${isJavaScript ? ' type="js"' : ''}>`
100100
},
101101
closeRender: (tokens, index) => (tokens[index].hidden ? '' : '</ChartJS>'),

plugins/markdown/plugin-markdown-chart/src/node/markdown-it-plugins/echarts.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,16 @@ export interface EChartsPluginOptions {
2424
allowScripts?: boolean
2525

2626
/**
27-
* Allow all scripts to be executed inside Echarts blocks.
28-
* 允许在 Echarts 块内执行所有脚本。
27+
* Allow all scripts to be executed inside ECharts blocks.
28+
* 允许在 ECharts 块内执行所有脚本。
2929
*
3030
* @default false
3131
*/
3232
allowAll?: boolean
3333

3434
/**
35-
* List of files allowed to execute scripts inside Echarts blocks.
36-
* 允许在 Echarts 块内执行脚本的文件列表。
35+
* List of files allowed to execute scripts inside ECharts blocks.
36+
* 允许在 ECharts 块内执行脚本的文件列表。
3737
*/
3838
allowList?: Set<string>
3939
}
@@ -47,7 +47,7 @@ export const echarts: PluginWithOptions<EChartsPluginOptions> = (
4747
md,
4848
options,
4949
) => {
50-
const { allowScripts, allowAll, allowList = new Set() } = options!
50+
const { allowScripts, allowAll, allowList = new Set() } = options ?? {}
5151

5252
// Handle ```echarts blocks
5353
const { fence } = md.renderer.rules
@@ -89,8 +89,8 @@ export const echarts: PluginWithOptions<EChartsPluginOptions> = (
8989
// eslint-disable-next-line no-console
9090
console.warn(
9191
`\
92-
${colors.magenta('[echarts]')}: JavaScript in echarts block is found in ${colors.cyan(filePathRelative)}, ${colors.red("it's ignored for security reasons")}.
93-
To enable the chart, you must manually add it to allowlist, see https://vuepress.vuejs.org/plugin/markdown/markdown-charts/echarts.html for details.
92+
${colors.magenta('[echarts]')}: JavaScript in echarts block is found in ${colors.cyan(filePathRelative)}, ${colors.red('it is ignored for security reasons')}.
93+
To enable the chart, you must manually add it to allowlist, see https://vuepress.vuejs.org/plugin/markdown/markdown-chart/echarts.html for details.
9494
`,
9595
)
9696
tokens[i].hidden = true

plugins/markdown/plugin-markdown-chart/tests/node/__snapshots__/chartjs.spec.ts.snap

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ exports[`chartjs > Should not break markdown fence 1`] = `
88

99
exports[`chartjs > Should resolve chart info with javascript block 1`] = `"<ChartJS config="eJyNUsFOwzAMve8rrHABKUJLSwcr4gAcOII4gGDikK5eqYiaKU2FJrR/x0nXbi0tYKmJXb+85xdlqYvSAq2rPIMr+JoA2M0aY2CJNIxTmUorY98AUDJBVcawYI+YMg7sRlXo9hdUSn+67M4gFi55qMxa+ea9kUWG7M2x1XwlWsfia9hxt/ykfQR6BU/aYulHqKMeZCECDmLOIeQQcaAi3BG7SOTyIzO6KtJbrbTZa7hgJkvkcRDRsTkRiJAOT0+DkwONBhSdUX9G/SAk9AjIMwXTGYcL+kZA54QRcz/zuJyIyI2YOj3H+ZueiGj0GY3XAx1egjYpmn9egPjb/iCka34Q0rU+COkZH1dqbXcgP0w/56l9j0E0/7d14nE+12ub05NvHnS5lArbCmCzT4kSs7y4tq9odAzWVNhj9Rst28vJNwOzs7M=" title="A%20bar%20chart" type="js"></ChartJS>"`;
1010

11-
exports[`chartjs > Should resolve chart with empty title and body 1`] = `"<ChartJS config="{}" type=""></ChartJS>"`;
11+
exports[`chartjs > Should resolve chart with empty title and body 1`] = `"<ChartJS config="{}"></ChartJS>"`;
1212

1313
exports[`chartjs > Should resolve chartjs info with js block 1`] = `"<ChartJS config="eJyNUsFOwzAMve8rrHABKUJLSwcr4gAcOII4gGDikK5eqYiaKU2FJrR/x0nXbi0tYKmJXb+85xdlqYvSAq2rPIMr+JoA2M0aY2CJNIxTmUorY98AUDJBVcawYI+YMg7sRlXo9hdUSn+67M4gFi55qMxa+ea9kUWG7M2x1XwlWsfia9hxt/ykfQR6BU/aYulHqKMeZCECDmLOIeQQcaAi3BG7SOTyIzO6KtJbrbTZa7hgJkvkcRDRsTkRiJAOT0+DkwONBhSdUX9G/SAk9AjIMwXTGYcL+kZA54QRcz/zuJyIyI2YOj3H+ZueiGj0GY3XAx1egjYpmn9egPjb/iCka34Q0rU+COkZH1dqbXcgP0w/56l9j0E0/7d14nE+12ub05NvHnS5lArbCmCzT4kSs7y4tq9odAzWVNhj9Rst28vJNwOzs7M=" title="A%20bar%20chart" type="js"></ChartJS>"`;
1414

15-
exports[`chartjs > Should resolve chartjs info with json block 1`] = `"<ChartJS config="eJyNUj1PwzAQ3fsrLLOAZKE6IYGwAQMjiAEEVQenOUKEFUeOI1Sh/HfuLLckKCkd/HH3nt/ds+57wRh32wb4NeO5slxQolBOYYJAjLTKQbcYr/gTFFwwfqs7oPMVtDZfdLu3ADVdHjvbaA8+WFWXwNekGDRbcF7HZ1jQ/61BPZww886ejYPWtxLg0NBKRoLJTLBYsEQwDOIg71m52nyW1nR1cWe0sYNKHrZlrk6jBB9mKCFjfL48j84GdXak5ALxFPEoRvYMyStFy1SwK1wzpEvkyMx3PV9OJuhHLqkeaR6qJxNsPcX2PGnPGf2CsQXYY39A/u9/kjJ2P0kZe5+k/HE+X2nvGykHXL9UhftA1zIAvT/XuPd+sE3jKlPTDIbZbjdK46jtYsxsBwHpQlnVN+4NrEHA2Q5G0rT3i37xA75CsCY=" title="A%20bar%20chart" type="json"></ChartJS>"`;
15+
exports[`chartjs > Should resolve chartjs info with json block 1`] = `"<ChartJS config="eJyNUj1PwzAQ3fsrLLOAZKE6IYGwAQMjiAEEVQenOUKEFUeOI1Sh/HfuLLckKCkd/HH3nt/ds+57wRh32wb4NeO5slxQolBOYYJAjLTKQbcYr/gTFFwwfqs7oPMVtDZfdLu3ADVdHjvbaA8+WFWXwNekGDRbcF7HZ1jQ/61BPZww886ejYPWtxLg0NBKRoLJTLBYsEQwDOIg71m52nyW1nR1cWe0sYNKHrZlrk6jBB9mKCFjfL48j84GdXak5ALxFPEoRvYMyStFy1SwK1wzpEvkyMx3PV9OJuhHLqkeaR6qJxNsPcX2PGnPGf2CsQXYY39A/u9/kjJ2P0kZe5+k/HE+X2nvGykHXL9UhftA1zIAvT/XuPd+sE3jKlPTDIbZbjdK46jtYsxsBwHpQlnVN+4NrEHA2Q5G0rT3i37xA75CsCY=" title="A%20bar%20chart"></ChartJS>"`;

plugins/markdown/plugin-markdown-chart/tests/node/chartjs.spec.ts

Lines changed: 60 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ import { describe, expect, it } from 'vitest'
44
import { chartjs } from '../../src/node/markdown-it-plugins/chartjs.js'
55

66
describe('chartjs', () => {
7-
const markdownIt = MarkdownIt({ linkify: true }).use(chartjs)
7+
const markdownIt = MarkdownIt({ linkify: true }).use(chartjs, {
8+
allowScripts: true,
9+
allowAll: true,
10+
})
811

912
it('Should resolve chartjs info with json block', () => {
1013
const result = markdownIt.render(
@@ -57,7 +60,7 @@ describe('chartjs', () => {
5760

5861
expect(result).toMatch(/<ChartJS.*><\/ChartJS>/)
5962
expect(result).toContain(`title="${encodeURIComponent('A bar chart')}"`)
60-
expect(result).toContain('type="json"')
63+
expect(result).not.toContain('type="')
6164
expect(result).toMatchSnapshot()
6265
})
6366

@@ -183,7 +186,7 @@ const config = {
183186

184187
expect(result).toMatch(/<ChartJS.*><\/ChartJS>/)
185188
expect(result).not.toContain('title="')
186-
expect(result).toContain('type=""')
189+
expect(result).not.toContain('type="')
187190
expect(result).toMatchSnapshot()
188191
})
189192

@@ -200,4 +203,58 @@ const a = 1;
200203
expect(result).toMatch(/<pre.*>[\s\S]*<\/pre>/)
201204
expect(result).toMatchSnapshot()
202205
})
206+
207+
it('Should remove unsafe script block by default', () => {
208+
const md = MarkdownIt({ linkify: true }).use(chartjs)
209+
210+
const result = md.render(
211+
`
212+
::: chartjs A bar chart
213+
214+
\`\`\`js
215+
const config = {
216+
type: "bar",
217+
data: {
218+
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
219+
datasets: [
220+
{
221+
label: "# of Votes",
222+
data: [12, 19, 3, 5, 2, 3],
223+
backgroundColor: [
224+
"rgba(255, 99, 132, 0.2)",
225+
"rgba(54, 162, 235, 0.2)",
226+
"rgba(255, 206, 86, 0.2)",
227+
"rgba(75, 192, 192, 0.2)",
228+
"rgba(153, 102, 255, 0.2)",
229+
"rgba(255, 159, 64, 0.2)",
230+
],
231+
borderColor: [
232+
"rgba(255, 99, 132, 1)",
233+
"rgba(54, 162, 235, 1)",
234+
"rgba(255, 206, 86, 1)",
235+
"rgba(75, 192, 192, 1)",
236+
"rgba(153, 102, 255, 1)",
237+
"rgba(255, 159, 64, 1)",
238+
],
239+
borderWidth: 1,
240+
},
241+
],
242+
},
243+
options: {
244+
scales: {
245+
y: {
246+
beginAtZero: true,
247+
},
248+
},
249+
},
250+
};
251+
\`\`\`
252+
253+
:::
254+
`,
255+
{},
256+
)
257+
258+
expect(result).toMatch('')
259+
})
203260
})

plugins/markdown/plugin-markdown-chart/tests/node/echarts.spec.ts

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ import { describe, expect, it } from 'vitest'
44
import { echarts } from '../../src/node/markdown-it-plugins/echarts.js'
55

66
describe('echarts', () => {
7-
const markdownIt = MarkdownIt({ linkify: true }).use(echarts)
7+
const markdownIt = MarkdownIt({ linkify: true }).use(echarts, {
8+
allowScripts: true,
9+
allowAll: true,
10+
})
811

912
it('Should resolve echarts container with json block', () => {
1013
const result = markdownIt.render(
@@ -182,4 +185,40 @@ const a = 1;
182185
expect(result).toMatch(/<pre.*>[\s\S]*<\/pre>/)
183186
expect(result).toMatchSnapshot()
184187
})
188+
189+
it('Should remove unsafe script block by default', () => {
190+
const md = MarkdownIt({ linkify: true }).use(echarts)
191+
192+
const result = md.render(
193+
`
194+
::: echarts A bar chart
195+
196+
\`\`\`js
197+
const option = {
198+
xAxis: {
199+
type: "category",
200+
data: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
201+
},
202+
yAxis: {
203+
type: "value",
204+
},
205+
series: [
206+
{
207+
data: [150, 230, 224, 218, 135, 147, 260],
208+
type: "line",
209+
},
210+
],
211+
tooltip: {
212+
trigger: "axis",
213+
},
214+
};
215+
\`\`\`
216+
217+
:::
218+
`,
219+
{},
220+
)
221+
222+
expect(result).toMatch('')
223+
})
185224
})

0 commit comments

Comments
 (0)