Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions prometheus_client/validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ def _validate_labelname(l):

This check uses the global legacy validation setting to determine the validation scheme.
"""
if not l:
raise ValueError('label name cannot be empty')
if get_legacy_validation():
if not METRIC_LABEL_NAME_RE.match(l):
raise ValueError('Invalid label metric name: ' + l)
Expand Down
1 change: 1 addition & 0 deletions tests/openmetrics/test_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -774,6 +774,7 @@ def test_invalid_input(self):
('a{a=" # "}1\n# EOF\n'),
('a{a=" # ",b=}1\n# EOF\n'),
('a{a=" # "b}1\n# EOF\n'),
('a{""="1"} 1\n# EOF\n'),
# Missing value.
('a\n# EOF\n'),
('a \n# EOF\n'),
Expand Down
15 changes: 15 additions & 0 deletions tests/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -818,6 +818,21 @@ def test_duplicate_labelnames_error_lists_only_duplicates(self):
self.assertEqual(str(error.exception), f'Duplicate label names: {expected!r}')
self.assertEqual(list(registry.collect()), [])

def test_empty_labelname_raises(self):
# The exposition would contain {="value"}, which no parser accepts.
for metric_type in (Counter, Gauge, Summary, Histogram, Info, Enum):
with self.subTest(metric_type=metric_type):
registry = CollectorRegistry()
kwargs = {'states': ['ready']} if metric_type is Enum else {}
with self.assertRaisesRegex(ValueError, '^label name cannot be empty$'):
metric_type('empty_label', 'help', labelnames=[''], registry=registry, **kwargs)
self.assertEqual(list(registry.collect()), [])

def test_empty_exemplar_labelname_raises(self):
counter = Counter('empty_exemplar', 'help', registry=self.registry)
with self.assertRaisesRegex(ValueError, '^label name cannot be empty$'):
counter.inc(exemplar={'': 'abc'})

def test_unique_labelnames_iterator(self):
# Valid one-shot label iterables still preserve both names.
counter = Counter('iter_labels', 'help', iter(['a', 'b']), registry=self.registry)
Expand Down
8 changes: 8 additions & 0 deletions tests/test_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,14 @@ def test_multiple_trailing_commas(self):
text = """# TYPE a counter
# HELP a help
a{foo="bar",, } 1
"""
self.assertRaises(ValueError,
lambda: list(text_string_to_metric_families(text)))

def test_quoted_empty_label_name(self):
text = """# TYPE a counter
# HELP a help
a{""="bar"} 1
"""
self.assertRaises(ValueError,
lambda: list(text_string_to_metric_families(text)))
Expand Down
Loading