Skip to content

fix: escape regex metacharacters in Q.like (LokiJS adapter diverges from SQLite)#1968

Open
sravan27 wants to merge 1 commit into
Nozbe:masterfrom
sravan27:fix/like-escape-regex-metachars
Open

fix: escape regex metacharacters in Q.like (LokiJS adapter diverges from SQLite)#1968
sravan27 wants to merge 1 commit into
Nozbe:masterfrom
sravan27:fix/like-escape-regex-metachars

Conversation

@sravan27

Copy link
Copy Markdown

Summary

likeToRegexp (used by the LokiJS/web adapter to evaluate Q.like/Q.notLike) builds a RegExp from the LIKE pattern but never escapes regex special characters — it only maps %.* and _.. SQL LIKE treats every character other than %/_ as a literal, and the SQLite adapter passes the pattern straight to SQL LIKE, so the two adapters disagree:

  • Silent wrong results: Q.like('%.pdf') matches 'docXpdf' on LokiJS (. = any char) but only real .pdf strings on SQLite; Q.like('a.b') matches 'axb'.
  • Crash: Q.like('a(b') / Q.like('%(foo)%') throws SyntaxError: Invalid regular expression (unbalanced group) on the LokiJS/web adapter.

Fix

Escape regex metacharacters before substituting the %/_ wildcards. The s/i flags are unchanged, so dotall + case-insensitive behaviour is preserved.

Tests

Added src/utils/fp/likeToRegexp/test.js: wildcards, dotall + case-insensitivity (no regression), literal metacharacters (matching the SQLite adapter), and the no-crash cases. The mapping was also cross-checked against SQLite LIKE with a reference script — the current implementation diverges or crashes on 6/12 inputs; the fixed one matches all 12.

Opened as a draft pending a CI run.

`likeToRegexp` (LokiJS/web adapter, used for Q.like/Q.notLike) built a RegExp
from the LIKE pattern without escaping regex special characters. SQL LIKE treats
everything except `%`/`_` as a literal, and the SQLite adapter does too, so the
two adapters diverged:

- silent wrong results: `Q.like('%.pdf')` matched 'docXpdf' (`.` = any char) on
  LokiJS but only real '.pdf' on SQLite; `Q.like('a.b')` matched 'axb'
- crash: `Q.like('a(b')` / `Q.like('%(foo)%')` threw "Invalid regular expression"

Escape regex metacharacters before substituting the `%`/`_` wildcards. The
`s`/`i` flags are unchanged, so dotall + case-insensitive behaviour is preserved.
Adds regression tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@sravan27 sravan27 marked this pull request as ready for review May 29, 2026 14:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant