Fix RegexpError 500 in search highlighting when a term contains regex metacharacters - #479
Fix RegexpError 500 in search highlighting when a term contains regex metacharacters#479jeremy wants to merge 1 commit into
Conversation
… metacharacters
SearchesHelper#whole_word_matchers interpolated a term straight into
/\b#{term}\b/ without escaping it. The terms come from SQLite FTS5
highlight() spans, which can carry document punctuation — a phrase match
spanning "foo) bar" yields a term with an unbalanced parenthesis, so the
Regexp constructor raises RegexpError and the leaf page 500s.
Escape the term with Regexp.escape so metacharacters are matched
literally. Adds a helper test and a controller test covering a phrase
match whose highlight span contains metacharacters.
There was a problem hiding this comment.
Pull request overview
Escapes FTS5 highlight spans before regex interpolation, preventing RegexpError while preserving literal highlighting.
Changes:
- Applies
Regexp.escapeto matched terms. - Adds helper and integration regression coverage.
Tip
If you aren't ready for review, convert to a draft PR.
Click "Convert to draft" or run gh pr ready --undo.
Click "Ready for review" or run gh pr ready to reengage.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
app/helpers/searches_helper.rb |
Safely constructs highlight regexes. |
test/helpers/searches_helper_test.rb |
Tests metacharacter highlighting. |
test/controllers/leafables_controller_test.rb |
Tests the full page-rendering regression. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| section = Section.new(body: "alpha) omega in the body") | ||
| books(:handbook).press(section, title: "Punctuated") | ||
| section.leaf.reindex |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f12c4cf0cf
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| section = Section.new(body: "alpha) omega in the body") | ||
| books(:handbook).press(section, title: "Punctuated") |
There was a problem hiding this comment.
Reuse the existing section fixture
This test creates and presses a new Section even though leaves(:welcome_section) already provides a section-backed leaf. Update that fixture's body for the test and reindex it instead, avoiding unnecessary record creation and following the repository's explicit testing convention.
AGENTS.md reference: AGENTS.md:L5-L6
Useful? React with 👍 / 👎.
|
🤖 Superseded by #481, which was merged and folded in this exact |
Problem
SearchesHelper#whole_word_matchersinterpolates a matched term straight into/\b#{term}\b/without escaping it:These terms are not the raw search query — they are spans pulled from SQLite FTS5's
highlight()output, which can include document punctuation. A phrase match spanning something likefoo) barproduces a term with an unbalanced parenthesis, so theRegexpconstructor raisesRegexpErrorand the leaf page 500s instead of rendering the highlighted result.Reproduction: a book body containing
alpha) omega, then viewing that page with?search="alpha omega"(a phrase query) raisesRegexpError: unmatched close parenthesis: /\balpha) omega\b/.Fix
Escape the term with
Regexp.escapebefore interpolation so metacharacters are matched literally:The whole-word
\bboundaries and the rest of the highlighting behavior are unchanged; the escaped term still highlights correctly.Tests
highlight_searched_contenthandles a matched term containing regex metacharacters.Both fail with
RegexpErrorbefore the change and pass after.