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
+6
View File
@@ -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/)
})
})
})
+4 -7
View File
@@ -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)