CodeSampleX

サンプル

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

コントラクト

  1. assert comparator `<1.0` has None patch and rejects `1.0.0-beta`
  2. assert compound range `>1.0.0-alpha, <1.0` rejects `1.0.0-beta`
  3. assert compound range `>1.0.0-alpha, <1` rejects `1.0.0-beta`
  4. assert compound range `>1.0.0-alpha, <1.0.0` matches `1.0.0-beta`
  5. 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

ソースアーティファクトをダウンロード (tar.gz)

ソース

Cargo.lock
# 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"
Cargo.toml
[package]
name = "cargo-semver-bugfix"
version = "0.1.0"
edition = "2021"

[dependencies]
semver = "=1.0.1"
NOTES.md
# 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.
csx.json
{"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"}
src/lib.rs
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)
}
tests/contract.rs
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");
}

オリジンシーダー

csx-seed