Repository: corazawaf/coraza
Pull request #626 (2023-02-10 09:42:57)

chore: avoids tmp dir instantiation when no FS access environment.
Currently we have a flag for tinygo compilation to avoid access to filesystem however this isn't a limitation of tinygo per-se and also this is more like a wasm runtime limitations. Also in envs where coraza is compiled into wasm to run over JS (e.g. the playground) we don't have `stat` implementation.

Ping @jptosso @anuraaga  

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=626)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=coraza&pullRequest=626&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=626&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=coraza&pullRequest=626&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=626&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=626&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=coraza&pullRequest=626&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=626&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=626&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=coraza&pullRequest=626&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=626&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=626&resolved=false&types=CODE_SMELL) [98 Code Smells](https://sonarcloud.io/project/issues?id=coraza&pullRequest=626&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=626&metric=new_coverage&view=list) [0.0% Coverage](https://sonarcloud.io/component_measures?id=coraza&pullRequest=626&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=626&metric=new_duplicated_lines_density&view=list) [0.1% Duplication](https://sonarcloud.io/component_measures?id=coraza&pullRequest=626&metric=new_duplicated_lines_density&view=list)


codecov[bot]: # [Codecov](https://codecov.io/gh/corazawaf/coraza/pull/626?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=corazawaf) Report
Base: **77.94**% // Head: **77.92**% // Decreases project coverage by **`-0.03%`** :warning:
> Coverage data is based on head [(`d22a3a7`)](https://codecov.io/gh/corazawaf/coraza/pull/626?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=corazawaf) compared to base [(`e7f216d`)](https://codecov.io/gh/corazawaf/coraza/commit/e7f216d8efef70cfa34d87492e1746ac6d4f07a4?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=corazawaf).
> Patch coverage: 71.42% of modified lines in pull request are covered.

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


```diff
@@            Coverage Diff             @@
##           v3/dev     #626      +/-   ##
==========================================
- Coverage   77.94%   77.92%   -0.03%     
==========================================
  Files         144      144              
  Lines        7600     7605       +5     
==========================================
+ Hits         5924     5926       +2     
- Misses       1443     1447       +4     
+ Partials      233      232       -1     
```

| Flag | Coverage Δ | |
|---|---|---|
| default | `73.73% <71.42%> (+0.01%)` | :arrow_up: |
| examples | `29.61% <64.28%> (+0.04%)` | :arrow_up: |
| ftw | `54.21% <64.28%> (+0.03%)` | :arrow_up: |
| ftw-multiphase | `54.30% <64.28%> (+0.03%)` | :arrow_up: |
| tinygo | `72.03% <71.42%> (+0.24%)` | :arrow_up: |

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/626?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=corazawaf) | Coverage Δ | |
|---|---|---|
| [waf.go](https://codecov.io/gh/corazawaf/coraza/pull/626?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=corazawaf#diff-d2FmLmdv) | `63.07% <0.00%> (ø)` | |
| [internal/corazawaf/body\_buffer.go](https://codecov.io/gh/corazawaf/coraza/pull/626?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=corazawaf#diff-aW50ZXJuYWwvY29yYXphd2FmL2JvZHlfYnVmZmVyLmdv) | `68.96% <66.66%> (ø)` | |
| [bodyprocessors/multipart.go](https://codecov.io/gh/corazawaf/coraza/pull/626?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=corazawaf#diff-Ym9keXByb2Nlc3NvcnMvbXVsdGlwYXJ0Lmdv) | `78.48% <100.00%> (-3.80%)` | :arrow_down: |
| [internal/corazawaf/waf.go](https://codecov.io/gh/corazawaf/coraza/pull/626?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=corazawaf#diff-aW50ZXJuYWwvY29yYXphd2FmL3dhZi5nbw==) | `94.47% <100.00%> (+0.17%)` | :arrow_up: |

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/626?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=626)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=coraza&pullRequest=626&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=626&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=coraza&pullRequest=626&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=626&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=626&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=coraza&pullRequest=626&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=626&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=626&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=coraza&pullRequest=626&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=626&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=626&resolved=false&types=CODE_SMELL) [98 Code Smells](https://sonarcloud.io/project/issues?id=coraza&pullRequest=626&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=626&metric=new_coverage&view=list) [0.0% Coverage](https://sonarcloud.io/component_measures?id=coraza&pullRequest=626&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=626&metric=new_duplicated_lines_density&view=list) [0.1% Duplication](https://sonarcloud.io/component_measures?id=coraza&pullRequest=626&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=626)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=coraza&pullRequest=626&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=626&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=coraza&pullRequest=626&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=626&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=626&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=coraza&pullRequest=626&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=626&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=626&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=coraza&pullRequest=626&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=626&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=626&resolved=false&types=CODE_SMELL) [98 Code Smells](https://sonarcloud.io/project/issues?id=coraza&pullRequest=626&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=626&metric=new_coverage&view=list) [0.0% Coverage](https://sonarcloud.io/component_measures?id=coraza&pullRequest=626&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=626&metric=new_duplicated_lines_density&view=list) [0.1% Duplication](https://sonarcloud.io/component_measures?id=coraza&pullRequest=626&metric=new_duplicated_lines_density&view=list)


jcchavezs: @anuraaga shall we do it the other way around? like instead of coraza knowing what os, arch and compiler has access to FS maybe just add a build tag `fs_access` and then use it in coraza proxy wasm and playground?
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=626)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=coraza&pullRequest=626&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=626&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=coraza&pullRequest=626&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=626&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=626&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=coraza&pullRequest=626&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=626&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=626&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=coraza&pullRequest=626&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=626&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=626&resolved=false&types=CODE_SMELL) [100 Code Smells](https://sonarcloud.io/project/issues?id=coraza&pullRequest=626&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=626&metric=new_coverage&view=list) [0.0% Coverage](https://sonarcloud.io/component_measures?id=coraza&pullRequest=626&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=626&metric=new_duplicated_lines_density&view=list) [0.1% Duplication](https://sonarcloud.io/component_measures?id=coraza&pullRequest=626&metric=new_duplicated_lines_density&view=list)



Patch:
diff --git a/actions/nolog.go b/actions/nolog.go
index 897c85a..809ea92 100644
--- a/actions/nolog.go
+++ b/actions/nolog.go
@@ -8,8 +8,7 @@ import (
 	"github.com/corazawaf/coraza/v3/rules"
 )
 
-type nologFn struct {
-}
+type nologFn struct{}
 
 func (a *nologFn) Init(r rules.RuleMetadata, data string) error {
 	// TODO(anuraaga): Confirm this is internal implementation detail
@@ -18,11 +17,7 @@ func (a *nologFn) Init(r rules.RuleMetadata, data string) error {
 	return nil
 }
 
-func (a *nologFn) Evaluate(r rules.RuleMetadata, tx rules.TransactionState) {
-	// TODO(anuraaga): Confirm this is internal implementation detail
-	// TODO(anuraaga): Confirm this is actually needed.
-	r.(*corazawaf.Rule).Audit = false
-}
+func (a *nologFn) Evaluate(_ rules.RuleMetadata, _ rules.TransactionState) {}
 
 func (a *nologFn) Type() rules.ActionType {
 	return rules.ActionTypeNondisruptive
diff --git a/bodyprocessors/multipart.go b/bodyprocessors/multipart.go
index 7effc84..d970bdc 100644
--- a/bodyprocessors/multipart.go
+++ b/bodyprocessors/multipart.go
@@ -56,7 +56,7 @@ func (mbp *multipartBodyProcessor) ProcessRequest(reader io.Reader, v rules.Tran
 		filename := originFileName(p)
 		if filename != "" {
 			var size int64
-			if !environment.IsTinyGo {
+			if environment.HasAccessToFS {
 				// Only copy file to temp when not running in TinyGo
 				temp, err := os.CreateTemp(storagePath, "crzmp*")
 				if err != nil {
diff --git a/collection/collection.go b/collection/collection.go
index 37d077f..af39535 100644
--- a/collection/collection.go
+++ b/collection/collection.go
@@ -19,9 +19,6 @@ type Collection interface {
 
 	// Name returns the name for the current CollectionMap
 	Name() string
-
-	// Reset the current Collection
-	Reset()
 }
 
 // Single is a Collection with a single element.
diff --git a/internal/collections/concat.go b/internal/collections/concat.go
index ff6f459..a9729dc 100644
--- a/internal/collections/concat.go
+++ b/internal/collections/concat.go
@@ -43,10 +43,6 @@ func (c *ConcatCollection) Name() string {
 	return c.name
 }
 
-// Reset the current ConcatMap
-func (c *ConcatCollection) Reset() {
-}
-
 // ConcatKeyed is a collection view over multiple keyed collections.
 type ConcatKeyed struct {
 	data     []collection.Keyed
@@ -104,7 +100,3 @@ func (c *ConcatKeyed) FindAll() []types.MatchData {
 func (c *ConcatKeyed) Name() string {
 	return c.name
 }
-
-// Reset the current ConcatMap
-func (c *ConcatKeyed) Reset() {
-}
diff --git a/internal/collections/named.go b/internal/collections/named.go
index bad5501..99e9ed2 100644
--- a/internal/collections/named.go
+++ b/internal/collections/named.go
@@ -132,9 +132,6 @@ func (c *NamedCollectionNames) Name() string {
 	return c.name
 }
 
-func (c *NamedCollectionNames) Reset() {
-}
-
 func (c *NamedCollectionNames) String() string {
 	res := strings.Builder{}
 	res.WriteString(c.name)
diff --git a/internal/collections/noop.go b/internal/collections/noop.go
new file mode 100644
index 0000000..ff4ad04
--- /dev/null
+++ b/internal/collections/noop.go
@@ -0,0 +1,21 @@
+// Copyright 2023 Juan Pablo Tosso and the OWASP Coraza contributors
+// SPDX-License-Identifier: Apache-2.0
+
+package collections
+
+import (
+	"github.com/corazawaf/coraza/v3/collection"
+	"github.com/corazawaf/coraza/v3/types"
+)
+
+var Noop collection.Collection = &noop{}
+
+type noop struct{}
+
+func (c *noop) FindAll() []types.MatchData {
+	return nil
+}
+
+func (c *noop) Name() string {
+	return ""
+}
diff --git a/internal/collections/sized.go b/internal/collections/sized.go
index 5de5386..1a9cea3 100644
--- a/internal/collections/sized.go
+++ b/internal/collections/sized.go
@@ -58,11 +58,6 @@ func (c *SizeCollection) Name() string {
 	return c.name
 }
 
-// Reset the current CollectionSizeProxy
-func (c *SizeCollection) Reset() {
-	// do nothing
-}
-
 func (c *SizeCollection) String() string {
 	return fmt.Sprintf("%s: %d", c.name, c.size())
 }
diff --git a/internal/corazawaf/body_buffer.go b/internal/corazawaf/body_buffer.go
index 80069bd..8d5e5ce 100644
--- a/internal/corazawaf/body_buffer.go
+++ b/internal/corazawaf/body_buffer.go
@@ -69,7 +69,7 @@ func (br *BodyBuffer) Write(data []byte) (n int, err error) {
 	// 32-bit machine: 1073741824 (2^30, 1GiB)
 	// 64-bit machine: 34359738368 (2^35, 32GiB) (Not reached the ErrTooLarge panic, the OS triggered an OOM)
 	if targetLen > br.options.MemoryLimit {
-		if environment.IsTinyGo {
+		if !environment.HasAccessToFS {
 			// TinyGo MemoryLimit should be equal to Limit. Therefore, Write function has been called without Limit check.
 			return 0, errors.New("MemoryLimit reached while writing")
 		} else {
@@ -99,7 +99,7 @@ type bodyBufferReader struct {
 }
 
 func (b *bodyBufferReader) Read(p []byte) (n int, err error) {
-	if environment.IsTinyGo || b.br.writer == nil {
+	if !environment.HasAccessToFS || b.br.writer == nil {
 		buf := b.br.buffer.Bytes()
 		n = len(p)
 		if b.pos+n > len(buf) {
@@ -134,7 +134,7 @@ func (br *BodyBuffer) Size() int64 {
 func (br *BodyBuffer) Reset() error {
 	br.buffer.Reset()
 	br.length = 0
-	if !environment.IsTinyGo && br.writer != nil {
+	if environment.HasAccessToFS && br.writer != nil {
 		w := br.writer
 		br.writer = nil
 		if err := w.Close(); err != nil {
diff --git a/internal/corazawaf/rule.go b/internal/corazawaf/rule.go
index db9b8ef..4c85598 100644
--- a/internal/corazawaf/rule.go
+++ b/internal/corazawaf/rule.go
@@ -528,14 +528,8 @@ func minPhase(v variables.RuleVariable) types.RulePhase {
 	case variables.ArgsCombinedSize:
 		// Size changes between phase 1 and 2 so evaluate both times
 		return types.PhaseRequestHeaders
-	case variables.AuthType:
-		// Not populated by Coraza, but should generally be in headers
-		return types.PhaseRequestHeaders
 	case variables.FilesCombinedSize:
 		return types.PhaseRequestBody
-	case variables.FullRequest:
-		// Not populated by Coraza
-		return types.PhaseRequestBody
 	case variables.FullRequestLength:
 		// Not populated by Coraza
 		return types.PhaseRequestBody
@@ -548,54 +542,12 @@ func minPhase(v variables.RuleVariable) types.RulePhase {
 	case variables.MatchedVarName:
 		// MatchedVar is only for logging, not evaluation
 		return types.PhaseUnknown
-	case variables.MultipartBoundaryQuoted:
-		// Not populated by Coraza
-		return types.PhaseRequestBody
 	// MultipartBoundaryWhitespace kept for compatibility
-	case variables.MultipartBoundaryWhitespace:
-		// Not populated by Coraza
-		return types.PhaseRequestBody
-	case variables.MultipartCrlfLfLines:
-		// Not populated by Coraza
-		return types.PhaseRequestBody
 	case variables.MultipartDataAfter:
 		// Not populated by Coraza
 		return types.PhaseRequestBody
-	case variables.MultipartDataBefore:
-		// Not populated by Coraza
-		return types.PhaseRequestBody
-	case variables.MultipartFileLimitExceeded:
-		// Not populated by Coraza
-		return types.PhaseRequestBody
-	case variables.MultipartHeaderFolding:
-		// Not populated by Coraza
-		return types.PhaseRequestBody
-	case variables.MultipartInvalidHeaderFolding:
-		// Not populated by Coraza
-		return types.PhaseRequestBody
-	case variables.MultipartInvalidPart:
-		// Not populated by Coraza
-		return types.PhaseRequestBody
-	case variables.MultipartInvalidQuoting:
-		// Not populated by Coraza
-		return types.PhaseRequestBody
-	case variables.MultipartLfLine:
-		// Not populated by Coraza
-		return types.PhaseRequestBody
-	case variables.MultipartMissingSemicolon:
-		// Not populated by Coraza
-		return types.PhaseRequestBody
-	case variables.MultipartStrictError:
-		// Not populated by Coraza
-		return types.PhaseRequestBody
-	case variables.MultipartUnmatchedBoundary:
-		// Not populated by Coraza
-		return types.PhaseRequestBody
 	case variables.OutboundDataError:
 		return types.PhaseResponseBody
-	case variables.PathInfo:
-		// Not populated by Coraza
-		return types.PhaseRequestHeaders
 	case variables.QueryString:
 		return types.PhaseRequestHeaders
 	case variables.RemoteAddr:
@@ -651,9 +603,6 @@ func minPhase(v variables.RuleVariable) types.RulePhase {
 	case variables.ServerPort:
 		// Configuration of the server itself
 		return types.PhaseRequestHeaders
-	case variables.Sessionid:
-		// Not populated by Coraza
-		return types.PhaseRequestHeaders
 	case variables.HighestSeverity:
 		// Result of matching, not used in phaes
 		return types.PhaseUnknown
@@ -668,9 +617,6 @@ func minPhase(v variables.RuleVariable) types.RulePhase {
 		return types.PhaseResponseHeaders
 	case variables.RequestHeadersNames:
 		return types.PhaseRequestHeaders
-	case variables.Userid:
-		// Not populated by Coraza
-		return types.PhaseRequestHeaders
 	case variables.Args:
 		// Updated between headers and body
 		return types.PhaseRequestBody
@@ -728,9 +674,6 @@ func minPhase(v variables.RuleVariable) types.RulePhase {
 		return types.PhaseRequestBody
 	case variables.Env:
 		return types.PhaseRequestHeaders
-	case variables.IP:
-		// Not populated by Coraza
-		return types.PhaseRequestHeaders
 	case variables.UrlencodedError:
 		return types.PhaseRequestHeaders
 	case variables.ResponseArgs:
diff --git a/internal/corazawaf/rulegroup.go b/internal/corazawaf/rulegroup.go
index 9a3c2af..7439bd6 100644
--- a/internal/corazawaf/rulegroup.go
+++ b/internal/corazawaf/rulegroup.go
@@ -172,7 +172,6 @@ RulesLoop:
 		// TODO these lines are SUPER SLOW
 		// we reset matched_vars, matched_vars_names, etc
 		tx.variables.matchedVars.Reset()
-		tx.variables.matchedVarsNames.Reset()
 
 		r.Evaluate(phase, tx, transformationCache)
 		tx.Capture = false // we reset captures
diff --git a/internal/corazawaf/transaction.go b/internal/corazawaf/transaction.go
index c463475..acb56d5 100644
--- a/internal/corazawaf/transaction.go
+++ b/internal/corazawaf/transaction.go
@@ -131,12 +131,8 @@ func (tx *Transaction) Collection(idx variables.RuleVariable) collection.Collect
 		return tx.variables.uniqueID
 	case variables.ArgsCombinedSize:
 		return tx.variables.argsCombinedSize
-	case variables.AuthType:
-		return tx.variables.authType
 	case variables.FilesCombinedSize:
 		return tx.variables.filesCombinedSize
-	case variables.FullRequest:
-		return tx.variables.fullRequest
 	case variables.FullRequestLength:
 		return tx.variables.fullRequestLength
 	case variables.InboundDataError:
@@ -145,38 +141,10 @@ func (tx *Transaction) Collection(idx variables.RuleVariable) collection.Collect
 		return tx.variables.matchedVar
 	case variables.MatchedVarName:
 		return tx.variables.matchedVarName
-	case variables.MultipartBoundaryQuoted:
-		return tx.variables.multipartBoundaryQuoted
-	case variables.MultipartBoundaryWhitespace:
-		return tx.variables.multipartBoundaryWhitespace
-	case variables.MultipartCrlfLfLines:
-		return tx.variables.multipartCrlfLfLines
 	case variables.MultipartDataAfter:
 		return tx.variables.multipartDataAfter
-	case variables.MultipartDataBefore:
-		return tx.variables.multipartDataBefore
-	case variables.MultipartFileLimitExceeded:
-		return tx.variables.multipartFileLimitExceeded
-	case variables.MultipartHeaderFolding:
-		return tx.variables.multipartHeaderFolding
-	case variables.MultipartInvalidHeaderFolding:
-		return tx.variables.multipartInvalidHeaderFolding
-	case variables.MultipartInvalidPart:
-		return tx.variables.multipartInvalidPart
-	case variables.MultipartInvalidQuoting:
-		return tx.variables.multipartInvalidQuoting
-	case variables.MultipartLfLine:
-		return tx.variables.multipartLfLine
-	case variables.MultipartMissingSemicolon:
-		return tx.variables.multipartMissingSemicolon
-	case variables.MultipartStrictError:
-		return tx.variables.multipartStrictError
-	case variables.MultipartUnmatchedBoundary:
-		return tx.variables.multipartUnmatchedBoundary
 	case variables.OutboundDataError:
 		return tx.variables.outboundDataError
-	case variables.PathInfo:
-		return tx.variables.pathInfo
 	case variables.QueryString:
 		return tx.variables.queryString
 	case variables.RemoteAddr:
@@ -227,8 +195,6 @@ func (tx *Transaction) Collection(idx variables.RuleVariable) collection.Collect
 		return tx.variables.serverName
 	case variables.ServerPort:
 		return tx.variables.serverPort
-	case variables.Sessionid:
-		return tx.variables.sessionID
 	case variables.HighestSeverity:
 		return tx.variables.highestSeverity
 	case variables.StatusLine:
@@ -241,8 +207,6 @@ func (tx *Transaction) Collection(idx variables.RuleVariable) collection.Collect
 		return tx.variables.responseHeadersNames
 	case variables.RequestHeadersNames:
 		return tx.variables.requestHeadersNames
-	case variables.Userid:
-		return tx.variables.userID
 	case variables.Args:
 		return tx.variables.args
 	case variables.ArgsGet:
@@ -294,8 +258,6 @@ func (tx *Transaction) Collection(idx variables.RuleVariable) collection.Collect
 		return nil
 	case variables.Env:
 		return tx.variables.env
-	case variables.IP:
-		return tx.variables.ip
 	case variables.UrlencodedError:
 		return tx.variables.urlencodedError
 	case variables.ResponseArgs:
@@ -311,7 +273,7 @@ func (tx *Transaction) Collection(idx variables.RuleVariable) collection.Collect
 		return tx.variables.multipartPartHeaders
 	}
 
-	return nil
+	return collections.Noop
 }
 
 func (tx *Transaction) Interrupt(interruption *types.Interruption) {
@@ -1434,67 +1396,49 @@ func (tx *Transaction) generateReqbodyError(err error) {
 // TransactionVariables has pointers to all the variables of the transaction
 type TransactionVariables struct {
 	// Single Variables
-	userID                        *collections.Single
-	urlencodedError               *collections.Single
-	responseContentType           *collections.Single
-	uniqueID                      *collections.Single
-	argsCombinedSize              *collections.SizeCollection
-	authType                      *collections.Single
-	filesCombinedSize             *collections.Single
-	fullRequest                   *collections.Single
-	fullRequestLength             *collections.Single
-	inboundDataError              *collections.Single
-	matchedVar                    *collections.Single
-	matchedVarName                *collections.Single
-	multipartBoundaryQuoted       *collections.Single
-	multipartBoundaryWhitespace   *collections.Single
-	multipartCrlfLfLines          *collections.Single
-	multipartDataAfter            *collections.Single
-	multipartDataBefore           *collections.Single
-	multipartFileLimitExceeded    *collections.Single
-	multipartHeaderFolding        *collections.Single
-	multipartInvalidHeaderFolding *collections.Single
-	multipartInvalidPart          *collections.Single
-	multipartInvalidQuoting       *collections.Single
-	multipartLfLine               *collections.Single
-	multipartMissingSemicolon     *collections.Single
-	multipartStrictError          *collections.Single
-	multipartUnmatchedBoundary    *collections.Single
-	outboundDataError             *collections.Single
-	pathInfo                      *collections.Single
-	queryString                   *collections.Single
-	remoteAddr                    *collections.Single
-	remoteHost                    *collections.Single
-	remotePort                    *collections.Single
-	reqbodyError                  *collections.Single
-	reqbodyErrorMsg               *collections.Single
-	reqbodyProcessorError         *collections.Single
-	reqbodyProcessorErrorMsg      *collections.Single
-	reqbodyProcessor              *collections.Single
-	requestBasename               *collections.Single
-	requestBody                   *collections.Single
-	requestBodyLength             *collections.Single
-	requestFilename               *collections.Single
-	requestLine                   *collections.Single
-	requestMethod                 *collections.Single
-	requestProtocol               *collections.Single
-	requestURI                    *collections.Single
-	requestURIRaw                 *collections.Single
-	responseBody                  *collections.Single
-	responseContentLength         *collections.Single
-	responseProtocol              *collections.Single
-	responseStatus                *collections.Single
-	serverAddr                    *collections.Single
-	serverName                    *collections.Single
-	serverPort                    *collections.Single
-	sessionID                     *collections.Single
-	highestSeverity               *collections.Single
-	statusLine                    *collections.Single
-	inboundErrorData              *collections.Single
+	urlencodedError          *collections.Single
+	responseContentType      *collections.Single
+	uniqueID                 *collections.Single
+	argsCombinedSize         *collections.SizeCollection
+	filesCombinedSize        *collections.Single
+	fullRequestLength        *collections.Single
+	inboundDataError         *collections.Single
+	matchedVar               *collections.Single
+	matchedVarName           *collections.Single
+	multipartDataAfter       *collections.Single
+	outboundDataError        *collections.Single
+	queryString              *collections.Single
+	remoteAddr               *collections.Single
+	remoteHost               *collections.Single
+	remotePort               *collections.Single
+	reqbodyError             *collections.Single
+	reqbodyErrorMsg          *collections.Single
+	reqbodyProcessorError    *collections.Single
+	reqbodyProcessorErrorMsg *collections.Single
+	reqbodyProcessor         *collections.Single
+	requestBasename          *collections.Single
+	requestBody              *collections.Single
+	requestBodyLength        *collections.Single
+	requestFilename          *collections.Single
+	requestLine              *collections.Single
+	requestMethod            *collections.Single
+	requestProtocol          *collections.Single
+	requestURI               *collections.Single
+	requestURIRaw            *collections.Single
+	responseBody             *collections.Single
+	responseContentLength    *collections.Single
+	responseProtocol         *collections.Single
+	responseStatus           *collections.Single
+	serverAddr               *collections.Single
+	serverName               *collections.Single
+	serverPort               *collections.Single
+	highestSeverity          *collections.Single
+	statusLine               *collections.Single
+	inboundErrorData         *collections.Single
 	// Custom
-	env                  collection.Map
-	tx                   collection.Map
-	rule                 collection.Map
+	env                  *collections.Map
+	tx                   *collections.Map
+	rule                 *collections.Map
 	duration             *collections.Single
 	args                 *collections.ConcatKeyed
 	argsGet              *collections.NamedCollection
@@ -1503,28 +1447,26 @@ type TransactionVariables struct {
 	argsPostNames        collection.Collection
 	argsPath             *collections.NamedCollection
 	argsNames            *collections.ConcatCollection
-	filesTmpNames        collection.Map
-	geo                  collection.Map
-	files                collection.Map
+	filesTmpNames        *collections.Map
+	geo                  *collections.Map
+	files                *collections.Map
 	requestCookies       *collections.NamedCollection
 	requestCookiesNames  collection.Collection
 	requestHeaders       *collections.NamedCollection
 	responseHeadersNames collection.Collection
 	responseHeaders      *collections.NamedCollection
 	requestHeadersNames  collection.Collection
-	multipartName        collection.Map
-	multipartFilename    collection.Map
+	multipartName        *collections.Map
+	multipartFilename    *collections.Map
 	matchedVars          *collections.NamedCollection
 	matchedVarsNames     collection.Collection
-	filesSizes           collection.Map
-	filesNames           collection.Map
-	filesTmpContent      collection.Map
-	xml                  collection.Map
-	requestXML           collection.Map
-	responseXML          collection.Map
-	multipartPartHeaders collection.Map
-	// Persistent variables
-	ip collection.Map
+	filesSizes           *collections.Map
+	filesNames           *collections.Map
+	filesTmpContent      *collections.Map
+	xml                  *collections.Map
+	requestXML           *collections.Map
+	responseXML          *collections.Map
+	multipartPartHeaders *collections.Map
 }
 
 func NewTransactionVariables() *TransactionVariables {
@@ -1532,29 +1474,13 @@ func NewTransactionVariables() *TransactionVariables {
 	v.urlencodedError = collections.NewSingle(variables.UrlencodedError)
 	v.responseContentType = collections.NewSingle(variables.ResponseContentType)
 	v.uniqueID = collections.NewSingle(variables.UniqueID)
-	v.authType = collections.NewSingle(variables.AuthType)
 	v.filesCombinedSize = collections.NewSingle(variables.FilesCombinedSize)
-	v.fullRequest = collections.NewSingle(variables.FullRequest)
 	v.fullRequestLength = collections.NewSingle(variables.FullRequestLength)
 	v.inboundDataError = collections.NewSingle(variables.InboundDataError)
 	v.matchedVar = collections.NewSingle(variables.MatchedVar)
 	v.matchedVarName = collections.NewSingle(variables.MatchedVarName)
-	v.multipartBoundaryQuoted = collections.NewSingle(variables.MultipartBoundaryQuoted)
-	v.multipartBoundaryWhitespace = collections.NewSingle(variables.MultipartBoundaryWhitespace)
-	v.multipartCrlfLfLines = collections.NewSingle(variables.MultipartCrlfLfLines)
 	v.multipartDataAfter = collections.NewSingle(variables.MultipartDataAfter)
-	v.multipartDataBefore = collections.NewSingle(variables.MultipartDataBefore)
-	v.multipartFileLimitExceeded = collections.NewSingle(variables.MultipartFileLimitExceeded)
-	v.multipartHeaderFolding = collections.NewSingle(variables.MultipartHeaderFolding)
-	v.multipartInvalidHeaderFolding = collections.NewSingle(variables.MultipartInvalidHeaderFolding)
-	v.multipartInvalidPart = collections.NewSingle(variables.MultipartInvalidPart)
-	v.multipartInvalidQuoting = collections.NewSingle(variables.MultipartInvalidQuoting)
-	v.multipartLfLine = collections.NewSingle(variables.MultipartLfLine)
-	v.multipartMissingSemicolon = collections.NewSingle(variables.MultipartMissingSemicolon)
-	v.multipartStrictError = collections.NewSingle(variables.MultipartStrictError)
-	v.multipartUnmatchedBoundary = collections.NewSingle(variables.MultipartUnmatchedBoundary)
 	v.outboundDataError = collections.NewSingle(variables.OutboundDataError)
-	v.pathInfo = collections.NewSingle(variables.PathInfo)
 	v.queryString = collections.NewSingle(variables.QueryString)
 	v.remoteAddr = collections.NewSingle(variables.RemoteAddr)
 	v.remoteHost = collections.NewSingle(variables.RemoteHost)
@@ -1580,12 +1506,10 @@ func NewTransactionVariables() *TransactionVariables {
 	v.serverAddr = collections.NewSingle(variables.ServerAddr)
 	v.serverName = collections.NewSingle(variables.ServerName)
 	v.serverPort = collections.NewSingle(variables.ServerPort)
-	v.sessionID = collections.NewSingle(variables.Sessionid)
 	v.highestSeverity = collections.NewSingle(variables.HighestSeverity)
 	v.statusLine = collections.NewSingle(variables.StatusLine)
 	v.inboundErrorData = collections.NewSingle(variables.InboundErrorData)
 	v.duration = collections.NewSingle(variables.Duration)
-	v.userID = collections.NewSingle(variables.Userid)
 
 	v.filesSizes = collections.NewMap(variables.FilesSizes)
 	v.filesTmpContent = collections.NewMap(variables.FilesTmpContent)
@@ -1603,7 +1527,6 @@ func NewTransactionVariables() *TransactionVariables {
 	v.tx = collections.NewMap(variables.TX)
 	v.rule = collections.NewMap(variables.Rule)
 	v.env = collections.NewMap(variables.Env)
-	v.ip = collections.NewMap(variables.IP)
 	v.files = collections.NewMap(variables.Files)
 	v.filesNames = collections.NewMap(variables.FilesNames)
 	v.filesTmpNames = collections.NewMap(variables.FilesTmpNames)
@@ -1636,10 +1559,6 @@ func NewTransactionVariables() *TransactionVariables {
 	return v
 }
 
-func (v *TransactionVariables) UserID() collection.Single {
-	return v.userID
-}
-
 func (v *TransactionVariables) UrlencodedError() collection.Single {
 	return v.urlencodedError
 }
@@ -1656,18 +1575,10 @@ func (v *TransactionVariables) ArgsCombinedSize() collection.Collection {
 	return v.argsCombinedSize
 }
 
-func (v *TransactionVariables) AuthType() collection.Single {
-	return v.authType
-}
-
 func (v *TransactionVariables) FilesCombinedSize() collection.Single {
 	return v.filesCombinedSize
 }
 
-func (v *TransactionVariables) FullRequest() collection.Single {
-	return v.fullRequest
-}
-
 func (v *TransactionVariables) FullRequestLength() collection.Single {
 	return v.fullRequestLength
 }
@@ -1684,74 +1595,18 @@ func (v *TransactionVariables) MatchedVarName() collection.Single {
 	return v.matchedVarName
 }
 
-func (v *TransactionVariables) MultipartBoundaryQuoted() collection.Single {
-	return v.multipartBoundaryQuoted
-}
-
-func (v *TransactionVariables) MultipartBoundaryWhitespace() collection.Single {
-	return v.multipartBoundaryWhitespace
-}
-
-func (v *TransactionVariables) MultipartCrlfLfLines() collection.Single {
-	return v.multipartCrlfLfLines
-}
-
 func (v *TransactionVariables) MultipartDataAfter() collection.Single {
 	return v.multipartDataAfter
 }
 
-func (v *TransactionVariables) MultipartDataBefore() collection.Single {
-	return v.multipartDataBefore
-}
-
-func (v *TransactionVariables) MultipartFileLimitExceeded() collection.Single {
-	return v.multipartFileLimitExceeded
-}
-
-func (v *TransactionVariables) MultipartHeaderFolding() collection.Single {
-	return v.multipartHeaderFolding
-}
-
-func (v *TransactionVariables) MultipartInvalidHeaderFolding() collection.Single {
-	return v.multipartInvalidHeaderFolding
-}
-
-func (v *TransactionVariables) MultipartInvalidPart() collection.Single {
-	return v.multipartInvalidPart
-}
-
-func (v *TransactionVariables) MultipartInvalidQuoting() collection.Single {
-	return v.multipartInvalidQuoting
-}
-
-func (v *TransactionVariables) MultipartLfLine() collection.Single {
-	return v.multipartLfLine
-}
-
-func (v *TransactionVariables) MultipartMissingSemicolon() collection.Single {
-	return v.multipartMissingSemicolon
-}
-
 func (v *TransactionVariables) MultipartPartHeaders() collection.Map {
 	return v.multipartPartHeaders
 }
 
-func (v *TransactionVariables) MultipartStrictError() collection.Single {
-	return v.multipartStrictError
-}
-
-func (v *TransactionVariables) MultipartUnmatchedBoundary() collection.Single {
-	return v.multipartUnmatchedBoundary
-}
-
 func (v *TransactionVariables) OutboundDataError() collection.Single {
 	return v.outboundDataError
 }
 
-func (v *TransactionVariables) PathInfo() collection.Single {
-	return v.pathInfo
-}
-
 func (v *TransactionVariables) QueryString() collection.Single {
 	return v.queryString
 }
@@ -1852,10 +1707,6 @@ func (v *TransactionVariables) ServerPort() collection.Single {
 	return v.serverPort
 }
 
-func (v *TransactionVariables) SessionID() collection.Single {
-	return v.sessionID
-}
-
 func (v *TransactionVariables) HighestSeverity() collection.Single {
 	return v.highestSeverity
 }
@@ -1976,10 +1827,6 @@ func (v *TransactionVariables) ResponseXML() collection.Map {
 	return v.responseXML
 }
 
-func (v *TransactionVariables) IP() collection.Map {
-	return v.ip
-}
-
 func (v *TransactionVariables) ArgsNames() collection.Collection {
 	return v.argsNames
 }
@@ -1993,34 +1840,16 @@ func (v *TransactionVariables) ArgsPostNames() collection.Collection {
 }
 
 func (v *TransactionVariables) reset() {
-	v.userID.Reset()
 	v.urlencodedError.Reset()
 	v.responseContentType.Reset()
 	v.uniqueID.Reset()
-	v.argsCombinedSize.Reset()
-	v.authType.Reset()
 	v.filesCombinedSize.Reset()
-	v.fullRequest.Reset()
 	v.fullRequestLength.Reset()
 	v.inboundDataError.Reset()
 	v.matchedVar.Reset()
 	v.matchedVarName.Reset()
-	v.multipartBoundaryQuoted.Reset()
-	v.multipartBoundaryWhitespace.Reset()
-	v.multipartCrlfLfLines.Reset()
 	v.multipartDataAfter.Reset()
-	v.multipartDataBefore.Reset()
-	v.multipartFileLimitExceeded.Reset()
-	v.multipartHeaderFolding.Reset()
-	v.multipartInvalidHeaderFolding.Reset()
-	v.multipartInvalidPart.Reset()
-	v.multipartInvalidQuoting.Reset()
-	v.multipartLfLine.Reset()
-	v.multipartMissingSemicolon.Reset()
-	v.multipartStrictError.Reset()
-	v.multipartUnmatchedBoundary.Reset()
 	v.outboundDataError.Reset()
-	v.pathInfo.Reset()
 	v.queryString.Reset()
 	v.remoteAddr.Reset()
 	v.remoteHost.Reset()
@@ -2046,7 +1875,6 @@ func (v *TransactionVariables) reset() {
 	v.serverAddr.Reset()
 	v.serverName.Reset()
 	v.serverPort.Reset()
-	v.sessionID.Reset()
 	v.highestSeverity.Reset()
 	v.statusLine.Reset()
 	v.inboundErrorData.Reset()
@@ -2054,7 +1882,6 @@ func (v *TransactionVariables) reset() {
 	v.tx.Reset()
 	v.rule.Reset()
 	v.duration.Reset()
-	v.args.Reset()
 	v.argsGet.Reset()
 	v.argsPost.Reset()
 	v.argsPath.Reset()
@@ -2065,21 +1892,13 @@ func (v *TransactionVariables) reset() {
 	v.requestHeaders.Reset()
 	v.responseHeaders.Reset()
 	v.multipartName.Reset()
-	v.matchedVarsNames.Reset()
 	v.multipartFilename.Reset()
 	v.matchedVars.Reset()
 	v.filesSizes.Reset()
 	v.filesNames.Reset()
 	v.filesTmpContent.Reset()
-	v.responseHeadersNames.Reset()
-	v.requestHeadersNames.Reset()
-	v.requestCookiesNames.Reset()
 	v.xml.Reset()
 	v.requestXML.Reset()
 	v.responseXML.Reset()
 	v.multipartPartHeaders.Reset()
-	v.ip.Reset()
-	v.argsNames.Reset()
-	v.argsGetNames.Reset()
-	v.argsPostNames.Reset()
 }
diff --git a/internal/corazawaf/waf.go b/internal/corazawaf/waf.go
index f453321..637f6d9 100644
--- a/internal/corazawaf/waf.go
+++ b/internal/corazawaf/waf.go
@@ -15,6 +15,7 @@ import (
 	"strings"
 	"time"
 
+	"github.com/corazawaf/coraza/v3/internal/environment"
 	ioutils "github.com/corazawaf/coraza/v3/internal/io"
 	stringutils "github.com/corazawaf/coraza/v3/internal/strings"
 	"github.com/corazawaf/coraza/v3/internal/sync"
@@ -182,12 +183,14 @@ func (w *WAF) newTransactionWithID(id string) *Transaction {
 			MemoryLimit: requestBodyInMemoryLimit,
 			Limit:       w.RequestBodyLimit,
 		})
+
 		tx.responseBodyBuffer = NewBodyBuffer(types.BodyBufferOptions{
 			TmpPath: w.TmpDir,
 			// the response body is just buffered in memory. Therefore, Limit and MemoryLimit are equal.
 			MemoryLimit: w.ResponseBodyLimit,
 			Limit:       w.ResponseBodyLimit,
 		})
+
 		tx.variables = *NewTransactionVariables()
 		tx.transformationCache = map[transformationKey]*transformationValue{}
 	}
@@ -202,20 +205,7 @@ func (w *WAF) newTransactionWithID(id string) *Transaction {
 	tx.variables.filesCombinedSize.Set("0")
 	tx.variables.urlencodedError.Set("0")
 	tx.variables.fullRequestLength.Set("0")
-	tx.variables.multipartBoundaryQuoted.Set("0")
-	tx.variables.multipartBoundaryWhitespace.Set("0")
-	tx.variables.multipartCrlfLfLines.Set("0")
 	tx.variables.multipartDataAfter.Set("0")
-	tx.variables.multipartDataBefore.Set("0")
-	tx.variables.multipartFileLimitExceeded.Set("0")
-	tx.variables.multipartHeaderFolding.Set("0")
-	tx.variables.multipartInvalidHeaderFolding.Set("0")
-	tx.variables.multipartInvalidPart.Set("0")
-	tx.variables.multipartInvalidQuoting.Set("0")
-	tx.variables.multipartLfLine.Set("0")
-	tx.variables.multipartMissingSemicolon.Set("0")
-	tx.variables.multipartStrictError.Set("0")
-	tx.variables.multipartUnmatchedBoundary.Set("0")
 	tx.variables.outboundDataError.Set("0")
 	tx.variables.reqbodyError.Set("0")
 	tx.variables.reqbodyProcessorError.Set("0")
@@ -283,13 +273,16 @@ func NewWAF() *WAF {
 		ResponseBodyLimit:  _1gb,
 		AuditLogWriter:     logWriter,
 		Logger:             logger,
-		TmpDir:             os.TempDir(),
+	}
+
+	if environment.HasAccessToFS {
+		waf.TmpDir = os.TempDir()
 	}
 
 	if err := waf.SetDebugLogPath(""); err != nil {
 		fmt.Println(err)
 	}
-	waf.Logger.Debug("a new waf instance was created")
+	waf.Logger.Debug("a new WAF instance was created")
 	return waf
 }
 
diff --git a/internal/environment/default.go b/internal/environment/default.go
index 1d2136b..214a457 100644
--- a/internal/environment/default.go
+++ b/internal/environment/default.go
@@ -1,10 +1,10 @@
 // Copyright 2022 Juan Pablo Tosso and the OWASP Coraza contributors
 // SPDX-License-Identifier: Apache-2.0
 
-//go:build !tinygo
-// +build !tinygo
+//go:build !no_fs_access
+// +build !no_fs_access
 
 package environment
 
-// IsTinyGo indicates whether the build environment is TinyGo.
-var IsTinyGo = false
+// HasAccessToFS indicates whether the build environment is TinyGo.
+var HasAccessToFS = true
diff --git a/internal/environment/nofsaccess.go b/internal/environment/nofsaccess.go
new file mode 100644
index 0000000..f283e3f
--- /dev/null
+++ b/internal/environment/nofsaccess.go
@@ -0,0 +1,11 @@
+// Copyright 2022 Juan Pablo Tosso and the OWASP Coraza contributors
+// SPDX-License-Identifier: Apache-2.0
+
+//go:build no_fs_access
+// +build no_fs_access
+
+package environment
+
+// HasAccessToFS indicates whether the build environment has access
+// to filesystem or not.
+var HasAccessToFS = false
diff --git a/internal/environment/tinygo.go b/internal/environment/tinygo.go
deleted file mode 100644
index 269f793..0000000
--- a/internal/environment/tinygo.go
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright 2022 Juan Pablo Tosso and the OWASP Coraza contributors
-// SPDX-License-Identifier: Apache-2.0
-
-//go:build tinygo
-// +build tinygo
-
-package environment
-
-// IsTinyGo indicates whether the build environment is TinyGo.
-var IsTinyGo = true
diff --git a/internal/seclang/parser.go b/internal/seclang/parser.go
index 3a56213..32a210f 100644
--- a/internal/seclang/parser.go
+++ b/internal/seclang/parser.go
@@ -13,6 +13,7 @@ import (
 	"strings"
 
 	"github.com/corazawaf/coraza/v3/internal/corazawaf"
+	"github.com/corazawaf/coraza/v3/internal/environment"
 	"github.com/corazawaf/coraza/v3/internal/io"
 	"github.com/corazawaf/coraza/v3/types"
 )
@@ -136,7 +137,8 @@ func (p *Parser) FromString(data string) error {
 
 func (p *Parser) evaluateLine(data string) error {
 	if data == "" || data[0] == '#' {
-		return errors.New("invalid lines")
+		// at this point we should not receive an empty line or a commented line
+		return errors.New("invalid line")
 	}
 	// first we get the directive
 	dir, opts, _ := strings.Cut(data, " ")
@@ -168,11 +170,13 @@ func (p *Parser) evaluateLine(data string) error {
 	p.options.Config.Set("parser_config_file", p.currentFile)
 	p.options.Config.Set("parser_config_dir", p.currentDir)
 	p.options.Config.Set("parser_root", p.root)
-	wd, err := os.Getwd()
-	if err != nil {
-		return err
+	if environment.HasAccessToFS {
+		wd, err := os.Getwd()
+		if err != nil {
+			return err
+		}
+		p.options.Config.Set("working_dir", wd)
 	}
-	p.options.Config.Set("working_dir", wd)
 
 	if err := d(p.options); err != nil {
 		return fmt.Errorf("failed to compile the directive %q: %w", directive, err)
diff --git a/internal/seclang/rule_parser.go b/internal/seclang/rule_parser.go
index 49d2acc..891aa37 100644
--- a/internal/seclang/rule_parser.go
+++ b/internal/seclang/rule_parser.go
@@ -188,10 +188,14 @@ func (p *RuleParser) ParseOperator(operator string) error {
 		Arguments: opdata,
 		Path: []string{
 			p.options.Config.Get("parser_config_dir", "").(string),
-			p.options.Config.Get("working_dir", "").(string),
 		},
 		Root: p.options.Config.Get("parser_root", io.OSFS{}).(fs.FS),
 	}
+
+	if wd := p.options.Config.Get("working_dir", "").(string); wd != "" {
+		opts.Path = append(opts.Path, wd)
+	}
+
 	opfn, err := operators.Get(op, opts)
 	if err != nil {
 		return err
diff --git a/types/variables/generator/main.go b/internal/variables/generator/main.go
similarity index 98%
rename from types/variables/generator/main.go
rename to internal/variables/generator/main.go
index 9f3c6b9..18f8c8a 100644
--- a/types/variables/generator/main.go
+++ b/internal/variables/generator/main.go
@@ -117,7 +117,7 @@ func main() {
 		log.Fatal(err)
 	}
 
-	vc, err := os.Create("../variablescount.gen.go")
+	vc, err := os.Create("./variablescount.gen.go")
 	if err != nil {
 		log.Fatal(err)
 	}
diff --git a/types/variables/generator/variablescount.go.tmpl b/internal/variables/generator/variablescount.go.tmpl
similarity index 94%
rename from types/variables/generator/variablescount.go.tmpl
rename to internal/variables/generator/variablescount.go.tmpl
index a03cbbe..c2668f7 100644
--- a/types/variables/generator/variablescount.go.tmpl
+++ b/internal/variables/generator/variablescount.go.tmpl
@@ -3,7 +3,7 @@
 
 // Code generated by types/variables/generator DO NOT EDIT.
 
-package types
+package variables
 
 // VariablesCount contains the number of variables handled by the variables package
 // It is used to create arrays of the correct size
diff --git a/types/variables/generator/variablesmap.go.tmpl b/internal/variables/generator/variablesmap.go.tmpl
similarity index 100%
rename from types/variables/generator/variablesmap.go.tmpl
rename to internal/variables/generator/variablesmap.go.tmpl
diff --git a/internal/variables/variables.go b/internal/variables/variables.go
new file mode 100644
index 0000000..20cea96
--- /dev/null
+++ b/internal/variables/variables.go
@@ -0,0 +1,230 @@
+// Copyright 2022 Juan Pablo Tosso and the OWASP Coraza contributors
+// SPDX-License-Identifier: Apache-2.0
+
+//go:generate go run generator/main.go
+
+// Package variables contains the representation of the variables used in the rules
+// Variables are created as bytes and they have a string representation
+package variables
+
+// This internal file contains all variables supported by handling of SecLang, such as
+// the parser and actions like setvar. Several of these variables are no-op and not
+// supported by Coraza - the public variables package only exposes the set of supported
+// variables for programmatic access.
+
+// RuleVariable is used to identify information from a transaction
+type RuleVariable byte
+
+const (
+	// Unknown is used as placeholder for errors
+	Unknown RuleVariable = iota
+	// ResponseContentType is the content type of the response
+	ResponseContentType
+	// UniqueID is the unique id of the transaction
+	UniqueID
+	// ArgsCombinedSize is the combined size of the arguments
+	ArgsCombinedSize
+	// FilesCombinedSize is the combined size of the uploaded files
+	FilesCombinedSize
+	// FullRequestLength is the length of the full request
+	FullRequestLength
+	// InboundDataError represents errors for inbound data
+	InboundDataError
+	// MatchedVar is the value of the matched variable
+	MatchedVar
+	// MatchedVarName is the name of the matched variable
+	MatchedVarName
+	// MultipartDataAfter kept for compatibility
+	MultipartDataAfter
+	// OutboundDataError will be set to 1 when the response body size
+	// is above the setting configured by SecResponseBodyLimit
+	OutboundDataError
+	// QueryString contains the raw query string part of a request URI
+	QueryString
+	// RemoteAddr is the remote address of the connection
+	RemoteAddr
+	// RemoteHost is the remote host of the connection, not implemented
+	RemoteHost
+	// RemotePort is the remote port of the connection
+	RemotePort
+	// ReqbodyError contains the status of the request body processor used
+	// for request body parsing, 0 means no error, 1 means error
+	ReqbodyError
+	// ReqbodyErrorMsg contains the error message of the request body processor error
+	ReqbodyErrorMsg
+	// ReqbodyProcessorError is the same as ReqbodyErrr ?
+	ReqbodyProcessorError
+	// ReqbodyProcessorErrorMsg is the same as ReqbodyErrorMsg ?
+	ReqbodyProcessorErrorMsg
+	// ReqbodyProcessor contains the name of the request body processor used, default
+	// ones are: URLENCODED, MULTIPART, and XML. They can be extended using plugins.
+	ReqbodyProcessor
+	// RequestBasename contains the name after the last slash in the request URI
+	// It does not pass through any anti-evasion, use with transformations
+	RequestBasename
+	// RequestBody contains the full request body, it will only be available
+	// For urlencoded requests. It is possible to force it's presence by using
+	// the ctl:forceRequestBodyVariable action
+	RequestBody
+	// RequestBodyLength contains the length of the request body in bytes calculated from
+	// the BodyBuffer, not from the content-type header
+	RequestBodyLength
+	// RequestFilename holds the relative request URL without the query string part.
+	// Anti-evasion transformations are not used by default
+	RequestFilename
+	// RequestLine This variable holds the complete request line sent to the server
+	// (including the request method and HTTP version information).
+	RequestLine
+	// RequestMethod is the request method
+	RequestMethod
+	// RequestProtocol is the protocol used in the request
+	RequestProtocol
+	// RequestURI holds the full request URL including the query string data without
+	// the domain name
+	RequestURI
+	// RequestURIRaw is the same as RequestURI but with the domain name in case
+	// it was provided in the request line
+	RequestURIRaw
+	// ResponseBody contains the full response body, it will only be available if
+	// responseBodyAccess is set to on and the response mime matches the configured
+	// processable mime types
+	ResponseBody
+	// ResponseContentLength contains the length of the response body in bytes calculated from
+	// the BodyBuffer, not from the content-type header
+	ResponseContentLength
+	// ResponseProtocol is the protocol used in the response
+	ResponseProtocol
+	// ResponseStatus is the status code of the response
+	ResponseStatus
+	// ServerAddr is the address of the server
+	ServerAddr
+	// ServerName is the name of the server
+	ServerName
+	// ServerPort is the port of the server
+	ServerPort
+	// HighestSeverity is the highest severity from all matched rules
+	HighestSeverity
+	// StatusLine is the status line of the response, including the request method
+	// and HTTP version information
+	StatusLine
+	// InboundErrorData will be set to 1 when the request body size
+	// is above the setting configured by SecRequesteBodyLimit
+	InboundErrorData
+	// Duration contains the time in miliseconds from
+	// the beginning of the transaction until this point
+	Duration
+	// ResponseHeadersNames contains the names of the response headers
+	ResponseHeadersNames
+	// RequestHeadersNames contains the names of the request headers
+	RequestHeadersNames
+	// Args contains copies of ArgsGet and ArgsPost
+	Args
+	// ArgsGet contains the GET (URL) arguments
+	ArgsGet
+	// ArgsPost contains the POST (BODY) arguments
+	ArgsPost
+	// ArgsPath contains the url path parts
+	ArgsPath
+	// FilesSizes contains the sizes of the uploaded files
+	FilesSizes
+	// FilesNames contains the names of the uploaded files
+	FilesNames
+	// FilesTmpContent is not supported
+	FilesTmpContent
+	// MultipartFilename contains the multipart data from field FILENAME
+	MultipartFilename
+	// MultipartName contains the multipart data from field NAME.
+	MultipartName
+	// MatchedVarsNames is similar to MATCHED_VAR_NAME except that it is
+	// a collection of all matches for the current operator check.
+	MatchedVarsNames
+	// MatchedVars is similar to MATCHED_VAR except that it is a collection
+	// of all matches for the current operator check
+	MatchedVars
+	// Files contains a collection of original file names
+	// (as they were called on the remote user’s filesys- tem).
+	// Available only on inspected multipart/form-data requests.
+	Files
+	// RequestCookies is a collection of all of request cookies (values only
+	RequestCookies
+	// RequestHeaders can be used as either a collection of all of the request
+	// headers or can be used to inspect selected headers
+	RequestHeaders
+	// ResponseHeaders can be used as either a collection of all of the response
+	// headers or can be used to inspect selected headers
+	ResponseHeaders
+	// Geo contains the location information of the client
+	Geo
+	// RequestCookiesNames contains the names of the request cookies
+	RequestCookiesNames
+	// FilesTmpNames contains the names of the uploaded temporal files
+	FilesTmpNames
+	// ArgsNames contains the names of the arguments (POST and GET)
+	ArgsNames
+	// ArgsGetNames contains the names of the GET arguments
+	ArgsGetNames
+	// ArgsPostNames contains the names of the POST arguments
+	ArgsPostNames
+	// TX contains transaction specific variables created with setvar
+	TX
+	// Rule contains rule metadata
+	Rule
+	// JSON does not provide any data, might be removed
+	JSON
+	// Env contains the process environment variables
+	Env
+	// UrlencodedError equals 1 if we failed to parse de URL
+	// It applies for URL query part and urlencoded post body
+	UrlencodedError
+	// ResponseArgs contains the response parsed arguments
+	ResponseArgs
+	// ResponseXML contains the response parsed XML
+	ResponseXML
+	// RequestXML contains the request parsed XML
+	RequestXML
+	// XML is a pointer to ResponseXML
+	XML
+	// MultipartPartHeaders contains the multipart headers
+	MultipartPartHeaders
+
+	// Unsupported variables
+
+	// AuthType is the authentication type
+	AuthType
+	// FullRequest is the full request
+	FullRequest
+	// MultipartBoundaryQuoted kept for compatibility
+	MultipartBoundaryQuoted
+	// MultipartBoundaryWhitespace kept for compatibility
+	MultipartBoundaryWhitespace
+	// MultipartCrlfLfLines kept for compatibility
+	MultipartCrlfLfLines
+	// MultipartDataBefore kept for compatibility
+	MultipartDataBefore
+	// MultipartFileLimitExceeded kept for compatibility
+	MultipartFileLimitExceeded
+	// MultipartHeaderFolding kept for compatibility
+	MultipartHeaderFolding
+	// MultipartInvalidHeaderFolding kept for compatibility
+	MultipartInvalidHeaderFolding
+	// MultipartInvalidPart kept for compatibility
+	MultipartInvalidPart
+	// MultipartInvalidQuoting kept for compatibility
+	MultipartInvalidQuoting
+	// MultipartLfLine kept for compatibility
+	MultipartLfLine
+	// MultipartMissingSemicolon kept for compatibility
+	MultipartMissingSemicolon
+	// MultipartStrictError kept for compatibility
+	MultipartStrictError
+	// MultipartUnmatchedBoundary kept for compatibility
+	MultipartUnmatchedBoundary
+	// PathInfo is kept for compatibility
+	PathInfo
+	// Sessionid is not supported
+	Sessionid
+	// Userid is not supported
+	Userid
+	// IP is kept for compatibility
+	IP
+)
diff --git a/types/variables/variables_test.go b/internal/variables/variables_test.go
similarity index 100%
rename from types/variables/variables_test.go
rename to internal/variables/variables_test.go
diff --git a/types/variablescount.gen.go b/internal/variables/variablescount.gen.go
similarity index 94%
rename from types/variablescount.gen.go
rename to internal/variables/variablescount.gen.go
index 293be1c..e1a64b5 100644
--- a/types/variablescount.gen.go
+++ b/internal/variables/variablescount.gen.go
@@ -3,7 +3,7 @@
 
 // Code generated by types/variables/generator DO NOT EDIT.
 
-package types
+package variables
 
 // VariablesCount contains the number of variables handled by the variables package
 // It is used to create arrays of the correct size
diff --git a/types/variables/variablesmap.gen.go b/internal/variables/variablesmap.gen.go
similarity index 100%
rename from types/variables/variablesmap.gen.go
rename to internal/variables/variablesmap.gen.go
index f43dc68..227e00d 100644
--- a/types/variables/variablesmap.gen.go
+++ b/internal/variables/variablesmap.gen.go
@@ -22,12 +22,8 @@ func (v RuleVariable) Name() string {
 		return "UNIQUE_ID"
 	case ArgsCombinedSize:
 		return "ARGS_COMBINED_SIZE"
-	case AuthType:
-		return "AUTH_TYPE"
 	case FilesCombinedSize:
 		return "FILES_COMBINED_SIZE"
-	case FullRequest:
-		return "FULL_REQUEST"
 	case FullRequestLength:
 		return "FULL_REQUEST_LENGTH"
 	case InboundDataError:
@@ -36,38 +32,10 @@ func (v RuleVariable) Name() string {
 		return "MATCHED_VAR"
 	case MatchedVarName:
 		return "MATCHED_VAR_NAME"
-	case MultipartBoundaryQuoted:
-		return "MULTIPART_BOUNDARY_QUOTED"
-	case MultipartBoundaryWhitespace:
-		return "MULTIPART_BOUNDARY_WHITESPACE"
-	case MultipartCrlfLfLines:
-		return "MULTIPART_CRLF_LF_LINES"
 	case MultipartDataAfter:
 		return "MULTIPART_DATA_AFTER"
-	case MultipartDataBefore:
-		return "MULTIPART_DATA_BEFORE"
-	case MultipartFileLimitExceeded:
-		return "MULTIPART_FILE_LIMIT_EXCEEDED"
-	case MultipartHeaderFolding:
-		return "MULTIPART_HEADER_FOLDING"
-	case MultipartInvalidHeaderFolding:
-		return "MULTIPART_INVALID_HEADER_FOLDING"
-	case MultipartInvalidPart:
-		return "MULTIPART_INVALID_PART"
-	case MultipartInvalidQuoting:
-		return "MULTIPART_INVALID_QUOTING"
-	case MultipartLfLine:
-		return "MULTIPART_LF_LINE"
-	case MultipartMissingSemicolon:
-		return "MULTIPART_MISSING_SEMICOLON"
-	case MultipartStrictError:
-		return "MULTIPART_STRICT_ERROR"
-	case MultipartUnmatchedBoundary:
-		return "MULTIPART_UNMATCHED_BOUNDARY"
 	case OutboundDataError:
 		return "OUTBOUND_DATA_ERROR"
-	case PathInfo:
-		return "PATH_INFO"
 	case QueryString:
 		return "QUERY_STRING"
 	case RemoteAddr:
@@ -118,8 +86,6 @@ func (v RuleVariable) Name() string {
 		return "SERVER_NAME"
 	case ServerPort:
 		return "SERVER_PORT"
-	case Sessionid:
-		return "SESSIONID"
 	case HighestSeverity:
 		return "HIGHEST_SEVERITY"
 	case StatusLine:
@@ -132,8 +98,6 @@ func (v RuleVariable) Name() string {
 		return "RESPONSE_HEADERS_NAMES"
 	case RequestHeadersNames:
 		return "REQUEST_HEADERS_NAMES"
-	case Userid:
-		return "USERID"
 	case Args:
 		return "ARGS"
 	case ArgsGet:
@@ -184,8 +148,6 @@ func (v RuleVariable) Name() string {
 		return "JSON"
 	case Env:
 		return "ENV"
-	case IP:
-		return "IP"
 	case UrlencodedError:
 		return "URLENCODED_ERROR"
 	case ResponseArgs:
@@ -198,6 +160,44 @@ func (v RuleVariable) Name() string {
 		return "XML"
 	case MultipartPartHeaders:
 		return "MULTIPART_PART_HEADERS"
+	case AuthType:
+		return "AUTH_TYPE"
+	case FullRequest:
+		return "FULL_REQUEST"
+	case MultipartBoundaryQuoted:
+		return "MULTIPART_BOUNDARY_QUOTED"
+	case MultipartBoundaryWhitespace:
+		return "MULTIPART_BOUNDARY_WHITESPACE"
+	case MultipartCrlfLfLines:
+		return "MULTIPART_CRLF_LF_LINES"
+	case MultipartDataBefore:
+		return "MULTIPART_DATA_BEFORE"
+	case MultipartFileLimitExceeded:
+		return "MULTIPART_FILE_LIMIT_EXCEEDED"
+	case MultipartHeaderFolding:
+		return "MULTIPART_HEADER_FOLDING"
+	case MultipartInvalidHeaderFolding:
+		return "MULTIPART_INVALID_HEADER_FOLDING"
+	case MultipartInvalidPart:
+		return "MULTIPART_INVALID_PART"
+	case MultipartInvalidQuoting:
+		return "MULTIPART_INVALID_QUOTING"
+	case MultipartLfLine:
+		return "MULTIPART_LF_LINE"
+	case MultipartMissingSemicolon:
+		return "MULTIPART_MISSING_SEMICOLON"
+	case MultipartStrictError:
+		return "MULTIPART_STRICT_ERROR"
+	case MultipartUnmatchedBoundary:
+		return "MULTIPART_UNMATCHED_BOUNDARY"
+	case PathInfo:
+		return "PATH_INFO"
+	case Sessionid:
+		return "SESSIONID"
+	case Userid:
+		return "USERID"
+	case IP:
+		return "IP"
 
 	default:
 		return "INVALID_VARIABLE"
@@ -209,29 +209,13 @@ var rulemapRev = map[string]RuleVariable{
 	"RESPONSE_CONTENT_TYPE":            ResponseContentType,
 	"UNIQUE_ID":                        UniqueID,
 	"ARGS_COMBINED_SIZE":               ArgsCombinedSize,
-	"AUTH_TYPE":                        AuthType,
 	"FILES_COMBINED_SIZE":              FilesCombinedSize,
-	"FULL_REQUEST":                     FullRequest,
 	"FULL_REQUEST_LENGTH":              FullRequestLength,
 	"INBOUND_DATA_ERROR":               InboundDataError,
 	"MATCHED_VAR":                      MatchedVar,
 	"MATCHED_VAR_NAME":                 MatchedVarName,
-	"MULTIPART_BOUNDARY_QUOTED":        MultipartBoundaryQuoted,
-	"MULTIPART_BOUNDARY_WHITESPACE":    MultipartBoundaryWhitespace,
-	"MULTIPART_CRLF_LF_LINES":          MultipartCrlfLfLines,
 	"MULTIPART_DATA_AFTER":             MultipartDataAfter,
-	"MULTIPART_DATA_BEFORE":            MultipartDataBefore,
-	"MULTIPART_FILE_LIMIT_EXCEEDED":    MultipartFileLimitExceeded,
-	"MULTIPART_HEADER_FOLDING":         MultipartHeaderFolding,
-	"MULTIPART_INVALID_HEADER_FOLDING": MultipartInvalidHeaderFolding,
-	"MULTIPART_INVALID_PART":           MultipartInvalidPart,
-	"MULTIPART_INVALID_QUOTING":        MultipartInvalidQuoting,
-	"MULTIPART_LF_LINE":                MultipartLfLine,
-	"MULTIPART_MISSING_SEMICOLON":      MultipartMissingSemicolon,
-	"MULTIPART_STRICT_ERROR":           MultipartStrictError,
-	"MULTIPART_UNMATCHED_BOUNDARY":     MultipartUnmatchedBoundary,
 	"OUTBOUND_DATA_ERROR":              OutboundDataError,
-	"PATH_INFO":                        PathInfo,
 	"QUERY_STRING":                     QueryString,
 	"REMOTE_ADDR":                      RemoteAddr,
 	"REMOTE_HOST":                      RemoteHost,
@@ -257,14 +241,12 @@ var rulemapRev = map[string]RuleVariable{
 	"SERVER_ADDR":                      ServerAddr,
 	"SERVER_NAME":                      ServerName,
 	"SERVER_PORT":                      ServerPort,
-	"SESSIONID":                        Sessionid,
 	"HIGHEST_SEVERITY":                 HighestSeverity,
 	"STATUS_LINE":                      StatusLine,
 	"INBOUND_ERROR_DATA":               InboundErrorData,
 	"DURATION":                         Duration,
 	"RESPONSE_HEADERS_NAMES":           ResponseHeadersNames,
 	"REQUEST_HEADERS_NAMES":            RequestHeadersNames,
-	"USERID":                           Userid,
 	"ARGS":                             Args,
 	"ARGS_GET":                         ArgsGet,
 	"ARGS_POST":                        ArgsPost,
@@ -290,13 +272,31 @@ var rulemapRev = map[string]RuleVariable{
 	"RULE":                             Rule,
 	"JSON":                             JSON,
 	"ENV":                              Env,
-	"IP":                               IP,
 	"URLENCODED_ERROR":                 UrlencodedError,
 	"RESPONSE_ARGS":                    ResponseArgs,
 	"RESPONSE_XML":                     ResponseXML,
 	"REQUEST_XML":                      RequestXML,
 	"XML":                              XML,
 	"MULTIPART_PART_HEADERS":           MultipartPartHeaders,
+	"AUTH_TYPE":                        AuthType,
+	"FULL_REQUEST":                     FullRequest,
+	"MULTIPART_BOUNDARY_QUOTED":        MultipartBoundaryQuoted,
+	"MULTIPART_BOUNDARY_WHITESPACE":    MultipartBoundaryWhitespace,
+	"MULTIPART_CRLF_LF_LINES":          MultipartCrlfLfLines,
+	"MULTIPART_DATA_BEFORE":            MultipartDataBefore,
+	"MULTIPART_FILE_LIMIT_EXCEEDED":    MultipartFileLimitExceeded,
+	"MULTIPART_HEADER_FOLDING":         MultipartHeaderFolding,
+	"MULTIPART_INVALID_HEADER_FOLDING": MultipartInvalidHeaderFolding,
+	"MULTIPART_INVALID_PART":           MultipartInvalidPart,
+	"MULTIPART_INVALID_QUOTING":        MultipartInvalidQuoting,
+	"MULTIPART_LF_LINE":                MultipartLfLine,
+	"MULTIPART_MISSING_SEMICOLON":      MultipartMissingSemicolon,
+	"MULTIPART_STRICT_ERROR":           MultipartStrictError,
+	"MULTIPART_UNMATCHED_BOUNDARY":     MultipartUnmatchedBoundary,
+	"PATH_INFO":                        PathInfo,
+	"SESSIONID":                        Sessionid,
+	"USERID":                           Userid,
+	"IP":                               IP,
 }
 
 var errUnknownVariable = errors.New("unknown variable")
diff --git a/rules/transaction.go b/rules/transaction.go
index e6fe0c3..2273e7f 100644
--- a/rules/transaction.go
+++ b/rules/transaction.go
@@ -46,35 +46,18 @@ type TransactionState interface {
 // TransactionVariables has pointers to all the variables of the transaction
 type TransactionVariables interface {
 	// Simple Variables
-	UserID() collection.Single
 	UrlencodedError() collection.Single
 	ResponseContentType() collection.Single
 	UniqueID() collection.Single
 	ArgsCombinedSize() collection.Collection
-	AuthType() collection.Single
 	FilesCombinedSize() collection.Single
-	FullRequest() collection.Single
 	FullRequestLength() collection.Single
 	InboundDataError() collection.Single
 	MatchedVar() collection.Single
 	MatchedVarName() collection.Single
-	MultipartBoundaryQuoted() collection.Single
-	MultipartBoundaryWhitespace() collection.Single
-	MultipartCrlfLfLines() collection.Single
 	MultipartDataAfter() collection.Single
-	MultipartDataBefore() collection.Single
-	MultipartFileLimitExceeded() collection.Single
 	MultipartPartHeaders() collection.Map
-	MultipartHeaderFolding() collection.Single
-	MultipartInvalidHeaderFolding() collection.Single
-	MultipartInvalidPart() collection.Single
-	MultipartInvalidQuoting() collection.Single
-	MultipartLfLine() collection.Single
-	MultipartMissingSemicolon() collection.Single
-	MultipartStrictError() collection.Single
-	MultipartUnmatchedBoundary() collection.Single
 	OutboundDataError() collection.Single
-	PathInfo() collection.Single
 	QueryString() collection.Single
 	RemoteAddr() collection.Single
 	RemoteHost() collection.Single
@@ -100,7 +83,6 @@ type TransactionVariables interface {
 	ServerAddr() collection.Single
 	ServerName() collection.Single
 	ServerPort() collection.Single
-	SessionID() collection.Single
 	HighestSeverity() collection.Single
 	StatusLine() collection.Single
 	InboundErrorData() collection.Single
@@ -131,7 +113,6 @@ type TransactionVariables interface {
 	XML() collection.Map
 	RequestXML() collection.Map
 	ResponseXML() collection.Map
-	IP() collection.Map
 	ArgsNames() collection.Collection
 	ArgsGetNames() collection.Collection
 	ArgsPostNames() collection.Collection
diff --git a/types/variables/variables.go b/types/variables/variables.go
index c9c95ec..defce46 100644
--- a/types/variables/variables.go
+++ b/types/variables/variables.go
@@ -1,225 +1,196 @@
 // Copyright 2022 Juan Pablo Tosso and the OWASP Coraza contributors
 // SPDX-License-Identifier: Apache-2.0
 
-//go:generate go run generator/main.go
-
 // Package variables contains the representation of the variables used in the rules
 // Variables are created as bytes and they have a string representation
 package variables
 
+import (
+	"github.com/corazawaf/coraza/v3/internal/variables"
+)
+
 // This file repeats the same content many times in order to make access
 // efficient for seclang and transactions
 
 // RuleVariable is used to identify information from a transaction
-type RuleVariable byte
+type RuleVariable = variables.RuleVariable
 
 const (
 	// Unknown is used as placeholder for errors
-	Unknown RuleVariable = iota
+	Unknown = variables.Unknown
 	// ResponseContentType is the content type of the response
-	ResponseContentType
+	ResponseContentType = variables.ResponseContentType
 	// UniqueID is the unique id of the transaction
-	UniqueID
+	UniqueID = variables.UniqueID
 	// ArgsCombinedSize is the combined size of the arguments
-	ArgsCombinedSize
-	// AuthType is the authentication type
-	AuthType
+	ArgsCombinedSize = variables.ArgsCombinedSize
 	// FilesCombinedSize is the combined size of the uploaded files
-	FilesCombinedSize
-	// FullRequest is the full request
-	FullRequest
+	FilesCombinedSize = variables.FilesCombinedSize
 	// FullRequestLength is the length of the full request
-	FullRequestLength
+	FullRequestLength = variables.FullRequestLength
 	// InboundDataError represents errors for inbound data
-	InboundDataError
+	InboundDataError = variables.InboundDataError
 	// MatchedVar is the value of the matched variable
-	MatchedVar
+	MatchedVar = variables.MatchedVar
 	// MatchedVarName is the name of the matched variable
-	MatchedVarName
-	// MultipartBoundaryQuoted kept for compatibility
-	MultipartBoundaryQuoted
-	// MultipartBoundaryWhitespace kept for compatibility
-	MultipartBoundaryWhitespace
-	// MultipartCrlfLfLines kept for compatibility
-	MultipartCrlfLfLines
+	MatchedVarName = variables.MatchedVarName
 	// MultipartDataAfter kept for compatibility
-	MultipartDataAfter
-	// MultipartDataBefore kept for compatibility
-	MultipartDataBefore
-	// MultipartFileLimitExceeded kept for compatibility
-	MultipartFileLimitExceeded
-	// MultipartHeaderFolding kept for compatibility
-	MultipartHeaderFolding
-	// MultipartInvalidHeaderFolding kept for compatibility
-	MultipartInvalidHeaderFolding
-	// MultipartInvalidPart kept for compatibility
-	MultipartInvalidPart
-	// MultipartInvalidQuoting kept for compatibility
-	MultipartInvalidQuoting
-	// MultipartLfLine kept for compatibility
-	MultipartLfLine
-	// MultipartMissingSemicolon kept for compatibility
-	MultipartMissingSemicolon
-	// MultipartStrictError kept for compatibility
-	MultipartStrictError
-	// MultipartUnmatchedBoundary kept for compatibility
-	MultipartUnmatchedBoundary
+	MultipartDataAfter = variables.MultipartDataAfter
 	// OutboundDataError will be set to 1 when the response body size
 	// is above the setting configured by SecResponseBodyLimit
-	OutboundDataError
-	// PathInfo is kept for compatibility
-	PathInfo
+	OutboundDataError = variables.OutboundDataError
 	// QueryString contains the raw query string part of a request URI
-	QueryString
+	QueryString = variables.QueryString
 	// RemoteAddr is the remote address of the connection
-	RemoteAddr
+	RemoteAddr = variables.RemoteAddr
 	// RemoteHost is the remote host of the connection, not implemented
-	RemoteHost
+	RemoteHost = variables.RemoteHost
 	// RemotePort is the remote port of the connection
-	RemotePort
+	RemotePort = variables.RemotePort
 	// ReqbodyError contains the status of the request body processor used
 	// for request body parsing, 0 means no error, 1 means error
-	ReqbodyError
+	ReqbodyError = variables.ReqbodyError
 	// ReqbodyErrorMsg contains the error message of the request body processor error
-	ReqbodyErrorMsg
+	ReqbodyErrorMsg = variables.ReqbodyErrorMsg
 	// ReqbodyProcessorError is the same as ReqbodyErrr ?
-	ReqbodyProcessorError
+	ReqbodyProcessorError = variables.ReqbodyProcessorError
 	// ReqbodyProcessorErrorMsg is the same as ReqbodyErrorMsg ?
-	ReqbodyProcessorErrorMsg
+	ReqbodyProcessorErrorMsg = variables.ReqbodyProcessorErrorMsg
 	// ReqbodyProcessor contains the name of the request body processor used, default
 	// ones are: URLENCODED, MULTIPART, and XML. They can be extended using plugins.
-	ReqbodyProcessor
+	ReqbodyProcessor = variables.ReqbodyProcessor
 	// RequestBasename contains the name after the last slash in the request URI
 	// It does not pass through any anti-evasion, use with transformations
-	RequestBasename
+	RequestBasename = variables.RequestBasename
 	// RequestBody contains the full request body, it will only be available
 	// For urlencoded requests. It is possible to force it's presence by using
 	// the ctl:forceRequestBodyVariable action
-	RequestBody
+	RequestBody = variables.RequestBody
 	// RequestBodyLength contains the length of the request body in bytes calculated from
 	// the BodyBuffer, not from the content-type header
-	RequestBodyLength
+	RequestBodyLength = variables.RequestBodyLength
 	// RequestFilename holds the relative request URL without the query string part.
 	// Anti-evasion transformations are not used by default
-	RequestFilename
+	RequestFilename = variables.RequestFilename
 	// RequestLine This variable holds the complete request line sent to the server
 	// (including the request method and HTTP version information).
-	RequestLine
+	RequestLine = variables.RequestLine
 	// RequestMethod is the request method
-	RequestMethod
+	RequestMethod = variables.RequestMethod
 	// RequestProtocol is the protocol used in the request
-	RequestProtocol
+	RequestProtocol = variables.RequestProtocol
 	// RequestURI holds the full request URL including the query string data without
 	// the domain name
-	RequestURI
+	RequestURI = variables.RequestURI
 	// RequestURIRaw is the same as RequestURI but with the domain name in case
 	// it was provided in the request line
-	RequestURIRaw
+	RequestURIRaw = variables.RequestURIRaw
 	// ResponseBody contains the full response body, it will only be available if
 	// responseBodyAccess is set to on and the response mime matches the configured
 	// processable mime types
-	ResponseBody
+	ResponseBody = variables.ResponseBody
 	// ResponseContentLength contains the length of the response body in bytes calculated from
 	// the BodyBuffer, not from the content-type header
-	ResponseContentLength
+	ResponseContentLength = variables.ResponseContentLength
 	// ResponseProtocol is the protocol used in the response
-	ResponseProtocol
+	ResponseProtocol = variables.ResponseProtocol
 	// ResponseStatus is the status code of the response
-	ResponseStatus
+	ResponseStatus = variables.ResponseStatus
 	// ServerAddr is the address of the server
-	ServerAddr
+	ServerAddr = variables.ServerAddr
 	// ServerName is the name of the server
-	ServerName
+	ServerName = variables.ServerName
 	// ServerPort is the port of the server
-	ServerPort
-	// Sessionid is not supported
-	Sessionid
+	ServerPort = variables.ServerPort
 	// HighestSeverity is the highest severity from all matched rules
-	HighestSeverity
+	HighestSeverity = variables.HighestSeverity
 	// StatusLine is the status line of the response, including the request method
 	// and HTTP version information
-	StatusLine
+	StatusLine = variables.StatusLine
 	// InboundErrorData will be set to 1 when the request body size
 	// is above the setting configured by SecRequesteBodyLimit
-	InboundErrorData
+	InboundErrorData = variables.InboundErrorData
 	// Duration contains the time in miliseconds from
 	// the beginning of the transaction until this point
-	Duration
+	Duration = variables.Duration
 	// ResponseHeadersNames contains the names of the response headers
-	ResponseHeadersNames
+	ResponseHeadersNames = variables.ResponseHeadersNames
 	// RequestHeadersNames contains the names of the request headers
-	RequestHeadersNames
-	// Userid is not supported
-	Userid
+	RequestHeadersNames = variables.RequestHeadersNames
 	// Args contains copies of ArgsGet and ArgsPost
-	Args
+	Args = variables.Args
 	// ArgsGet contains the GET (URL) arguments
-	ArgsGet
+	ArgsGet = variables.ArgsGet
 	// ArgsPost contains the POST (BODY) arguments
-	ArgsPost
+	ArgsPost = variables.ArgsPost
 	// ArgsPath contains the url path parts
-	ArgsPath
+	ArgsPath = variables.ArgsPath
 	// FilesSizes contains the sizes of the uploaded files
-	FilesSizes
+	FilesSizes = variables.FilesSizes
 	// FilesNames contains the names of the uploaded files
-	FilesNames
+	FilesNames = variables.FilesNames
 	// FilesTmpContent is not supported
-	FilesTmpContent
+	FilesTmpContent = variables.FilesTmpContent
 	// MultipartFilename contains the multipart data from field FILENAME
-	MultipartFilename
+	MultipartFilename = variables.MultipartFilename
 	// MultipartName contains the multipart data from field NAME.
-	MultipartName
+	MultipartName = variables.MultipartName
 	// MatchedVarsNames is similar to MATCHED_VAR_NAME except that it is
 	// a collection of all matches for the current operator check.
-	MatchedVarsNames
+	MatchedVarsNames = variables.MatchedVarsNames
 	// MatchedVars is similar to MATCHED_VAR except that it is a collection
 	// of all matches for the current operator check
-	MatchedVars
+	MatchedVars = variables.MatchedVars
 	// Files contains a collection of original file names
 	// (as they were called on the remote user’s filesys- tem).
 	// Available only on inspected multipart/form-data requests.
-	Files
+	Files = variables.Files
 	// RequestCookies is a collection of all of request cookies (values only
-	RequestCookies
+	RequestCookies = variables.RequestCookies
 	// RequestHeaders can be used as either a collection of all of the request
 	// headers or can be used to inspect selected headers
-	RequestHeaders
+	RequestHeaders = variables.RequestHeaders
 	// ResponseHeaders can be used as either a collection of all of the response
 	// headers or can be used to inspect selected headers
-	ResponseHeaders
+	ResponseHeaders = variables.ResponseHeaders
 	// Geo contains the location information of the client
-	Geo
+	Geo = variables.Geo
 	// RequestCookiesNames contains the names of the request cookies
-	RequestCookiesNames
+	RequestCookiesNames = variables.RequestCookiesNames
 	// FilesTmpNames contains the names of the uploaded temporal files
-	FilesTmpNames
+	FilesTmpNames = variables.FilesTmpNames
 	// ArgsNames contains the names of the arguments (POST and GET)
-	ArgsNames
+	ArgsNames = variables.ArgsNames
 	// ArgsGetNames contains the names of the GET arguments
-	ArgsGetNames
+	ArgsGetNames = variables.ArgsGetNames
 	// ArgsPostNames contains the names of the POST arguments
-	ArgsPostNames
+	ArgsPostNames = variables.ArgsPostNames
 	// TX contains transaction specific variables created with setvar
-	TX
+	TX = variables.TX
 	// Rule contains rule metadata
-	Rule
+	Rule = variables.Rule
 	// JSON does not provide any data, might be removed
-	JSON
+	JSON = variables.JSON
 	// Env contains the process environment variables
-	Env
-	// IP is kept for compatibility
-	IP
+	Env = variables.Env
 	// UrlencodedError equals 1 if we failed to parse de URL
 	// It applies for URL query part and urlencoded post body
-	UrlencodedError
+	UrlencodedError = variables.UrlencodedError
 	// ResponseArgs contains the response parsed arguments
-	ResponseArgs
+	ResponseArgs = variables.ResponseArgs
 	// ResponseXML contains the response parsed XML
-	ResponseXML
+	ResponseXML = variables.ResponseXML
 	// RequestXML contains the request parsed XML
-	RequestXML
+	RequestXML = variables.RequestXML
 	// XML is a pointer to ResponseXML
-	XML
+	XML = variables.XML
 	// MultipartPartHeaders contains the multipart headers
-	MultipartPartHeaders
+	MultipartPartHeaders = variables.MultipartPartHeaders
 )
+
+// Parse returns the byte interpretation
+// of a variable from a string
+// Returns error if there is no representation
+func Parse(v string) (RuleVariable, error) {
+	return variables.Parse(v)
+}
diff --git a/types/variablescount.go b/types/variablescount.go
new file mode 100644
index 0000000..4782e1c
--- /dev/null
+++ b/types/variablescount.go
@@ -0,0 +1,12 @@
+// Copyright 2022 Juan Pablo Tosso and the OWASP Coraza contributors
+// SPDX-License-Identifier: Apache-2.0
+
+package types
+
+import (
+	"github.com/corazawaf/coraza/v3/internal/variables"
+)
+
+// VariablesCount contains the number of variables handled by the variables package
+// It is used to create arrays of the correct size
+const VariablesCount = variables.VariablesCount
diff --git a/waf.go b/waf.go
index ce39840..8f5dbc4 100644
--- a/waf.go
+++ b/waf.go
@@ -44,15 +44,15 @@ func NewWAF(config WAFConfig) (WAF, error) {
 		switch {
 		case r.rule != nil:
 			if err := waf.Rules.Add(r.rule); err != nil {
-				return nil, fmt.Errorf("invalid WAF config: %w", err)
+				return nil, fmt.Errorf("invalid WAF config from rule: %w", err)
 			}
 		case r.str != "":
 			if err := parser.FromString(r.str); err != nil {
-				return nil, fmt.Errorf("invalid WAF config: %w", err)
+				return nil, fmt.Errorf("invalid WAF config from string: %w", err)
 			}
 		case r.file != "":
 			if err := parser.FromFile(r.file); err != nil {
-				return nil, fmt.Errorf("invalid WAF config: %w", err)
+				return nil, fmt.Errorf("invalid WAF config from file: %w", err)
 			}
 		}
 	}


Test patch:
diff --git a/internal/collections/noop_test.go b/internal/collections/noop_test.go
new file mode 100644
index 0000000..4ececa4
--- /dev/null
+++ b/internal/collections/noop_test.go
@@ -0,0 +1,17 @@
+// Copyright 2023 Juan Pablo Tosso and the OWASP Coraza contributors
+// SPDX-License-Identifier: Apache-2.0
+
+package collections
+
+import (
+	"testing"
+)
+
+func TestNoop(t *testing.T) {
+	c := Noop
+
+	if c.Name() != "" {
+		t.Error("noop name failed")
+	}
+	assertValuesMatch(t, c.FindAll(), "")
+}
diff --git a/internal/corazawaf/body_buffer_test.go b/internal/corazawaf/body_buffer_test.go
index 540ce27..0ed8631 100644
--- a/internal/corazawaf/body_buffer_test.go
+++ b/internal/corazawaf/body_buffer_test.go
@@ -37,7 +37,7 @@ func TestBodyReaderMemory(t *testing.T) {
 }
 
 func TestBodyReaderFile(t *testing.T) {
-	if environment.IsTinyGo {
+	if !environment.HasAccessToFS {
 		return // t.Skip doesn't work on TinyGo
 	}
 
diff --git a/internal/seclang/directives_log_test.go b/internal/seclang/directives_log_test.go
index 3dee27c..2dd8736 100644
--- a/internal/seclang/directives_log_test.go
+++ b/internal/seclang/directives_log_test.go
@@ -1,8 +1,7 @@
 // Copyright 2022 Juan Pablo Tosso and the OWASP Coraza contributors
 // SPDX-License-Identifier: Apache-2.0
 
-// Logs are currently disabled for tinygo
-
+// Logs are currently disabled for tinygo builds.
 //go:build !tinygo
 // +build !tinygo