M1: reject leading-zero numeric prerelease versions

This commit is contained in:
Mex authored and GitHub committed 2026-11-14 21:35:21 +01:00
1 parent b0c77ebd6a
commit 10fef35fe6
1 file changed
+18 -1
+18 -1
View File
@@ -49,7 +49,12 @@ pub fn validate(v: &str) -> Result<(), String> {
return bad();
}
if let Some(p) = pre
&& (p.is_empty() || p.split('.').any(|id| id.is_empty() || !id.bytes().all(|b| b.is_ascii_alphanumeric() || b == b'-')))
&& (p.is_empty()
|| p.split('.').any(|id| {
id.is_empty()
|| !id.bytes().all(|b| b.is_ascii_alphanumeric() || b == b'-')
|| (id.len() > 1 && id.starts_with('0') && id.bytes().all(|b| b.is_ascii_digit()))
}))
{
return bad();
}
@@ -144,6 +149,18 @@ mod tests {
assert!(replace(MANIFEST, "nope").is_err());
}
#[test]
fn numeric_prerelease_identifiers_have_no_leading_zeroes() {
for bad in ["1.0.0-00", "1.0.0-01", "1.0.0-rc.01"] {
assert!(validate(bad).is_err(), "{bad}");
assert!(replace(MANIFEST, bad).is_err(), "{bad} must not reach the manifest");
}
for ok in ["1.0.0-0", "1.0.0-rc.0", "1.0.0-01a", "1.0.0-0-1"] {
assert!(validate(ok).is_ok(), "{ok}");
assert_eq!(read(&replace(MANIFEST, ok).unwrap()).unwrap(), ok);
}
}
#[test]
fn the_real_manifest_has_a_valid_version() {
let text = std::fs::read_to_string(crate::root().join("Cargo.toml")).unwrap();