fix(metrics): validate label names in Metric, sanitize in AppsInfo
Add validation in the Metric constructor that rejects invalid OpenMetrics label names with InvalidArgumentException. Sanitize app IDs at the source in AppsInfo by replacing hyphens with underscores before creating the Metric. Fixes nextcloud/server#59247 Signed-off-by: moktamd <moktamd@users.noreply.github.com>
This commit is contained in:
@@ -47,10 +47,10 @@ class AppsInfo implements IMetricFamily {
|
||||
|
||||
#[Override]
|
||||
public function metrics(): Generator {
|
||||
yield new Metric(
|
||||
1,
|
||||
$this->appManager->getAppInstalledVersions(true),
|
||||
time()
|
||||
);
|
||||
$apps = [];
|
||||
foreach ($this->appManager->getAppInstalledVersions(true) as $appId => $version) {
|
||||
$apps[str_replace('-', '_', $appId)] = $version;
|
||||
}
|
||||
yield new Metric(1, $apps, time());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,9 +19,18 @@ final readonly class Metric {
|
||||
public array $labels = [],
|
||||
public int|float|null $timestamp = null,
|
||||
) {
|
||||
$this->validateLabels();
|
||||
}
|
||||
|
||||
public function label(string $name): ?string {
|
||||
return $this->labels[$name] ?? null;
|
||||
}
|
||||
|
||||
private function validateLabels(): void {
|
||||
foreach ($this->labels as $label => $_value) {
|
||||
if (preg_match('/^[a-zA-Z_][a-zA-Z0-9_]*$/', (string)$label) !== 1) {
|
||||
throw new \InvalidArgumentException('Invalid OpenMetrics label name: "' . $label . '"');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,6 +87,17 @@ class OpenMetricsControllerTest extends TestCase {
|
||||
$this->assertStringMatchesFormat($expected, $fullOutput);
|
||||
}
|
||||
|
||||
public function testMetricRejectsInvalidLabelNames(): void {
|
||||
$this->expectException(\InvalidArgumentException::class);
|
||||
new Metric(1, ['hide-photos' => '1.0.0']);
|
||||
}
|
||||
|
||||
public function testMetricAcceptsValidLabelNames(): void {
|
||||
$metric = new Metric(1, ['hide_photos' => '1.0.0', 'normal_app' => '2.0.0']);
|
||||
$this->assertEquals('1.0.0', $metric->label('hide_photos'));
|
||||
$this->assertEquals('2.0.0', $metric->label('normal_app'));
|
||||
}
|
||||
|
||||
public function testGetMetricsFromForbiddenIp(): void {
|
||||
$this->config->expects($this->once())
|
||||
->method('getSystemValue')
|
||||
|
||||
Reference in New Issue
Block a user