diff --git a/prometheus_client/openmetrics/parser.py b/prometheus_client/openmetrics/parser.py index 50fa3419..fe4d90cd 100644 --- a/prometheus_client/openmetrics/parser.py +++ b/prometheus_client/openmetrics/parser.py @@ -72,7 +72,7 @@ def _unescape_help(text): def _parse_value(value): value = ''.join(value) - if value != value.strip(): + if value != value.strip() or '_' in value: raise ValueError("Invalid value: {0!r}".format(value)) try: return int(value) @@ -84,7 +84,7 @@ def _parse_timestamp(timestamp): timestamp = ''.join(timestamp) if not timestamp: return None - if timestamp != timestamp.strip(): + if timestamp != timestamp.strip() or '_' in timestamp: raise ValueError("Invalid timestamp: {0!r}".format(timestamp)) try: # Simple int. diff --git a/tests/openmetrics/test_parser.py b/tests/openmetrics/test_parser.py index 63dd5e42..b5585762 100644 --- a/tests/openmetrics/test_parser.py +++ b/tests/openmetrics/test_parser.py @@ -53,6 +53,22 @@ def test_float_gauge(self): """) self.assertEqual([GaugeMetricFamily("a", "help", value=1.2)], list(families)) + def test_leading_zeros_simple_gauge(self): + families = text_string_to_metric_families("""# TYPE a gauge +# HELP a help +a 0000000000000000000000000000000000000000001 +# EOF +""") + self.assertEqual([GaugeMetricFamily("a", "help", value=1)], list(families)) + + def test_leading_zeros_float_gauge(self): + families = text_string_to_metric_families("""# TYPE a gauge +# HELP a help +a 0000000000000000000000000000000000000000001.2e-1 +# EOF +""") + self.assertEqual([GaugeMetricFamily("a", "help", value=.12)], list(families)) + def test_nan_gauge(self): families = text_string_to_metric_families("""# TYPE a gauge # HELP a help @@ -610,14 +626,25 @@ def test_invalid_input(self): ('a 1\n# EOF\n'), ('a 1\t\n# EOF\n'), ('a 1 \n# EOF\n'), + ('a 1_2\n# EOF\n'), + ('a 0x1p-3\n# EOF\n'), + ('a 0x1P-3\n# EOF\n'), + ('a 0b1\n# EOF\n'), + ('a 0B1\n# EOF\n'), + ('a 0x1\n# EOF\n'), + ('a 0X1\n# EOF\n'), + ('a 0o1\n# EOF\n'), + ('a 0O1\n# EOF\n'), # Bad timestamp. ('a 1 z\n# EOF\n'), ('a 1 1z\n# EOF\n'), + ('a 1 1_2\n# EOF\n'), ('a 1 1.1.1\n# EOF\n'), ('a 1 NaN\n# EOF\n'), ('a 1 Inf\n# EOF\n'), ('a 1 +Inf\n# EOF\n'), ('a 1 -Inf\n# EOF\n'), + ('a 1 0x1p-3\n# EOF\n'), # Bad exemplars. ('# TYPE a histogram\na_bucket{le="+Inf"} 1 #\n# EOF\n'), ('# TYPE a histogram\na_bucket{le="+Inf"} 1# {} 1\n# EOF\n'), @@ -627,6 +654,8 @@ def test_invalid_input(self): ('# TYPE a histogram\na_bucket{le="+Inf"} 1 # {} 1 1 \n# EOF\n'), ('# TYPE a histogram\na_bucket{le="+Inf"} 1 # ' '{a="2345678901234567890123456789012345678901234567890123456789012345"} 1 1\n# EOF\n'), + ('# TYPE a histogram\na_bucket{le="+Inf"} 1 # {} 0x1p-3\n# EOF\n'), + ('# TYPE a histogram\na_bucket{le="+Inf"} 1 # {} 1 0x1p-3\n# EOF\n'), # Exemplars on unallowed samples. ('# TYPE a histogram\na_sum 1 # {a="b"} 0.5\n# EOF\n'), ('# TYPE a gaugehistogram\na_sum 1 # {a="b"} 0.5\n# EOF\n'), @@ -695,7 +724,7 @@ def test_invalid_input(self): ('# TYPE a gauge\na 0\na 0 0\n# EOF\n'), ('# TYPE a gauge\na 0 0\na 0\n# EOF\n'), ]: - with self.assertRaises(ValueError): + with self.assertRaises(ValueError, msg=case): list(text_string_to_metric_families(case)) @unittest.skipIf(sys.version_info < (2, 7), "float repr changed from 2.6 to 2.7")