Skip to content

Performance tweaks#3468

Open
edding3000 wants to merge 10 commits intoowasp-modsecurity:v3/masterfrom
edding3000:performance_tweaks
Open

Performance tweaks#3468
edding3000 wants to merge 10 commits intoowasp-modsecurity:v3/masterfrom
edding3000:performance_tweaks

Conversation

@edding3000
Copy link

what

Range based for loops with references are already used in this project, but in a few places not.
I am not sure why. I changed this code locations and executed unit tests.
Also use '*' for pointers when using auto keyword, makes it more readable.

why

Improve performance a little bit.

questions

"const auto&" could also be used in many places. Is there a reason why it is not used?

@edding3000
Copy link
Author

I was not sure if there was any restriction not to use const, thats why i asked. I could extend the PR with more positions for "const auto&" if you like.

@airween
Copy link
Member

airween commented Nov 20, 2025

I was not sure if there was any restriction not to use const, thats why i asked. I could extend the PR with more positions for "const auto&" if you like.

Sure, go! If the tests will be passed, I'll be happy :).

Btw you could review the tests too, may be you will find some lack there too (for eg. you're checking the code...)

@sonarqubecloud
Copy link

@airween airween added the 3.x Related to ModSecurity version 3.x label Jan 24, 2026
@airween
Copy link
Member

airween commented Jan 24, 2026

Hi @edding3000,

sorry for the long delay, it seems like this PR is ready to merge. Just one question: could you merge the current v3/master into this one?

@airween
Copy link
Member

airween commented Jan 24, 2026

@edding3000,

also please take a look at the few request changes.

@edding3000
Copy link
Author

@airween I merged v3/master. cppcheck fails now. Can you see the reason?

@airween
Copy link
Member

airween commented Feb 17, 2026

@airween I merged v3/master. cppcheck fails now. Can you see the reason?

Yes:

2026-02-17T18:48:51.1404560Z warning: src/run_time_string.cc,54,style,functionConst,The member function 'modsecurity::RunTimeString::evaluate' 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?

I think cppcheck realized that you changed the loop's variable to const, and figured out the function can't change the object (I don't see the relationship what this const triggered this error), so it expects to make the fn to const - but warns us that it might be wrong.

So what you can try now:

  • change the function signature to const: std::string RunTimeString::evaluate(Transaction *t, Rule *r) const {
  • if the build will be failed, rollback that change and add an inline suppression to that line: std::string RunTimeString::evaluate(Transaction *t, Rule *r) { // cppcheck-suppress functionConst
  • in this case, please add this note to the PR's description

Do you have cppcheck on your local dev environment? It's important to use the latest release, and on Linux only Debian SID contains that version. Here you can see how do we use it in Docker.

@sonarqubecloud
Copy link

@edding3000
Copy link
Author

Thx for your hint. I build cppcheck from source, but it did not find this - perhaps I did not use correct settings. Anyway, warning is fixed now.

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 makes small performance-oriented C++ adjustments across the ModSecurity codebase, primarily by avoiding unnecessary copies in range-based for loops and tightening const-correctness in a few helper APIs.

Changes:

  • Convert multiple range-based loops to iterate by const auto& (or equivalent) to avoid copies.
  • Adjust a few APIs/usages for const-correctness (e.g., RunTimeString::evaluate, RulesExceptions::merge, RuleWithActions::containsTag).
  • Replace C-style casts with reinterpret_cast for request/response body buffer pointers in regression tests.

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
test/unit/unit.cc Avoids copies in iteration and uses auto* for pointer-returning factory calls.
test/regression/regression.cc Minor cleanup + safer casts to const unsigned char* for body buffers.
src/variables/xml.cc Iteration tweaks while registering XML namespaces from actions.
src/variables/variable.h Avoids string copy by passing toOmit argument by const reference.
src/transaction.cc Avoids copies when iterating over rule messages and tags during JSON generation.
src/run_time_string.h Makes evaluate overloads const (and adjusts inline evaluate()).
src/run_time_string.cc Implements RunTimeString::evaluate as const and iterates elements as const.
src/rules_exceptions.cc Iteration by const reference + merge now takes a const pointer.
src/rule_with_operator.cc Iterates variables by const reference to avoid pointer copies.
src/rule_with_actions.cc Iteration tweaks + makes containsTag const.
src/engine/lua.cc Iterates variable-value pointers without copying when building Lua tables.
src/collection/backend/in_memory-per_process.cc Avoids copying map entries during iteration.
src/actions/block.cc Avoids copying default action smart pointers during iteration.
headers/modsecurity/rules_exceptions.h Public header signature updated for merge (const pointer).
headers/modsecurity/rule_with_actions.h Public header signature updated for containsTag (const method).

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

@@ -51,7 +51,7 @@ class RulesExceptions {
bool addRange(int a, int b);
bool addNumber(int a);
bool contains(int a);
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

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

Changing RulesExceptions::merge to take a const RulesExceptions* alters the exported C++ symbol in an installed public header, which is an ABI-breaking change for downstream binaries linked against an older libmodsecurity. To keep backward compatibility, preserve the original signature and add a const overload (or keep the old signature and treat the parameter as const internally).

Suggested change
bool contains(int a);
bool contains(int a);
bool merge(RulesExceptions *from) {
return merge(static_cast<const RulesExceptions *>(from));
}

Copilot uses AI. Check for mistakes.
Copy link
Member

Choose a reason for hiding this comment

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

@edding3000 I think this suggestion makes sense.

@@ -80,7 +80,7 @@ class RuleWithActions : public Rule {

std::vector<actions::Action *> getActionsByName(const std::string& name,
const Transaction *t);
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

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

Making RuleWithActions::containsTag const changes the mangled name in an installed public header, which can break ABI for external connectors compiled against a previous version of the library. Consider keeping the existing non-const method for compatibility and adding a const overload (with the non-const delegating to the const implementation).

Suggested change
const Transaction *t);
const Transaction *t);
bool containsTag(const std::string& name, Transaction *t)
{
return static_cast<const RuleWithActions *>(this)->containsTag(name, t);
}

Copilot uses AI. Check for mistakes.
Copy link
Member

Choose a reason for hiding this comment

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

This suggestion makes sense.

Comment on lines +51 to 55
std::string evaluate(Transaction *t) const;
std::string evaluate(Transaction *t, Rule *r) const;
std::string evaluate() const{
return evaluate(NULL);
}
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

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

Minor formatting/style: evaluate() const{ is missing a space before {, and this still uses NULL in C++ code. Prefer consistent spacing (const {) and consider nullptr to avoid integral null pointer constants.

Copilot uses AI. Check for mistakes.
Copy link
Member

Choose a reason for hiding this comment

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

This one also makes sense.

Copy link
Member

@airween airween left a comment

Choose a reason for hiding this comment

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

@edding3000 thanks, please take a look at Copilot reviews and my suggestions below.

@@ -51,7 +51,7 @@ class RulesExceptions {
bool addRange(int a, int b);
bool addNumber(int a);
bool contains(int a);
Copy link
Member

Choose a reason for hiding this comment

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

@edding3000 I think this suggestion makes sense.

Comment on lines +51 to 55
std::string evaluate(Transaction *t) const;
std::string evaluate(Transaction *t, Rule *r) const;
std::string evaluate() const{
return evaluate(NULL);
}
Copy link
Member

Choose a reason for hiding this comment

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

This one also makes sense.

@@ -80,7 +80,7 @@ class RuleWithActions : public Rule {

std::vector<actions::Action *> getActionsByName(const std::string& name,
const Transaction *t);
Copy link
Member

Choose a reason for hiding this comment

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

This suggestion makes sense.

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.

3 participants