From 2bd95b2eb5bf0901cecae6ee5e1717a0ebee2a26 Mon Sep 17 00:00:00 2001 From: Jake Leahy Date: Wed, 26 Jun 2024 01:39:32 +1000 Subject: [PATCH] Prometheus: Fix quote stripping in parser (#87675) * Prometheus: Fix quote stripping in parser Currently only double quotes are stripped from the end, while single quotes are left. Moreover, double quotes are stripped even when part of the value * Prometheus: Double escape the string, apply linting fixes for files that I touched --- .../src/querybuilder/parsing.test.ts | 37 +++++++++++++++++++ .../src/querybuilder/parsing.ts | 2 +- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/packages/grafana-prometheus/src/querybuilder/parsing.test.ts b/packages/grafana-prometheus/src/querybuilder/parsing.test.ts index 3bbb8d32aeb..a41be98ada3 100644 --- a/packages/grafana-prometheus/src/querybuilder/parsing.test.ts +++ b/packages/grafana-prometheus/src/querybuilder/parsing.test.ts @@ -746,6 +746,43 @@ describe('buildVisualQueryFromString', () => { }, }); }); + + it('strips enclosing quotes', () => { + expect(buildVisualQueryFromString("counters_logins{app='frontend', host=`localhost`}")).toEqual( + noErrors({ + metric: 'counters_logins', + labels: [ + { + op: '=', + value: 'frontend', + label: 'app', + }, + { + op: '=', + value: 'localhost', + label: 'host', + }, + ], + operations: [], + }) + ); + }); + + it('leaves escaped quotes inside string', () => { + expect(buildVisualQueryFromString('counters_logins{app="fron\\"\\"tend"}')).toEqual( + noErrors({ + metric: 'counters_logins', + labels: [ + { + op: '=', + value: 'fron\\"\\"tend', + label: 'app', + }, + ], + operations: [], + }) + ); + }); }); function noErrors(query: PromVisualQuery) { diff --git a/packages/grafana-prometheus/src/querybuilder/parsing.ts b/packages/grafana-prometheus/src/querybuilder/parsing.ts index 01fd244012e..95a12032051 100644 --- a/packages/grafana-prometheus/src/querybuilder/parsing.ts +++ b/packages/grafana-prometheus/src/querybuilder/parsing.ts @@ -205,7 +205,7 @@ function isIntervalVariableError(node: SyntaxNode) { function getLabel(expr: string, node: SyntaxNode): QueryBuilderLabelFilter { const label = getString(expr, node.getChild(LabelName)); const op = getString(expr, node.getChild(MatchOp)); - const value = getString(expr, node.getChild(StringLiteral)).replace(/"/g, ''); + const value = getString(expr, node.getChild(StringLiteral)).replace(/^["'`]|["'`]$/g, ''); return { label, op,