From 6568f3669dce0c2e951a72bfa0833be1d1084838 Mon Sep 17 00:00:00 2001 From: Galen Kistler <109082771+gtk-grafana@users.noreply.github.com> Date: Fri, 10 Jan 2025 10:01:17 -0600 Subject: [PATCH] Loki Datasource: Don't escape single quotes (#98767) * fix: remove single quote escape --- .../datasource/loki/datasource.test.ts | 13 +++++++--- .../app/plugins/datasource/loki/datasource.ts | 24 ++++--------------- 2 files changed, 14 insertions(+), 23 deletions(-) diff --git a/public/app/plugins/datasource/loki/datasource.test.ts b/public/app/plugins/datasource/loki/datasource.test.ts index 1e5158630aa..c650ba4e4e9 100644 --- a/public/app/plugins/datasource/loki/datasource.test.ts +++ b/public/app/plugins/datasource/loki/datasource.test.ts @@ -269,7 +269,7 @@ describe('LokiDatasource', () => { }, ]; expect(ds.applyTemplateVariables(query, {}, adhocFilters).expr).toBe( - 'rate({bar="baz", job="foo", k1=~"v.*", k2=~"v\\\\\'.*"} |= "bar" [5m])' + `rate({bar="baz", job="foo", k1=~"v.*", k2=~"v'.*"} |= "bar" [5m])` ); }); @@ -325,8 +325,15 @@ describe('LokiDatasource', () => { variable = {} as unknown as CustomVariableModel; }); - it('should only escape single quotes', () => { - expect(ds.interpolateQueryExpr("abc'$^*{}[]+?.()|", variable)).toEqual("abc\\\\'$^*{}[]+?.()|"); + it('should not escape', () => { + expect(ds.interpolateQueryExpr("abc'$^*{}[]+?.()|", variable)).toEqual("abc'$^*{}[]+?.()|"); + }); + + it('should not escape single quotes in line filters', () => { + expect(ds.interpolateQueryExpr("|= `abc'$^*{}[]+?.()|`", variable)).toEqual("|= `abc'$^*{}[]+?.()|`"); + expect(ds.interpolateQueryExpr("|~ `abc'$^*{}[]+?.()|`", variable)).toEqual("|~ `abc'$^*{}[]+?.()|`"); + expect(ds.interpolateQueryExpr("!= `abc'$^*{}[]+?.()|`", variable)).toEqual("!= `abc'$^*{}[]+?.()|`"); + expect(ds.interpolateQueryExpr("!~ `abc'$^*{}[]+?.()|`", variable)).toEqual("!~ `abc'$^*{}[]+?.()|`"); }); it('should return a number', () => { diff --git a/public/app/plugins/datasource/loki/datasource.ts b/public/app/plugins/datasource/loki/datasource.ts index 4a436dc4b87..ca87c5de46f 100644 --- a/public/app/plugins/datasource/loki/datasource.ts +++ b/public/app/plugins/datasource/loki/datasource.ts @@ -814,7 +814,7 @@ export class LokiDatasource interpolateQueryExpr(value: any, variable: QueryVariableModel | CustomVariableModel) { // if no multi or include all do not regexEscape if (!variable.multi && !variable.includeAll) { - return lokiRegularEscape(value); + return value; } if (typeof value === 'string') { @@ -1097,13 +1097,8 @@ export class LokiDatasource expr = adhocFilters.reduce((acc: string, filter: { key: string; operator: string; value: string }) => { const { key, operator } = filter; let { value } = filter; - if (isRegexSelector(operator)) { - // Adhoc filters don't support multiselect, therefore if user selects regex operator - // we are going to consider value to be regex filter and use lokiRegularEscape - // that does not escape regex special characters (e.g. .*test.* => .*test.*) - value = lokiRegularEscape(value); - } else { - // Otherwise, we want to escape special characters in value + if (!isRegexSelector(operator)) { + // We want to escape special characters in value for non-regex selectors to match the same char in the log line as the user types in the input value = escapeLabelValueInSelector(value, operator); } return addLabelToQuery(acc, key, operator, value); @@ -1207,20 +1202,9 @@ export class LokiDatasource }; } } - -// NOTE: these two functions are very similar to the escapeLabelValueIn* functions -// 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 lokiRegularEscape(value: T) { - if (typeof value === 'string') { - return value.replace(/'/g, "\\\\'"); - } - return value; -} - export function lokiSpecialRegexEscape(value: T) { if (typeof value === 'string') { - return lokiRegularEscape(value.replace(/\\/g, '\\\\\\\\').replace(/[$^*{}\[\]+?.()|]/g, '\\\\$&')); + return value.replace(/\\/g, '\\\\\\\\').replace(/[$^*{}\[\]+?.()|]/g, '\\\\$&'); } return value; }