mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Prometheus: Fix escaping of quotation marks for variables (#93415)
* Prometheus: Fix escaping of quotation marks for non-regex variables * Prometheus: Fix escaping of double quotation marks for regex variables * Prometheus: Add escaping for adhoc filter label queries
This commit is contained in:
parent
228bf711f9
commit
2bfdee73e3
@ -289,6 +289,16 @@ describe('PrometheusDatasource', () => {
|
||||
operator: '=~',
|
||||
value: `v'.*`,
|
||||
},
|
||||
{
|
||||
key: 'k3',
|
||||
operator: '=~',
|
||||
value: `v".*`,
|
||||
},
|
||||
{
|
||||
key: 'k4',
|
||||
operator: '=~',
|
||||
value: `\\v.*`,
|
||||
},
|
||||
];
|
||||
ds.query({
|
||||
interval: '15s',
|
||||
@ -298,7 +308,7 @@ describe('PrometheusDatasource', () => {
|
||||
} as DataQueryRequest<PromQuery>);
|
||||
const [result] = fetchMockCalledWith(fetchMock);
|
||||
expect(result).toMatchObject({
|
||||
expr: `metric{job="foo", k1=~"v.*", k2=~"v\\\\'.*"} - metric{k1=~"v.*", k2=~"v\\\\'.*"}`,
|
||||
expr: `metric{job="foo", k1=~"v.*", k2=~"v'.*", k3=~"v\\".*", k4=~"\\\\v.*"} - metric{k1=~"v.*", k2=~"v'.*", k3=~"v\\".*", k4=~"\\\\v.*"}`,
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -478,8 +488,12 @@ describe('PrometheusDatasource', () => {
|
||||
expect(prometheusRegularEscape('cryptodepression')).toEqual('cryptodepression');
|
||||
});
|
||||
|
||||
it("should escape '", () => {
|
||||
expect(prometheusRegularEscape("looking'glass")).toEqual("looking\\\\'glass");
|
||||
it("should not escape '", () => {
|
||||
expect(prometheusRegularEscape("looking'glass")).toEqual("looking'glass");
|
||||
});
|
||||
|
||||
it('should escape "', () => {
|
||||
expect(prometheusRegularEscape('looking"glass')).toEqual('looking\\"glass');
|
||||
});
|
||||
|
||||
it('should escape \\', () => {
|
||||
@ -487,11 +501,11 @@ describe('PrometheusDatasource', () => {
|
||||
});
|
||||
|
||||
it('should escape multiple characters', () => {
|
||||
expect(prometheusRegularEscape("'looking'glass'")).toEqual("\\\\'looking\\\\'glass\\\\'");
|
||||
expect(prometheusRegularEscape('"looking"glass"')).toEqual('\\"looking\\"glass\\"');
|
||||
});
|
||||
|
||||
it('should escape multiple different characters', () => {
|
||||
expect(prometheusRegularEscape("'loo\\king'glass'")).toEqual("\\\\'loo\\\\king\\\\'glass\\\\'");
|
||||
expect(prometheusRegularEscape('"loo\\king"glass"')).toEqual('\\"loo\\\\king\\"glass\\"');
|
||||
});
|
||||
});
|
||||
|
||||
@ -500,8 +514,9 @@ describe('PrometheusDatasource', () => {
|
||||
expect(prometheusSpecialRegexEscape('cryptodepression')).toEqual('cryptodepression');
|
||||
});
|
||||
|
||||
it('should escape $^*+?.()|\\', () => {
|
||||
it('should escape $^*+?.()|\\"', () => {
|
||||
expect(prometheusSpecialRegexEscape("looking'glass")).toEqual("looking\\\\'glass");
|
||||
expect(prometheusSpecialRegexEscape('looking"glass')).toEqual('looking\\\\\\"glass');
|
||||
expect(prometheusSpecialRegexEscape('looking{glass')).toEqual('looking\\\\{glass');
|
||||
expect(prometheusSpecialRegexEscape('looking}glass')).toEqual('looking\\\\}glass');
|
||||
expect(prometheusSpecialRegexEscape('looking[glass')).toEqual('looking\\\\[glass');
|
||||
@ -549,8 +564,8 @@ describe('PrometheusDatasource', () => {
|
||||
});
|
||||
|
||||
describe('and value is a string', () => {
|
||||
it('should only escape single quotes', () => {
|
||||
expect(ds.interpolateQueryExpr("abc'$^*{}[]+?.()|", customVariable)).toEqual("abc\\\\'$^*{}[]+?.()|");
|
||||
it('should only escape double quotes and backslashes', () => {
|
||||
expect(ds.interpolateQueryExpr('abc\'"$^*{}[]+?.()|\\', customVariable)).toEqual('abc\'\\"$^*{}[]+?.()|\\\\');
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -640,7 +640,7 @@ export class PrometheusDatasource
|
||||
|
||||
const labelFilters: QueryBuilderLabelFilter[] = options.filters.map((f) => ({
|
||||
label: f.key,
|
||||
value: f.value,
|
||||
value: prometheusRegularEscape(f.value),
|
||||
op: f.operator,
|
||||
}));
|
||||
const expr = promQueryModeller.renderLabels(labelFilters);
|
||||
@ -672,7 +672,7 @@ export class PrometheusDatasource
|
||||
|
||||
const labelFilters: QueryBuilderLabelFilter[] = options.filters.map((f) => ({
|
||||
label: f.key,
|
||||
value: f.value,
|
||||
value: prometheusRegularEscape(f.value),
|
||||
op: f.operator,
|
||||
}));
|
||||
|
||||
@ -1045,9 +1045,14 @@ export function extractRuleMappingFromGroups(groups: RawRecordingRules[]): RuleQ
|
||||
// in language_utils.ts, but they are not exactly the same algorithm, and we found
|
||||
// no way to reuse one in the another or vice versa.
|
||||
export function prometheusRegularEscape<T>(value: T) {
|
||||
return typeof value === 'string' ? value.replace(/\\/g, '\\\\').replace(/'/g, "\\\\'") : value;
|
||||
return typeof value === 'string' ? value.replace(/\\/g, '\\\\').replace(/"/g, '\\"') : value;
|
||||
}
|
||||
|
||||
export function prometheusSpecialRegexEscape<T>(value: T) {
|
||||
return typeof value === 'string' ? value.replace(/\\/g, '\\\\\\\\').replace(/[$^*{}\[\]\'+?.()|]/g, '\\\\$&') : value;
|
||||
return typeof value === 'string'
|
||||
? value
|
||||
.replace(/\\/g, '\\\\\\\\')
|
||||
.replace(/"/g, '\\\\\\"')
|
||||
.replace(/[$^*{}\[\]\'+?.()|]/g, '\\\\$&')
|
||||
: value;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user