URL escape and unescape normalier. Fixes #110 (#119)

# Describe Request

URL escape and unescape normalier. 

Fixes #110

# Change Type

New normalizer.
This commit is contained in:
Onur Cinar 2023-06-25 11:29:17 -07:00 committed by GitHub
commit 20edd60174
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 184 additions and 1 deletions

View file

@ -99,13 +99,15 @@ This package currently provides the following checkers:
This package currently provides the following normalizers. They can be mixed with the checkers when defining the validation steps for user data.
- [html-escape](doc/normalizers/html_escape.md) applies HTML escaping to special characters.
- [html-unescape](doc//normalizers/html_unescape.md) applies HTML unescaping to special characters.
- [html-unescape](doc/normalizers/html_unescape.md) applies HTML unescaping to special characters.
- [lower](doc/normalizers/lower.md) maps all Unicode letters in the given value to their lower case.
- [upper](doc/normalizers/upper.md) maps all Unicode letters in the given value to their upper case.
- [title](doc/normalizers/title.md) maps the first letter of each word to their upper case.
- [trim](doc/normalizers/trim.md) removes the whitespaces at the beginning and at the end of the given value.
- [trim-left](doc/normalizers/trim_left.md) removes the whitespaces at the beginning of the given value.
- [trim-right](doc/normalizers/trim_right.md) removes the whitespaces at the end of the given value.
- [url-escape](doc/normalizers/url_escape.md) applies URL escaping to special characters.
- [url-unescape](doc/normalizers/url_unescape.md) applies URL unescaping to special characters.
# Custom Checkers

View file

@ -66,6 +66,8 @@ var makers = map[string]MakeFunc{
NormalizerTrim: makeTrim,
NormalizerTrimLeft: makeTrimLeft,
NormalizerTrimRight: makeTrimRight,
NormalizerURLEscape: makeURLEscape,
NormalizerURLUnescape: makeURLUnescape,
}
// Register registers the given checker name and the maker function.

View file

@ -0,0 +1,22 @@
# URL Escape Normalizer
The `url-escape` normalizer uses [net.url.QueryEscape](https://pkg.go.dev/net/url#QueryEscape) to escape the string so it can be safely placed inside a URL query.
```golang
type Request struct {
Query string `checkers:"url-escape"`
}
request := &Request{
Query: "param1/param2 = 1 + 2 & 3 + 4",
}
_, valid := checker.Check(request)
if !valid {
t.Fail()
}
// Outputs:
// param1%2Fparam2+%3D+1+%2B+2+%26+3+%2B+4
fmt.Println(request.Query)
```

View file

@ -0,0 +1,26 @@
# URL Unescape Normalizer
The `url-unescape` normalizer uses [net.url.QueryUnescape](https://pkg.go.dev/net/url#QueryUnescape) to converte each 3-byte encoded substring of the form "%AB" into the hex-decoded byte 0xAB.
```golang
type Request struct {
Query string `checkers:"url-unescape"`
}
request := &Request{
Query: "param1%2Fparam2+%3D+1+%2B+2+%26+3+%2B+4",
}
_, valid := checker.Check(request)
if !valid {
t.Fail()
}
if request.Query != "param1/param2 = 1 + 2 & 3 + 4" {
t.Fail()
}
// Outputs:
// param1/param2 = 1 + 2 & 3 + 4
fmt.Println(comment.Body)
```

26
url_escape.go Normal file
View file

@ -0,0 +1,26 @@
package checker
import (
"net/url"
"reflect"
)
// NormalizerURLEscape is the name of the normalizer.
const NormalizerURLEscape = "url-escape"
// makeURLEscape makes a normalizer function for the URL escape normalizer.
func makeURLEscape(_ string) CheckFunc {
return normalizeURLEscape
}
// normalizeURLEscape applies URL escaping to special characters.
// Uses net.url.QueryEscape for the actual escape operation.
func normalizeURLEscape(value, _ reflect.Value) Result {
if value.Kind() != reflect.String {
panic("string expected")
}
value.SetString(url.QueryEscape(value.String()))
return ResultValid
}

38
url_escape_test.go Normal file
View file

@ -0,0 +1,38 @@
package checker_test
import (
"testing"
"github.com/cinar/checker"
)
func TestNormalizeURLEscapeNonString(t *testing.T) {
defer checker.FailIfNoPanic(t)
type Request struct {
Query int `checkers:"url-escape"`
}
request := &Request{}
checker.Check(request)
}
func TestNormalizeURLEscape(t *testing.T) {
type Request struct {
Query string `checkers:"url-escape"`
}
request := &Request{
Query: "param1/param2 = 1 + 2 & 3 + 4",
}
_, valid := checker.Check(request)
if !valid {
t.Fail()
}
if request.Query != "param1%2Fparam2+%3D+1+%2B+2+%26+3+%2B+4" {
t.Fail()
}
}

29
url_unescape.go Normal file
View file

@ -0,0 +1,29 @@
package checker
import (
"net/url"
"reflect"
)
// NormalizerURLUnescape is the name of the normalizer.
const NormalizerURLUnescape = "url-unescape"
// makeURLUnescape makes a normalizer function for the URL unscape normalizer.
func makeURLUnescape(_ string) CheckFunc {
return normalizeURLUnescape
}
// normalizeURLUnescape applies URL unescaping to special characters.
// Uses url.QueryUnescape for the actual unescape operation.
func normalizeURLUnescape(value, _ reflect.Value) Result {
if value.Kind() != reflect.String {
panic("string expected")
}
unescaped, err := url.QueryUnescape(value.String())
if err == nil {
value.SetString(unescaped)
}
return ResultValid
}

38
url_unescape_test.go Normal file
View file

@ -0,0 +1,38 @@
package checker_test
import (
"testing"
"github.com/cinar/checker"
)
func TestNormalizeURLUnescapeNonString(t *testing.T) {
defer checker.FailIfNoPanic(t)
type Request struct {
Query int `checkers:"url-unescape"`
}
request := &Request{}
checker.Check(request)
}
func TestNormalizeURLUnescape(t *testing.T) {
type Request struct {
Query string `checkers:"url-unescape"`
}
request := &Request{
Query: "param1%2Fparam2+%3D+1+%2B+2+%26+3+%2B+4",
}
_, valid := checker.Check(request)
if !valid {
t.Fail()
}
if request.Query != "param1/param2 = 1 + 2 & 3 + 4" {
t.Fail()
}
}