fix: enforce root containment for renderFile/parseFile lookups (#870)

Made-with: Cursor
This commit is contained in:
Yang Jun
2026-04-07 23:18:53 +08:00
committed by GitHub
parent db4348507e
commit f41c1fc02f
5 changed files with 31 additions and 10 deletions
+18 -1
View File
@@ -109,6 +109,7 @@ describe('Liquid', function () {
})
})
describe('#renderFile', function () {
afterEach(restore)
it('should throw with lookup list when file not exist', function () {
const engine = new Liquid({
root: ['/boo', '/root/'],
@@ -116,6 +117,22 @@ describe('Liquid', function () {
})
return expect(engine.renderFile('/not/exist.html')).rejects.toThrow(/Failed to lookup "\/not\/exist.html" in "\/boo,\/root\/"/)
})
it('should reject absolute paths outside root', async function () {
mock({
'/safe/foo.html': 'safe',
'/etc/secret': 'SECRET'
})
const engine = new Liquid({ root: ['/safe'] })
await expect(engine.renderFile('/etc/secret')).rejects.toThrow(/Failed to lookup/)
})
it('should reject absolute paths outside root (sync)', function () {
mock({
'/safe/foo.html': 'safe',
'/etc/secret': 'SECRET'
})
const engine = new Liquid({ root: ['/safe'] })
expect(() => engine.renderFileSync('/etc/secret')).toThrow(/Failed to lookup/)
})
})
describe('#parseFile', function () {
it('should throw with lookup list when file not exist', function () {
@@ -127,7 +144,7 @@ describe('Liquid', function () {
})
it('should fallback to require.resolve in Node.js', async function () {
const engine = new Liquid({
root: ['/root/'],
root: [process.cwd()],
extname: '.html'
})
const tpls = await engine.parseFileSync('jest')