mirror of
https://github.com/iptv-org/iptv
synced 2026-09-09 05:17:04 -04:00
fix: harden getStoragePath and keep CRLF endings
- Normalize the returned path to forward slashes so it matches what Storage.list() (glob) returns, instead of leaking `\` on Windows. - Treat the storage root itself as "not inside", so passing a directory no longer yields an empty path that Storage.load() would open as a dir. - Extract the containment check into isInsideDirectory() and drop the redundant isAbsolute(filepath) branch (path.resolve already handles it). - Restore the repository's CRLF line endings in the nested fixture.
This commit is contained in:
+17
-12
@@ -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 {
|
export function getStoragePath(filepath: string, rootDir: string): string {
|
||||||
const root = path.resolve(rootDir)
|
const root = path.resolve(rootDir)
|
||||||
const candidate = path.resolve(filepath)
|
const fromWorkspace = path.resolve(filepath)
|
||||||
const candidateRelative = path.relative(root, candidate)
|
const target = isInsideDirectory(root, fromWorkspace)
|
||||||
const target =
|
? fromWorkspace
|
||||||
path.isAbsolute(filepath) ||
|
: path.resolve(root, filepath)
|
||||||
(candidateRelative !== '..' &&
|
|
||||||
!candidateRelative.startsWith(`..${path.sep}`) &&
|
|
||||||
!path.isAbsolute(candidateRelative))
|
|
||||||
? candidate
|
|
||||||
: path.resolve(root, filepath)
|
|
||||||
const relative = path.relative(root, target)
|
|
||||||
|
|
||||||
if (relative === '..' || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative)) {
|
if (!isInsideDirectory(root, target)) {
|
||||||
throw new Error(`Filepath "${filepath}" is outside the storage directory`)
|
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) {
|
export function truncate(string: string, limit: number = 100) {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#EXTM3U
|
#EXTM3U
|
||||||
#EXTINF:-1 tvg-id="",Zulu (720p)
|
#EXTINF:-1 tvg-id="",Zulu (720p)
|
||||||
https://example.com/zulu.m3u8
|
https://example.com/zulu.m3u8
|
||||||
#EXTINF:-1 tvg-id="",Alpha (720p)
|
#EXTINF:-1 tvg-id="",Alpha (720p)
|
||||||
https://example.com/alpha.m3u8
|
https://example.com/alpha.m3u8
|
||||||
|
|||||||
Reference in New Issue
Block a user