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) and Zplayer.Upstream (library/src/commonMain/.../extractors/Zplayer.kt) match the upstream.to domain
- Due to reverse iteration,
Zplayer.Upstream wins
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.kt
library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Zplayer.kt (contains a nested Upstream class with mainUrl = "https://upstream.to")
Suggested fix (pick one):
- Delete
Zplayer.Upstream if UpstreamExtractor is the canonical one (preferred — fewer files, less confusion)
- Delete
UpstreamExtractor if Zplayer.Upstream is 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
Steps to reproduce
upstream.to(e.g.https://upstream.to/embed-abc123.html)loadExtractor()dispatch (ExtractorApi.kt:902–971) iterates extractors in reverse order (last-registered wins)UpstreamExtractor(library/src/commonMain/.../extractors/UpstreamExtractor.kt) andZplayer.Upstream(library/src/commonMain/.../extractors/Zplayer.kt) match theupstream.todomainZplayer.UpstreamwinsExpected behavior
The canonical
UpstreamExtractorshould 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 insideZplayer.kt) shadowsUpstreamExtractor. 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 thoughUpstreamExtractorwould 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):
Zplayer.UpstreamifUpstreamExtractoris the canonical one (preferred — fewer files, less confusion)UpstreamExtractorifZplayer.Upstreamis newerSeverity: Medium (silent quality degradation; depends on which extractor is actually working)
Also affects:
VidStack.kthas a similar issue — localobject AesHelpershadows the sharedhelper/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