Split __init__.py into focused modules #30

Merged
coding-agent-marvin8 merged 0 commits from refs/pull/30/head into main 2026-06-24 09:04:27 +00:00
coding-agent-marvin8 commented 2026-06-24 08:22:43 +00:00 (Migrated from codeberg.org)

Splits the 1320-line __init__.py into six focused single-responsibility modules with no behaviour changes.

Modules created

Module Responsibility
models.py Three dataclasses (VulnAdvisory, PyPIPackageData, DependencyResult)
pypi.py PyPI HTTP client and response parsers
version.py All version classification, aged-fallback, library-constraint logic
vulns.py Vulnerability filtering and _norm_pkg
render.py Text and JSON rendering
checker.py Dependency processing pipeline

__init__.py is reduced to ~190 lines of thin CLI glue.

Notes

  • Pure code relocation — no logic changes
  • Mock patch paths in tests updated to point at new canonical module locations (zaojun.checker.*)
  • Module dependency graph is acyclic: modelspypi/version/vulns/renderchecker__init__
  • 291 tests pass across Python 3.11–3.14

Closes #29

Splits the 1320-line `__init__.py` into six focused single-responsibility modules with no behaviour changes. ## Modules created | Module | Responsibility | |---|---| | `models.py` | Three dataclasses (`VulnAdvisory`, `PyPIPackageData`, `DependencyResult`) | | `pypi.py` | PyPI HTTP client and response parsers | | `version.py` | All version classification, aged-fallback, library-constraint logic | | `vulns.py` | Vulnerability filtering and `_norm_pkg` | | `render.py` | Text and JSON rendering | | `checker.py` | Dependency processing pipeline | `__init__.py` is reduced to ~190 lines of thin CLI glue. ## Notes - Pure code relocation — no logic changes - Mock patch paths in tests updated to point at new canonical module locations (`zaojun.checker.*`) - Module dependency graph is acyclic: `models` ← `pypi/version/vulns/render` ← `checker` ← `__init__` - 291 tests pass across Python 3.11–3.14 Closes #29
coding-agent-marvin8 commented 2026-06-24 08:32:07 +00:00 (Migrated from codeberg.org)

src/zaojun/pypi.py line 93

A03: Injection / A10: SSRF – The package_name is used directly in URL construction without sanitization…

🔴 Declining — package_name always reaches this function via parse_dependency() in checker.py, which parses the raw string through packaging.requirements.Requirement(). A PEP 508 package name cannot contain ../, /, or \, so a path-traversal payload would raise InvalidRequirement and never reach get_latest_pypi_version. No sanitisation is needed at this layer; the validation happens at the boundary.

[`src/zaojun/pypi.py` line 93](https://codeberg.org/marvin8/zaojun/pulls/30#issuecomment-17991614) > A03: Injection / A10: SSRF – The package_name is used directly in URL construction without sanitization… 🔴 Declining — `package_name` always reaches this function via `parse_dependency()` in `checker.py`, which parses the raw string through `packaging.requirements.Requirement()`. A PEP 508 package name cannot contain `../`, `/`, or `\`, so a path-traversal payload would raise `InvalidRequirement` and never reach `get_latest_pypi_version`. No sanitisation is needed at this layer; the validation happens at the boundary.
coding-agent-marvin8 commented 2026-06-24 08:32:14 +00:00 (Migrated from codeberg.org)

src/zaojun/pypi.py line 93

A10: SSRF – The index_url parameter is user-controlled (from CLI or config) and is used to construct the request URL without validation…

🔴 Declining — --index-url is intentionally user-controlled by design. zaojun explicitly supports private and corporate PyPI mirrors (e.g. Artifactory, Nexus, devpi) via this flag. This is a local developer CLI tool, not a web service; the person running it is also the person controlling --index-url. An allowlist would break legitimate use cases and add no security value in this threat model.

[`src/zaojun/pypi.py` line 93](https://codeberg.org/marvin8/zaojun/pulls/30#issuecomment-17991617) > A10: SSRF – The index_url parameter is user-controlled (from CLI or config) and is used to construct the request URL without validation… 🔴 Declining — `--index-url` is intentionally user-controlled by design. zaojun explicitly supports private and corporate PyPI mirrors (e.g. Artifactory, Nexus, devpi) via this flag. This is a local developer CLI tool, not a web service; the person running it is also the person controlling `--index-url`. An allowlist would break legitimate use cases and add no security value in this threat model.
Sign in to join this conversation.
No description provided.