Repository: corazawaf/coraza
Pull request #646 (2023-02-13 10:38:01)

Improves actions code
Let's merge it after https://github.com/corazawaf/coraza/pull/645

codecov[bot]: # [Codecov](https://codecov.io/gh/corazawaf/coraza/pull/646?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=corazawaf) Report
Base: **78.69**% // Head: **78.62**% // Decreases project coverage by **`-0.07%`** :warning:
> Coverage data is based on head [(`e81389c`)](https://codecov.io/gh/corazawaf/coraza/pull/646?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=corazawaf) compared to base [(`0ab3c89`)](https://codecov.io/gh/corazawaf/coraza/commit/0ab3c89db173701f95ff49302a0751b6a9001ffc?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=corazawaf).
> Patch coverage: 69.56% of modified lines in pull request are covered.

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##           v3/dev     #646      +/-   ##
==========================================
- Coverage   78.69%   78.62%   -0.07%     
==========================================
  Files         144      137       -7     
  Lines        7683     7622      -61     
==========================================
- Hits         6046     5993      -53     
+ Misses       1404     1397       -7     
+ Partials      233      232       -1     
```

| Flag | Coverage Δ | |
|---|---|---|
| default | `74.51% <66.66%> (-0.01%)` | :arrow_down: |
| examples | `30.08% <20.28%> (-0.12%)` | :arrow_down: |
| ftw | `54.40% <50.72%> (-0.07%)` | :arrow_down: |
| ftw-multiphase | `?` | |
| tinygo | `?` | |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=corazawaf#carryforward-flags-in-the-pull-request-comment) to find out more.

| [Impacted Files](https://codecov.io/gh/corazawaf/coraza/pull/646?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=corazawaf) | Coverage Δ | |
|---|---|---|
| [actions/exec.go](https://codecov.io/gh/corazawaf/coraza/pull/646?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=corazawaf#diff-YWN0aW9ucy9leGVjLmdv) | `0.00% <0.00%> (ø)` | |
| [actions/expirevar.go](https://codecov.io/gh/corazawaf/coraza/pull/646?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=corazawaf#diff-YWN0aW9ucy9leHBpcmV2YXIuZ28=) | `0.00% <0.00%> (ø)` | |
| [actions/id.go](https://codecov.io/gh/corazawaf/coraza/pull/646?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=corazawaf#diff-YWN0aW9ucy9pZC5nbw==) | `40.90% <0.00%> (+1.77%)` | :arrow_up: |
| [actions/logdata.go](https://codecov.io/gh/corazawaf/coraza/pull/646?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=corazawaf#diff-YWN0aW9ucy9sb2dkYXRhLmdv) | `78.57% <ø> (ø)` | |
| [actions/maturity.go](https://codecov.io/gh/corazawaf/coraza/pull/646?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=corazawaf#diff-YWN0aW9ucy9tYXR1cml0eS5nbw==) | `0.00% <0.00%> (ø)` | |
| [actions/msg.go](https://codecov.io/gh/corazawaf/coraza/pull/646?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=corazawaf#diff-YWN0aW9ucy9tc2cuZ28=) | `71.42% <0.00%> (+4.76%)` | :arrow_up: |
| [actions/phase.go](https://codecov.io/gh/corazawaf/coraza/pull/646?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=corazawaf#diff-YWN0aW9ucy9waGFzZS5nbw==) | `66.66% <0.00%> (+5.12%)` | :arrow_up: |
| [actions/rev.go](https://codecov.io/gh/corazawaf/coraza/pull/646?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=corazawaf#diff-YWN0aW9ucy9yZXYuZ28=) | `0.00% <0.00%> (ø)` | |
| [actions/severity.go](https://codecov.io/gh/corazawaf/coraza/pull/646?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=corazawaf#diff-YWN0aW9ucy9zZXZlcml0eS5nbw==) | `66.66% <0.00%> (+5.12%)` | :arrow_up: |
| [actions/tag.go](https://codecov.io/gh/corazawaf/coraza/pull/646?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=corazawaf#diff-YWN0aW9ucy90YWcuZ28=) | `88.88% <0.00%> (+8.88%)` | :arrow_up: |
| ... and [37 more](https://codecov.io/gh/corazawaf/coraza/pull/646?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=corazawaf) | |

Help us with your feedback. Take ten seconds to tell us [how you rate us](https://about.codecov.io/nps?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=corazawaf). Have a feature suggestion? [Share it here.](https://app.codecov.io/gh/feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=corazawaf)

</details>

[:umbrella: View full report at Codecov](https://codecov.io/gh/corazawaf/coraza/pull/646?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=corazawaf).   
:loudspeaker: Do you have feedback about the report comment? [Let us know in this issue](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=corazawaf).

sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!&nbsp; &nbsp; [![Quality Gate passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')](https://sonarcloud.io/dashboard?id=coraza&pullRequest=646)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=coraza&pullRequest=646&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=coraza&pullRequest=646&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=coraza&pullRequest=646&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=coraza&pullRequest=646&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=coraza&pullRequest=646&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=coraza&pullRequest=646&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=coraza&pullRequest=646&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=coraza&pullRequest=646&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=coraza&pullRequest=646&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=coraza&pullRequest=646&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=coraza&pullRequest=646&resolved=false&types=CODE_SMELL) [124 Code Smells](https://sonarcloud.io/project/issues?id=coraza&pullRequest=646&resolved=false&types=CODE_SMELL)

[![0.0%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/0-16px.png '0.0%')](https://sonarcloud.io/component_measures?id=coraza&pullRequest=646&metric=new_coverage&view=list) [0.0% Coverage](https://sonarcloud.io/component_measures?id=coraza&pullRequest=646&metric=new_coverage&view=list)  
[![0.1%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3-16px.png '0.1%')](https://sonarcloud.io/component_measures?id=coraza&pullRequest=646&metric=new_duplicated_lines_density&view=list) [0.1% Duplication](https://sonarcloud.io/component_measures?id=coraza&pullRequest=646&metric=new_duplicated_lines_density&view=list)


sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!&nbsp; &nbsp; [![Quality Gate passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')](https://sonarcloud.io/dashboard?id=coraza&pullRequest=646)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=coraza&pullRequest=646&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=coraza&pullRequest=646&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=coraza&pullRequest=646&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=coraza&pullRequest=646&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=coraza&pullRequest=646&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=coraza&pullRequest=646&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=coraza&pullRequest=646&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=coraza&pullRequest=646&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=coraza&pullRequest=646&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=coraza&pullRequest=646&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=coraza&pullRequest=646&resolved=false&types=CODE_SMELL) [124 Code Smells](https://sonarcloud.io/project/issues?id=coraza&pullRequest=646&resolved=false&types=CODE_SMELL)

[![0.0%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/0-16px.png '0.0%')](https://sonarcloud.io/component_measures?id=coraza&pullRequest=646&metric=new_coverage&view=list) [0.0% Coverage](https://sonarcloud.io/component_measures?id=coraza&pullRequest=646&metric=new_coverage&view=list)  
[![0.1%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3-16px.png '0.1%')](https://sonarcloud.io/component_measures?id=coraza&pullRequest=646&metric=new_duplicated_lines_density&view=list) [0.1% Duplication](https://sonarcloud.io/component_measures?id=coraza&pullRequest=646&metric=new_duplicated_lines_density&view=list)


sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!&nbsp; &nbsp; [![Quality Gate passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')](https://sonarcloud.io/dashboard?id=coraza&pullRequest=646)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=coraza&pullRequest=646&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=coraza&pullRequest=646&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=coraza&pullRequest=646&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=coraza&pullRequest=646&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=coraza&pullRequest=646&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=coraza&pullRequest=646&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=coraza&pullRequest=646&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=coraza&pullRequest=646&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=coraza&pullRequest=646&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=coraza&pullRequest=646&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=coraza&pullRequest=646&resolved=false&types=CODE_SMELL) [105 Code Smells](https://sonarcloud.io/project/issues?id=coraza&pullRequest=646&resolved=false&types=CODE_SMELL)

[![0.0%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/0-16px.png '0.0%')](https://sonarcloud.io/component_measures?id=coraza&pullRequest=646&metric=new_coverage&view=list) [0.0% Coverage](https://sonarcloud.io/component_measures?id=coraza&pullRequest=646&metric=new_coverage&view=list)  
[![0.1%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3-16px.png '0.1%')](https://sonarcloud.io/component_measures?id=coraza&pullRequest=646&metric=new_duplicated_lines_density&view=list) [0.1% Duplication](https://sonarcloud.io/component_measures?id=coraza&pullRequest=646&metric=new_duplicated_lines_density&view=list)


sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!&nbsp; &nbsp; [![Quality Gate passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')](https://sonarcloud.io/dashboard?id=coraza&pullRequest=646)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=coraza&pullRequest=646&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=coraza&pullRequest=646&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=coraza&pullRequest=646&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=coraza&pullRequest=646&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=coraza&pullRequest=646&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=coraza&pullRequest=646&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=coraza&pullRequest=646&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=coraza&pullRequest=646&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=coraza&pullRequest=646&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=coraza&pullRequest=646&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=coraza&pullRequest=646&resolved=false&types=CODE_SMELL) [108 Code Smells](https://sonarcloud.io/project/issues?id=coraza&pullRequest=646&resolved=false&types=CODE_SMELL)

[![0.0%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/0-16px.png '0.0%')](https://sonarcloud.io/component_measures?id=coraza&pullRequest=646&metric=new_coverage&view=list) [0.0% Coverage](https://sonarcloud.io/component_measures?id=coraza&pullRequest=646&metric=new_coverage&view=list)  
[![0.1%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3-16px.png '0.1%')](https://sonarcloud.io/component_measures?id=coraza&pullRequest=646&metric=new_duplicated_lines_density&view=list) [0.1% Duplication](https://sonarcloud.io/component_measures?id=coraza&pullRequest=646&metric=new_duplicated_lines_density&view=list)


sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!&nbsp; &nbsp; [![Quality Gate passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')](https://sonarcloud.io/dashboard?id=coraza&pullRequest=646)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=coraza&pullRequest=646&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=coraza&pullRequest=646&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=coraza&pullRequest=646&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=coraza&pullRequest=646&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=coraza&pullRequest=646&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=coraza&pullRequest=646&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=coraza&pullRequest=646&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=coraza&pullRequest=646&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=coraza&pullRequest=646&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=coraza&pullRequest=646&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=coraza&pullRequest=646&resolved=false&types=CODE_SMELL) [95 Code Smells](https://sonarcloud.io/project/issues?id=coraza&pullRequest=646&resolved=false&types=CODE_SMELL)

[![0.0%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/0-16px.png '0.0%')](https://sonarcloud.io/component_measures?id=coraza&pullRequest=646&metric=new_coverage&view=list) [0.0% Coverage](https://sonarcloud.io/component_measures?id=coraza&pullRequest=646&metric=new_coverage&view=list)  
[![0.1%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3-16px.png '0.1%')](https://sonarcloud.io/component_measures?id=coraza&pullRequest=646&metric=new_duplicated_lines_density&view=list) [0.1% Duplication](https://sonarcloud.io/component_measures?id=coraza&pullRequest=646&metric=new_duplicated_lines_density&view=list)



Patch:
diff --git a/actions/actions.go b/actions/actions.go
index 0ab88dd..5799a2e 100644
--- a/actions/actions.go
+++ b/actions/actions.go
@@ -4,12 +4,19 @@
 package actions
 
 import (
+	"errors"
 	"fmt"
 	"strings"
 
 	"github.com/corazawaf/coraza/v3/rules"
 )
 
+var (
+	ErrUnexpectedArguments = errors.New("unexpected arguments")
+	ErrMissingArguments    = errors.New("missing arguments")
+	ErrInvalidKVArguments  = errors.New("invalid arguments, expected syntax {action}:{key}={value}")
+)
+
 // ruleActionWrapper is used to wrap a RuleAction so that it can be registered
 // and recreated on each call
 type ruleActionWrapper = func() rules.Action
diff --git a/actions/allow.go b/actions/allow.go
index de68dff..12abc47 100644
--- a/actions/allow.go
+++ b/actions/allow.go
@@ -16,8 +16,8 @@ type allowFn struct {
 	allow corazatypes.AllowType
 }
 
-func (a *allowFn) Init(r rules.RuleMetadata, b1 string) error {
-	switch b1 {
+func (a *allowFn) Init(_ rules.RuleMetadata, data string) error {
+	switch data {
 	case "phase":
 		a.allow = corazatypes.AllowTypePhase // skip current phase
 	case "request":
@@ -25,7 +25,7 @@ func (a *allowFn) Init(r rules.RuleMetadata, b1 string) error {
 	case "":
 		a.allow = corazatypes.AllowTypeAll // skip all phases
 	default:
-		return fmt.Errorf("invalid argument %s for allow", b1)
+		return fmt.Errorf("invalid argument %q", data)
 	}
 	return nil
 }
diff --git a/actions/auditlog.go b/actions/auditlog.go
index d571c84..5d37d97 100644
--- a/actions/auditlog.go
+++ b/actions/auditlog.go
@@ -11,14 +11,15 @@ import (
 type auditlogFn struct{}
 
 func (a *auditlogFn) Init(r rules.RuleMetadata, data string) error {
-	// TODO(anuraaga): Confirm this is internal implementation detail
+	if len(data) > 0 {
+		return ErrUnexpectedArguments
+	}
+
 	r.(*corazawaf.Rule).Audit = true
 	return nil
 }
 
-func (a *auditlogFn) Evaluate(r rules.RuleMetadata, tx rules.TransactionState) {
-	// Nothing here
-}
+func (a *auditlogFn) Evaluate(_ rules.RuleMetadata, _ rules.TransactionState) {}
 
 func (a *auditlogFn) Type() rules.ActionType {
 	return rules.ActionTypeNondisruptive
diff --git a/actions/block.go b/actions/block.go
index 2eb944f..c3b03a6 100644
--- a/actions/block.go
+++ b/actions/block.go
@@ -9,12 +9,17 @@ import (
 
 type blockFn struct{}
 
-func (a *blockFn) Init(r rules.RuleMetadata, b1 string) error {
+func (a *blockFn) Init(_ rules.RuleMetadata, data string) error {
+	if len(data) > 0 {
+		return ErrUnexpectedArguments
+	}
+
 	return nil
 }
 
-func (a *blockFn) Evaluate(r rules.RuleMetadata, tx rules.TransactionState) {
+func (a *blockFn) Evaluate(_ rules.RuleMetadata, _ rules.TransactionState) {
 	// This should never run
+	// TODO(jcchavezs): check if we return a panic
 }
 
 func (a *blockFn) Type() rules.ActionType {
diff --git a/actions/capture.go b/actions/capture.go
index 4bed9cb..2a7c5d8 100644
--- a/actions/capture.go
+++ b/actions/capture.go
@@ -10,16 +10,16 @@ import (
 
 type captureFn struct{}
 
-func (a *captureFn) Init(r rules.RuleMetadata, b1 string) error {
-	// this will capture only the current rule
-	// TODO(anuraaga): Confirm this is internal implementation detail
+func (a *captureFn) Init(r rules.RuleMetadata, data string) error {
+	if len(data) > 0 {
+		return ErrUnexpectedArguments
+	}
+
 	r.(*corazawaf.Rule).Capture = true
 	return nil
 }
 
-func (a *captureFn) Evaluate(r rules.RuleMetadata, tx rules.TransactionState) {
-
-}
+func (a *captureFn) Evaluate(_ rules.RuleMetadata, _ rules.TransactionState) {}
 
 func (a *captureFn) Type() rules.ActionType {
 	return rules.ActionTypeNondisruptive
diff --git a/actions/chain.go b/actions/chain.go
index 943b58a..2f028a2 100644
--- a/actions/chain.go
+++ b/actions/chain.go
@@ -10,15 +10,16 @@ import (
 
 type chainFn struct{}
 
-func (a *chainFn) Init(r rules.RuleMetadata, b1 string) error {
-	// TODO(anuraaga): Confirm this is internal implementation detail
+func (a *chainFn) Init(r rules.RuleMetadata, data string) error {
+	if len(data) > 0 {
+		return ErrUnexpectedArguments
+	}
+
 	r.(*corazawaf.Rule).HasChain = true
 	return nil
 }
 
-func (a *chainFn) Evaluate(r rules.RuleMetadata, tx rules.TransactionState) {
-	// Not evaluated
-}
+func (a *chainFn) Evaluate(_ rules.RuleMetadata, _ rules.TransactionState) {}
 
 func (a *chainFn) Type() rules.ActionType {
 	return rules.ActionTypeFlow
diff --git a/actions/ctl.go b/actions/ctl.go
index 55847fc..57f6b0d 100644
--- a/actions/ctl.go
+++ b/actions/ctl.go
@@ -49,7 +49,7 @@ type ctlFn struct {
 	colRx      *regexp.Regexp
 }
 
-func (a *ctlFn) Init(r rules.RuleMetadata, data string) error {
+func (a *ctlFn) Init(_ rules.RuleMetadata, data string) error {
 	var err error
 	a.action, a.value, a.collection, a.colKey, err = parseCtl(data)
 	if len(a.colKey) > 2 && a.colKey[0] == '/' && a.colKey[len(a.colKey)-1] == '/' {
@@ -74,8 +74,7 @@ func parseOnOff(s string) (bool, bool) {
 	}
 }
 
-func (a *ctlFn) Evaluate(r rules.RuleMetadata, txS rules.TransactionState) {
-	// TODO(anuraaga): Confirm this is internal implementation detail
+func (a *ctlFn) Evaluate(_ rules.RuleMetadata, txS rules.TransactionState) {
 	tx := txS.(*corazawaf.Transaction)
 	switch a.action {
 	case ctlRuleRemoveTargetByID:
diff --git a/actions/deny.go b/actions/deny.go
index cfd3ed0..3b5b1ef 100644
--- a/actions/deny.go
+++ b/actions/deny.go
@@ -10,7 +10,10 @@ import (
 
 type denyFn struct{}
 
-func (a *denyFn) Init(r rules.RuleMetadata, data string) error {
+func (a *denyFn) Init(_ rules.RuleMetadata, data string) error {
+	if len(data) > 0 {
+		return ErrUnexpectedArguments
+	}
 	return nil
 }
 
diff --git a/actions/drop.go b/actions/drop.go
index 8a20ff8..af6dc07 100644
--- a/actions/drop.go
+++ b/actions/drop.go
@@ -10,7 +10,10 @@ import (
 
 type dropFn struct{}
 
-func (a *dropFn) Init(r rules.RuleMetadata, data string) error {
+func (a *dropFn) Init(_ rules.RuleMetadata, data string) error {
+	if len(data) > 0 {
+		return ErrUnexpectedArguments
+	}
 	return nil
 }
 
diff --git a/actions/exec.go b/actions/exec.go
index 1b6a893..b1fb83d 100644
--- a/actions/exec.go
+++ b/actions/exec.go
@@ -7,16 +7,16 @@ import (
 	"github.com/corazawaf/coraza/v3/rules"
 )
 
-type execFn struct {
-}
+type execFn struct{}
 
-func (a *execFn) Init(r rules.RuleMetadata, data string) error {
+func (a *execFn) Init(_ rules.RuleMetadata, data string) error {
+	if len(data) > 0 {
+		return ErrUnexpectedArguments
+	}
 	return nil
 }
 
-func (a *execFn) Evaluate(r rules.RuleMetadata, tx rules.TransactionState) {
-	// Not implemented
-}
+func (a *execFn) Evaluate(_ rules.RuleMetadata, _ rules.TransactionState) {}
 
 func (a *execFn) Type() rules.ActionType {
 	return rules.ActionTypeNondisruptive
diff --git a/actions/expirevar.go b/actions/expirevar.go
index 5519859..8ffd60c 100644
--- a/actions/expirevar.go
+++ b/actions/expirevar.go
@@ -4,6 +4,7 @@
 package actions
 
 import (
+	"errors"
 	"fmt"
 	"strconv"
 	"strings"
@@ -17,20 +18,35 @@ type expirevarFn struct {
 	key        string
 }
 
-func (a *expirevarFn) Init(r rules.RuleMetadata, data string) error {
-	v, ttl, _ := strings.Cut(data, "=")
-	col, key, ok := strings.Cut(v, ".")
+func (a *expirevarFn) Init(_ rules.RuleMetadata, data string) error {
+	k, ttl, ok := strings.Cut(data, "=")
 	if !ok {
-		return fmt.Errorf("expirevar must contain key and value (syntax expirevar:key=value)")
+		return ErrInvalidKVArguments
 	}
-	a.ttl, _ = strconv.Atoi(ttl)
+
+	col, key, ok := strings.Cut(k, ".")
+	if !ok {
+		return errors.New("invalid arguments, expected syntax {collection}.{key}={ttl}")
+	}
+
+	ittl, err := strconv.Atoi(ttl)
+	if err != nil {
+		return fmt.Errorf("invalid TTL argument %q: %s", ttl, err.Error())
+	}
+
+	if ittl < int(1) {
+		return fmt.Errorf("invalid TTL argument, %d must be greater than 1", ittl)
+	}
+
+	a.ttl = ittl
 	a.collection = col
 	a.key = key
 	return nil
 }
 
-func (a *expirevarFn) Evaluate(r rules.RuleMetadata, tx rules.TransactionState) {
+func (a *expirevarFn) Evaluate(_ rules.RuleMetadata, _ rules.TransactionState) {
 	// Not supported
+	// TODO(jcchavezs): Shall we log a message?
 	// tx.WAF.Logger.Error("Expirevar was used but it's not supported", zap.Int("rule", r.Id))
 }
 
diff --git a/actions/id.go b/actions/id.go
index c6ec562..4b88410 100644
--- a/actions/id.go
+++ b/actions/id.go
@@ -11,32 +11,27 @@ import (
 	"github.com/corazawaf/coraza/v3/rules"
 )
 
-type idFn struct {
-}
+type idFn struct{}
 
 func (a *idFn) Init(r rules.RuleMetadata, data string) error {
-	if data == "" {
-		return fmt.Errorf("id action requires a parameter")
+	if len(data) == 0 {
+		return ErrMissingArguments
 	}
 	i, err := strconv.Atoi(data)
 	if err != nil {
-		return fmt.Errorf("invalid rule id %s", data)
-	}
-	// TODO(anuraaga): Confirm this is internal implementation detail
-	rInt := r.(*corazawaf.Rule)
-	rInt.ID_ = int(i)
-	if rInt.ID_ < 0 {
-		return fmt.Errorf("rule id (%d) cannot be negative", rInt.ID_)
+		return err
 	}
-	if rInt.ID_ == 0 {
-		return fmt.Errorf("rule id (%d) cannot be zero", rInt.ID_)
+
+	if i <= 0 {
+		return fmt.Errorf("invalid id argument, %d must be positive", i)
 	}
+
+	cr := r.(*corazawaf.Rule)
+	cr.ID_ = int(i)
 	return nil
 }
 
-func (a *idFn) Evaluate(r rules.RuleMetadata, tx rules.TransactionState) {
-	// Not evaluated
-}
+func (a *idFn) Evaluate(_ rules.RuleMetadata, _ rules.TransactionState) {}
 
 func (a *idFn) Type() rules.ActionType {
 	return rules.ActionTypeMetadata
diff --git a/actions/initcol.go b/actions/initcol.go
index 7c8e5ee..a55d180 100644
--- a/actions/initcol.go
+++ b/actions/initcol.go
@@ -16,15 +16,19 @@ type initcolFn struct {
 	key        string
 }
 
-func (a *initcolFn) Init(r rules.RuleMetadata, data string) error {
-	col, key, _ := strings.Cut(data, "=")
+func (a *initcolFn) Init(_ rules.RuleMetadata, data string) error {
+	col, key, ok := strings.Cut(data, "=")
+	if !ok {
+		return ErrInvalidKVArguments
+	}
+
 	a.collection = col
 	a.key = key
 	a.variable = 0x0
 	return nil
 }
 
-func (a *initcolFn) Evaluate(r rules.RuleMetadata, tx rules.TransactionState) {
+func (a *initcolFn) Evaluate(_ rules.RuleMetadata, _ rules.TransactionState) {
 	// tx.WAF.Logger.Error("initcol was used but it's not supported", zap.Int("rule", r.Id))
 	/*
 		key := tx.MacroExpansion(a.key)
diff --git a/actions/log.go b/actions/log.go
index bcc6bfe..b460ef5 100644
--- a/actions/log.go
+++ b/actions/log.go
@@ -8,18 +8,19 @@ import (
 	"github.com/corazawaf/coraza/v3/rules"
 )
 
-type logFn struct {
-}
+type logFn struct{}
 
 func (a *logFn) Init(r rules.RuleMetadata, data string) error {
-	// TODO(anuraaga): Confirm this is internal implementation detail
+	if len(data) > 0 {
+		return ErrUnexpectedArguments
+	}
+
 	r.(*corazawaf.Rule).Log = true
 	r.(*corazawaf.Rule).Audit = true
 	return nil
 }
 
-func (a *logFn) Evaluate(r rules.RuleMetadata, tx rules.TransactionState) {
-}
+func (a *logFn) Evaluate(_ rules.RuleMetadata, _ rules.TransactionState) {}
 
 func (a *logFn) Type() rules.ActionType {
 	return rules.ActionTypeNondisruptive
diff --git a/actions/logdata.go b/actions/logdata.go
index be5f94c..35a0fab 100644
--- a/actions/logdata.go
+++ b/actions/logdata.go
@@ -9,21 +9,22 @@ import (
 	"github.com/corazawaf/coraza/v3/rules"
 )
 
-type logdataFn struct {
-}
+type logdataFn struct{}
 
 func (a *logdataFn) Init(r rules.RuleMetadata, data string) error {
+	if len(data) == 0 {
+		return ErrMissingArguments
+	}
+
 	m, err := macro.NewMacro(data)
 	if err != nil {
 		return err
 	}
-	// TODO(anuraaga): Confirm this is internal implementation detail
 	r.(*corazawaf.Rule).LogData = m
 	return nil
 }
 
 func (a *logdataFn) Evaluate(r rules.RuleMetadata, tx rules.TransactionState) {
-	// TODO(anuraaga): Confirm this is internal implementation detail
 	tx.(*corazawaf.Transaction).Logdata = r.(*corazawaf.Rule).LogData.Expand(tx)
 }
 
diff --git a/actions/maturity.go b/actions/maturity.go
index 007a509..f95a469 100644
--- a/actions/maturity.go
+++ b/actions/maturity.go
@@ -11,8 +11,7 @@ import (
 	"github.com/corazawaf/coraza/v3/rules"
 )
 
-type maturityFn struct {
-}
+type maturityFn struct{}
 
 func (a *maturityFn) Init(r rules.RuleMetadata, data string) error {
 	m, err := strconv.Atoi(data)
@@ -20,16 +19,13 @@ func (a *maturityFn) Init(r rules.RuleMetadata, data string) error {
 		return err
 	}
 	if m < 1 || m > 9 {
-		return fmt.Errorf("maturity must be between 1 and 9, not %d", m)
+		return fmt.Errorf("invalid argument, %d should be between 1 and 9", m)
 	}
-	// TODO(anuraaga): Confirm this is internal implementation detail
 	r.(*corazawaf.Rule).Maturity_ = m
 	return nil
 }
 
-func (a *maturityFn) Evaluate(r rules.RuleMetadata, tx rules.TransactionState) {
-	// Not evaluated
-}
+func (a *maturityFn) Evaluate(_ rules.RuleMetadata, _ rules.TransactionState) {}
 
 func (a *maturityFn) Type() rules.ActionType {
 	return rules.ActionTypeMetadata
diff --git a/actions/msg.go b/actions/msg.go
index 69328eb..60a1ffd 100644
--- a/actions/msg.go
+++ b/actions/msg.go
@@ -10,24 +10,23 @@ import (
 	"github.com/corazawaf/coraza/v3/rules"
 )
 
-type msgFn struct {
-}
+type msgFn struct{}
 
 func (a *msgFn) Init(r rules.RuleMetadata, data string) error {
 	data = utils.MaybeRemoveQuotes(data)
-	msg, err := macro.NewMacro(data)
+	if len(data) == 0 {
+		return ErrMissingArguments
+	}
 
+	msg, err := macro.NewMacro(data)
 	if err != nil {
 		return err
 	}
-	// TODO(anuraaga): Confirm this is internal implementation detail
 	r.(*corazawaf.Rule).Msg = msg
 	return nil
 }
 
-func (a *msgFn) Evaluate(r rules.RuleMetadata, tx rules.TransactionState) {
-	// Not evaluated
-}
+func (a *msgFn) Evaluate(_ rules.RuleMetadata, _ rules.TransactionState) {}
 
 func (a *msgFn) Type() rules.ActionType {
 	return rules.ActionTypeMetadata
diff --git a/actions/multimatch.go b/actions/multimatch.go
index eeec292..18e718c 100644
--- a/actions/multimatch.go
+++ b/actions/multimatch.go
@@ -8,18 +8,17 @@ import (
 	"github.com/corazawaf/coraza/v3/rules"
 )
 
-type multimatchFn struct {
-}
+type multimatchFn struct{}
 
 func (a *multimatchFn) Init(r rules.RuleMetadata, data string) error {
-	// TODO(anuraaga): Confirm this is internal implementation detail
+	if len(data) > 0 {
+		return ErrUnexpectedArguments
+	}
 	r.(*corazawaf.Rule).MultiMatch = true
 	return nil
 }
 
-func (a *multimatchFn) Evaluate(r rules.RuleMetadata, tx rules.TransactionState) {
-	// Not evaluated
-}
+func (a *multimatchFn) Evaluate(_ rules.RuleMetadata, _ rules.TransactionState) {}
 
 func (a *multimatchFn) Type() rules.ActionType {
 	return rules.ActionTypeNondisruptive
diff --git a/actions/noauditlog.go b/actions/noauditlog.go
index 9a937a6..1e19b39 100644
--- a/actions/noauditlog.go
+++ b/actions/noauditlog.go
@@ -8,17 +8,18 @@ import (
 	"github.com/corazawaf/coraza/v3/rules"
 )
 
-type noauditlogFn struct {
-}
+type noauditlogFn struct{}
 
 func (a *noauditlogFn) Init(r rules.RuleMetadata, data string) error {
-	// TODO(anuraaga): Confirm this is internal implementation detail
+	if len(data) > 0 {
+		return ErrUnexpectedArguments
+	}
+
 	r.(*corazawaf.Rule).Audit = false
 	return nil
 }
 
-func (a *noauditlogFn) Evaluate(r rules.RuleMetadata, tx rules.TransactionState) {
-}
+func (a *noauditlogFn) Evaluate(_ rules.RuleMetadata, _ rules.TransactionState) {}
 
 func (a *noauditlogFn) Type() rules.ActionType {
 	return rules.ActionTypeNondisruptive
diff --git a/actions/nolog.go b/actions/nolog.go
index 809ea92..95903e7 100644
--- a/actions/nolog.go
+++ b/actions/nolog.go
@@ -11,7 +11,10 @@ import (
 type nologFn struct{}
 
 func (a *nologFn) Init(r rules.RuleMetadata, data string) error {
-	// TODO(anuraaga): Confirm this is internal implementation detail
+	if len(data) > 0 {
+		return ErrUnexpectedArguments
+	}
+
 	r.(*corazawaf.Rule).Log = false
 	r.(*corazawaf.Rule).Audit = false
 	return nil
diff --git a/actions/pass.go b/actions/pass.go
index d9ad102..569e393 100644
--- a/actions/pass.go
+++ b/actions/pass.go
@@ -7,16 +7,16 @@ import (
 	"github.com/corazawaf/coraza/v3/rules"
 )
 
-type passFn struct {
-}
+type passFn struct{}
 
-func (a *passFn) Init(r rules.RuleMetadata, data string) error {
+func (a *passFn) Init(_ rules.RuleMetadata, data string) error {
+	if len(data) > 0 {
+		return ErrUnexpectedArguments
+	}
 	return nil
 }
 
-func (a *passFn) Evaluate(r rules.RuleMetadata, tx rules.TransactionState) {
-	// Not evaluated
-}
+func (a *passFn) Evaluate(_ rules.RuleMetadata, _ rules.TransactionState) {}
 
 func (a *passFn) Type() rules.ActionType {
 	return rules.ActionTypeDisruptive
diff --git a/actions/phase.go b/actions/phase.go
index 79368f3..c13483e 100644
--- a/actions/phase.go
+++ b/actions/phase.go
@@ -12,18 +12,19 @@ import (
 type phaseFn struct{}
 
 func (a *phaseFn) Init(r rules.RuleMetadata, data string) error {
+	if len(data) == 0 {
+		return ErrMissingArguments
+	}
+
 	p, err := types.ParseRulePhase(data)
 	if err != nil {
 		return err
 	}
-	// TODO(anuraaga): Confirm this is internal implementation detail
 	r.(*corazawaf.Rule).Phase_ = p
 	return nil
 }
 
-func (a *phaseFn) Evaluate(r rules.RuleMetadata, tx rules.TransactionState) {
-	// Not evaluated
-}
+func (a *phaseFn) Evaluate(_ rules.RuleMetadata, _ rules.TransactionState) {}
 
 func (a *phaseFn) Type() rules.ActionType {
 	return rules.ActionTypeMetadata
diff --git a/actions/redirect.go b/actions/redirect.go
index 19447a9..1ae5079 100644
--- a/actions/redirect.go
+++ b/actions/redirect.go
@@ -1,22 +1,9 @@
-// Copyright 2022 The Corazawaf Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
+// Copyright 2022 Juan Pablo Tosso and the OWASP Coraza contributors
+// SPDX-License-Identifier: Apache-2.0
 
 package actions
 
 import (
-	"fmt"
-
 	"github.com/corazawaf/coraza/v3/rules"
 	"github.com/corazawaf/coraza/v3/types"
 )
@@ -25,9 +12,9 @@ type redirectFn struct {
 	target string
 }
 
-func (a *redirectFn) Init(r rules.RuleMetadata, data string) error {
-	if data == "" {
-		return fmt.Errorf("redirect action requires a parameter")
+func (a *redirectFn) Init(_ rules.RuleMetadata, data string) error {
+	if len(data) == 0 {
+		return ErrMissingArguments
 	}
 
 	a.target = data
diff --git a/actions/rev.go b/actions/rev.go
index d7a62ae..aa63ea5 100644
--- a/actions/rev.go
+++ b/actions/rev.go
@@ -8,18 +8,17 @@ import (
 	"github.com/corazawaf/coraza/v3/rules"
 )
 
-type revFn struct {
-}
+type revFn struct{}
 
 func (a *revFn) Init(r rules.RuleMetadata, data string) error {
-	// TODO(anuraaga): Confirm this is internal implementation detail
+	if len(data) == 0 {
+		return ErrMissingArguments
+	}
 	r.(*corazawaf.Rule).Rev_ = data
 	return nil
 }
 
-func (a *revFn) Evaluate(r rules.RuleMetadata, tx rules.TransactionState) {
-	// Not evaluated
-}
+func (a *revFn) Evaluate(_ rules.RuleMetadata, _ rules.TransactionState) {}
 
 func (a *revFn) Type() rules.ActionType {
 	return rules.ActionTypeMetadata
diff --git a/actions/setenv.go b/actions/setenv.go
index 818d423..0f9145d 100644
--- a/actions/setenv.go
+++ b/actions/setenv.go
@@ -4,7 +4,7 @@
 package actions
 
 import (
-	"fmt"
+	"errors"
 	"os"
 	"strings"
 
@@ -17,11 +17,24 @@ type setenvFn struct {
 	value macro.Macro
 }
 
-func (a *setenvFn) Init(r rules.RuleMetadata, data string) error {
+func (a *setenvFn) Init(_ rules.RuleMetadata, data string) error {
+	if len(data) == 0 {
+		return ErrMissingArguments
+	}
+
 	key, val, ok := strings.Cut(data, "=")
 	if !ok {
-		return fmt.Errorf("invalid key value for setvar")
+		return ErrInvalidKVArguments
+	}
+
+	if len(key) == 0 {
+		return errors.New("missing env key")
 	}
+
+	if len(val) == 0 {
+		return errors.New("missing env value")
+	}
+
 	m, err := macro.NewMacro(val)
 	if err != nil {
 		return err
diff --git a/actions/setvar.go b/actions/setvar.go
index 816b027..20d6bb6 100644
--- a/actions/setvar.go
+++ b/actions/setvar.go
@@ -4,7 +4,6 @@
 package actions
 
 import (
-	"fmt"
 	"strconv"
 	"strings"
 
@@ -21,9 +20,9 @@ type setvarFn struct {
 	isRemove   bool
 }
 
-func (a *setvarFn) Init(r rules.RuleMetadata, data string) error {
-	if data == "" {
-		return fmt.Errorf("setvar requires arguments")
+func (a *setvarFn) Init(_ rules.RuleMetadata, data string) error {
+	if len(data) == 0 {
+		return ErrMissingArguments
 	}
 
 	if data[0] == '!' {
@@ -33,7 +32,6 @@ func (a *setvarFn) Init(r rules.RuleMetadata, data string) error {
 
 	var err error
 	key, val, valOk := strings.Cut(data, "=")
-
 	colKey, colVal, colOk := strings.Cut(key, ".")
 	a.collection, err = variables.Parse(colKey)
 	if err != nil {
@@ -46,6 +44,7 @@ func (a *setvarFn) Init(r rules.RuleMetadata, data string) error {
 		}
 		a.key = macro
 	}
+
 	if valOk {
 		macro, err := macro.NewMacro(val)
 		if err != nil {
diff --git a/actions/severity.go b/actions/severity.go
index 9c0af68..6f6bb2e 100644
--- a/actions/severity.go
+++ b/actions/severity.go
@@ -9,22 +9,22 @@ import (
 	"github.com/corazawaf/coraza/v3/types"
 )
 
-type severityFn struct {
-}
+type severityFn struct{}
 
 func (a *severityFn) Init(r rules.RuleMetadata, data string) error {
+	if len(data) == 0 {
+		return ErrMissingArguments
+	}
+
 	sev, err := types.ParseRuleSeverity(data)
 	if err != nil {
 		return err
 	}
-	// TODO(anuraaga): Confirm this is internal implementation detail
 	r.(*corazawaf.Rule).Severity_ = sev
 	return nil
 }
 
-func (a *severityFn) Evaluate(r rules.RuleMetadata, tx rules.TransactionState) {
-	// Not evaluated
-}
+func (a *severityFn) Evaluate(_ rules.RuleMetadata, _ rules.TransactionState) {}
 
 func (a *severityFn) Type() rules.ActionType {
 	return rules.ActionTypeMetadata
diff --git a/actions/skip.go b/actions/skip.go
index 8c271e9..ea36af0 100644
--- a/actions/skip.go
+++ b/actions/skip.go
@@ -15,20 +15,23 @@ type skipFn struct {
 	data int
 }
 
-func (a *skipFn) Init(r rules.RuleMetadata, data string) error {
+func (a *skipFn) Init(_ rules.RuleMetadata, data string) error {
+	if len(data) == 0 {
+		return ErrMissingArguments
+	}
+
 	i, err := strconv.Atoi(data)
 	if err != nil {
-		return fmt.Errorf("invalid value for skip")
+		return err
 	}
 	if i < 1 {
-		return fmt.Errorf("skip cannot be less than 1, got %d", i)
+		return fmt.Errorf("invalid argument, %d must be greater than 1", i)
 	}
 	a.data = i
 	return nil
 }
 
 func (a *skipFn) Evaluate(r rules.RuleMetadata, tx rules.TransactionState) {
-	// TODO(anuraaga): Confirm this is internal implementation detail
 	tx.(*corazawaf.Transaction).Skip = a.data
 }
 
diff --git a/actions/skipafter.go b/actions/skipafter.go
index c4789a5..613c443 100644
--- a/actions/skipafter.go
+++ b/actions/skipafter.go
@@ -4,9 +4,8 @@
 package actions
 
 import (
-	"strings"
-
 	"github.com/corazawaf/coraza/v3/internal/corazawaf"
+	utils "github.com/corazawaf/coraza/v3/internal/strings"
 	"github.com/corazawaf/coraza/v3/rules"
 )
 
@@ -14,14 +13,17 @@ type skipafterFn struct {
 	data string
 }
 
-func (a *skipafterFn) Init(r rules.RuleMetadata, data string) error {
-	a.data = strings.Trim(data, `"`)
+func (a *skipafterFn) Init(_ rules.RuleMetadata, data string) error {
+	data = utils.MaybeRemoveQuotes(data)
+	if len(data) == 0 {
+		return ErrMissingArguments
+	}
+	a.data = data
 	return nil
 }
 
 func (a *skipafterFn) Evaluate(r rules.RuleMetadata, tx rules.TransactionState) {
 	tx.DebugLogger().Debug("[%s] Starting secmarker %q", tx.ID(), a.data)
-	// TODO(anuraaga): Confirm this is internal implementation detail
 	tx.(*corazawaf.Transaction).SkipAfter = a.data
 }
 
diff --git a/actions/status.go b/actions/status.go
index b1852b5..15b826e 100644
--- a/actions/status.go
+++ b/actions/status.go
@@ -4,27 +4,30 @@
 package actions
 
 import (
+	"fmt"
 	"strconv"
 
 	"github.com/corazawaf/coraza/v3/internal/corazawaf"
 	"github.com/corazawaf/coraza/v3/rules"
 )
 
-type statusFn struct {
-}
+type statusFn struct{}
+
+func (a *statusFn) Init(r rules.RuleMetadata, data string) error {
+	if len(data) == 0 {
+		return ErrMissingArguments
+	}
 
-func (a *statusFn) Init(r rules.RuleMetadata, b1 string) error {
-	status, err := strconv.Atoi(b1)
+	// TODO(jcchavezs): Shall we validate valid status e.g. >200 && <600?
+	status, err := strconv.Atoi(data)
 	if err != nil {
-		return err
+		return fmt.Errorf("invalid argument: %s", err.Error())
 	}
-	// TODO(anuraaga): Confirm this is internal implementation detail
 	r.(*corazawaf.Rule).DisruptiveStatus = status
 	return nil
 }
 
-func (a *statusFn) Evaluate(r rules.RuleMetadata, tx rules.TransactionState) {
-}
+func (a *statusFn) Evaluate(_ rules.RuleMetadata, _ rules.TransactionState) {}
 
 func (a *statusFn) Type() rules.ActionType {
 	return rules.ActionTypeData
diff --git a/actions/t.go b/actions/t.go
index 2cf485e..6e92031 100644
--- a/actions/t.go
+++ b/actions/t.go
@@ -11,25 +11,23 @@ import (
 
 type tFn struct{}
 
-func (a *tFn) Init(r rules.RuleMetadata, input string) error {
+func (a *tFn) Init(r rules.RuleMetadata, data string) error {
 	// TODO there is a chance that it won't work, it requires tests
 	// none is a special hardcoded transformation, it must remove previous transformations
-	if input == "none" {
+	if data == "none" {
 		// remove elements
-		// TODO(anuraaga): Confirm this is internal implementation detail
 		r.(*corazawaf.Rule).ClearTransformations()
 		return nil
 	}
-	tt, err := transformations.GetTransformation(input)
+
+	tt, err := transformations.GetTransformation(data)
 	if err != nil {
 		return err
 	}
-	return r.(*corazawaf.Rule).AddTransformation(input, tt)
+	return r.(*corazawaf.Rule).AddTransformation(data, tt)
 }
 
-func (a *tFn) Evaluate(r rules.RuleMetadata, tx rules.TransactionState) {
-	// Not evaluated
-}
+func (a *tFn) Evaluate(_ rules.RuleMetadata, _ rules.TransactionState) {}
 
 func (a *tFn) Type() rules.ActionType {
 	return rules.ActionTypeNondisruptive
diff --git a/actions/tag.go b/actions/tag.go
index 6600987..caa8b6e 100644
--- a/actions/tag.go
+++ b/actions/tag.go
@@ -8,18 +8,17 @@ import (
 	"github.com/corazawaf/coraza/v3/rules"
 )
 
-type tagFn struct {
-}
+type tagFn struct{}
 
 func (a *tagFn) Init(r rules.RuleMetadata, data string) error {
-	// TODO(anuraaga): Confirm this is internal implementation detail
+	if len(data) == 0 {
+		return ErrMissingArguments
+	}
 	r.(*corazawaf.Rule).Tags_ = append(r.(*corazawaf.Rule).Tags_, data)
 	return nil
 }
 
-func (a *tagFn) Evaluate(r rules.RuleMetadata, tx rules.TransactionState) {
-	// Not evaluated
-}
+func (a *tagFn) Evaluate(_ rules.RuleMetadata, _ rules.TransactionState) {}
 
 func (a *tagFn) Type() rules.ActionType {
 	return rules.ActionTypeMetadata
diff --git a/actions/ver.go b/actions/ver.go
index 10c8d9a..d036d86 100644
--- a/actions/ver.go
+++ b/actions/ver.go
@@ -8,18 +8,17 @@ import (
 	"github.com/corazawaf/coraza/v3/rules"
 )
 
-type verFn struct {
-}
+type verFn struct{}
 
 func (a *verFn) Init(r rules.RuleMetadata, data string) error {
-	// TODO(anuraaga): Confirm this is internal implementation detail
+	if len(data) == 0 {
+		return ErrMissingArguments
+	}
 	r.(*corazawaf.Rule).Version_ = data
 	return nil
 }
 
-func (a *verFn) Evaluate(r rules.RuleMetadata, tx rules.TransactionState) {
-	// Not evaluated
-}
+func (a *verFn) Evaluate(_ rules.RuleMetadata, _ rules.TransactionState) {}
 
 func (a *verFn) Type() rules.ActionType {
 	return rules.ActionTypeMetadata
diff --git a/internal/seclang/rule_parser.go b/internal/seclang/rule_parser.go
index 891aa37..a9ce49c 100644
--- a/internal/seclang/rule_parser.go
+++ b/internal/seclang/rule_parser.go
@@ -258,7 +258,7 @@ func (p *RuleParser) ParseActions(actions string) error {
 	for _, a := range act {
 		if a.Atype == rules.ActionTypeMetadata {
 			if err := a.F.Init(p.rule, a.Value); err != nil {
-				return err
+				return fmt.Errorf("failed to init action %s: %s", a.Key, err.Error())
 			}
 		}
 	}


Test patch:
diff --git a/actions/allow_test.go b/actions/allow_test.go
new file mode 100644
index 0000000..36cdc23
--- /dev/null
+++ b/actions/allow_test.go
@@ -0,0 +1,35 @@
+package actions
+
+import (
+	"testing"
+
+	"github.com/corazawaf/coraza/v3/internal/corazatypes"
+)
+
+func TestAllowInit(t *testing.T) {
+	for _, test := range []struct {
+		data              string
+		expectedAllowType corazatypes.AllowType
+	}{
+		{"", corazatypes.AllowTypeAll},
+		{"phase", corazatypes.AllowTypePhase},
+		{"request", corazatypes.AllowTypeRequest},
+	} {
+		t.Run(test.data, func(t *testing.T) {
+			a := allow()
+			if err := a.Init(nil, test.data); err != nil {
+				t.Errorf("unexpected error: %s", err.Error())
+			}
+
+			if want, have := a.(*allowFn).allow, test.expectedAllowType; want != have {
+				t.Errorf("unexpected allow type, want: %d, have: %d", want, have)
+			}
+		})
+	}
+
+	t.Run("invalid", func(t *testing.T) {
+		if err := allow().Init(nil, "response"); err == nil {
+			t.Errorf("expected error")
+		}
+	})
+}
diff --git a/actions/block_test.go b/actions/block_test.go
new file mode 100644
index 0000000..2944310
--- /dev/null
+++ b/actions/block_test.go
@@ -0,0 +1,19 @@
+package actions
+
+import "testing"
+
+func TestBlockInit(t *testing.T) {
+	t.Run("no arguments", func(t *testing.T) {
+		a := block()
+		if err := a.Init(nil, ""); err != nil {
+			t.Error(err)
+		}
+	})
+
+	t.Run("unexpected arguments", func(t *testing.T) {
+		a := block()
+		if err := a.Init(nil, "abc"); err == nil || err != ErrUnexpectedArguments {
+			t.Error("expected error ErrUnexpectedArguments")
+		}
+	})
+}
diff --git a/actions/capture_test.go b/actions/capture_test.go
new file mode 100644
index 0000000..c8529a5
--- /dev/null
+++ b/actions/capture_test.go
@@ -0,0 +1,27 @@
+package actions
+
+import (
+	"testing"
+
+	"github.com/corazawaf/coraza/v3/internal/corazawaf"
+)
+
+func TestCaptureInit(t *testing.T) {
+	t.Run("passed arguments", func(t *testing.T) {
+		a := capture()
+		r := &corazawaf.Rule{}
+		if err := a.Init(r, ""); err != nil {
+			t.Error(err)
+		}
+		if want, have := true, r.Capture; want != have {
+			t.Errorf("expected action %t, got %t", want, have)
+		}
+	})
+
+	t.Run("no arguments", func(t *testing.T) {
+		a := capture()
+		if err := a.Init(nil, "abc"); err == nil || err != ErrUnexpectedArguments {
+			t.Error("expected error ErrUnexpectedArguments")
+		}
+	})
+}
diff --git a/actions/chain_test.go b/actions/chain_test.go
new file mode 100644
index 0000000..a52fdbb
--- /dev/null
+++ b/actions/chain_test.go
@@ -0,0 +1,28 @@
+package actions
+
+import (
+	"testing"
+
+	"github.com/corazawaf/coraza/v3/internal/corazawaf"
+)
+
+func TestChainInit(t *testing.T) {
+	t.Run("no arguments", func(t *testing.T) {
+		a := chain()
+		r := &corazawaf.Rule{}
+		if err := a.Init(r, ""); err != nil {
+			t.Error(err)
+		}
+
+		if want, have := true, r.HasChain; want != have {
+			t.Errorf("expected action %t, got %t", want, have)
+		}
+	})
+
+	t.Run("unexpected arguments", func(t *testing.T) {
+		a := chain()
+		if err := a.Init(nil, "abc"); err == nil || err != ErrUnexpectedArguments {
+			t.Error("expected error ErrUnexpectedArguments")
+		}
+	})
+}
diff --git a/actions/ctl_test.go b/actions/ctl_test.go
index 1675420..0790a55 100644
--- a/actions/ctl_test.go
+++ b/actions/ctl_test.go
@@ -16,23 +16,23 @@ func TestCtl(t *testing.T) {
 	waf := corazawaf.NewWAF()
 	tx := waf.NewTransaction()
 	r := corazawaf.NewRule()
-	ctlf := ctl()
+	a := ctl()
 
 	bodyprocessors := []string{"XML", "JSON", "URLENCODED", "MULTIPART"}
 	for _, bp := range bodyprocessors {
-		if err := ctlf.Init(r, "requestBodyProcessor="+bp); err != nil {
+		if err := a.Init(r, "requestBodyProcessor="+bp); err != nil {
 			t.Errorf("failed to init requestBodyProcessor %s", bp)
 		}
-		ctlf.Evaluate(r, tx)
+		a.Evaluate(r, tx)
 		if tx.Variables().RequestBodyProcessor().Get() != bp {
 			t.Error("failed to set RequestBodyProcessor " + bp)
 		}
 	}
 
-	if err := ctlf.Init(r, "ruleRemoveTargetById=981260;ARGS:user"); err != nil {
+	if err := a.Init(r, "ruleRemoveTargetById=981260;ARGS:user"); err != nil {
 		t.Error("failed to init ruleRemoveTargetById=981260;ARGS:user")
 	}
-	ctlf.Evaluate(r, tx)
+	a.Evaluate(r, tx)
 	/*
 		TODO
 		if tx.ruleRemoveTargetById[981260] == nil {
@@ -47,28 +47,28 @@ func TestCtl(t *testing.T) {
 		}
 	*/
 
-	if err := ctlf.Init(r, "auditEngine=Off"); err != nil {
+	if err := a.Init(r, "auditEngine=Off"); err != nil {
 		t.Error("failed to init ctl with auditEngine=Off")
 	}
-	ctlf.Evaluate(r, tx)
+	a.Evaluate(r, tx)
 
 	if tx.AuditEngine != types.AuditEngineOff {
 		t.Error("Failed to disable audit log")
 	}
 
-	if err := ctlf.Init(r, "ruleEngine=Off"); err != nil {
+	if err := a.Init(r, "ruleEngine=Off"); err != nil {
 		t.Error("failed to init ctl using ruleEngine=Off")
 	}
-	ctlf.Evaluate(r, tx)
+	a.Evaluate(r, tx)
 
 	if tx.RuleEngine != types.RuleEngineOff {
 		t.Errorf("Failed to disable rule engine, got %s", tx.RuleEngine.String())
 	}
 
-	if err := ctlf.Init(r, "requestBodyLimit=12345"); err != nil {
+	if err := a.Init(r, "requestBodyLimit=12345"); err != nil {
 		t.Error("failed to init ctl with requestBodyLimit=12345")
 	}
-	ctlf.Evaluate(r, tx)
+	a.Evaluate(r, tx)
 
 	if tx.RequestBodyLimit != 12345 {
 		t.Error("Failed to set request body limit")
diff --git a/actions/deny_test.go b/actions/deny_test.go
new file mode 100644
index 0000000..c2e53a8
--- /dev/null
+++ b/actions/deny_test.go
@@ -0,0 +1,19 @@
+package actions
+
+import "testing"
+
+func TestDenyInit(t *testing.T) {
+	t.Run("no arguments", func(t *testing.T) {
+		a := deny()
+		if err := a.Init(nil, ""); err != nil {
+			t.Error(err)
+		}
+	})
+
+	t.Run("unexpected arguments", func(t *testing.T) {
+		a := deny()
+		if err := a.Init(nil, "abc"); err == nil || err != ErrUnexpectedArguments {
+			t.Error("expected error ErrUnexpectedArguments")
+		}
+	})
+}
diff --git a/actions/drop_test.go b/actions/drop_test.go
new file mode 100644
index 0000000..33111e6
--- /dev/null
+++ b/actions/drop_test.go
@@ -0,0 +1,19 @@
+package actions
+
+import "testing"
+
+func TestDropInit(t *testing.T) {
+	t.Run("no arguments", func(t *testing.T) {
+		a := drop()
+		if err := a.Init(nil, ""); err != nil {
+			t.Error(err)
+		}
+	})
+
+	t.Run("unexpected arguments", func(t *testing.T) {
+		a := drop()
+		if err := a.Init(nil, "abc"); err == nil || err != ErrUnexpectedArguments {
+			t.Error("expected error ErrUnexpectedArguments")
+		}
+	})
+}
diff --git a/actions/exec_test.go b/actions/exec_test.go
new file mode 100644
index 0000000..010e159
--- /dev/null
+++ b/actions/exec_test.go
@@ -0,0 +1,19 @@
+package actions
+
+import "testing"
+
+func TestExecInit(t *testing.T) {
+	t.Run("no arguments", func(t *testing.T) {
+		a := exec()
+		if err := a.Init(nil, ""); err != nil {
+			t.Error(err)
+		}
+	})
+
+	t.Run("unexpected arguments", func(t *testing.T) {
+		a := exec()
+		if err := a.Init(nil, "abc"); err == nil || err != ErrUnexpectedArguments {
+			t.Error("expected error ErrUnexpectedArguments")
+		}
+	})
+}
diff --git a/actions/expirevar_test.go b/actions/expirevar_test.go
new file mode 100644
index 0000000..4938da4
--- /dev/null
+++ b/actions/expirevar_test.go
@@ -0,0 +1,29 @@
+package actions
+
+import "testing"
+
+func TestExpirevarInit(t *testing.T) {
+	for _, test := range []struct {
+		data          string
+		expectedError bool
+	}{
+		{"", true},
+		{"session", true},
+		{"session.suspicious", true},
+		{"session.suspicious=abc", true},
+		{"session.suspicious=-3600", true},
+		{"session.suspicious=3600", false},
+	} {
+		a := expirevar()
+		err := a.Init(nil, test.data)
+		if test.expectedError {
+			if err == nil {
+				t.Errorf("expected error: %s", err.Error())
+			}
+		} else {
+			if err != nil {
+				t.Errorf("unexpected error: %s", err.Error())
+			}
+		}
+	}
+}
diff --git a/actions/id_test.go b/actions/id_test.go
new file mode 100644
index 0000000..aae26bd
--- /dev/null
+++ b/actions/id_test.go
@@ -0,0 +1,37 @@
+package actions
+
+import (
+	"testing"
+
+	"github.com/corazawaf/coraza/v3/internal/corazawaf"
+)
+
+func TestIdInit(t *testing.T) {
+	for _, test := range []struct {
+		data         string
+		expectedID   int
+		expectsError bool
+	}{
+		{"", 0, true},
+		{"x", 0, true},
+		{"0", 0, true},
+		{"-10", 0, true},
+		{"10", 10, false},
+	} {
+		r := &corazawaf.Rule{}
+		t.Run(test.data, func(t *testing.T) {
+			a := id()
+			err := a.Init(r, test.data)
+
+			if test.expectsError && err == nil {
+				t.Error("expected error")
+			} else if !test.expectsError && err != nil {
+				t.Errorf("unexpected error: %s", err.Error())
+			}
+
+			if want, have := test.expectedID, r.ID_; want != have {
+				t.Errorf("unexpected id, want: %d, have: %d", want, have)
+			}
+		})
+	}
+}
diff --git a/actions/initcol_test.go b/actions/initcol_test.go
new file mode 100644
index 0000000..fe80bf4
--- /dev/null
+++ b/actions/initcol_test.go
@@ -0,0 +1,21 @@
+package actions
+
+import "testing"
+
+func TestInitcolInit(t *testing.T) {
+	t.Run("invalid argument", func(t *testing.T) {
+		initcol := initcol()
+		err := initcol.Init(nil, "foo")
+		if err == nil {
+			t.Errorf("expected error")
+		}
+	})
+
+	t.Run("passing argument", func(t *testing.T) {
+		initcol := initcol()
+		err := initcol.Init(nil, "foo=bar")
+		if err != nil {
+			t.Errorf("unexpected error: %s", err.Error())
+		}
+	})
+}
diff --git a/actions/log_test.go b/actions/log_test.go
new file mode 100644
index 0000000..7c135c5
--- /dev/null
+++ b/actions/log_test.go
@@ -0,0 +1,24 @@
+package actions
+
+import (
+	"testing"
+
+	"github.com/corazawaf/coraza/v3/internal/corazawaf"
+)
+
+func TestLogInit(t *testing.T) {
+	a := log()
+	r := &corazawaf.Rule{}
+	err := a.Init(r, "")
+	if err != nil {
+		t.Errorf("unexpected error: %s", err.Error())
+	}
+
+	if want, have := true, r.Log; want != have {
+		t.Errorf("unexpected log value, want %t, have %t", want, have)
+	}
+
+	if want, have := true, r.Audit; want != have {
+		t.Errorf("unexpected audit value, want %t, have %t", want, have)
+	}
+}
diff --git a/actions/logdata_test.go b/actions/logdata_test.go
new file mode 100644
index 0000000..e7e79fa
--- /dev/null
+++ b/actions/logdata_test.go
@@ -0,0 +1,29 @@
+package actions
+
+import (
+	"testing"
+
+	"github.com/corazawaf/coraza/v3/internal/corazawaf"
+)
+
+func TestLogDataInit(t *testing.T) {
+	for name, test := range map[string]struct {
+		data        string
+		expectError bool
+	}{
+		"empty":   {"", true},
+		"valid":   {"%{tx.count}", false},
+		"invalid": {"%{tx.count", true},
+	} {
+		t.Run(name, func(t *testing.T) {
+			action := logdata()
+			r := &corazawaf.Rule{}
+			err := action.Init(r, test.data)
+			if test.expectError && err == nil {
+				t.Errorf("expected error")
+			} else if !test.expectError && err != nil {
+				t.Errorf("unexpected error: %s", err.Error())
+			}
+		})
+	}
+}
diff --git a/actions/maturity_test.go b/actions/maturity_test.go
new file mode 100644
index 0000000..1abd11e
--- /dev/null
+++ b/actions/maturity_test.go
@@ -0,0 +1,39 @@
+package actions
+
+import (
+	"testing"
+
+	"github.com/corazawaf/coraza/v3/internal/corazawaf"
+)
+
+func TestMaturityInit(t *testing.T) {
+	for _, test := range []struct {
+		data             string
+		expectedError    bool
+		expectedMaturity int
+	}{
+		{"", true, 0},
+		{"abc", true, 0},
+		{"-10", true, 0},
+		{"0", true, 0},
+		{"5", false, 5},
+		{"10", true, 0},
+	} {
+		a := maturity()
+		r := &corazawaf.Rule{}
+		err := a.Init(r, test.data)
+		if test.expectedError {
+			if err == nil {
+				t.Errorf("expected error: %s", err.Error())
+			}
+		} else {
+			if err != nil {
+				t.Errorf("unexpected error: %s", err.Error())
+			}
+
+			if want, have := test.expectedMaturity, r.Maturity_; want != have {
+				t.Errorf("unexpected maturity value, want %d, have %d", want, have)
+			}
+		}
+	}
+}
diff --git a/actions/msg_test.go b/actions/msg_test.go
new file mode 100644
index 0000000..92943b5
--- /dev/null
+++ b/actions/msg_test.go
@@ -0,0 +1,28 @@
+package actions
+
+import (
+	"testing"
+
+	"github.com/corazawaf/coraza/v3/internal/corazawaf"
+)
+
+func TestMsgInit(t *testing.T) {
+	t.Run("no arguments", func(t *testing.T) {
+		a := msg()
+		if err := a.Init(nil, ""); err == nil || err != ErrMissingArguments {
+			t.Error("expected error ErrMissingArguments")
+		}
+	})
+
+	t.Run("with arguments", func(t *testing.T) {
+		a := msg()
+		r := &corazawaf.Rule{}
+		if err := a.Init(r, "test"); err != nil {
+			t.Error(err)
+		}
+
+		if r.Msg == nil {
+			t.Error("expected msg to be set")
+		}
+	})
+}
diff --git a/actions/multimatch_test.go b/actions/multimatch_test.go
new file mode 100644
index 0000000..c0749c5
--- /dev/null
+++ b/actions/multimatch_test.go
@@ -0,0 +1,28 @@
+package actions
+
+import (
+	"testing"
+
+	"github.com/corazawaf/coraza/v3/internal/corazawaf"
+)
+
+func TestMultiMatchInit(t *testing.T) {
+	t.Run("with arguments", func(t *testing.T) {
+		a := multimatch()
+		if err := a.Init(nil, "abc"); err == nil || err != ErrUnexpectedArguments {
+			t.Error("expected error ErrUnexpectedArguments")
+		}
+	})
+
+	t.Run("no arguments", func(t *testing.T) {
+		a := multimatch()
+		r := &corazawaf.Rule{}
+		if err := a.Init(r, ""); err != nil {
+			t.Error(err)
+		}
+
+		if !r.MultiMatch {
+			t.Errorf("expected multimatch to be true")
+		}
+	})
+}
diff --git a/actions/noauditlog_test.go b/actions/noauditlog_test.go
new file mode 100644
index 0000000..a4ff2b0
--- /dev/null
+++ b/actions/noauditlog_test.go
@@ -0,0 +1,28 @@
+package actions
+
+import (
+	"testing"
+
+	"github.com/corazawaf/coraza/v3/internal/corazawaf"
+)
+
+func TestNoauditlogInit(t *testing.T) {
+	t.Run("no arguments", func(t *testing.T) {
+		a := noauditlog()
+		r := &corazawaf.Rule{}
+		if err := a.Init(r, ""); err != nil {
+			t.Error(err)
+		}
+
+		if r.Audit {
+			t.Error("unexpected audit value")
+		}
+	})
+
+	t.Run("unexpected arguments", func(t *testing.T) {
+		a := noauditlog()
+		if err := a.Init(nil, "abc"); err == nil || err != ErrUnexpectedArguments {
+			t.Error("expected error ErrUnexpectedArguments")
+		}
+	})
+}
diff --git a/actions/nolog_test.go b/actions/nolog_test.go
new file mode 100644
index 0000000..3bd9522
--- /dev/null
+++ b/actions/nolog_test.go
@@ -0,0 +1,32 @@
+package actions
+
+import (
+	"testing"
+
+	"github.com/corazawaf/coraza/v3/internal/corazawaf"
+)
+
+func TestNologInit(t *testing.T) {
+	t.Run("no arguments", func(t *testing.T) {
+		a := nolog()
+		r := &corazawaf.Rule{}
+		if err := a.Init(r, ""); err != nil {
+			t.Error(err)
+		}
+
+		if r.Audit {
+			t.Error("unexpected audit value")
+		}
+
+		if r.Log {
+			t.Error("unexpected log value")
+		}
+	})
+
+	t.Run("unexpected arguments", func(t *testing.T) {
+		a := nolog()
+		if err := a.Init(nil, "abc"); err == nil || err != ErrUnexpectedArguments {
+			t.Error("expected error ErrUnexpectedArguments")
+		}
+	})
+}
diff --git a/actions/pass_test.go b/actions/pass_test.go
new file mode 100644
index 0000000..2d73fc2
--- /dev/null
+++ b/actions/pass_test.go
@@ -0,0 +1,21 @@
+package actions
+
+import (
+	"testing"
+)
+
+func TestPassInit(t *testing.T) {
+	t.Run("no arguments", func(t *testing.T) {
+		a := pass()
+		if err := a.Init(nil, ""); err != nil {
+			t.Error(err)
+		}
+	})
+
+	t.Run("unexpected arguments", func(t *testing.T) {
+		a := nolog()
+		if err := a.Init(nil, "abc"); err == nil || err != ErrUnexpectedArguments {
+			t.Error("expected error ErrUnexpectedArguments")
+		}
+	})
+}
diff --git a/actions/phase_test.go b/actions/phase_test.go
new file mode 100644
index 0000000..c621a3c
--- /dev/null
+++ b/actions/phase_test.go
@@ -0,0 +1,22 @@
+package actions
+
+import (
+	"strings"
+	"testing"
+)
+
+func TestPhaseInit(t *testing.T) {
+	t.Run("no arguments", func(t *testing.T) {
+		a := phase()
+		if err := a.Init(nil, ""); err == nil || err != ErrMissingArguments {
+			t.Error("expected error ErrMissingArguments")
+		}
+	})
+
+	t.Run("unknown phase", func(t *testing.T) {
+		a := phase()
+		if err := a.Init(nil, "connect"); err == nil || strings.Contains(err.Error(), "unknown phase") {
+			t.Error("expected error for unknown phase")
+		}
+	})
+}
diff --git a/actions/redirect_test.go b/actions/redirect_test.go
new file mode 100644
index 0000000..1abfd93
--- /dev/null
+++ b/actions/redirect_test.go
@@ -0,0 +1,23 @@
+package actions
+
+import "testing"
+
+func TestRedirectInit(t *testing.T) {
+	t.Run("no arguments", func(t *testing.T) {
+		a := redirect()
+		if err := a.Init(nil, ""); err == nil || err != ErrMissingArguments {
+			t.Error("expected error ErrMissingArguments")
+		}
+	})
+
+	t.Run("passed arguments", func(t *testing.T) {
+		a := redirect()
+		if err := a.Init(nil, "abc"); err != nil {
+			t.Error("unexpected error")
+		}
+
+		if want, have := "abc", a.(*redirectFn).target; want != have {
+			t.Errorf("unexpected target, want %q, got %q", want, have)
+		}
+	})
+}
diff --git a/actions/setvar_test.go b/actions/setvar_test.go
new file mode 100644
index 0000000..ffab1f8
--- /dev/null
+++ b/actions/setvar_test.go
@@ -0,0 +1,12 @@
+package actions
+
+import "testing"
+
+func TestSetvarInit(t *testing.T) {
+	t.Run("no arguments", func(t *testing.T) {
+		a := setvar()
+		if err := a.Init(nil, ""); err == nil || err != ErrMissingArguments {
+			t.Error("expected error ErrMissingArguments")
+		}
+	})
+}
diff --git a/actions/skip_test.go b/actions/skip_test.go
new file mode 100644
index 0000000..53fba51
--- /dev/null
+++ b/actions/skip_test.go
@@ -0,0 +1,43 @@
+package actions
+
+import (
+	"testing"
+)
+
+func TestSkipInit(t *testing.T) {
+	t.Run("no arguments", func(t *testing.T) {
+		a := skip()
+		if err := a.Init(nil, ""); err == nil || err != ErrMissingArguments {
+			t.Error("expected error ErrMissingArguments")
+		}
+	})
+
+	t.Run("with arguments", func(t *testing.T) {
+		for _, test := range []struct {
+			data          string
+			expectedError bool
+			expectedData  int
+		}{
+			{"abc", true, 0},
+			{"-10", true, 0},
+			{"0", true, 0},
+			{"5", false, 5},
+		} {
+			a := skip()
+			err := a.Init(nil, test.data)
+			if test.expectedError {
+				if err == nil {
+					t.Errorf("expected error: %s", err.Error())
+				}
+			} else {
+				if err != nil {
+					t.Errorf("unexpected error: %s", err.Error())
+				}
+
+				if want, have := test.expectedData, a.(*skipFn).data; want != have {
+					t.Errorf("unexpected maturity value, want %d, have %d", want, have)
+				}
+			}
+		}
+	})
+}
diff --git a/actions/ver_test.go b/actions/ver_test.go
new file mode 100644
index 0000000..67f0662
--- /dev/null
+++ b/actions/ver_test.go
@@ -0,0 +1,28 @@
+package actions
+
+import (
+	"testing"
+
+	"github.com/corazawaf/coraza/v3/internal/corazawaf"
+)
+
+func TestVerInit(t *testing.T) {
+	t.Run("passed arguments", func(t *testing.T) {
+		a := ver()
+		r := &corazawaf.Rule{}
+		if err := a.Init(r, "1.2.3"); err != nil {
+			t.Error(err)
+		}
+
+		if want, have := "1.2.3", r.Version_; want != have {
+			t.Errorf("expected version %s, got %s", want, have)
+		}
+	})
+
+	t.Run("missing arguments", func(t *testing.T) {
+		a := ver()
+		if err := a.Init(nil, ""); err == nil || err != ErrMissingArguments {
+			t.Error("expected error ErrMissingArguments")
+		}
+	})
+}