Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions tuf/src/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3871,6 +3871,16 @@ mod test {
assert!(serde_json::from_value::<TargetsMetadata>(targets).is_err());
}

#[test]
fn deserialize_json_root_accepts_1_0_x_spec_version() {
let mut root = make_root();
let _ = root
.as_object_mut()
.unwrap()
.insert("spec_version".into(), json!("1.0.31"));
assert!(serde_json::from_value::<RootMetadata>(root).is_ok());
}

// Refuse to deserialize delegations with duplicated roles
#[test]
fn deserialize_json_delegations_duplicated_roles() {
Expand Down
33 changes: 29 additions & 4 deletions tuf/src/pouf/pouf1/shims.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,35 @@ use {

const SPEC_VERSION: &str = "1.0";

// Ensure the given spec version matches our spec version.
fn is_semver_numeric_identifier(identifier: &str) -> bool {
if identifier.is_empty() {
return false;
}

if !identifier.bytes().all(|b| b.is_ascii_digit()) {
return false;
}

identifier == "0" || !identifier.starts_with('0')
}

// Ensure the given spec version stays within the supported TUF 1.0.x line.
//
// We also need to handle the literal "1.0" here, despite that fact that it is not a valid version
// according to the SemVer spec, because it is already baked into some of the old roots.
fn valid_spec_version(other: &str) -> bool {
matches!(other, "1.0" | "1.0.0")
if other == SPEC_VERSION {
return true;
}

let Some(patch) = other
.strip_prefix(SPEC_VERSION)
.and_then(|suffix| suffix.strip_prefix('.'))
else {
return false;
};

is_semver_numeric_identifier(patch)
}

fn parse_datetime(ts: &str) -> Result<DateTime<Utc>> {
Expand Down Expand Up @@ -637,13 +660,15 @@ mod test {

#[test]
fn spec_version_validation() {
let valid_spec_versions = ["1.0.0", "1.0"];
let valid_spec_versions = ["1.0.0", "1.0", "1.0.1", "1.0.34", "1.0.999"];

for version in valid_spec_versions {
assert!(valid_spec_version(version), "{:?} should be valid", version);
}

let invalid_spec_versions = ["1.0.1", "1.1.0", "2.0.0", "3.0"];
let invalid_spec_versions = [
"1.1.0", "2.0.0", "3.0", "1", "1.1", "1.0.beta", "1.0.0.1", "1.0.00", "1.0.01",
];

for version in invalid_spec_versions {
assert!(
Expand Down
Loading