diff --git a/scripts/utils.ts b/scripts/utils.ts index 20dc5dd402..4674abaea0 100644 --- a/scripts/utils.ts +++ b/scripts/utils.ts @@ -53,24 +53,29 @@ export function normalizeURL(url: string): string { } } +function isInsideDirectory(rootDir: string, target: string): boolean { + const relative = path.relative(rootDir, target) + + return ( + relative !== '' && + relative !== '..' && + !relative.startsWith(`..${path.sep}`) && + !path.isAbsolute(relative) + ) +} + export function getStoragePath(filepath: string, rootDir: string): string { const root = path.resolve(rootDir) - const candidate = path.resolve(filepath) - const candidateRelative = path.relative(root, candidate) - const target = - path.isAbsolute(filepath) || - (candidateRelative !== '..' && - !candidateRelative.startsWith(`..${path.sep}`) && - !path.isAbsolute(candidateRelative)) - ? candidate - : path.resolve(root, filepath) - const relative = path.relative(root, target) + const fromWorkspace = path.resolve(filepath) + const target = isInsideDirectory(root, fromWorkspace) + ? fromWorkspace + : path.resolve(root, filepath) - if (relative === '..' || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative)) { + if (!isInsideDirectory(root, target)) { throw new Error(`Filepath "${filepath}" is outside the storage directory`) } - return relative + return path.relative(root, target).split(path.sep).join('/') } export function truncate(string: string, limit: number = 100) { diff --git a/tests/__data__/input/playlist_format/nested/nested.m3u b/tests/__data__/input/playlist_format/nested/nested.m3u index 9e54864def..34fe6f1cce 100644 --- a/tests/__data__/input/playlist_format/nested/nested.m3u +++ b/tests/__data__/input/playlist_format/nested/nested.m3u @@ -1,5 +1,5 @@ -#EXTM3U -#EXTINF:-1 tvg-id="",Zulu (720p) -https://example.com/zulu.m3u8 -#EXTINF:-1 tvg-id="",Alpha (720p) -https://example.com/alpha.m3u8 +#EXTM3U +#EXTINF:-1 tvg-id="",Zulu (720p) +https://example.com/zulu.m3u8 +#EXTINF:-1 tvg-id="",Alpha (720p) +https://example.com/alpha.m3u8