Prometheus: Fix operator handling when making label expressions utf-8 friendly (#100475)

* fix: operator handling

* refactor: stay dry
This commit is contained in:
Nick Richmond
2025-02-12 07:09:22 -05:00
committed by GitHub
parent 2f329c211d
commit 91242340c1
2 changed files with 38 additions and 5 deletions
@@ -124,4 +124,31 @@ describe('wrapUtf8Filters', () => {
const expected = 'key1="nested \\"escaped\\" quotes",key2="value with \\"escaped\\" quotes"';
expect(result).toEqual(expected);
});
it('should handle different Prometheus operators correctly', () => {
const inputs = [
'label="value"', // equals
'label!="different value"', // not equals
'label=~"regex.*value"', // regex match
'label!~"not.regex.*value"', // regex not match
'utf8.label.spaß!="no match"', // utf8 with not equals
'utf8.label.spaß=~"match.*"', // utf8 with regex match
'complex case=~".*",simple="value"', // multiple operators
];
const expected = [
'label="value"',
'label!="different value"',
'label=~"regex.*value"',
'label!~"not.regex.*value"',
'"utf8.label.spaß"!="no match"',
'"utf8.label.spaß"=~"match.*"',
'"complex case"=~".*",simple="value"',
];
inputs.forEach((input, index) => {
const result = wrapUtf8Filters(input);
expect(result).toEqual(expected[index]);
});
});
});
@@ -82,10 +82,19 @@ const isValidCodePoint = (codePoint: number): boolean => {
export const wrapUtf8Filters = (filterStr: string): string => {
const resultArray: string[] = [];
const operatorRegex = /(=~|!=|!~|=)/; // NOTE: the order of the operators is important here
let currentKey = '';
let currentValue = '';
let inQuotes = false;
let temp = '';
const addResult = () => {
const operatorMatch = temp.match(operatorRegex);
if (operatorMatch) {
const operator = operatorMatch[0];
[currentKey, currentValue] = temp.split(operator);
resultArray.push(`${utf8Support(currentKey.trim())}${operator}"${currentValue.slice(1, -1)}"`);
}
};
for (const char of filterStr) {
if (char === '"' && temp[temp.length - 1] !== '\\') {
@@ -94,8 +103,7 @@ export const wrapUtf8Filters = (filterStr: string): string => {
temp += char;
} else if (char === ',' && !inQuotes) {
// When outside quotes and encountering ',', finalize the current pair
[currentKey, currentValue] = temp.split('=');
resultArray.push(`${utf8Support(currentKey.trim())}="${currentValue.slice(1, -1)}"`);
addResult();
temp = ''; // Reset for the next pair
} else {
// Collect characters
@@ -105,9 +113,7 @@ export const wrapUtf8Filters = (filterStr: string): string => {
// Handle the last key-value pair
if (temp) {
[currentKey, currentValue] = temp.split('=');
resultArray.push(`${utf8Support(currentKey.trim())}="${currentValue.slice(1, -1)}"`);
addResult();
}
return resultArray.join(',');
};