Skip to content

Commit

Permalink
Metadata API: Accept X.Y spec_version
Browse files Browse the repository at this point in the history
All TUF implementations used to use "1.0" as the spec version and most
of them have never modified that value since.

Accept two-digit spec_version for legacy compatibility: it is strictly
speaking against the current spec (which requires semver) but there
should be no harm in doing this and it allows us to deserialize
metadata generated by e.g. go-tuf.

Fixes #1751

Signed-off-by: Jussi Kukkonen <[email protected]>
  • Loading branch information
Jussi Kukkonen committed Jan 26, 2022
1 parent e0736d6 commit 4cd9e15
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 8 deletions.
6 changes: 4 additions & 2 deletions tests/test_metadata_serialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ class TestSerialization(unittest.TestCase):
"_type wrong type": '{"_type": "foo", "spec_version": "1.0.0", "version": 1, "expires": "2030-01-01T00:00:00Z", "meta": {}}',
"version wrong type": '{"_type": "signed", "spec_version": "1.0.0", "version": "a", "expires": "2030-01-01T00:00:00Z", "meta": {}}',
"invalid spec_version str": '{"_type": "signed", "spec_version": "abc", "version": 1, "expires": "2030-01-01T00:00:00Z", "meta": {}}',
"two digit spec_version": '{"_type": "signed", "spec_version": "1.2.a", "version": 1, "expires": "2030-01-01T00:00:00Z", "meta": {}}',
"no digit spec_version": '{"_type": "signed", "spec_version": "a.b.c", "version": 1, "expires": "2030-01-01T00:00:00Z", "meta": {}}',
"non-number spec_version": '{"_type": "signed", "spec_version": "1.2.a", "version": 1, "expires": "2030-01-01T00:00:00Z", "meta": {}}',
"one part spec_version": '{"_type": "signed", "spec_version": "1", "version": 1, "expires": "2030-01-01T00:00:00Z", "meta": {}}',
"different major spec_version": '{"_type": "signed", "spec_version": "0.0.0", "version": 1, "expires": "2030-01-01T00:00:00Z", "meta": {}}',
"version 0": '{"_type": "signed", "spec_version": "1.0.0", "version": 0, "expires": "2030-01-01T00:00:00Z", "meta": {}}',
"version below 0": '{"_type": "signed", "spec_version": "1.0.0", "version": -1, "expires": "2030-01-01T00:00:00Z", "meta": {}}',
Expand Down Expand Up @@ -254,6 +254,8 @@ def test_invalid_timestamp_serialization(self, test_case_data: str) -> None:
valid_timestamps: utils.DataSet = {
"all": '{ "_type": "timestamp", "spec_version": "1.0.0", "version": 1, "expires": "2030-01-01T00:00:00Z", \
"meta": {"snapshot.json": {"hashes": {"sha256" : "abc"}, "version": 1}}}',
"two part spec_version": '{ "_type": "timestamp", "spec_version": "1.9000", "version": 1, "expires": "2030-01-01T00:00:00Z", \
"meta": {"snapshot.json": {"hashes": {"sha256" : "abc"}, "version": 1}}}',
"unrecognized field": '{ "_type": "timestamp", "spec_version": "1.0.0", "version": 1, "expires": "2030-01-01T00:00:00Z", \
"meta": {"snapshot.json": {"hashes": {"sha256" : "abc"}, "version": 1}}, "foo": "bar"}',
}
Expand Down
14 changes: 8 additions & 6 deletions tuf/api/metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -431,16 +431,18 @@ def __init__(
expires: datetime,
unrecognized_fields: Optional[Mapping[str, Any]] = None,
):
# Accept semver (X.Y.Z) but also X.Y for legacy compatibility
spec_list = spec_version.split(".")
if (
len(spec_list) != 3
len(spec_list) not in [2, 3]
or not all(el.isdigit() for el in spec_list)
or spec_list[0] != SPECIFICATION_VERSION[0]
):
raise ValueError(
f"Unsupported spec_version, got {spec_list}, "
f"supported {'.'.join(SPECIFICATION_VERSION)}"
)
raise ValueError(f"Failed to parse spec_version {spec_version}")

# major version must match
if spec_list[0] != SPECIFICATION_VERSION[0]:
raise ValueError(f"Unsupported spec_version {spec_version}")

self.spec_version = spec_version
self.expires = expires

Expand Down

0 comments on commit 4cd9e15

Please sign in to comment.