diff --git a/CHANGELOG.md b/CHANGELOG.md index 28fcc2319..3ee5eada6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ### Bug Fixes +1. [#5554](https://github.com/influxdata/chronograf/pull/5554): Escape tag values in query builder. 1. [#5551](https://github.com/influxdata/chronograf/pull/5551): Sort namespaces by database and retention policy. ### Features diff --git a/ui/src/utils/influxql.ts b/ui/src/utils/influxql.ts index 50f52cc70..da946af98 100644 --- a/ui/src/utils/influxql.ts +++ b/ui/src/utils/influxql.ts @@ -154,11 +154,13 @@ export function buildWhereClause({ const cond = areTagsAccepted ? ' OR ' : ' AND ' if (tags[k].length > 1) { - const joinedOnOr = tags[k].map(v => `"${k}"${operator}'${v}'`).join(cond) + const joinedOnOr = tags[k] + .map(v => `"${k}"${operator}'${v.replace(/'/g, "\\'")}'`) + .join(cond) return `(${joinedOnOr})` } - return `"${k}"${operator}'${tags[k]}'` + return `"${k}"${operator}'${tags[k].map(v => v.replace(/'/g, "\\'"))}'` }) const subClauses = timeClauses.concat(tagClauses) diff --git a/ui/test/utils/influxql.test.ts b/ui/test/utils/influxql.test.ts index 1fb09873b..69a1ffb68 100644 --- a/ui/test/utils/influxql.test.ts +++ b/ui/test/utils/influxql.test.ts @@ -331,21 +331,49 @@ describe('buildInfluxQLQuery', () => { }) describe('build query', () => { - beforeEach(() => { - config = mergeConfig({ + it('builds an influxql relative time bound query', () => { + const queryConfig = mergeConfig({ database: 'db1', measurement: 'm1', retentionPolicy: 'rp1', fields: [{value: 'f1', type: 'field'}], groupBy: {time: '10m', tags: []}, }) - }) - it('builds an influxql relative time bound query', () => { const timeRange = {upper: null, lower: 'now() - 15m'} const expected = 'SELECT "f1" FROM "db1"."rp1"."m1" WHERE time > now() - 15m GROUP BY time(10m) FILL(null)' - const actual = buildQuery(TYPE_QUERY_CONFIG, timeRange, config) + const actual = buildQuery(TYPE_QUERY_CONFIG, timeRange, queryConfig) + + expect(actual).toBe(expected) + }) + it('builds an influxql with escaped tag value', () => { + const queryConfig = mergeConfig({ + database: 'db1', + measurement: 'm1', + retentionPolicy: 'rp1', + tags: {t1: ["pavel's"]}, + fields: [{value: 'f1', type: 'field'}], + }) + + const timeRange = {lower: ''} + const expected = `SELECT "f1" FROM "db1"."rp1"."m1" WHERE "t1"='pavel\\'s'` + const actual = buildQuery(TYPE_QUERY_CONFIG, timeRange, queryConfig) + + expect(actual).toBe(expected) + }) + it('builds an influxql with escaped tag values', () => { + const queryConfig = mergeConfig({ + database: 'db1', + measurement: 'm1', + retentionPolicy: 'rp1', + tags: {t1: ["pavel's", "o'harry's", 'a']}, + fields: [{value: 'f1', type: 'field'}], + }) + + const timeRange = {lower: ''} + const expected = `SELECT "f1" FROM "db1"."rp1"."m1" WHERE ("t1"='pavel\\'s' OR "t1"='o\\'harry\\'s' OR "t1"='a')` + const actual = buildQuery(TYPE_QUERY_CONFIG, timeRange, queryConfig) expect(actual).toBe(expected) })