recloudstream / recloudstream/cloudstream
Bug: `Zplayer.Upstream` extractor shadows `UpstreamExtractor` — wrong extractor wins for upstream.to URLs due to reverse-iteration dispatch
Nobody has claimed this yet.
- Dominant language
- Kotlin
- Stars
- 10.7k
- Forks
- 1.1k
- Avg merge
- 1d 23h
- Merged PRs (30d)
- 15
Description
Steps to reproduce
- A provider returns a video URL on
upstream.to(e.g.https://upstream.to/embed-abc123.html) loadExtractor()dispatch (ExtractorApi.kt:902–971) iterates extractors in reverse order (last-registered wins)- Both
UpstreamExtractor(library/src/commonMain/.../extractors/UpstreamExtractor.kt) andZplayer.Upstream(library/src/commonMain/.../extractors/Zplayer.kt) match theupstream.todomain - Due to reverse iteration,
Zplayer.Upstreamwins
Expected behavior
The canonical UpstreamExtractor should handle upstream.to URLs, OR the two should be merged/unified. Having two extractors for the same domain with different extraction logic is a footgun.
Actual behavior
Zplayer.Upstream (defined as a nested class inside Zplayer.kt) shadows UpstreamExtractor. Whichever was registered last wins — and registration order depends on file loading order, which is fragile.
If Zplayer.Upstream's extraction logic is outdated or broken, upstream.to URLs silently fail even though UpstreamExtractor would have worked.
Cloudstream version and commit hash
4.7.0 bfb85ca
Android version
Found via static code analysis. Reproducible on any Android version when an extension returns an upstream.to URL.
Logcat
N/A — silent failure or wrong extractor runs.
Other details
Location:
library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/UpstreamExtractor.ktlibrary/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Zplayer.kt(contains a nestedUpstreamclass withmainUrl = "https://upstream.to")
Suggested fix (pick one):
- Delete
Zplayer.UpstreamifUpstreamExtractoris the canonical one (preferred — fewer files, less confusion) - Delete
UpstreamExtractorifZplayer.Upstreamis newer - Rename one to handle a different domain if they're actually for different sites
Severity: Medium (silent quality degradation; depends on which extractor is actually working)
Also affects: VidStack.kt has a similar issue — local object AesHelper shadows the shared helper/AesHelper.kt. Worth checking together.
Discovered during: Static code analysis of the CloudStream codebase for the CloudStream Web port (https://github.com/mindflarevortx-maker/cloudstream-web).
Acknowledgements
- I am sure my issue is related to the app and NOT some extension.
- I have searched the existing issues and this is a new ticket, NOT a duplicate or related to another open issue.
- I have written a short but informative title.
- I have updated the app to pre-release version Latest.
- I will fill out all of the requested information in this form.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Read ExtractorApi.kt:902–971 to confirm reverse-order dispatch, then compare UpstreamExtractor.kt with the nested Upstream class in Zplayer.kt. Determine which implementation is canonical and inspect the similarly named AesHelper entries in VidStack.kt and helper/AesHelper.kt if investigating the related issue. Done means upstream.to URLs have one unambiguous extractor without shadowing.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- kotlin
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100