From b07b927a9457a33c270b4515711768f56c2a7784 Mon Sep 17 00:00:00 2001 From: ttshivers Date: Tue, 14 May 2024 09:57:35 -0500 Subject: [PATCH] Tempo: Escape backslash in span name for promsql query (#83024) * Tempo: Escape backslash in span name for promsql query In promsql, backslashes in regexes must be doubly escaped for them to be interpreted as a literal backslash character. Fixes #79791 * Fix regex replace --------- Co-authored-by: Andrej Ocenas --- public/app/plugins/datasource/tempo/datasource.test.ts | 2 ++ public/app/plugins/datasource/tempo/datasource.ts | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/public/app/plugins/datasource/tempo/datasource.test.ts b/public/app/plugins/datasource/tempo/datasource.test.ts index 6b46d252b8f..957eefec24a 100644 --- a/public/app/plugins/datasource/tempo/datasource.test.ts +++ b/public/app/plugins/datasource/tempo/datasource.test.ts @@ -724,12 +724,14 @@ describe('Tempo service graph view', () => { '/actuator/health/**', '$type + [test]|HTTP POST - post', 'server.cluster.local:9090^/sample.test(.*)?', + 'test\\path', ]; let escaped = getEscapedSpanNames(spanNames); expect(escaped).toEqual([ '/actuator/health/\\\\*\\\\*', '\\\\$type \\\\+ \\\\[test\\\\]\\\\|HTTP POST - post', 'server\\\\.cluster\\\\.local:9090\\\\^/sample\\\\.test\\\\(\\\\.\\\\*\\\\)\\\\?', + 'test\\\\\\\\path', ]); }); diff --git a/public/app/plugins/datasource/tempo/datasource.ts b/public/app/plugins/datasource/tempo/datasource.ts index a453700ed83..04b3ac936e1 100644 --- a/public/app/plugins/datasource/tempo/datasource.ts +++ b/public/app/plugins/datasource/tempo/datasource.ts @@ -955,8 +955,10 @@ function makePromLink(title: string, expr: string, datasourceUid: string, instan }; } +// TODO: this is basically the same as prometheus/datasource.ts#prometheusSpecialRegexEscape which is used to escape +// template variable values. It would be best to move it to some common place. export function getEscapedSpanNames(values: string[]) { - return values.map((value: string) => value.replace(/[.*+?^${}()|[\]\\]/g, '\\\\$&')); + return values.map((value: string) => value.replace(/\\/g, '\\\\\\\\').replace(/[$^*{}\[\]\'+?.()|]/g, '\\\\$&')); } export function getFieldConfig(