[PR #1054] [CLOSED] fix: handle quotes in project filter titles #4654

Closed
opened 2026-04-16 13:12:02 -05:00 by GiteaMirror · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/go-vikunja/vikunja/pull/1054
Author: @dpschen
Created: 7/1/2025
Status: Closed

Base: mainHead: feat/fix-project-filter-issue-with-special-characters


📝 Commits (1)

  • 2b16c22 fix: handle quotes in project filter titles

📊 Changes

2 files changed (+24 additions, -4 deletions)

View changed files

📝 frontend/src/helpers/filters.test.ts (+20 -0)
📝 frontend/src/helpers/filters.ts (+4 -4)

📄 Description

Summary

  • allow quotes in filter regex
  • adjust filter parsing logic
  • test converting project titles with single quotes

Fixes #743


The filter helper getFilterFieldRegexPattern() changed how it parses filter values.
Earlier versions matched optional quotes around the value and disallowed any quote characters inside it:

export const FILTER_OPERATORS_REGEX = '(<|>|<=|>=|=|!=|in)'

export function getFilterFieldRegexPattern(field: string): RegExp {
        return new RegExp('(' + field + '\\s*' + FILTER_OPERATORS_REGEX + '\\s*)([\\'\"]?)([^\\'\"&|()<]+\\1?)?', 'ig')
}

This meant values like project = Todo's failed to match because the single quote was interpreted as closing a quoted value.

The current code dropped the quote-specific groups and simply captures any characters until a filter operator or parenthesis:

export const FILTER_OPERATORS_REGEX = '(<|>|<=|>=|=|!=|not in|in)'

export function getFilterFieldRegexPattern(field: string): RegExp {
        return new RegExp('(' + field + '\\s*' + FILTER_OPERATORS_REGEX + '\\s*)([^&|()]+)', 'ig')
}

This mirrors the server-side regex used to parse filter expressions:

// Regex pattern to match filter expressions
re := regexp.MustCompile(`(\w+)\s*(>=|<=|!=|~|\?=|\?!=|=|>|<)\s*([^&|()]+)`)

Why it was like it was before:

The old pattern expected a value to be optionally wrapped in quotes and prohibited any internal quote characters. That avoided accidental splitting if quotes were used as delimiters, but it broke when project or tag names themselves contained a ' or ".

Why it changed:

To support names that include quotes, the frontend regex now matches everything up to &, |, or parentheses—just like the backend. This allows titles such as "Todo's" to be parsed correctly, ensuring filters behave consistently across frontend and backend.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/go-vikunja/vikunja/pull/1054 **Author:** [@dpschen](https://github.com/dpschen) **Created:** 7/1/2025 **Status:** ❌ Closed **Base:** `main` ← **Head:** `feat/fix-project-filter-issue-with-special-characters` --- ### 📝 Commits (1) - [`2b16c22`](https://github.com/go-vikunja/vikunja/commit/2b16c22f29a1fe60303dc5da82487daa7db04c5b) fix: handle quotes in project filter titles ### 📊 Changes **2 files changed** (+24 additions, -4 deletions) <details> <summary>View changed files</summary> 📝 `frontend/src/helpers/filters.test.ts` (+20 -0) 📝 `frontend/src/helpers/filters.ts` (+4 -4) </details> ### 📄 Description ## Summary - allow quotes in filter regex - adjust filter parsing logic - test converting project titles with single quotes Fixes #743 ------- The filter helper getFilterFieldRegexPattern() changed how it parses filter values. Earlier versions matched optional quotes around the value and disallowed any quote characters inside it: ```ts export const FILTER_OPERATORS_REGEX = '(<|>|<=|>=|=|!=|in)' export function getFilterFieldRegexPattern(field: string): RegExp { return new RegExp('(' + field + '\\s*' + FILTER_OPERATORS_REGEX + '\\s*)([\\'\"]?)([^\\'\"&|()<]+\\1?)?', 'ig') } ``` This meant values like project = Todo's failed to match because the single quote was interpreted as closing a quoted value. The current code dropped the quote-specific groups and simply captures any characters until a filter operator or parenthesis: ```ts export const FILTER_OPERATORS_REGEX = '(<|>|<=|>=|=|!=|not in|in)' export function getFilterFieldRegexPattern(field: string): RegExp { return new RegExp('(' + field + '\\s*' + FILTER_OPERATORS_REGEX + '\\s*)([^&|()]+)', 'ig') } ``` This mirrors the server-side regex used to parse filter expressions: ```go // Regex pattern to match filter expressions re := regexp.MustCompile(`(\w+)\s*(>=|<=|!=|~|\?=|\?!=|=|>|<)\s*([^&|()]+)`) ``` ### Why it was like it was before: The old pattern expected a value to be optionally wrapped in quotes and prohibited any internal quote characters. That avoided accidental splitting if quotes were used as delimiters, but it broke when project or tag names themselves contained a ' or ". ### Why it changed: To support names that include quotes, the frontend regex now matches everything up to &, |, or parentheses—just like the backend. This allows titles such as "Todo's" to be parsed correctly, ensuring filters behave consistently across frontend and backend. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
GiteaMirror added the pull-request label 2026-04-16 13:12:02 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/vikunja#4654