Skip to content

Bug: Zplayer.Upstream extractor shadows UpstreamExtractor — wrong extractor wins for upstream.to URLs due to reverse-iteration dispatch #3016

Description

@mindflarevortx-maker

Steps to reproduce

  1. A provider returns a video URL on upstream.to (e.g. https://upstream.to/embed-abc123.html)
  2. loadExtractor() dispatch (ExtractorApi.kt:902–971) iterates extractors in reverse order (last-registered wins)
  3. Both UpstreamExtractor (library/src/commonMain/.../extractors/UpstreamExtractor.kt) and Zplayer.Upstream (library/src/commonMain/.../extractors/Zplayer.kt) match the upstream.to domain
  4. 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):

  1. Delete Zplayer.Upstream if UpstreamExtractor is the canonical one (preferred — fewer files, less confusion)
  2. Delete UpstreamExtractor if Zplayer.Upstream is newer
  3. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions