Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

Empty string accepted as a valid version in Maven/NuGet/RubyGems, and sorts as minimum

未关闭
#204 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

@MGpromax 已经在做这个了。

开始于 2026年8月25日。

  • #209 来自 @MGpromax —— 未关闭

评估

难度
3/5
预计耗时
1-2 天
新手友好度
70/100
Issue 类型
缺陷
描述清晰度
基本清楚
活跃度
冷清
技术栈
python
领域
backend

调研方向

该 issue 指向 univers.versions 以及 MavenVersion、NugetVersion、RubygemsVersion、SemverVersion 和 PypiVersion 类,因此请检查这些实现对空字符串的处理和比较行为。比较 SemVer/PyPI 当前如何拒绝 "",然后据此统一调整这三个不一致的 scheme,并添加涵盖 Version("") 构造以及跨 scheme 排序的测试。先使用提供的 Python snippets 复现,然后运行相关的版本解析/比较测试子集;当空输入具有一种一致的结果,并且跨 scheme 测试在没有静默的最小值排序行为的情况下通过时,即完成。

由索引模型根据 Issue 内容生成。

描述

Summary

MavenVersion, NugetVersion and RubygemsVersion accept the empty string "" as a valid version, while SemverVersion, PypiVersion and others correctly raise InvalidVersion. Worse, the accepted empty version then sorts below every real version, so downstream range logic silently produces a confident but wrong answer rather than failing.

Tested with univers 32.0.1 on CPython 3.13.

Reproducer
from univers.versions import (
    MavenVersion, NugetVersion, RubygemsVersion, SemverVersion, PypiVersion,
)

# Accepted (inconsistent):
MavenVersion("")     # -> MavenVersion(string='')
NugetVersion("")     # -> NugetVersion(string='')
RubygemsVersion("")  # -> RubygemsVersion(string='')

# Correctly rejected:
SemverVersion("")    # -> InvalidVersion
PypiVersion("")      # -> InvalidVersion

Three different behaviours across schemes, none of them an error for the first group:

MavenVersion("") < MavenVersion("0.0.1")     # True  -- sorts as minimum
RubygemsVersion("") < RubygemsVersion("0.0.1")  # True  -- sorts as minimum
NugetVersion("") < NugetVersion("0.0.1")     # TypeError:
#   '<' not supported between instances of 'NoneType' and 'Version'

So NugetVersion accepts the value at construction and then raises on comparison, which is a third distinct outcome.

Why the silent ordering is the harmful part

Consider an OSV range built from a malformed advisory:

{"type": "ECOSYSTEM", "events": [{"introduced": "0"}, {"fixed": ""}]}

Because MavenVersion("") is accepted and sorts as the minimum, the interval [0, "") evaluates to the empty set. Code comparing this against the advisory's previous range concludes, with no error and no warning, that the affected set was reduced to nothing — i.e. that the range was retracted.

We hit this in a measurement study over the git history of the GitHub Advisory Database. GHSA emitted schema-invalid {"fixed": ""} into 2,107 advisory revisions during a single week in March 2023. Because three of the ecosystems we needed silently accepted it, our comparator produced roughly 1,000 spurious "affected range narrowed" events in Maven alone — a confidently wrong classification, not a crash we could catch. The npm/PyPI/Go paths were unaffected precisely because they raise InvalidVersion.

The general hazard: a caller cannot rely on "the version parsed successfully" as a validity check, and the failure is scheme-dependent, so it shows up only in some ecosystems and looks like real data.

Suggested resolution

Whatever the decision on leniency, the three schemes should agree with each other and with the rest of the library. Options, in our order of preference:

  1. Raise InvalidVersion for "" in MavenVersion, NugetVersion and RubygemsVersion, matching SemverVersion/PypiVersion. An empty string is not a version in any of these ecosystems' specs.
  2. If empty is to be accepted deliberately (see #10), make it consistent across all schemes and define its ordering explicitly rather than letting it fall out of the attribute tuple — the current NugetVersion TypeError on comparison shows the ordering is not well-defined today.

A test asserting identical "" behaviour across every Version subclass would prevent the schemes drifting apart again.

Related
  • #10 parse_version() should accept None and empty strings — related but pointing the other way; this report is about the inconsistency between schemes and the silently wrong ordering, independent of which behaviour is chosen. The comment there that "None or empty would be the same... I am not sure this would make any sense" suggests option 1 is the intended direction.
  • #203 Do not allow creation of VersionRange with empty constraint — same family of problem one level up, at the range rather than the version.

Happy to send a PR for option 1 plus the cross-scheme test if that is the direction you'd like.

主要语言
Python
星标
50
派生
31
PR 合并指标
30 天内没有已合并 PR

环境准备

这个项目没有提供开发容器、Dockerfile 或贡献指南,环境需要你自己搭建:先看它的 README,通用步骤见我们的新手贡献指南。

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

aboutcode-org/univers 的其他 Issue

查看 aboutcode-org/univers 的全部 Issue

相似的 Issue

更多 Python Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。