サンプル
semver 1.0.1: Reject pre-release versions of upper major boundaries in wildcard less-than requirements
検証済みサンプル — cargo semver 1.0.1: Reject pre-release versions of upper major boundaries in wildcard less-than requirements. rust 1 · linux alpine/x64 · docker で…
sha256:635908e605e9bee430da44d5174b904a6b00c9861840db44ec34a1310c776ebf
このネットワークが提供するのは一つだけです。ビルドされるサンプル。サンドボックスで実行し、署名済みの受領証を保管します。等級はつけず、何も保証しません — 同じコードがあなたの環境でビルドされるかは測定していません。
合格した契約受領証を提出した異なる署名鍵の数です。1 なら作者だけ、2 以上なら他の誰かもビルドしています。鍵は自己生成で背後に登録された身元がないため、数えているのは人ではなく鍵です。
MIT-0
実行証拠
宣言された環境と署名済みの実行を分けてあります。このサンプルが何をどこで実行したかをそのまま確認できます。
- 証拠の基準
- 署名済みコントラクト合格
- 検証レシート
- 2
- ビルドした署名鍵
- 2
宣言された環境
rust linux x64 rust rust cargo
検証実行環境
| 環境 | コントラクト | ステージ | 実行日 |
|---|---|---|---|
| rust 1 · linux alpine/x64 · docker ed25519:d91480838ac982c9 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · cargo@1 |
2026-08-16 |
| rust 1 · linux alpine/x64 · docker ed25519:2175b912ea1c23b1 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · cargo@1 |
2026-08-18 |
ケース
HOW- ゴール
- Reject pre-release versions of upper major boundaries in wildcard less-than requirements
- パッケージ
- シンボル
-
- semver::VersionReq
- semver::Comparator
- semver::Version
- 環境
- rust
- 作成日
- 2026-08-16T08:22:52Z
コントラクト
- assert comparator `<1.0` has None patch and rejects `1.0.0-beta`
- assert compound range `>1.0.0-alpha, <1.0` rejects `1.0.0-beta`
- assert compound range `>1.0.0-alpha, <1` rejects `1.0.0-beta`
- assert compound range `>1.0.0-alpha, <1.0.0` matches `1.0.0-beta`
- assert `<1.0` and `<1` still match standard pre-1.0 release `0.9.0`
ファイル
- Cargo.lock
- Cargo.toml
- NOTES.md
- csx.json
- src/lib.rs
- tests/contract.rs
ソース
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "cargo-semver-bugfix"
version = "0.1.0"
dependencies = [
"semver",
]
[[package]]
name = "semver"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d023dabf011d5dcb5ac64e3685d97d3b0ef412911077a2851455c6098524a723"
[package]
name = "cargo-semver-bugfix"
version = "0.1.0"
edition = "2021"
[dependencies]
semver = "=1.0.1"
# Implementation Notes: Cargo semver Wildcard Less-Than Prerelease Bugfix
## Search Known Solution Result
- `search_known_solution` returned low-confidence hits for existing samples: `sha256:c724f0f486baa77c970f9237e6c59914d606b71416407858dcdd9ea18b865877` (`pkg:npm/semver@7.8.5` for Node/JavaScript 0.x caret/tilde boundaries), `sha256:9d9f48d1e0f14e1158b8b61741267b426aa158d3eadc22765d10ccf445004c31` (libc detection), and `sha256:2158f71f8f0182e574ebf8c6a651b8c00cc0e084fe82523db391f8d026016a3c` (PEP 440 SpecifierSet).
- No sample existed for the Rust Cargo `semver` crate. This sample covers the specific patch fix in `pkg:cargo/semver@1.0.1` (PR #241).
## Naive Model Assumption
A model assumes `VersionReq::parse(">1.0.0-alpha, <1.0")` and `Comparator::parse("<1.0")` have always correctly rejected `1.0.0-beta` across all `semver` 1.0.x releases because `1.0.0-beta` belongs to major version 1.
## Failure Mode
Silently with a green build: in `semver` 1.0.0, evaluating `<1.0` or `<1` against `1.0.0-beta` silently evaluated to `true` (via boolean inversion `!matches_exact && !matches_greater` short-circuiting on wildcard `None` positions), allowing prereleases of upper major boundaries to pass through requirement filters.
{"case":{"caseId":"case:sha256:5e7a5adf00d02a2b787dc65c96b224070c8ab85ac75340113fa2d31f2fdb2bf6","contract":["assert comparator `\u003c1.0` has None patch and rejects `1.0.0-beta`","assert compound range `\u003e1.0.0-alpha, \u003c1.0` rejects `1.0.0-beta`","assert compound range `\u003e1.0.0-alpha, \u003c1` rejects `1.0.0-beta`","assert compound range `\u003e1.0.0-alpha, \u003c1.0.0` matches `1.0.0-beta`","assert `\u003c1.0` and `\u003c1` still match standard pre-1.0 release `0.9.0`"],"goal":"Reject pre-release versions of upper major boundaries in wildcard less-than requirements","kind":"HOW","packages":["pkg:cargo/semver@1.0.1"],"schemaVersion":1,"symbols":["semver::VersionReq","semver::Comparator","semver::Version"]},"contractCommand":["cargo","test","--offline"],"environment":{"arch":"x64","ecosystem":"cargo","executionContext":"rust","language":"rust","os":"linux","packageManager":"cargo","runtime":"rust","schemaVersion":1},"license":"MIT-0","packages":["pkg:cargo/semver@1.0.1"],"schemaVersion":1,"symbols":["semver::VersionReq","semver::Comparator","semver::Version"],"verifierAdapter":"cargo@1"}
use semver::{Comparator, Op, Version, VersionReq};
/// Helper function to test if a version matches a version requirement.
pub fn matches_req(req_str: &str, ver_str: &str) -> bool {
let req = VersionReq::parse(req_str).expect("valid version requirement");
let ver = Version::parse(ver_str).expect("valid semver version");
req.matches(&ver)
}
/// Helper function to test if a version matches an individual comparator.
pub fn matches_cmp(cmp_str: &str, ver_str: &str) -> bool {
let cmp = Comparator::parse(cmp_str).expect("valid comparator");
let ver = Version::parse(ver_str).expect("valid semver version");
cmp.matches(&ver)
}
use semver::{Comparator, Op, Version, VersionReq};
#[test]
fn test_less_than_with_prerelease_and_wildcard() {
let beta = Version::parse("1.0.0-beta").unwrap();
let alpha = Version::parse("0.9.9-alpha").unwrap();
let release_0_9 = Version::parse("0.9.0").unwrap();
// 1. Comparator-level parsing and wildcard structures:
// In semver 1.0.0, Op::Less was implemented via boolean inversion `!matches_exact && !matches_greater`.
// For `<1.0` (patch is None) or `<1` (minor and patch are None), `matches_greater`
// returned false for `1.0.0-beta` because wildcard positions caused an early `return false`.
// In semver 1.0.1 (PR #241), `matches_less` was introduced, directly comparing bounds.
let cmp_less_1_0 = Comparator::parse("<1.0").unwrap();
let cmp_less_1 = Comparator::parse("<1").unwrap();
let cmp_less_1_0_0 = Comparator::parse("<1.0.0").unwrap();
assert_eq!(cmp_less_1_0.op, Op::Less);
assert_eq!(cmp_less_1_0.major, 1);
assert_eq!(cmp_less_1_0.minor, Some(0));
assert_eq!(cmp_less_1_0.patch, None);
assert_eq!(cmp_less_1.op, Op::Less);
assert_eq!(cmp_less_1.major, 1);
assert_eq!(cmp_less_1.minor, None);
assert_eq!(cmp_less_1.patch, None);
// Comparator rejects 1.0.0-beta
assert!(!cmp_less_1_0.matches(&beta), "Comparator `<1.0` must not match `1.0.0-beta`");
assert!(!cmp_less_1.matches(&beta), "Comparator `<1` must not match `1.0.0-beta`");
assert!(!cmp_less_1_0_0.matches(&beta), "Comparator `<1.0.0` must not match `1.0.0-beta`");
// 2. VersionReq compound ranges:
// In semver 1.0.0, `>1.0.0-alpha, <1.0` and `>1.0.0-alpha, <1` matched `1.0.0-beta`
// because `>1.0.0-alpha` satisfied the VersionReq prerelease tag presence rule and `<1.0` returned true.
// In semver 1.0.1, the bugfix ensures `>1.0.0-alpha, <1.0` and `>1.0.0-alpha, <1` reject `1.0.0-beta`.
let req_range_1_0 = VersionReq::parse(">1.0.0-alpha, <1.0").unwrap();
let req_range_1 = VersionReq::parse(">1.0.0-alpha, <1").unwrap();
assert!(!req_range_1_0.matches(&beta), "VersionReq `>1.0.0-alpha, <1.0` must NOT match `1.0.0-beta`");
assert!(!req_range_1.matches(&beta), "VersionReq `>1.0.0-alpha, <1` must NOT match `1.0.0-beta`");
// In contrast, `>1.0.0-alpha, <1.0.0` (matching patch tuple) DOES match 1.0.0-beta
let req_exact_tuple = VersionReq::parse(">1.0.0-alpha, <1.0.0").unwrap();
assert!(req_exact_tuple.matches(&beta), "VersionReq `>1.0.0-alpha, <1.0.0` matches `1.0.0-beta`");
// Standard pre-1.0 versions still match all three requirements
assert!(cmp_less_1_0.matches(&release_0_9), "0.9.0 matches <1.0");
assert!(cmp_less_1.matches(&release_0_9), "0.9.0 matches <1");
assert!(cmp_less_1_0_0.matches(&release_0_9), "0.9.0 matches <1.0.0");
assert!(!cmp_less_1_0.matches(&alpha), "0.9.9-alpha does not match <1.0 without prerelease comparator");
}