version: reject an empty debian revision
DebianVersion::parse accepted '1.0-' (empty revision after rsplit on the last hyphen), where dpkg rejects it with 'revision number is empty'; downstream filename construction produced garbage like 'foo_1.0-.dsc'. Keep the start-digit warning-only semantics of dpkg (no new check there) and the accepted '1.0--1' split.
This commit is contained in:
@@ -48,6 +48,12 @@ impl DebianVersion {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(rev) = &debian_revision {
|
if let Some(rev) = &debian_revision {
|
||||||
|
if rev.is_empty() {
|
||||||
|
// dpkg rejects a trailing hyphen: "bad syntax: revision
|
||||||
|
// number is empty". Native versions (no `-` at all) are
|
||||||
|
// handled above and stay valid.
|
||||||
|
return Err(format!("empty debian revision in '{}'", raw));
|
||||||
|
}
|
||||||
for c in rev.chars() {
|
for c in rev.chars() {
|
||||||
if !(c.is_ascii_alphanumeric() || matches!(c, '.' | '+' | '~') || !c.is_ascii()) {
|
if !(c.is_ascii_alphanumeric() || matches!(c, '.' | '+' | '~') || !c.is_ascii()) {
|
||||||
return Err(format!(
|
return Err(format!(
|
||||||
@@ -329,6 +335,27 @@ mod tests {
|
|||||||
assert!(DebianVersion::parse("1.0~rc1-2").is_ok());
|
assert!(DebianVersion::parse("1.0~rc1-2").is_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// dpkg rejects a trailing `-` ("bad syntax: revision number is
|
||||||
|
/// empty") but accepts `1.0--1`, where the revision is the text after
|
||||||
|
/// the *last* hyphen (upstream `1.0-` + revision `1`).
|
||||||
|
#[test]
|
||||||
|
fn version_empty_revision() {
|
||||||
|
let err = DebianVersion::parse("1.0-").unwrap_err();
|
||||||
|
assert!(err.contains("empty"), "unexpected message: {err}");
|
||||||
|
|
||||||
|
assert!(DebianVersion::parse("1.0-").is_err());
|
||||||
|
// Epoch variants take the same path.
|
||||||
|
assert!(DebianVersion::parse("3:1.0-").is_err());
|
||||||
|
assert!(DebianVersion::parse("1.0-1").is_ok());
|
||||||
|
// Native versions (no revision at all) are still fine.
|
||||||
|
assert!(DebianVersion::parse("1.0").is_ok());
|
||||||
|
assert!(DebianVersion::parse("3:1.0").is_ok());
|
||||||
|
|
||||||
|
let v = DebianVersion::parse("1.0--1").unwrap();
|
||||||
|
assert_eq!(v.upstream, "1.0-");
|
||||||
|
assert_eq!(v.debian_revision.as_deref(), Some("1"));
|
||||||
|
}
|
||||||
|
|
||||||
fn cmp_sign(a: &DebianVersion, b: &DebianVersion) -> i32 {
|
fn cmp_sign(a: &DebianVersion, b: &DebianVersion) -> i32 {
|
||||||
match a.cmp(b) {
|
match a.cmp(b) {
|
||||||
std::cmp::Ordering::Less => -1,
|
std::cmp::Ordering::Less => -1,
|
||||||
|
|||||||
Reference in New Issue
Block a user