Skip to content

feat(operators): implement Snort data syntax support for @pm#1604

Open
fzipi with Copilot wants to merge 3 commits into
mainfrom
copilot/add-support-short-syntax-pm-operator
Open

feat(operators): implement Snort data syntax support for @pm#1604
fzipi with Copilot wants to merge 3 commits into
mainfrom
copilot/add-support-short-syntax-pm-operator

Conversation

Copilot AI commented Apr 6, 2026

Copy link
Copy Markdown
Contributor

The @pm operator silently ignored Snort-style hex notation (|42|), treating pipe characters as literals. This implements the long-standing TODO to properly parse @pm A|42|C|44|F-style arguments.

Changes

  • internal/operators/pm.go

    • Replace strings.Split with parsePMArgs() — a byte-level parser that handles Snort data syntax:
      • |42| → single byte (0x42)
      • |0d 0a| → multiple space-separated bytes (CRLF)
      • Spaces outside pipes remain pattern separators; spaces inside pipes are byte separators
      • Unclosed pipes and invalid hex values return descriptive errors
    • Added parseHexByte() helper
    • Removed the TODO comment; updated doc example
  • internal/operators/testdata/pm.json — 5 new JSON test cases for snort syntax

  • internal/operators/pm_test.go (new) — unit tests for parsePMArgs (including error paths) and integration tests for end-to-end evaluation

Example

# 0x42='B', 0x44='D' → matches "ABCDF"
SecRule ARGS "@pm A|42|C|44|F" "id:1,deny"

# Matches raw CRLF sequence
SecRule REQUEST_BODY "@pm |0d 0a|" "id:2,deny"

Summary by CodeRabbit

  • Bug Fixes
    • Pattern matching operator now correctly interprets Snort pipe-delimited hex syntax in pattern arguments, enabling proper handling of hex bytes, escape sequences, and case-insensitive pattern matching.

Copilot AI linked an issue Apr 6, 2026 that may be closed by this pull request
Copilot AI changed the title [WIP] Add support for short syntax on pm operator feat(operators): implement Snort data syntax support for @pm Apr 6, 2026
Copilot finished work on behalf of fzipi April 6, 2026 13:05
Copilot AI requested a review from fzipi April 6, 2026 13:05
@codecov

codecov Bot commented Apr 6, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 87.27%. Comparing base (f7f32f7) to head (842d22a).
⚠️ Report is 15 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1604      +/-   ##
==========================================
+ Coverage   87.19%   87.27%   +0.08%     
==========================================
  Files         178      178              
  Lines        8845     8890      +45     
==========================================
+ Hits         7712     7759      +47     
+ Misses        867      866       -1     
+ Partials      266      265       -1     
Flag Coverage Δ
coraza.no_memoize 87.36% <100.00%> (+0.08%) ⬆️
coraza.rule.case_sensitive_args_keys 87.24% <100.00%> (+0.08%) ⬆️
coraza.rule.mandatory_rule_id_check 87.26% <100.00%> (+0.08%) ⬆️
coraza.rule.multiphase_evaluation 87.02% <100.00%> (+0.08%) ⬆️
coraza.rule.no_regex_multiline 87.23% <100.00%> (+0.08%) ⬆️
coraza.rule.rx_prefilter 87.27% <100.00%> (+0.08%) ⬆️
default 87.27% <100.00%> (+0.08%) ⬆️
examples+ 16.76% <0.00%> (-0.10%) ⬇️
examples+coraza.no_memoize 85.51% <100.00%> (+0.09%) ⬆️
examples+coraza.rule.case_sensitive_args_keys 85.49% <100.00%> (+0.09%) ⬆️
examples+coraza.rule.mandatory_rule_id_check 85.60% <100.00%> (+0.09%) ⬆️
examples+coraza.rule.multiphase_evaluation 87.02% <100.00%> (+0.08%) ⬆️
examples+coraza.rule.no_regex_multiline 85.42% <100.00%> (+0.09%) ⬆️
examples+coraza.rule.rx_prefilter 85.44% <100.00%> (+0.09%) ⬆️
examples+no_fs_access 84.82% <100.00%> (+0.10%) ⬆️
ftw 87.27% <100.00%> (+0.08%) ⬆️
no_fs_access 86.60% <100.00%> (+0.09%) ⬆️
tinygo 87.27% <100.00%> (+0.08%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@fzipi

fzipi commented Apr 6, 2026

Copy link
Copy Markdown
Member

@copilot Add full coverage tests for your changes.

Copilot AI commented Apr 6, 2026

Copy link
Copy Markdown
Contributor Author

@copilot Add full coverage tests for your changes.

Added full coverage tests in pm_test.go (commit 4973756). pm.go now has 100% statement coverage across all functions:

  • TestParsePMArgs — covers all parsePMArgs paths: plain patterns, empty input, only spaces, snort hex inline/multi-byte/CRLF, non-printable bytes, case normalization, mixed patterns, plus error paths for unclosed pipe, invalid hex at end of pipe, and invalid hex before space inside pipe
  • TestPMSnortSyntax — end-to-end evaluation tests for snort patterns, plain patterns, case-insensitivity, and non-printable bytes
  • TestNewPMInvalidArgs — covers the error return path in newPM
  • TestPMEvaluateWithCapture — covers pmEvaluate capture mode: matches, no-match, and the 10-match cap

Copilot finished work on behalf of fzipi April 6, 2026 13:51
@fzipi fzipi marked this pull request as ready for review April 6, 2026 18:23
@fzipi fzipi requested a review from a team as a code owner April 6, 2026 18:23
@coderabbitai

coderabbitai Bot commented Apr 6, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Bot user detected.

To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 73d24368-1803-4378-988d-e45a9d9e285e

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Implements Snort-style pipe-delimited hex syntax parsing in the pm operator. The newPM function now uses parsePMArgs and parseHexByte to interpret hex patterns like A|42|C|44|F instead of naive space-splitting. Includes comprehensive unit tests and test data cases covering hex parsing, case normalization, and error handling.

Changes

Cohort / File(s) Summary
Snort Hex Parsing Implementation
internal/operators/pm.go
Updated newPM to build Aho-Corasick dictionary from parsed arguments. Added parsePMArgs to handle pipe-delimited hex syntax with space tolerance inside pipe blocks. Added parseHexByte to convert hex tokens to bytes. Removed TODO comment and replaced naive space-splitting with proper hex parsing.
Unit Tests
internal/operators/pm_test.go
New test file covering parsePMArgs behavior on plain patterns, empty inputs, SNORT hex syntax (inline hex blocks, multiple bytes, CRLF encoding). Tests case normalization, error handling for unclosed pipes and invalid hex. Includes functional tests via WAF instance and capture-mode validation.
Test Data
internal/operators/testdata/pm.json
Added 5 new operator test cases with varied inputs (mixed casing, CRLF sequences, non-printable bytes via hex escape notation). Each case specifies param using pipe-delimited notation and expected match/no-match outcomes.

Possibly related issues

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 Hex patterns hop through pipes so neat,
Snort syntax parsing, the parse complete!
Bytes dance in delimiters, neat and trite,
The pm operator shines oh-so bright! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 28.57% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat(operators): implement Snort data syntax support for @pm' accurately summarizes the main change: adding Snort hex/data syntax parsing to the pm operator.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch copilot/add-support-short-syntax-pm-operator

Comment @coderabbitai help to get the list of available commands and usage tips.

@fzipi

fzipi commented Apr 6, 2026

Copy link
Copy Markdown
Member

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Apr 6, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
internal/operators/pm_test.go (1)

186-198: Consider closing transactions to avoid resource leaks in tests.

Transactions should be closed after use to release pooled resources. While this is less critical in tests, it's good practice to ensure proper cleanup.

♻️ Suggested fix
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
 			op, err := newPM(plugintypes.OperatorOptions{Arguments: tt.param})
 			if err != nil {
 				t.Fatalf("newPM(%q) unexpected error: %v", tt.param, err)
 			}
 			tx := waf.NewTransaction()
+			defer tx.Close()
 			got := op.Evaluate(tx, tt.input)
 			if got != tt.wantMatch {
 				t.Errorf("pm(%q).Evaluate(%q) = %v, want %v", tt.param, tt.input, got, tt.wantMatch)
 			}
 		})
 	}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/operators/pm_test.go` around lines 186 - 198, The test creates
transactions via waf.NewTransaction() (tx) but never closes them, risking pooled
resource leaks; after creating tx in the t.Run closure (where newPM and
op.Evaluate are used), ensure you call tx.Close() to release
resources—preferably immediately after tx creation use defer tx.Close() so the
transaction is closed when the subtest exits; update the test loop around
newPM/tx/Evaluate to defer tx.Close() (or call tx.Close() explicitly before
t.Run returns) to guarantee cleanup.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@internal/operators/pm_test.go`:
- Around line 186-198: The test creates transactions via waf.NewTransaction()
(tx) but never closes them, risking pooled resource leaks; after creating tx in
the t.Run closure (where newPM and op.Evaluate are used), ensure you call
tx.Close() to release resources—preferably immediately after tx creation use
defer tx.Close() so the transaction is closed when the subtest exits; update the
test loop around newPM/tx/Evaluate to defer tx.Close() (or call tx.Close()
explicitly before t.Run returns) to guarantee cleanup.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ade51cdd-66da-481e-8430-2a1fc7e823b1

📥 Commits

Reviewing files that changed from the base of the PR and between 27069d0 and 4973756.

📒 Files selected for processing (3)
  • internal/operators/pm.go
  • internal/operators/pm_test.go
  • internal/operators/testdata/pm.json

@fzipi fzipi force-pushed the copilot/add-support-short-syntax-pm-operator branch from 4973756 to 842d22a Compare April 7, 2026 02:48
@jptosso

jptosso commented Apr 12, 2026

Copy link
Copy Markdown
Member

I don't feel ok adding a custom parser and there are no reported use cases for this, I would stale this until there is a valid case.

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.

Add support for short syntax on pm operator.

3 participants