From 10fdd5b97e91e5b3ccbce5bf4fed3d20265d75c5 Mon Sep 17 00:00:00 2001 From: David Karchmer Date: Sat, 3 Mar 2018 11:12:41 -0800 Subject: [PATCH] Explicitly check for upper limits for the different IOTileCloudSlug IDs (#33) --- CHANGELOG.md | 4 ++++ iotile_cloud/utils/gid.py | 35 ++++++++++++++++++++++++----------- tests/test_gid.py | 25 +++++++++++++++++-------- version.py | 2 +- 4 files changed, 46 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8cf7b8b..222fd50 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +### v0.8.9 (2018-03-02) + + * Explicitly check for upper limits for the different IOTileCloudSlug IDs + ### v0.8.8 (2018-03-02) * Better testing of IOTileCloudSlug corner cases diff --git a/iotile_cloud/utils/gid.py b/iotile_cloud/utils/gid.py index 7fd6d55..3063016 100644 --- a/iotile_cloud/utils/gid.py +++ b/iotile_cloud/utils/gid.py @@ -76,11 +76,24 @@ class IOTileProjectSlug(IOTileCloudSlug): def __init__(self, id): if isinstance(id, int): - if id < 0: - raise ValueError('IOTileProjectSlug: UUID should be greater or equal than zero') + if id < 0 or id >= pow(16, 8): + raise ValueError('IOTileProjectSlug: UUID should be greater or equal than zero and less than 16^8') pid = int2pid(id) else: - pid = id + parts = gid_split(id) + if len(parts) == 1: + pid = parts[0] + else: + if parts[0] != 'p': + raise ValueError('IOTileProjectSlug: must start with a "p"') + pid = gid_join(parts[1:]) + + # Convert to int and back to get rid of anything above 48 bits + id = gid2int(pid) + if id <= 0 or id >= pow(16, 8): + raise ValueError('IOTileProjectSlug: UUID should be greater than zero and less than 16^8') + pid = int2did(id) + self.set_from_single_id_slug('p', 2, pid) @@ -93,8 +106,8 @@ def __init__(self, id): return if isinstance(id, int): - if id <= 0: - raise ValueError('IOTileDeviceSlug: UUID should be greater than zero') + if id <= 0 or id >= pow(16, 12): + raise ValueError('IOTileDeviceSlug: UUID should be greater than zero and less than 16^12') did = int2did(id) else: if not isinstance(id, str): @@ -109,8 +122,8 @@ def __init__(self, id): # Convert to int and back to get rid of anything above 48 bits id = gid2int(did) - if id <= 0: - raise ValueError('IOTileDeviceSlug: UUID should be greater than zero') + if id <= 0 or id >= pow(16, 12): + raise ValueError('IOTileDeviceSlug: UUID should be greater than zero and less than 16^12') did = int2did(id) self.set_from_single_id_slug('d', 4, did) @@ -133,15 +146,15 @@ class IOTileBlockSlug(IOTileCloudSlug): def __init__(self, id, block=0): if isinstance(id, int): - if id <= 0: - raise ValueError('IOTileBlockSlug: UUID should be greater than zero') + if id <= 0 or id >= pow(16, 16): + raise ValueError('IOTileBlockSlug: UUID should be greater than zero and less than 16^16') did = int2did(id) else: parts = gid_split(id) if(len(parts) == 1): # gid2int will raise exception if not a proper HEX string id = gid2int(parts[0]) - if id <= 0: + if id <= 0 or id >= pow(16, 16): raise ValueError('IOTileBlockSlug: UUID should be greater than zero') parts = ['d',] + parts if parts[0] not in ['d', 'b']: @@ -234,7 +247,7 @@ def __init__(self, id, project=IOTileProjectSlug(0)): project = IOTileProjectSlug(project) if isinstance(id, int): - if id <= 0: + if id <= 0 or id >= pow(16, 4): raise ValueError('IOTileVariableSlug: UUID should be greater than zero') vid = int2vid(id) self._slug = gid_join(['v', project.formatted_id(), vid]) diff --git a/tests/test_gid.py b/tests/test_gid.py index 8dbf0d2..b4d3b62 100644 --- a/tests/test_gid.py +++ b/tests/test_gid.py @@ -10,6 +10,10 @@ def test_project_slug(self): id = IOTileProjectSlug(5) self.assertEqual(str(id), 'p--0000-0005') + # We allow projects to be zero as we use that to represent no project + id = IOTileProjectSlug(0) + self.assertEqual(str(id), 'p--0000-0000') + id = IOTileProjectSlug('p--0000-1234') self.assertEqual(str(id), 'p--0000-1234') @@ -21,6 +25,13 @@ def test_project_slug(self): self.assertEqual(id.formatted_id(), '0000-0005') + self.assertRaises(ValueError, IOTileProjectSlug, 'string') + self.assertRaises(ValueError, IOTileProjectSlug, 'x--0000-0001') + self.assertRaises(ValueError, IOTileProjectSlug, 'p--1234-0000-0000-0001') # > 16bts + self.assertRaises(ValueError, IOTileProjectSlug, -5) + self.assertRaises(ValueError, IOTileProjectSlug, pow(16,8)) + + def test_device_slug(self): id = IOTileDeviceSlug(5) self.assertEqual(str(id), 'd--0000-0000-0000-0005') @@ -42,19 +53,13 @@ def test_device_slug(self): self.assertEqual(str(id), 'd--0000-0000-0000-0005') self.assertEqual(id.formatted_id(), '0000-0000-0000-0005') - id = IOTileDeviceSlug('d--1234-0000-0000-0001') - self.assertEqual(str(id), 'd--0000-0000-0000-0001') - self.assertEqual(id.get_id(), 1) - - id = IOTileDeviceSlug('1234-0000-0000-0001') - self.assertEqual(str(id), 'd--0000-0000-0000-0001') - self.assertEqual(id.get_id(), 1) - self.assertRaises(ValueError, IOTileDeviceSlug, 'string') self.assertRaises(ValueError, IOTileDeviceSlug, 'x--0000-0000-0000-0001') self.assertRaises(ValueError, IOTileDeviceSlug, '0000-0000-0000-0000') + self.assertRaises(ValueError, IOTileDeviceSlug, 'd--1234-0000-0000-0001') # > 48bts self.assertRaises(ValueError, IOTileDeviceSlug, -5) self.assertRaises(ValueError, IOTileDeviceSlug, 0) + self.assertRaises(ValueError, IOTileDeviceSlug, pow(16,12)) def test_block_slug(self): id = IOTileBlockSlug(5) @@ -85,6 +90,7 @@ def test_block_slug(self): self.assertRaises(ValueError, IOTileBlockSlug, '0000-0000-0000-0000') self.assertRaises(ValueError, IOTileBlockSlug, -5) self.assertRaises(ValueError, IOTileBlockSlug, 0) + self.assertRaises(ValueError, IOTileBlockSlug, pow(16,16)) def test_variable_slug(self): self.assertRaises(ValueError, IOTileVariableSlug, 'foo') @@ -107,8 +113,11 @@ def test_variable_slug(self): id = IOTileVariableSlug('v--0000-1234--0005') self.assertEqual(str(id), 'v--0000-1234--0005') + self.assertRaises(ValueError, IOTileVariableSlug, 'string') + self.assertRaises(ValueError, IOTileVariableSlug, 'v--0123') self.assertRaises(ValueError, IOTileVariableSlug, -5) self.assertRaises(ValueError, IOTileVariableSlug, 0) + self.assertRaises(ValueError, IOTileVariableSlug, pow(16,4)) def test_stream_slug(self): self.assertRaises(ValueError, IOTileStreamSlug, 5) diff --git a/version.py b/version.py index 0c10f92..eed7e58 100644 --- a/version.py +++ b/version.py @@ -1 +1 @@ -version = '0.8.8' +version = '0.8.9'