Fix metrics broken by comma and equal in labels

The logic for turning a key back into the labelles that defined it would
not account for the labels values possibly including a comma or equal
sign, which in turn broke the logic for handling these metrics.

Fix by properly parsing the keys.
This commit is contained in:
Hornwitser committed 2026-03-09 19:35:02 +01:00
1 parent b0595a6502
commit f6eb55163f
2 files changed
+30 -8

No files matched your search

+15 -6
View File
@@ -272,18 +272,27 @@ function labelsToKey(labels: LabelValues, metricLabels: string[]) {
function keyToLabels(key: string) {
let labels = new Map<string, string>();
if (key !== "") {
for (let pair of key.split(",")) {
let [name, value] = pair.split("=", 2);
if (!name || value === undefined) {
continue;
let pos = 0;
let matchLabel = /([^=]+)="(([^\\"]|\\["n\\])+)"/y;
while (pos < key.length) {
if (pos !== 0) {
if (key[pos] !== ",") {
throw Error(`Expected , at pos ${pos} in "${key}"`);
}
pos += 1;
}
matchLabel.lastIndex = pos;
const match = matchLabel.exec(key);
if (match) {
let [, name, value] = match;
labels.set(name, value
.slice(1, -1)
.replace(/\\"/g, "\"")
.replace(/\\n/g, "\n")
.replace(/\\\\/g, "\\")
);
pos += match[0].length;
} else {
throw new Error(`Failed to parse label at pos ${pos} in "${key}"`);
}
}
+15 -2
View File
@@ -651,8 +651,21 @@ describe("lib/prometheus", function() {
let gauge = new prometheus.Gauge(
"test", "Help", { register: false, labels: ["a", "b"] }
);
gauge.labels('x\\\\\n\"\"\n\\', "2");
gauge.removeAll({ a: 'x\\\\\n\"\"\n\\' });
let labelValue = "";
for (let i = 0; i < 128; i++) {
const char = String.fromCodePoint(i);
if (!/[1-9B-Zb-z]/.test(char)) { // exclude boring characters
labelValue += char;
}
}
labelValue += "©💣";
gauge.labels(labelValue, "2");
gauge.removeAll({ a: labelValue });
assert(gauge._values.size === 0, "Matching labels remained");
gauge.labels("1", labelValue);
gauge.removeAll({ a: "1" });
assert(gauge._values.size === 0, "Matching labels remained");
});
});