From 7312096bf66811d4c2fd0e4162fe778265b2c224 Mon Sep 17 00:00:00 2001 From: Brian Brazil Date: Tue, 6 Aug 2019 17:10:17 +0100 Subject: [PATCH] Check for duplicate label names, add missing checks on new code path. Signed-off-by: Brian Brazil --- prometheus_client/openmetrics/parser.py | 13 ++++++++++--- tests/openmetrics/test_parser.py | 5 +++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/prometheus_client/openmetrics/parser.py b/prometheus_client/openmetrics/parser.py index 9fca8e6b..d1148ca6 100644 --- a/prometheus_client/openmetrics/parser.py +++ b/prometheus_client/openmetrics/parser.py @@ -139,9 +139,12 @@ def _parse_labels_with_state_machine(text): if char == '\\': state = 'labelvalueslash' elif char == '"': - if not METRIC_LABEL_NAME_RE.match(''.join(labelname)): - raise ValueError("Invalid line: " + text) - labels[''.join(labelname)] = ''.join(labelvalue) + ln = ''.join(labelname) + if not METRIC_LABEL_NAME_RE.match(ln): + raise ValueError("Invalid line, bad label name: " + text) + if ln in labels: + raise ValueError("Invalid line, duplicate label name: " + text) + labels[ln] = ''.join(labelvalue) labelname = [] labelvalue = [] state = 'endoflabelvalue' @@ -217,6 +220,10 @@ def _parse_labels(text): # Replace escaping if needed if "\\" in label_value: label_value = _replace_escaping(label_value) + if not METRIC_LABEL_NAME_RE.match(label_name): + raise ValueError("invalid line, bad label name: " + text) + if label_name in labels: + raise ValueError("invalid line, duplicate label name: " + text) labels[label_name] = label_value # Remove the processed label from the sub-slice for next iteration diff --git a/tests/openmetrics/test_parser.py b/tests/openmetrics/test_parser.py index 815f749f..38fbef46 100644 --- a/tests/openmetrics/test_parser.py +++ b/tests/openmetrics/test_parser.py @@ -550,6 +550,11 @@ def test_invalid_input(self): ('a{a="1"b="2"} 1\n# EOF\n'), ('a{a="1",,b="2"} 1\n# EOF\n'), ('a{a="1",b="2",} 1\n# EOF\n'), + # Invalid labels. + ('a{1="1"} 1\n# EOF\n'), + ('a{a="1",a="1"} 1\n# EOF\n'), + ('a{1=" # "} 1\n# EOF\n'), + ('a{a=" # ",a=" # "} 1\n# EOF\n'), # Missing value. ('a\n# EOF\n'), ('a \n# EOF\n'),