diff --git a/prometheus_client/core.py b/prometheus_client/core.py index f730e095..95dce1c7 100644 --- a/prometheus_client/core.py +++ b/prometheus_client/core.py @@ -607,6 +607,10 @@ def _read_all_values(self): while pos < used: encoded_len = _unpack_integer(data, pos)[0] + # check we are not reading beyond bounds + if encoded_len + pos > used: + msg = 'Read beyond file size detected, %s is corrupted.' + raise RuntimeError(msg % self._fname) pos += 4 encoded = unpack_from(('%ss' % encoded_len).encode(), data, pos)[0] padded_len = encoded_len + (8 - (encoded_len + 4) % 8) diff --git a/tests/test_multiprocess.py b/tests/test_multiprocess.py index e2745b0b..a479e64c 100644 --- a/tests/test_multiprocess.py +++ b/tests/test_multiprocess.py @@ -296,6 +296,13 @@ def test_multi_expansion(self): [('abc', 42.0), (key, 123.0), ('def', 17.0)], list(self.d.read_all_values())) + def test_corruption_detected(self): + self.d.write_value('abc', 42.0) + # corrupt the written data + self.d._m[8:16] = b'somejunk' + with self.assertRaises(RuntimeError): + list(self.d.read_all_values()) + def tearDown(self): os.unlink(self.tempfile)