Skip to content

Commit

Permalink
Merge pull request #202 from redis/issue-198-tag-wildcard
Browse files Browse the repository at this point in the history
Fixed problem with escaping question marks in TAGs
  • Loading branch information
guyroyse authored Jul 26, 2023
2 parents 39fa5ff + 8da813f commit 73abb62
Show file tree
Hide file tree
Showing 10 changed files with 29 additions and 21 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and Redis OM adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## 0.4.2 - 2023-07-26
### Fixed
- Fixed issue with TAGs not properl;y escaping question marks

## 0.4.1 - 2023-07-26
### Added
- Added new type of `number[]` which works just like `number` but against an array of them
Expand Down
10 changes: 8 additions & 2 deletions lib/search/where-field.ts
Original file line number Diff line number Diff line change
Expand Up @@ -310,13 +310,19 @@ export abstract class WhereField {
/** @internal */
protected buildQuery(valuePortion: string): string {
const negationPortion = this.negated ? '-' : ''
const fieldPortion = this.escapePunctuation(this.field.name)
const fieldPortion = this.escapePunctuationAndSpaces(this.field.name)
return `(${negationPortion}@${fieldPortion}:${valuePortion})`
}

/** @internal */
protected escapePunctuation(value: string): string {
const matchPunctuation = /[,.<>{}[\]"':;!@#$%^&()\-+=~|/\\ ]/g
const matchPunctuation = /[,.?<>{}[\]"':;!@#$%^&()\-+=~|/\\]/g
return value.replace(matchPunctuation, '\\$&')
}

/** @internal */
protected escapePunctuationAndSpaces(value: string): string {
const matchPunctuation = /[,.?<>{}[\]"':;!@#$%^&()\-+=~|/\\ ]/g
return value.replace(matchPunctuation, '\\$&')
}
}
3 changes: 1 addition & 2 deletions lib/search/where-string-array.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ export class WhereStringArray extends WhereField {
containOneOf(...value: Array<string>): Search { return this.containsOneOf(...value) }

toString(): string {
const matchPunctuation = /[,.<>{}[\]"':;!@#$%^&()\-+=~| ]/g
const escapedValue = this.value.map(s => s.replace(matchPunctuation, '\\$&')).join('|')
const escapedValue = this.value.map(s => this.escapePunctuationAndSpaces(s)).join('|')
return this.buildQuery(`{${escapedValue}}`)
}
}
2 changes: 1 addition & 1 deletion lib/search/where-string.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export class WhereString extends WhereField {
get exactly() { return this.throwMatchExcpetionReturningThis() }

toString(): string {
const escapedValue = this.escapePunctuation(this.value)
const escapedValue = this.escapePunctuationAndSpaces(this.value)
return this.buildQuery(`{${escapedValue}}`)
}

Expand Down
3 changes: 1 addition & 2 deletions lib/search/where-text.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,7 @@ export class WhereText extends WhereField {
equalTo(_: string | number | boolean): Search { return this.throwEqualsExcpetion() }

toString(): string {
const matchPunctuation = /[,.<>{}[\]"':;!@#$%^&()\-+=~|]/g
const escapedValue = this.value.replace(matchPunctuation, '\\$&')
const escapedValue = this.escapePunctuation(this.value)

if (this.exactValue) {
return this.buildQuery(`"${escapedValue}"`)
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "redis-om",
"version": "0.4.1",
"version": "0.4.2",
"description": "Object mapping, and more, for Redis and Node.js. Written in TypeScript.",
"main": "dist/index.js",
"types": "./dist/index.d.ts",
Expand Down
8 changes: 4 additions & 4 deletions spec/unit/search/search-by-string-array.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,13 @@ describe("Search", () => {
it("generates a query with .does.not.containOneOf", () => expectToBeNegatedContainsOneQuery(where.does.not.containOneOf(A_STRING, ANOTHER_STRING, A_THIRD_STRING)))

it("generates a query with .contains that escapes all punctuation", () => {
let query = where.contains(",.<>{}[]\"':;|!@#$%^&()-+=~ ").query
expect(query).toBe("(@someStrings:{\\,\\.\\<\\>\\{\\}\\[\\]\\\"\\'\\:\\;\\|\\!\\@\\#\\$\\%\\^\\&\\(\\)\\-\\+\\=\\~\\ })")
let query = where.contains(",.?<>{}[]\"':;|!@#$%^&()-+=~/\\ ").query
expect(query).toBe("(@someStrings:{\\,\\.\\?\\<\\>\\{\\}\\[\\]\\\"\\'\\:\\;\\|\\!\\@\\#\\$\\%\\^\\&\\(\\)\\-\\+\\=\\~\\/\\\\\\ })")
})

it("generates a query with .containsOneOf that escapes all punctuation", () => {
let query = where.containsOneOf(",.<>{}[]\"':;|", "!@#$%^&()-+=~ ").query
expect(query).toBe("(@someStrings:{\\,\\.\\<\\>\\{\\}\\[\\]\\\"\\'\\:\\;\\||\\!\\@\\#\\$\\%\\^\\&\\(\\)\\-\\+\\=\\~\\ })")
let query = where.containsOneOf(",.?<>{}[]\"':;|", "!@#$%^&()-+=~/\\ ").query
expect(query).toBe("(@someStrings:{\\,\\.\\?\\<\\>\\{\\}\\[\\]\\\"\\'\\:\\;\\||\\!\\@\\#\\$\\%\\^\\&\\(\\)\\-\\+\\=\\~\\/\\\\\\ })")
})

it("generates a query with .contains with a prefix matching wildcard", () => {
Expand Down
6 changes: 3 additions & 3 deletions spec/unit/search/search-by-string.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,11 @@ describe("Search", () => {
})

it("generates a query that escapes all punctuation", () => {
let query = where.eq(",.<>{}[]\"':;!@#$%^&()-+=~|/\\ ").query
expect(query).toBe("(@aString:{\\,\\.\\<\\>\\{\\}\\[\\]\\\"\\'\\:\\;\\!\\@\\#\\$\\%\\^\\&\\(\\)\\-\\+\\=\\~\\|\\/\\\\\\ })")
let query = where.eq(",.?<>{}[]\"':;!@#$%^&()-+=~|/\\ ").query
expect(query).toBe("(@aString:{\\,\\.\\?\\<\\>\\{\\}\\[\\]\\\"\\'\\:\\;\\!\\@\\#\\$\\%\\^\\&\\(\\)\\-\\+\\=\\~\\|\\/\\\\\\ })")
})

it("generates a query with a prefix matching wildcard", () => {
it("generates a query with a prefix matching wildcards", () => {
let query = where.eq("foo*").query
expect(query).toBe("(@aString:{foo*})")
})
Expand Down
8 changes: 4 additions & 4 deletions spec/unit/search/search-by-text.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,13 +117,13 @@ describe("Search", () => {

describe("when generating a query with special characters in the string", () => {
it("generates a query that escapes all punctuation for a match", () => {
let query = where.match(",.<>{}[]\"':;!@#$%^&()-+=~|").query
expect(query).toBe("(@someText:'\\,\\.\\<\\>\\{\\}\\[\\]\\\"\\'\\:\\;\\!\\@\\#\\$\\%\\^\\&\\(\\)\\-\\+\\=\\~\\|')")
let query = where.match(",.?<>{}[]\"':;!@#$%^&()-+=~|\\").query
expect(query).toBe("(@someText:'\\,\\.\\?\\<\\>\\{\\}\\[\\]\\\"\\'\\:\\;\\!\\@\\#\\$\\%\\^\\&\\(\\)\\-\\+\\=\\~\\|\\\\')")
})

it("generates a query that escapes all punctuation for an exact match", () => {
let query = where.exact.match(",.<>{}[]\"':;!@#$%^&()-+=~|").query
expect(query).toBe('(@someText:"\\,\\.\\<\\>\\{\\}\\[\\]\\"\\\'\\:\\;\\!\\@\\#\\$\\%\\^\\&\\(\\)\\-\\+\\=\\~\\|")')
let query = where.exact.match(",.?<>{}[]\"':;!@#$%^&()-+=~|\\").query
expect(query).toBe('(@someText:"\\,\\.\\?\\<\\>\\{\\}\\[\\]\\"\\\'\\:\\;\\!\\@\\#\\$\\%\\^\\&\\(\\)\\-\\+\\=\\~\\|\\\\")')
})
})

Expand Down

0 comments on commit 73abb62

Please sign in to comment.