mirror of
https://gitlab.com/fdroid/fdroidserver.git
synced 2024-08-18 20:30:09 +02:00
metadata: handle SHA-256 values that parse as decimal ints
https://gitlab.com/fdroid/fdroidserver/-/merge_requests/1350#note_1370665635
This commit is contained in:
parent
642e444cfa
commit
2aa0403208
@ -908,6 +908,11 @@ def _normalize_type_string(v):
|
||||
numbers. Like "versionName: 1.0" would be a YAML float, but
|
||||
should be a string.
|
||||
|
||||
SHA-256 values are string values, but YAML 1.2 can interpret some
|
||||
unquoted values as decimal ints. This converts those to a string
|
||||
if they are over 50 digits. In the wild, the longest 0 padding on
|
||||
a SHA-256 key fingerprint I found was 8 zeros.
|
||||
|
||||
"""
|
||||
if isinstance(v, bool):
|
||||
if v:
|
||||
@ -921,6 +926,9 @@ def _normalize_type_string(v):
|
||||
if v > 0:
|
||||
return '.inf'
|
||||
return '-.inf'
|
||||
if v and isinstance(v, int):
|
||||
if math.log10(v) > 50: # only if the int has this many digits
|
||||
return '%064d' % v
|
||||
return str(v)
|
||||
|
||||
|
||||
|
@ -343,6 +343,13 @@ class MetadataTest(unittest.TestCase):
|
||||
self.assertEqual('false', metadata._normalize_type_string(False))
|
||||
self.assertEqual('true', metadata._normalize_type_string(True))
|
||||
|
||||
def test_normalize_type_string_sha256(self):
|
||||
"""SHA-256 values are TYPE_STRING, which YAML can parse as decimal ints."""
|
||||
yaml = ruamel.yaml.YAML(typ='safe')
|
||||
for v in range(1, 1000):
|
||||
s = '%064d' % (v * (10**51))
|
||||
self.assertEqual(s, metadata._normalize_type_string(yaml.load(s)))
|
||||
|
||||
def test_normalize_type_stringmap_none(self):
|
||||
self.assertEqual(dict(), metadata._normalize_type_stringmap('key', None))
|
||||
|
||||
@ -420,13 +427,13 @@ class MetadataTest(unittest.TestCase):
|
||||
with self.assertRaises(MetaDataException):
|
||||
metadata.post_parse_yaml_metadata(yamldata)
|
||||
|
||||
def test_post_parse_yaml_metadata_0padding_fails(self):
|
||||
"""Special case: ideally 0 padding would be kept in string, but it is not."""
|
||||
def test_post_parse_yaml_metadata_0padding_sha256(self):
|
||||
"""SHA-256 values are strings, but YAML 1.2 will read some as decimal ints."""
|
||||
v = '0027293472934293872934729834729834729834729834792837487293847926'
|
||||
yaml = ruamel.yaml.YAML(typ='safe')
|
||||
yamldata = yaml.load('AllowedAPKSigningKeys: ' + v)
|
||||
metadata.post_parse_yaml_metadata(yamldata)
|
||||
self.assertNotEqual(yamldata['AllowedAPKSigningKeys'], v)
|
||||
self.assertEqual(yamldata['AllowedAPKSigningKeys'], [v])
|
||||
|
||||
def test_post_parse_yaml_metadata_builds(self):
|
||||
yamldata = OrderedDict()
|
||||
@ -543,28 +550,6 @@ class MetadataTest(unittest.TestCase):
|
||||
with self.assertRaises(MetaDataException):
|
||||
metadata.parse_yaml_metadata(mf)
|
||||
|
||||
def test_parse_yaml_metadata_0padding_fails(self):
|
||||
"""Special case: ideally this would keep 0 padding in string, but it does not.
|
||||
|
||||
It seems the only option is to quote values like that, or add
|
||||
quirks to the YAML parsing.
|
||||
|
||||
"""
|
||||
v = '0027293472934293872934729834729834729834729834792837487293847926'
|
||||
mf = io.StringIO('AllowedAPKSigningKeys: %s' % v)
|
||||
mf.name = 'mock_filename.yaml'
|
||||
self.assertNotEqual(
|
||||
v,
|
||||
metadata.parse_yaml_metadata(mf)['AllowedAPKSigningKeys'][0],
|
||||
)
|
||||
|
||||
mf = io.StringIO('AllowedAPKSigningKeys: "%s"' % v)
|
||||
mf.name = 'mock_filename.yaml'
|
||||
self.assertEqual(
|
||||
v,
|
||||
metadata.parse_yaml_metadata(mf)['AllowedAPKSigningKeys'][0],
|
||||
)
|
||||
|
||||
def test_parse_yaml_metadata_unknown_app_field(self):
|
||||
mf = io.StringIO(
|
||||
textwrap.dedent(
|
||||
@ -2146,6 +2131,24 @@ class PostMetadataParseTest(unittest.TestCase):
|
||||
self.assertEqual(*self._post_metadata_parse_build_script(123456, ['123456']))
|
||||
self.assertEqual(*self._post_metadata_parse_build_string(123456, '123456'))
|
||||
|
||||
def test_post_metadata_parse_sha256(self):
|
||||
"""Run a SHA-256 that YAML calls an int through the various types.
|
||||
|
||||
The current f-droid.org signer set has SHA-256 values with a
|
||||
maximum of two leading zeros, but this will handle more.
|
||||
|
||||
"""
|
||||
yaml = ruamel.yaml.YAML(typ='safe', pure=True)
|
||||
str_sha256 = '0000000000000498456908409534729834729834729834792837487293847926'
|
||||
sha256 = yaml.load('a: ' + str_sha256)['a']
|
||||
self.assertEqual(*self._post_metadata_parse_app_list(sha256, [str_sha256]))
|
||||
self.assertEqual(*self._post_metadata_parse_app_string(sha256, str_sha256))
|
||||
self.assertEqual(*self._post_metadata_parse_build_bool(sha256, True))
|
||||
self.assertEqual(*self._post_metadata_parse_build_int(sha256, sha256))
|
||||
self.assertEqual(*self._post_metadata_parse_build_list(sha256, [str_sha256]))
|
||||
self.assertEqual(*self._post_metadata_parse_build_script(sha256, [str_sha256]))
|
||||
self.assertEqual(*self._post_metadata_parse_build_string(sha256, str_sha256))
|
||||
|
||||
def test_post_metadata_parse_int_0(self):
|
||||
"""Run the int 0 through the various field and flag types."""
|
||||
self.assertEqual(*self._post_metadata_parse_app_list(0, ['0']))
|
||||
|
Loading…
Reference in New Issue
Block a user