mirror of
https://github.com/opentofu/opentofu.git
synced 2024-12-24 16:10:46 -06:00
Signed-off-by: pooriaghaedi <pooria.ghaedi@gmail.com>
This commit is contained in:
parent
835dcb8121
commit
b5889b10eb
@ -522,6 +522,10 @@ var DescriptionList = map[string]descriptionEntry{
|
||||
Description: "`urlencode` applies URL encoding to a given string.",
|
||||
ParamDescription: []string{""},
|
||||
},
|
||||
"urldecode": {
|
||||
Description: "`urldecode` applies URL decoding to a given encoded string.",
|
||||
ParamDescription: []string{""},
|
||||
},
|
||||
"uuid": {
|
||||
Description: "`uuid` generates a unique identifier string.",
|
||||
ParamDescription: []string{},
|
||||
|
@ -227,6 +227,26 @@ var URLEncodeFunc = function.New(&function.Spec{
|
||||
},
|
||||
})
|
||||
|
||||
// URLDecodeFunc constructs a function that applies URL decoding to a given encoded string.
|
||||
var URLDecodeFunc = function.New(&function.Spec{
|
||||
Params: []function.Parameter{
|
||||
{
|
||||
Name: "str",
|
||||
Type: cty.String,
|
||||
},
|
||||
},
|
||||
Type: function.StaticReturnType(cty.String),
|
||||
RefineResult: refineNotNull,
|
||||
Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
|
||||
query, err := url.QueryUnescape(args[0].AsString())
|
||||
if err != nil {
|
||||
return cty.UnknownVal(cty.String), fmt.Errorf("failed to decode URL '%s': %v", query, err)
|
||||
}
|
||||
|
||||
return cty.StringVal(query), nil
|
||||
},
|
||||
})
|
||||
|
||||
// Base64Decode decodes a string containing a base64 sequence.
|
||||
//
|
||||
// OpenTofu uses the "standard" Base64 alphabet as defined in RFC 4648 section 4.
|
||||
@ -281,6 +301,16 @@ func URLEncode(str cty.Value) (cty.Value, error) {
|
||||
return URLEncodeFunc.Call([]cty.Value{str})
|
||||
}
|
||||
|
||||
// URLDecode decodes a URL encoded string.
|
||||
//
|
||||
// This function decodes the given string that has been encoded.
|
||||
//
|
||||
// If the given string contains non-ASCII characters, these are first encoded as
|
||||
// UTF-8 and then percent decoding is applied separately to each UTF-8 byte.
|
||||
func URLDecode(str cty.Value) (cty.Value, error) {
|
||||
return URLDecodeFunc.Call([]cty.Value{str})
|
||||
}
|
||||
|
||||
// TextEncodeBase64 applies Base64 encoding to a string that was encoded before with a target encoding.
|
||||
//
|
||||
// OpenTofu uses the "standard" Base64 alphabet as defined in RFC 4648 section 4.
|
||||
|
@ -243,6 +243,141 @@ func TestURLEncode(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestURLDecode(t *testing.T) {
|
||||
tests := []struct {
|
||||
String cty.Value
|
||||
Want cty.Value
|
||||
Err bool
|
||||
}{
|
||||
{
|
||||
cty.StringVal("abc123-_"),
|
||||
cty.StringVal("abc123-_"),
|
||||
false,
|
||||
},
|
||||
{
|
||||
cty.StringVal("foo%3Abar%40localhost%3Ffoo%3Dbar%26bar%3Dbaz"),
|
||||
cty.StringVal("foo:bar@localhost?foo=bar&bar=baz"),
|
||||
false,
|
||||
},
|
||||
{
|
||||
cty.StringVal("mailto%3Aemail%3Fsubject%3Dthis%2Bis%2Bmy%2Bsubject"),
|
||||
cty.StringVal("mailto:email?subject=this+is+my+subject"),
|
||||
false,
|
||||
},
|
||||
{
|
||||
cty.StringVal("foo%2Fbar"),
|
||||
cty.StringVal("foo/bar"),
|
||||
false,
|
||||
},
|
||||
{
|
||||
cty.StringVal("foo% bar"),
|
||||
cty.UnknownVal(cty.String),
|
||||
true,
|
||||
},
|
||||
{
|
||||
cty.StringVal("foo%2 bar"),
|
||||
cty.UnknownVal(cty.String),
|
||||
true,
|
||||
},
|
||||
{
|
||||
cty.StringVal("%GGfoo%2bar"),
|
||||
cty.UnknownVal(cty.String),
|
||||
true,
|
||||
},
|
||||
{
|
||||
cty.StringVal("foo%00, bar!"),
|
||||
cty.StringVal("foo\x00, bar!"),
|
||||
false,
|
||||
},
|
||||
{
|
||||
cty.StringVal("hello%20%E4%B8%96%E7%95%8C"), //Unicode character support
|
||||
cty.StringVal("hello 世界"),
|
||||
false,
|
||||
},
|
||||
{
|
||||
cty.StringVal("hello%20%D8%AF%D9%86%DB%8C%D8%A7"), //Unicode character support
|
||||
cty.StringVal("hello دنیا"),
|
||||
false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(fmt.Sprintf("urldecode(%#v)", test.String), func(t *testing.T) {
|
||||
got, err := URLDecode(test.String)
|
||||
|
||||
if test.Err {
|
||||
if err == nil {
|
||||
t.Fatal("succeeded; want error")
|
||||
}
|
||||
return
|
||||
} else if err != nil {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
|
||||
if !got.RawEquals(test.Want) {
|
||||
t.Errorf("wrong result\ngot: %#v\nwant: %#v", got, test.Want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestURLEncodeDecode(t *testing.T) {
|
||||
tests := []struct {
|
||||
String cty.Value
|
||||
Want cty.Value
|
||||
Err bool
|
||||
}{
|
||||
{
|
||||
cty.StringVal("abc123-_"),
|
||||
cty.StringVal("abc123-_"),
|
||||
false,
|
||||
},
|
||||
{
|
||||
cty.StringVal("foo:bar@localhost?foo=bar&bar=baz"),
|
||||
cty.StringVal("foo:bar@localhost?foo=bar&bar=baz"),
|
||||
false,
|
||||
},
|
||||
{
|
||||
cty.StringVal("mailto:email?subject=this+is+my+subject"),
|
||||
cty.StringVal("mailto:email?subject=this+is+my+subject"),
|
||||
false,
|
||||
},
|
||||
{
|
||||
cty.StringVal("foo/bar"),
|
||||
cty.StringVal("foo/bar"),
|
||||
false,
|
||||
},
|
||||
{
|
||||
cty.StringVal("foo%00, bar!"),
|
||||
cty.StringVal("foo%00, bar!"),
|
||||
false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(fmt.Sprintf("url encode decode(%#v)", test.String), func(t *testing.T) {
|
||||
encoded, err := URLEncode(test.String)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
got, err := URLDecode(encoded)
|
||||
|
||||
if test.Err {
|
||||
if err == nil {
|
||||
t.Fatal("succeeded; want error")
|
||||
}
|
||||
return
|
||||
} else if err != nil {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
|
||||
if !got.RawEquals(test.Want) {
|
||||
t.Errorf("wrong result\ngot: %#v\nwant: %#v", got, test.Want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestBase64TextEncode(t *testing.T) {
|
||||
tests := []struct {
|
||||
String cty.Value
|
||||
|
@ -148,6 +148,7 @@ func (s *Scope) Functions() map[string]function.Function {
|
||||
"try": tryfunc.TryFunc,
|
||||
"upper": stdlib.UpperFunc,
|
||||
"urlencode": funcs.URLEncodeFunc,
|
||||
"urldecode": funcs.URLDecodeFunc,
|
||||
"uuid": funcs.UUIDFunc,
|
||||
"uuidv5": funcs.UUIDV5Func,
|
||||
"values": stdlib.ValuesFunc,
|
||||
|
@ -1132,6 +1132,12 @@ func TestFunctions(t *testing.T) {
|
||||
cty.StringVal("foo%3Abar%40localhost%3Ffoo%3Dbar%26bar%3Dbaz"),
|
||||
},
|
||||
},
|
||||
"urldecode": {
|
||||
{
|
||||
`urldecode("foo%3Abar%40localhost%3Ffoo%3Dbar%26bar%3Dbaz")`,
|
||||
cty.StringVal("foo:bar@localhost?foo=bar&bar=baz"),
|
||||
},
|
||||
},
|
||||
|
||||
"uuidv5": {
|
||||
{
|
||||
|
@ -541,6 +541,10 @@
|
||||
"title": "<code>urlencode</code>",
|
||||
"path": "language/functions/urlencode"
|
||||
},
|
||||
{
|
||||
"title": "<code>urldecode</code>",
|
||||
"path": "language/functions/urldecode"
|
||||
},
|
||||
{
|
||||
"title": "<code>yamldecode</code>",
|
||||
"path": "language/functions/yamldecode"
|
||||
@ -1180,6 +1184,11 @@
|
||||
"title": "urlencode",
|
||||
"path": "language/functions/urlencode",
|
||||
"hidden": true
|
||||
},
|
||||
{
|
||||
"title": "urldecode",
|
||||
"path": "language/functions/urldecode",
|
||||
"hidden": true
|
||||
},
|
||||
{ "title": "uuid", "path": "language/functions/uuid", "hidden": true },
|
||||
{
|
||||
@ -1358,4 +1367,4 @@
|
||||
"title": "v1.x Compatibility Promises",
|
||||
"path": "language/v1-compatibility-promises"
|
||||
}
|
||||
]
|
||||
]
|
25
website/docs/language/functions/urldecode.mdx
Normal file
25
website/docs/language/functions/urldecode.mdx
Normal file
@ -0,0 +1,25 @@
|
||||
---
|
||||
sidebar_label: urldecode
|
||||
description: The urldecode function applies URL decoding to a given string.
|
||||
---
|
||||
|
||||
# `urldecode` Function
|
||||
|
||||
`urldecode` targets encoded characters within a string.
|
||||
|
||||
The function is capable of decoding a comprehensive range of characters,
|
||||
including those outside the ASCII range. Non-ASCII characters are first treated as UTF-8 bytes,
|
||||
followed by the application of percent decoding to each byte,
|
||||
facilitating the accurate decoding of multibyte characters.
|
||||
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> urldecode("Hello+World%21")
|
||||
Hello World!
|
||||
> urldecode("%E2%98%83")
|
||||
☃
|
||||
> urldecode("foo%3Abar%40localhost%3Ffoo%3Dbar%26bar%3Dbaz")
|
||||
foo:bar@localhost?foo=bar&bar=baz
|
||||
```
|
Loading…
Reference in New Issue
Block a user