From 7c6bab8c58e5fb3c07df78d2fea1cdac2dd020a5 Mon Sep 17 00:00:00 2001 From: Asish Kumar Date: Mon, 11 May 2026 11:25:29 +0530 Subject: [PATCH] ui: escape label values in PromQL autocomplete Signed-off-by: Asish Kumar --- .../module/codemirror-promql/src/complete/hybrid.test.ts | 8 ++++++++ web/ui/module/codemirror-promql/src/complete/hybrid.ts | 6 +++++- .../codemirror-promql/src/test/label_env_values.json | 4 +++- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/web/ui/module/codemirror-promql/src/complete/hybrid.test.ts b/web/ui/module/codemirror-promql/src/complete/hybrid.test.ts index facda35ac8..35fcebe63a 100644 --- a/web/ui/module/codemirror-promql/src/complete/hybrid.test.ts +++ b/web/ui/module/codemirror-promql/src/complete/hybrid.test.ts @@ -1568,6 +1568,14 @@ describe('autocomplete promQL test', () => { label: 'demo', type: 'text', }, + { + label: '\\\\x2d', + type: 'text', + }, + { + label: 'quoted\\"value', + type: 'text', + }, ], from: 25, to: 25, diff --git a/web/ui/module/codemirror-promql/src/complete/hybrid.ts b/web/ui/module/codemirror-promql/src/complete/hybrid.ts index cff7457c93..91dd9d7ae7 100644 --- a/web/ui/module/codemirror-promql/src/complete/hybrid.ts +++ b/web/ui/module/codemirror-promql/src/complete/hybrid.ts @@ -168,6 +168,10 @@ function arrayToCompletionResult(data: Completion[], from: number, to: number, i } as CompletionResult; } +function escapePromQLString(str: string): string { + return str.replace(/([\\"])/g, '\\$1'); +} + // computeEndCompletePosition calculates the end position for autocompletion replacement. // When the cursor is in the middle of a token, this ensures the entire token is replaced, // not just the portion before the cursor. This fixes issue #15839. @@ -794,7 +798,7 @@ export class HybridComplete implements CompleteStrategy { return result; } return this.prometheusClient.labelValues(context.labelName, context.metricName, context.matchers).then((labelValues: string[]) => { - return result.concat(labelValues.map((value) => ({ label: value, type: 'text' }))); + return result.concat(labelValues.map((value) => ({ label: escapePromQLString(value), type: 'text' }))); }); } } diff --git a/web/ui/module/codemirror-promql/src/test/label_env_values.json b/web/ui/module/codemirror-promql/src/test/label_env_values.json index 4710cd76e3..dc3aa8c5d7 100644 --- a/web/ui/module/codemirror-promql/src/test/label_env_values.json +++ b/web/ui/module/codemirror-promql/src/test/label_env_values.json @@ -1,6 +1,8 @@ { "status": "success", "data": [ - "demo" + "demo", + "\\x2d", + "quoted\"value" ] }