diff --git a/lib/plugins/tag/include_code.ts b/lib/plugins/tag/include_code.ts index 8457c75294..0d9b09b2f9 100644 --- a/lib/plugins/tag/include_code.ts +++ b/lib/plugins/tag/include_code.ts @@ -46,32 +46,32 @@ export = ctx => function includeCodeTag(args) { // If the language is not defined, use file extension instead lang = lang || extname(path).substring(1); - const src = join(ctx.source_dir, codeDir, path); + const src = join(codeDir, path); // If the title is not defined, use file name instead const title = match[1] || basename(path); const caption = `${title}view raw`; - return exists(src).then(exist => { - if (exist) return readFile(src); - }).then((code: string) => { - if (!code) return; + // Prevent path traversal: https://github.com/hexojs/hexo/issues/5250 + const Page = ctx.model('Page'); + const doc = Page.findOne({ source: src }); + if (!doc) return; - const lines = code.split('\n'); - code = lines.slice(from, to).join('\n').trim(); + let code = doc.content; + const lines = code.split('\n'); + code = lines.slice(from, to).join('\n').trim(); - if (ctx.extend.highlight.query(ctx.config.syntax_highlighter)) { - const options = { - lang, - caption, - lines_length: lines.length - }; - return ctx.extend.highlight.exec(ctx.config.syntax_highlighter, { - context: ctx, - args: [code, options] - }); - } + if (ctx.extend.highlight.query(ctx.config.syntax_highlighter)) { + const options = { + lang, + caption, + lines_length: lines.length + }; + return ctx.extend.highlight.exec(ctx.config.syntax_highlighter, { + context: ctx, + args: [code, options] + }); + } - return `
${code}
`; - }); + return `
${code}
`; }; diff --git a/test/scripts/tags/include_code.js b/test/scripts/tags/include_code.js index 3c18068609..6d3954c2da 100644 --- a/test/scripts/tags/include_code.js +++ b/test/scripts/tags/include_code.js @@ -21,7 +21,11 @@ describe('include_code', () => { const code = args => includeCode(args.split(' ')); - before(() => writeFile(path, fixture)); + before(async () => { + await writeFile(path, fixture); + await hexo.init(); + await hexo.load(); + }); beforeEach(() => { hexo.config = JSON.parse(JSON.stringify(defaultCfg));