Skip to content

Commit

Permalink
feat: add hexDecode transformation (#1275)
Browse files Browse the repository at this point in the history
* with commented code

* go sum update

* simple implementation

* add comment

* add unit tests

* change names in tests, remove redundant

* grammar fix

* updated hex method and tests

---------

Co-authored-by: Roman Suvorov <[email protected]>
Co-authored-by: José Carlos Chávez <[email protected]>
Co-authored-by: Felipe Zipitría <[email protected]>
  • Loading branch information
4 people authored Jan 24, 2025
1 parent 077bde8 commit 761cd64
Show file tree
Hide file tree
Showing 4 changed files with 150 additions and 42 deletions.
16 changes: 16 additions & 0 deletions internal/transformations/hex_decode.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package transformations

import (
"encoding/hex"

"github.com/corazawaf/coraza/v3/internal/strings"
)

func hexDecode(data string) (string, bool, error) {
dst, err := hex.DecodeString(data)
if err != nil {
return "", false, err
}

return strings.WrapUnsafe(dst), true, nil
}
98 changes: 98 additions & 0 deletions internal/transformations/hex_decode_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package transformations

import (
"testing"
)

func TestHexDecode(t *testing.T) {
tests := []struct {
name string
input string
expectedOutput string
expectedValid bool
expectError bool
}{
{
name: "valid hexadecimal string",
input: "48656c6c6f",
expectedOutput: "Hello",
expectedValid: true,
expectError: false,
},
{
name: "odd length",
input: "48656c6c6f7",
expectedOutput: "",
expectedValid: false,
expectError: true,
},
{
name: "invalid with non hex characters",
input: "YyYy",
expectedOutput: "",
expectedValid: false,
expectError: true,
},
{
name: "invalid with extra characters",
input: "123G",
expectedOutput: "",
expectedValid: false,
expectError: true,
},
{
name: "empty input",
input: "",
expectedOutput: "",
expectedValid: true,
expectError: false,
},
{
name: "uppercase hex string",
input: "48454C4C4F",
expectedOutput: "HELLO",
expectedValid: true,
expectError: false,
},
{
name: "mixed case",
input: "48454c4C4f",
expectedOutput: "HELLO",
expectedValid: true,
expectError: false,
},
{
name: "special characters",
input: "21402324255E262A28",
expectedOutput: "!@#$%^&*(",
expectedValid: true,
expectError: false,
},
{
name: "odd length with invalid character",
input: "48656c6c6fZ",
expectedOutput: "",
expectedValid: false,
expectError: true,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
output, valid, err := hexDecode(tt.input)

if (err != nil) != tt.expectError {
t.Errorf("hexDecode(%q): expected error=%v, got error=%v", tt.input, tt.expectError, err)
}

if output != tt.expectedOutput {
t.Errorf("hexDecode(%q): expected output=%q, got output=%q", tt.input, tt.expectedOutput, output)
}

if valid != tt.expectedValid {
t.Errorf("hexDecode(%q): expected valid=%v, got valid=%v", tt.input, tt.expectedValid, valid)
}
})
}
}
77 changes: 35 additions & 42 deletions internal/transformations/testdata/hexDecode.json
Original file line number Diff line number Diff line change
@@ -1,44 +1,37 @@
[
{
"ret" : 1,
"input" : "",
"type" : "tfn",
"name" : "hexDecode",
"output" : ""
},
{
"output" : "TestCase",
"ret" : 1,
"name" : "hexDecode",
"input" : "5465737443617365",
"type" : "tfn"
},
{
"type" : "tfn",
"input" : "546573740043617365",
"name" : "hexDecode",
"ret" : 1,
"output" : "Test\\u0000Case"
},
{
"output" : "\\x01#Eg\\x89\\x0a#\\x01#Eg\\x89\\x0a",
"type" : "tfn",
"input" : "01234567890a0z01234567890a",
"name" : "hexDecode",
"ret" : 1
},
{
"type" : "tfn",
"name" : "hexDecode",
"input" : "01234567890az",
"output" : "\\x01#Eg\\x89\\x0a",
"ret" : 1
},
{
"type" : "tfn",
"name" : "hexDecode",
"input" : "01234567890a0",
"output" : "\\x01#Eg\\x89\\x0a",
"ret" : 1
}
{
"ret": 1,
"input": "",
"type": "tfn",
"name": "hexDecode",
"output": ""
},
{
"output": "TestCase",
"ret": 1,
"name": "hexDecode",
"input": "5465737443617365",
"type": "tfn"
},
{
"type": "tfn",
"input": "546573740043617365",
"name": "hexDecode",
"ret": 1,
"output": "Test\\u0000Case"
},
{
"type": "tfn",
"name": "invalidCharacter",
"input": "01234567890z",
"output": "",
"ret": 0
},
{
"type": "tfn",
"name": "invalidLen",
"input": "54657374004",
"output": "",
"ret": 0
}
]
1 change: 1 addition & 0 deletions internal/transformations/transformations.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ func init() {
Register("compressWhitespace", compressWhitespace)
Register("cssDecode", cssDecode)
Register("escapeSeqDecode", escapeSeqDecode)
Register("hexDecode", hexDecode)
Register("hexEncode", hexEncode)
Register("htmlEntityDecode", htmlEntityDecode)
Register("jsDecode", jsDecode)
Expand Down

0 comments on commit 761cd64

Please sign in to comment.