mirror of
https://github.com/iptv-org/iptv
synced 2026-10-25 20:38:55 -04:00
fix: keep %20, %2F and %23 encoded when playlist:format normalizes links
This commit is contained in:
3 files changed
+34
-2
No files matched your search
+13
-2
@@ -46,11 +46,22 @@ export function normalizeURL(url: string): string {
|
|||||||
return url.replace(/\s/g, '+')
|
return url.replace(/\s/g, '+')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let decoded: string
|
||||||
try {
|
try {
|
||||||
return decodeURIComponent(normalized).replace(/\s/g, '+')
|
// decodeURI keeps escapes like %2F, %3F and %23, which would change the URL if decoded
|
||||||
|
decoded = decodeURI(normalized)
|
||||||
} catch {
|
} catch {
|
||||||
return normalized.replace(/\s/g, '+')
|
decoded = normalized
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// "+" means a space only in the query; in the path it is a plus sign
|
||||||
|
const queryStart = decoded.indexOf('?')
|
||||||
|
if (queryStart === -1) return decoded.replace(/\s/g, '%20')
|
||||||
|
|
||||||
|
return (
|
||||||
|
decoded.slice(0, queryStart).replace(/\s/g, '%20') +
|
||||||
|
decoded.slice(queryStart).replace(/\s/g, '+')
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function isInsideDirectory(rootDir: string, target: string): boolean {
|
function isInsideDirectory(rootDir: string, target: string): boolean {
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
#EXTM3U
|
||||||
|
#EXTINF:-1 tvg-id="",Example Path Space (720p)
|
||||||
|
http://example.com/TVP%20Wilno%20HD/index.m3u8
|
||||||
|
#EXTINF:-1 tvg-id="",Example Path Slash (720p)
|
||||||
|
http://example.com/a%2Fb/index.m3u8
|
||||||
|
#EXTINF:-1 tvg-id="",Example Query Hash (720p)
|
||||||
|
http://example.com/index.m3u8?id=1%232
|
||||||
@@ -54,6 +54,20 @@ describe('playlist:format', () => {
|
|||||||
'http://example.com/a%ZZ'
|
'http://example.com/a%ZZ'
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('keeps percent escapes whose decoding would change the link', () => {
|
||||||
|
fs.emptyDirSync('tests/__data__/output')
|
||||||
|
fs.copySync('tests/__data__/input/playlist_normalize', 'tests/__data__/output/streams')
|
||||||
|
|
||||||
|
const cmd =
|
||||||
|
'cross-env STREAMS_DIR=tests/__data__/output/streams DATA_DIR=tests/__data__/input/data npm run playlist:format'
|
||||||
|
execSync(cmd, { encoding: 'utf8' })
|
||||||
|
|
||||||
|
const output = content('tests/__data__/output/streams/reserved_escapes.m3u')
|
||||||
|
expect(output).toContain('http://example.com/TVP%20Wilno%20HD/index.m3u8')
|
||||||
|
expect(output).toContain('http://example.com/a%2Fb/index.m3u8')
|
||||||
|
expect(output).toContain('http://example.com/index.m3u8?id=1%232')
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
function content(filepath: string) {
|
function content(filepath: string) {
|
||||||
|
|||||||
Reference in new issue
Block a user