Skip to content

V3/do not add newline to test body lines#3486

Merged
airween merged 29 commits intoowasp-modsecurity:v3/masterfrom
hnakamur:v3/do_not_add_newline_to_test_body_lines
Feb 12, 2026
Merged

V3/do not add newline to test body lines#3486
airween merged 29 commits intoowasp-modsecurity:v3/masterfrom
hnakamur:v3/do_not_add_newline_to_test_body_lines

Conversation

@hnakamur
Copy link
Contributor

what

  • Stop adding newline to each line of request or response body in regression tests.
  • Add format subcommand to regression_tests command.
  • Support updating Content-Length header by running (cd test; UPDATE_CONTENT_LENGTH=1 ./regression_tests format)
  • Update regression test JSON files:
    • Add newlines to request bodies where needed.
    • Add Content-Length headers.
    • Adjust test casses to pass after above modifications.

why

  • Enable to test edge cases (such as request body lines with newline except the last line). This is important for multipart request bodies.

references

This is needed to test edge cases like a body missing the final newline,
for example:

[
  "a\r\n",
  "b\r"
]

And it is clearer than to add implicit newline to each line except the
final line.
when UPDATE_CONTENT_LENGTH env var is set
by running the following command:
```
(cd test; ./regression_tests format)
```
by running the following command:
```
(cd test; UPDATE_CONTENT_LENGTH=1 ./regression_tests format)
```
@hnakamur hnakamur force-pushed the v3/do_not_add_newline_to_test_body_lines branch from 8fefe12 to 9b49187 Compare January 25, 2026 23:59
@hnakamur
Copy link
Contributor Author

I found JSON was corrupted since some of http_version was empty. I fixed it and force pushed.
However some of tests do not pass right now. I am trying to fix them.

@hnakamur
Copy link
Contributor Author

I fixed tests at aefd4a4 and now all tests pass again.

@airween
Copy link
Member

airween commented Jan 27, 2026

Hi @hnakamur,

thank you for this improved PR.

Unfortunately there are two warnings from cppcheck:

2026-01-26T00:29:37.2162370Z warning: test/regression/regression.cc,444,style,shadowVariable,Local variable 'test' shadows outer variable
2026-01-26T00:29:37.2943530Z warning: test/regression/regression_test.cc,366,style,functionConst,The member function 'modsecurity_test::RegressionTests::toJSON' can be made a const function. Making this function 'const' should not cause compiler errors. Even though the function can be made const function technically it may not make sense conceptually. Think about your design and the task of the function first - is it a function that must not change object internal state?

Also, SonarCloud reported a few new issues (some of them are same as cppcheck found):

https://sonarcloud.io/project/issues?id=owasp-modsecurity_ModSecurity&pullRequest=3486&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true

As I mentioned previously, I don't expect to fix all Sonar issues. If the cppcheck will be passed, I'll review all Sonar issues and try to mark the "old" issues as accepted.

Thank you again.

@airween airween added the 3.x Related to ModSecurity version 3.x label Jan 27, 2026
@airween airween requested a review from Copilot February 6, 2026 16:52
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the regression-test JSON format to preserve request/response body line endings (no implicit newline per line), adds a format subcommand to reformat/normalize test JSON files, and introduces tooling to auto-update Content-Length headers during formatting.

Changes:

  • Added a format subcommand to the regression test runner and optional UPDATE_CONTENT_LENGTH behavior.
  • Updated regression-test parsing structures (e.g., std::unique_ptr, std::optional) and introduced a RegressionTests wrapper with JSON serialization.
  • Mass-updated regression test JSON files to use line-array bodies, normalize escaping, and add Content-Length headers.

Reviewed changes

Copilot reviewed 117 out of 202 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
test/test-cases/regression/transformations.json Reformats request/response bodies as arrays; normalizes headers and adds Content-Length
test/test-cases/regression/transformation-none.json Reformats request/response bodies as arrays; normalizes headers and adds Content-Length
test/test-cases/regression/secruleengine.json Adds explicit client/server/request/response blocks for formatting/schema consistency
test/test-cases/regression/secmarker.json Reformats request/response bodies as arrays; normalizes headers and adds Content-Length
test/test-cases/regression/secargumentslimit.json Adds Content-Length and response skeletons to align with new formatting
test/test-cases/regression/secaction.json Reformats request/response bodies as arrays; normalizes headers and adds Content-Length
test/test-cases/regression/sec_component_signature.json Normalizes escaping and adds Content-Length headers
test/test-cases/regression/rule-920274.json Adds Content-Length and moves to body-as-array representation
test/test-cases/regression/rule-920200.json Adds Content-Length and moves to body-as-array representation
test/test-cases/regression/rule-920120.json Updates multipart body line endings and Content-Length
test/test-cases/regression/request-body-parser-multipart-crlf.json Updates multipart body line endings and Content-Length
test/test-cases/regression/operator-verifysvnr.json Updates Content-Length values and expected http_code
test/test-cases/regression/operator-verifyssn.json Updates Content-Length values and expected http_code
test/test-cases/regression/operator-verifycpf.json Updates Content-Length values and expected http_code
test/test-cases/regression/operator-verifycc.json Updates Content-Length values and expected http_code
test/test-cases/regression/operator-validate-byte-range.json Adds Content-Length, changes empty body representation, adds expected http_code
test/test-cases/regression/operator-rxGlobal.json Adds Content-Length, appends expected http_code
test/test-cases/regression/operator-rx.json Normalizes headers/bodies, adds Content-Length/expected http_code across cases
test/test-cases/regression/operator-pmfromfile.json Normalizes escaping and switches response to explicit headers/body
test/test-cases/regression/operator-pm.json Normalizes escaping, adds Content-Length and explicit empty response body
test/test-cases/regression/operator-ipMatchFromFile.json Normalizes paths/headers, adds Content-Length and expected http_code
test/test-cases/regression/operator-detectxss.json Normalizes body escaping, updates Content-Length and expected http_code
test/test-cases/regression/operator-detectsqli.json Updates Content-Length and expected http_code
test/test-cases/regression/operator-UnconditionalMatch.json Adds Content-Length and expected http_code
test/test-cases/regression/misc.json Adds explicit client/server/request/response blocks and expected http_code
test/test-cases/regression/misc-variable-under-quotes.json Adds Content-Length/body arrays and expected http_code
test/test-cases/regression/issue-960.json Fixes issue metadata fields and normalizes request/response schema
test/test-cases/regression/issue-849.json Normalizes escaping and adds Content-Length/body arrays
test/test-cases/regression/issue-394.json Normalizes request/response schema and expected fields
test/test-cases/regression/issue-3340.json Normalizes escaping and response structure
test/test-cases/regression/issue-2427.json Updates multipart body-to-lines representation and Content-Length
test/test-cases/regression/issue-2423-msg-in-chain.json Adds explicit request/response blocks and normalizes expected fields
test/test-cases/regression/issue-2196.json Adds explicit request/response blocks and normalizes expected fields
test/test-cases/regression/issue-2111.json Adds explicit request/response blocks and normalizes expected fields
test/test-cases/regression/issue-2000.json Adds explicit request/response blocks and normalizes expected fields
test/test-cases/regression/issue-1960.json Adds Content-Length/body arrays and normalizes headers
test/test-cases/regression/issue-1943.json Normalizes escaping, adds Content-Length/body arrays
test/test-cases/regression/issue-1850.json Normalizes escaping and adds Content-Length/body arrays
test/test-cases/regression/issue-1844.json Updates Content-Length and response headers
test/test-cases/regression/issue-1812.json Normalizes escaping and adds expected http_code
test/test-cases/regression/issue-1785.json Normalizes escaping and adds request/response schema
test/test-cases/regression/issue-1743.json Normalizes escaping and adds request/response schema
test/test-cases/regression/issue-1725.json Normalizes issue metadata and request/response schema
test/test-cases/regression/issue-1591.json Normalizes issue metadata and request/response schema
test/test-cases/regression/issue-1576.json Normalizes issue metadata; adds server/response blocks and Content-Length headers
test/test-cases/regression/issue-1565.json Normalizes issue metadata and request/response schema
test/test-cases/regression/issue-1528.json Normalizes issue metadata and request/response schema
test/test-cases/regression/fn-setHostname.json Adds Content-Length/body array and normalizes client/server fields
test/test-cases/regression/debug_log.json Normalizes escaping and adds Content-Length/body arrays
test/test-cases/regression/config-xml_external_entity.json Normalizes resource formatting and adds server/response blocks
test/test-cases/regression/config-update-target-by-tag.json Adds Content-Length/body arrays and normalizes expected fields
test/test-cases/regression/config-update-target-by-msg.json Adds Content-Length/body arrays and normalizes expected fields
test/test-cases/regression/config-update-target-by-id.json Adds Content-Length/body arrays and normalizes expected fields
test/test-cases/regression/config-secremoterules.json Adds format-aligned request/response blocks and expected http_code for parser errors
test/test-cases/regression/config-response_type.json Normalizes escaping; adds Content-Length/body arrays; updates expected http_code
test/test-cases/regression/config-remove_by_tag.json Adds Content-Length/body arrays and expected http_code
test/test-cases/regression/config-remove_by_msg.json Adds Content-Length/body arrays and expected http_code
test/test-cases/regression/config-remove_by_id.json Adds Content-Length/body arrays and expected http_code
test/test-cases/regression/config-include-bad.json Adds explicit request/response schema and expected http_code for parser errors
test/test-cases/regression/config-calling_phases_by_name.json Adds Content-Length/body arrays and expected http_code
test/test-cases/regression/collection-resource.json Normalizes escaping and adds content-length and empty response bodies
test/test-cases/regression/collection-regular_expression_selection.json Normalizes escaping and adds Content-Length/body arrays
test/test-cases/regression/collection-lua.json Normalizes empty body/headers handling and adds expected http_code
test/test-cases/regression/collection-case-insensitive.json Normalizes escaping and adds Content-Length/body arrays
test/test-cases/regression/action-xmlns.json Adds explicit request/response schema and expected http_code for parser errors
test/test-cases/regression/action-tnf-base64.json Updates expected output due to newline handling; adds Content-Length/http_code
test/test-cases/regression/action-tag.json Normalizes escaping and adds Content-Length/body arrays
test/test-cases/regression/action-skip.json Adds explicit request/response schema and expected http_code
test/test-cases/regression/action-setuid.json Adds explicit request/response schema and expected http_code
test/test-cases/regression/action-setsid.json Adds explicit request/response schema and expected http_code
test/test-cases/regression/action-setrsc.json Adds explicit request/response schema and expected http_code
test/test-cases/regression/action-setenv.json Adds explicit request/response schema and expected http_code
test/test-cases/regression/action-msg.json Normalizes escaping and expected debug output; adds expected http_code
test/test-cases/regression/action-initcol.json Adds explicit request/response schema and expected http_code
test/test-cases/regression/action-id.json Adds Content-Length and expected http_code to parser-error cases
test/test-cases/regression/action-expirevar.json Adds explicit request/response schema and expected http_code
test/test-cases/regression/action-disruptive.json Adds explicit client/server/request/response blocks for formatting/schema consistency
test/test-cases/regression/action-ctl_rule_remove_target_by_tag.json Adds explicit request/response schema and expected http_code
test/test-cases/regression/action-ctl_rule_remove_by_tag.json Adds Content-Length/body arrays and expected http_code
test/test-cases/regression/action-ctl_rule_remove_by_id.json Adds explicit request/response schema and expected http_code
test/test-cases/regression/action-ctl_rule_engine.json Normalizes request bodies/Content-Length and response headers
test/test-cases/regression/action-ctl_request_body_processor_urlencoded.json Updates Content-Length and response headers
test/test-cases/regression/action-ctl_request_body_processor.json Adds server/response blocks and normalizes expected structure
test/test-cases/regression/action-ctl_request_body_access.json Updates Content-Length and expected structure
test/test-cases/regression/action-ctl_audit_engine.json Adds explicit response skeleton and request body array
test/test-cases/regression/action-block.json Adds explicit request/response schema and expected http_code for parser errors
test/test-cases/regression/action-allow.json Adds explicit request/response schema and expected http_code
test/regression/regression_test.h Adds formatting-related fields, switches to unique_ptr/optional, introduces RegressionTests
test/regression/regression.cc Adds format mode that writes normalized JSON and optionally updates Content-Length
test/common/modsecurity_test.h Modernizes member initialization and adds flags for format/content-length updating
test/common/modsecurity_test.cc Adds format-mode JSON loading path and parses format positional + env var

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@airween
Copy link
Member

airween commented Feb 6, 2026

Hi @hnakamur,

finally I was able to start to review this PR, but it's very huge... 😃, so I asked Copilot (mainly to review the tests' changes).

It seems like everything is okay, Copilot made one suggestion - would you mind to take a look at that?

And thank you again.

@hnakamur
Copy link
Contributor Author

hnakamur commented Feb 7, 2026

@airween Thank you for your comment. I added commits to resolve issues reported by Copilot.
Would you take a look?
Thank you!

@airween
Copy link
Member

airween commented Feb 7, 2026

Hi @hnakamur,

@airween Thank you for your comment. I added commits to resolve issues reported by Copilot. Would you take a look? Thank you!

thank - now there is a new Sonar issue, could you fix that?

This reverts commit af09a15.

The RegressionTest::update_content_lengths method modifies the state
so it cannot be const. Therefore the test here cannot be const.
@hnakamur
Copy link
Contributor Author

hnakamur commented Feb 7, 2026

It turned out the Sonar issue is a false positive.
The RegressionTest::update_content_lengths method modifies the state of the test, so the loop variable test cannot be const.

@airween
Copy link
Member

airween commented Feb 11, 2026

Hi @hnakamur,

thank you again for this awesome PR.

There are a lot of changes in tests - I think it's obvious that this can't be reviewed one by one.

For the first look, it seems all tests are structured and organized - which is excellent. I assume you used a tool which produced these files.

If this is true and if it's possible, could you share that tool (may be through a gist)? I would like to reproduce your results just for sure.

Thank you.

@hnakamur hnakamur requested a review from airween February 12, 2026 01:13
@sonarqubecloud
Copy link

sonarqubecloud bot commented Feb 12, 2026

Quality Gate Passed Quality Gate passed

Issues
0 New issues
1 Accepted issue

Measures
0 Security Hotspots
No data about Coverage
0.0% Duplication on New Code

See analysis details on SonarQube Cloud

@airween
Copy link
Member

airween commented Feb 12, 2026

Hi @hnakamur,

thank you so much for your effort and your patience. I see this is a huge PR and I'm sure you spent a lot of time with this.

I don't know if you seen this comment, it's not important now - I solved the comparison in other way.

But for the future: now - as I wrote - you organized and cleaned all the test cases, it would be nice to have to keep this strict format. So if you have more patience, and have some idea how could we implement a GH CI job where we can check the syntax of all tests, and add some tool to maintain the tests for other developer, please share that with us.

And thank you again for this huge PR.

@airween airween merged commit 5ed6c9e into owasp-modsecurity:v3/master Feb 12, 2026
50 checks passed
@hnakamur
Copy link
Contributor Author

Thank your for your thourough review!

I don't know if you seen this comment, it's not important now - I solved the comparison in other way.

Sorry I had missed that comment.

Yes, I added the format subcommand to regression_tests command at b1c59b7.
I also added support for updating the Content-Length request headers at 37e1f13

To format regression test case json files, run the following command:

(cd test && ./regression_tests format)

The format subcommand takes filename arguments and formats only the specified files if filename arguments are present.

To update the Content-Length request headers, run the following command:

(cd test && UPDATE_CONTENT_LENGTH=1 ./regression_tests format)

The above command adds or updates the Content-Length request header when the test case does not have Transfer-Encoding: chunked in request headers.

Maybe we can add the latter command to the git pre-commit hook, or we can just add the explanation to README
since we may want a test case whose Content-Length value is intentionally different from the actual length.

@hnakamur hnakamur deleted the v3/do_not_add_newline_to_test_body_lines branch February 13, 2026 04:15
@airween
Copy link
Member

airween commented Feb 13, 2026

Thank your for your thourough review!

yw!

Yes, I added the format subcommand to regression_tests command at b1c59b7. I also added support for updating the Content-Length request headers at 37e1f13

sorry, I didn't realize that.

To format regression test case json files, run the following command:

(cd test && ./regression_tests format)

The format subcommand takes filename arguments and formats only the specified files if filename arguments are present.

To update the Content-Length request headers, run the following command:

(cd test && UPDATE_CONTENT_LENGTH=1 ./regression_tests format)

The above command adds or updates the Content-Length request header when the test case does not have Transfer-Encoding: chunked in request headers.

That's awesome!

I'm going to update the README, especially this section, and add this tool.

Maybe we can add the latter command to the git pre-commit hook, or we can just add the explanation to README since we may want a test case whose Content-Length value is intentionally different from the actual length.

Yes, that's also a good idea!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

3.x Related to ModSecurity version 3.x

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants