Skip to content

Commit 9d15485

Browse files
ttkLKaemmerling
andauthored
Properly validate label names (#82)
* Fix typo in readme. Redis=>redis Signed-off-by: Tom Kaminski <tom.kaminski@futurenet.com> * Validate label name against proper regex pattern. Add unit tests Signed-off-by: Tom Kaminski <tom.kaminski@futurenet.com> * Throw exception for reserved label names Signed-off-by: Tom Kaminski <tom.kaminski@futurenet.com> * Sign off Signed-off-by: Tom Kaminski <tom.kaminski@futurenet.com> Co-authored-by: Lukas Kämmerling <lukas.kaemmerling@hetzner-cloud.de>
1 parent d137a46 commit 9d15485

File tree

3 files changed

+54
-4
lines changed

3 files changed

+54
-4
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ composer require promphp/prometheus_push_gateway_php
137137

138138
Start a Redis instance:
139139
```
140-
docker-compose up Redis
140+
docker-compose up redis
141141
```
142142

143143
Run the tests:

src/Prometheus/Collector.php

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99

1010
abstract class Collector
1111
{
12-
const RE_METRIC_LABEL_NAME = '/^[a-zA-Z_:][a-zA-Z0-9_:]*$/';
12+
const RE_METRIC_NAME = '/^[a-zA-Z_:][a-zA-Z0-9_:]*$/';
13+
const RE_LABEL_NAME = '/^[a-zA-Z_][a-zA-Z0-9_]*$/';
1314

1415
/**
1516
* @var Adapter
@@ -103,7 +104,7 @@ protected function assertLabelsAreDefinedCorrectly(array $labels): void
103104
*/
104105
public static function assertValidMetricName(string $metricName): void
105106
{
106-
if (preg_match(self::RE_METRIC_LABEL_NAME, $metricName) !== 1) {
107+
if (preg_match(self::RE_METRIC_NAME, $metricName) !== 1) {
107108
throw new InvalidArgumentException("Invalid metric name: '" . $metricName . "'");
108109
}
109110
}
@@ -113,8 +114,11 @@ public static function assertValidMetricName(string $metricName): void
113114
*/
114115
public static function assertValidLabel(string $label): void
115116
{
116-
if (preg_match(self::RE_METRIC_LABEL_NAME, $label) !== 1) {
117+
if (preg_match(self::RE_LABEL_NAME, $label) !== 1) {
117118
throw new InvalidArgumentException("Invalid label name: '" . $label . "'");
118119
}
120+
else if (strpos($label, "__") === 0) {
121+
throw new InvalidArgumentException("Can't used a reserved label name: '" . $label . "'");
122+
}
119123
}
120124
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Test\Prometheus;
6+
7+
use PHPUnit\Framework\TestCase;
8+
use Prometheus\CollectorRegistry;
9+
use Prometheus\Storage\InMemory;
10+
11+
class CollectorTest extends TestCase
12+
{
13+
/**
14+
* @var CollectorRegistry
15+
*/
16+
public $registry;
17+
18+
public function setUp(): void
19+
{
20+
$this->registry = new CollectorRegistry(new InMemory(), false);
21+
}
22+
23+
public function testInvalidNamespace(): void
24+
{
25+
$this->expectException(\InvalidArgumentException::class);
26+
$this->registry->getOrRegisterCounter('bad%namespace', 'counter', 'counter-help-text');
27+
}
28+
29+
public function testInvalidMetricName(): void
30+
{
31+
$this->expectException(\InvalidArgumentException::class);
32+
$this->registry->getOrRegisterCounter('mynamespace', 'coun^ter', 'counter-help-text');
33+
}
34+
35+
public function testInvalidLabelName(): void
36+
{
37+
$this->expectException(\InvalidArgumentException::class);
38+
$this->registry->getOrRegisterCounter('mynamespace', 'counter', 'counter-help-text', ['label1','label:2']);
39+
}
40+
41+
public function testReservedLabelName(): void
42+
{
43+
$this->expectException(\InvalidArgumentException::class);
44+
$this->registry->getOrRegisterCounter('mynamespace', 'counter', 'counter-help-text', ['__reserved']);
45+
}
46+
}

0 commit comments

Comments
 (0)