Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/fs/loader.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,11 @@ describe('fs/loader', function () {
const result = toValueSync(loader.lookup('./foo/bar', LookupType.Partials, true, '/root/current'))
expect(result).toBe(resolve('/root/foo/bar'))
})
it('should enforce containment for LookupType.Root', function () {
const mockFs = { ...fs, existsSync: () => true, exists: async () => true }
const loader = new Loader({ relativeReference: false, fs: mockFs, extname: '', root: ['/safe'] } as any)
expect(() => toValueSync(loader.lookup('/etc/hosts', LookupType.Root, true)))
.toThrow(/ENOENT/)
})
})
})
11 changes: 4 additions & 7 deletions src/fs/loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,12 @@ export class Loader {

public * lookup (file: string, type: LookupType, sync?: boolean, currentFile?: string): Generator<unknown, string, string> {
const dirs = this.options[type]
const enforceRoot = type !== LookupType.Root
for (const filepath of this.candidates(file, dirs, currentFile)) {
if (enforceRoot) {
let allowed = false
for (const dir of dirs) {
if (yield this.contains(!!sync, dir, filepath)) { allowed = true; break }
}
if (!allowed) continue
let allowed = false
for (const dir of dirs) {
if (yield this.contains(!!sync, dir, filepath)) { allowed = true; break }
}
if (!allowed) continue
if (yield this.exists(!!sync, filepath)) return filepath
}
throw this.lookupError(file, dirs)
Expand Down
1 change: 1 addition & 0 deletions test/e2e/render-file.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ describe('#renderFile()', function () {
return expect(html).toContain('"name": "liquidjs"')
})
it('should render file with context', async function () {
engine = new Liquid({ root: views, extname: '.html' })
const html = await engine.renderFile(resolve(views, 'name.html'), { name: 'harttle' })
return expect(html).toBe('My name is harttle.')
})
Expand Down
4 changes: 2 additions & 2 deletions test/e2e/render-to-node-stream.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import { drainStream } from '../stub/stream'
describe('.renderToNodeStream()', function () {
it('should render to stream in Node.js', done => {
const cjs = require('../../dist/liquid.node')
const engine = new cjs.Liquid()
const tpl = engine.parseFileSync(resolve(__dirname, '../stub/root/foo.html'))
const engine = new cjs.Liquid({ root: resolve(__dirname, '../stub/root/') })
const tpl = engine.parseFileSync('foo.html')
const stream = engine.renderToNodeStream(tpl)
let html = ''
stream.on('data', (data: string) => { html += data })
Expand Down
19 changes: 18 additions & 1 deletion test/integration/liquid/liquid.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,13 +109,30 @@ 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/'],
extname: '.html'
})
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 () {
Expand All @@ -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')
Expand Down
Loading