What version of HLS.js are you using?
latest (master branch)
What browser (including version) are you using?
All
What OS (including version) are you using?
All
Test stream
No response
Configuration
Additional player setup steps
Bug Report: mapPartIntersection off-by-one error causes incorrect delta calculation
Environment
- hls.js version: latest (master branch)
- OS: All
- Browser: All
Detailed description
In src/utils/level-helper.ts, the mapPartIntersection function has an off-by-one error in its loop condition. The loop uses i <= len instead of i < len, causing an extra iteration where oldParts[i] is undefined.
Location
File: src/utils/level-helper.ts
Line: 391
Current code
export function mapPartIntersection(
oldParts: Part[] | null,
newParts: Part[] | null,
intersectionFn: PartIntersection,
) {
if (oldParts && newParts) {
let delta = 0;
for (let i = 0, len = oldParts.length; i <= len; i++) { // BUG: i <= len
const oldPart = oldParts[i];
const newPart = newParts[i + delta];
if (
(oldPart as any) &&
(newPart as any) &&
oldPart.index === newPart.index &&
oldPart.fragment.sn === newPart.fragment.sn
) {
intersectionFn(oldPart, newPart);
} else {
delta--;
}
}
}
}
Expected behavior
The loop should iterate from i = 0 to i < len (not i <= len). When i === len, oldParts[i] is undefined, which triggers the else branch and incorrectly decrements delta by 1.
Impact
This function is called during playlist delta updates to merge part data between old and new playlists (mapPartIntersection is called in mergeDetails). The incorrect delta value on the final iteration could potentially affect part matching behavior for subsequent iterations if the loop logic were to be extended, though in practice the loop ends immediately after. The as any type casts suppress TypeScript warnings that would normally catch this issue.
Proposed fix
Change line 391 from:
for (let i = 0, len = oldParts.length; i <= len; i++) {
To:
for (let i = 0, len = oldParts.length; i < len; i++) {
Reproduction
The existing unit test in tests/unit/controller/level-helper.ts passes because the test case has equal-length arrays with all parts matching, so the extra iteration doesn't change the number of intersection callback calls. However, the delta variable ends up at -1 instead of 0 after the loop completes.
Checklist
Steps to reproduce
The existing unit test in tests/unit/controller/level-helper.ts passes because the test case has equal-length arrays with all parts matching, so the extra iteration doesn't change the number of intersection callback calls. However, the delta variable ends up at -1 instead of 0 after the loop completes.
Expected behaviour
The loop should iterate from i = 0 to i < len (not i <= len). When i === len, oldParts[i] is undefined, which triggers the else branch and incorrectly decrements delta by 1.
What actually happened?
### Console output
```shell
Chrome media internals output
What version of HLS.js are you using?
latest (master branch)
What browser (including version) are you using?
All
What OS (including version) are you using?
All
Test stream
No response
Configuration
Additional player setup steps
Bug Report:
mapPartIntersectionoff-by-one error causes incorrect delta calculationEnvironment
Detailed description
In
src/utils/level-helper.ts, themapPartIntersectionfunction has an off-by-one error in its loop condition. The loop usesi <= leninstead ofi < len, causing an extra iteration whereoldParts[i]isundefined.Location
File:
src/utils/level-helper.tsLine: 391
Current code
Expected behavior
The loop should iterate from
i = 0toi < len(noti <= len). Wheni === len,oldParts[i]isundefined, which triggers theelsebranch and incorrectly decrementsdeltaby 1.Impact
This function is called during playlist delta updates to merge part data between old and new playlists (
mapPartIntersectionis called inmergeDetails). The incorrectdeltavalue on the final iteration could potentially affect part matching behavior for subsequent iterations if the loop logic were to be extended, though in practice the loop ends immediately after. Theas anytype casts suppress TypeScript warnings that would normally catch this issue.Proposed fix
Change line 391 from:
To:
Reproduction
The existing unit test in
tests/unit/controller/level-helper.tspasses because the test case has equal-length arrays with all parts matching, so the extra iteration doesn't change the number of intersection callback calls. However, thedeltavariable ends up at-1instead of0after the loop completes.Checklist
Steps to reproduce
The existing unit test in
tests/unit/controller/level-helper.tspasses because the test case has equal-length arrays with all parts matching, so the extra iteration doesn't change the number of intersection callback calls. However, thedeltavariable ends up at-1instead of0after the loop completes.Expected behaviour
The loop should iterate from
i = 0toi < len(noti <= len). Wheni === len,oldParts[i]isundefined, which triggers theelsebranch and incorrectly decrementsdeltaby 1.What actually happened?
Chrome media internals output