diff --git a/x/logic/predicate/uri.go b/x/logic/predicate/uri.go index 63dffd49..ee6b7311 100644 --- a/x/logic/predicate/uri.go +++ b/x/logic/predicate/uri.go @@ -45,7 +45,7 @@ func NewComponent(v string) (Component, error) { // escaping doesn't fit to the SWI-Prolog escaping due to RFC discrepancy between those two implementations. // // Another discrepancy is on the query component that escape the space character ' ' to a '+' (plus sign) on the -// golang library and to '%20' escaping on the SWI-Prolog implementation. +// golang library and to '%20' escaping on the [SWI-Prolog implementation](https://www.swi-prolog.org/pldoc/doc/_SWI_/library/uri.pl?show=src#uri_encoded/3). // // Here some reported issues on golang about the RFC non-compliance. // - golang.org/issue/5684. @@ -125,19 +125,8 @@ func (comp Component) Escape(v string) string { return string(t) } -func (comp Component) Decode(v string) (string, error) { - switch comp { - case QueryComponent: - return url.QueryUnescape(v) - case FragmentComponent: - return "", fmt.Errorf("fragment not implemented") - case PathComponent: - return url.PathUnescape(v) - case SegmentComponent: - return "", fmt.Errorf("segment not implemented") - default: - return "", fmt.Errorf("wrong component") - } +func (comp Component) Unescape(v string) (string, error) { + return url.PathUnescape(v) } func URIEncoded(vm *engine.VM, component, decoded, encoded engine.Term, cont engine.Cont, env *engine.Env) *engine.Promise { @@ -167,13 +156,13 @@ func URIEncoded(vm *engine.VM, component, decoded, encoded engine.Term, cont eng case engine.Variable: return engine.Unify(vm, encoded, util.StringToTerm(dec), cont, env) case engine.Atom: - enc, err := comp.Decode(e.String()) + enc, err := comp.Unescape(e.String()) if err != nil { return engine.Error(fmt.Errorf("uri_encoded/3: %w", err)) } return engine.Unify(vm, decoded, util.StringToTerm(enc), cont, env) default: - return engine.Error(fmt.Errorf("uri_encoded/3: invalid encpded type: %T, should be Variable or Atom", component)) + return engine.Error(fmt.Errorf("uri_encoded/3: invalid encoded type: %T, should be Variable or Atom", component)) } }) } diff --git a/x/logic/predicate/uri_test.go b/x/logic/predicate/uri_test.go index 5f617d47..1250e9b7 100644 --- a/x/logic/predicate/uri_test.go +++ b/x/logic/predicate/uri_test.go @@ -86,6 +86,34 @@ func TestURIEncoded(t *testing.T) { "Encoded": "'%20!%22%23$%25&\\'()*+,-./0123456789:;%3C=%3E?@ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5C%5D%5E_%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D~'", }}, }, + { + query: "uri_encoded(query, Decoded, '%20!%22%23$%25%26\\'()*%2B,-./0123456789%3A%3B%3C%3D%3E?@ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5C%5D%5E_%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D~+').", + wantSuccess: true, + wantResult: []types.TermResults{{ + "Decoded": "' !\"#$%&\\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\]^_`abcdefghijklmnopqrstuvwxyz{|}~+'", + }}, + }, + { + query: "uri_encoded(path, Decoded, '%20!%22%23$%25&\\'()*+,-./0123456789%3A;%3C=%3E%3F@ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5C%5D%5E_%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D~').", + wantSuccess: true, + wantResult: []types.TermResults{{ + "Decoded": "' !\"#$%&\\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\]^_`abcdefghijklmnopqrstuvwxyz{|}~'", + }}, + }, + { + query: "uri_encoded(segment, Decoded, '%20!%22%23$%25&\\'()*+,-.%2F0123456789%3A;%3C=%3E%3F@ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5C%5D%5E_%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D~').", + wantSuccess: true, + wantResult: []types.TermResults{{ + "Decoded": "' !\"#$%&\\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\]^_`abcdefghijklmnopqrstuvwxyz{|}~'", + }}, + }, + { + query: "uri_encoded(fragment, Decoded, '%20!%22%23$%25&\\'()*+,-./0123456789:;%3C=%3E?@ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5C%5D%5E_%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D~').", + wantSuccess: true, + wantResult: []types.TermResults{{ + "Decoded": "' !\"#$%&\\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\]^_`abcdefghijklmnopqrstuvwxyz{|}~'", + }}, + }, } for nc, tc := range cases { Convey(fmt.Sprintf("Given the query #%d: %s", nc, tc.query), func() {