Skip to content

feat: escape special characters in filter values#147

Draft
trejjam wants to merge 6 commits intomainfrom
feature/filter-escape-chars
Draft

feat: escape special characters in filter values#147
trejjam wants to merge 6 commits intomainfrom
feature/filter-escape-chars

Conversation

@trejjam
Copy link
Copy Markdown
Member

@trejjam trejjam commented Apr 7, 2026

Problem

MoneyERP's filter DSL uses #, |, and ~ as structural operators (AND, OR, and operator delimiter respectively). When a field value contains any of these characters — e.g. a Colombian street address CRA 80A # 17-85 — the filter string becomes ambiguous and the server misparses it.

Real-world example (anonymized):

Kod~sw~ABC123#FaktNazev~eq~John Doe#FaktUlice~eq~CRA 80A # 17-85#FaktMisto~eq~Bogota

The # inside the street address is indistinguishable from the AND operator, causing the server to parse 5 clauses instead of 4.

What was tried

Approach Result
URL encoding (%23, %7C) ❌ Server does not decode — treats %23 as literal text
Backslash escaping (\#, |, \~) ❌ Server does not interpret — likely uses naive Split('#')

Conclusion: The MoneyERP server has no escape mechanism for operator characters in filter values. This is a server-side limitation that requires a fix from Solitea (MoneyERP vendor).

Changes

FilterFor.cs — Configurable value escaping infrastructure

  • Added EscapeFilterValue() method that scans values for operator characters and replaces them using configurable EscapeRules
  • Escape rules are defined as (char Character, string Replacement) tuples — easy to swap the escaping scheme when a working one is found
  • Fast path: values without special characters are returned unchanged (no allocation)
  • GetFilterClause now calls EscapeFilterValue before interpolating the value

FilterForTests.ValueContainingOperatorCharacters.cs — Unit tests

  • AndWithValueContainingHashIsEscaped — Full reproduction of the real failing request (anonymized 8-clause AND filter with # in street address)
  • EqualWithValueContainingHash/Tilde/Pipe/Backslash — Isolated tests per operator character
  • EqualWithValueContainingMultipleSpecialCharacters — All operators in one value
  • EqualWithValueWithoutSpecialCharactersIsUnchanged — Fast path verification
  • EscapeFilterValue* — Direct unit tests of the escape method

MoneyErpCompanyFilterTests.cs — Integration test

  • Creates a company with # in the street address via GraphQL mutation
  • Queries it back using a filter containing the # value
  • If filter-with-# returns nothing but filter-without-# finds the company → Assert.Fail proving the escaping bug
  • Marked Explicit = true (requires MONEYERP_CLIENT_ID, MONEYERP_CLIENT_SECRET, MONEYERP_ENDPOINT env vars)

Status

⚠️ Tests currently fail because no escaping scheme works with the MoneyERP server. The infrastructure is in place — once Solitea provides a working escape mechanism, we just update the EscapeRules array and the test assertions.

References

trejjam added 6 commits April 7, 2026 19:48
MoneyERP filter DSL uses #, |, ~ as structural operators (AND, OR,
operator delimiter). When field values contain these characters
(e.g. street address "CRA 80A # 17-85"), the filter string becomes
ambiguous and the server misparses it.

Add EscapeFilterValue() to FilterFor<T> that replaces operator
characters with configurable escape sequences. Currently uses
backslash escaping (\#, \|, \~) but this does NOT work with the
MoneyERP server - they appear to use a naive Split('#') approach
with no escape support. The escape rules are configurable via the
EscapeRules array for when/if a working scheme is found.

Also adds:
- Unit tests for all operator characters in filter values
- Integration test (MoneyErpCompanyFilterTests) that creates a
  company with '#' in the street address and verifies the filter
  round-trip, exposing the server-side parsing limitation.

URL encoding (%23, %7C) was also tested and does not work.
This is likely a MoneyERP server limitation requiring their fix.
Refactor MoneyErpCompanyFilterTests to extract shared logic into
a parameterized helper. Add two new test methods covering tilde
and pipe characters in company street address filter values,
alongside the existing hash test.
@trejjam trejjam force-pushed the feature/filter-escape-chars branch from ce6e085 to 8432131 Compare April 7, 2026 17:48
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