Skip to content

Commit

Permalink
fix vincent-petithory#5 by using url methods instead of re-implementi…
Browse files Browse the repository at this point in the history
…ng these
  • Loading branch information
MagicalTux committed May 28, 2021
1 parent d1553a7 commit d28ab02
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 104 deletions.
109 changes: 6 additions & 103 deletions rfc2396.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
package dataurl

import (
"bytes"
"fmt"
"io"
"strings"
"net/url"
)

// Escape implements URL escaping, as defined in RFC 2397 (http://tools.ietf.org/html/rfc2397).
Expand All @@ -13,118 +10,24 @@ import (
// Only ASCII chars are allowed. Reserved chars are escaped to their %xx form.
// Unreserved chars are [a-z], [A-Z], [0-9], and -_.!~*\().
func Escape(data []byte) string {
var buf = new(bytes.Buffer)
for _, b := range data {
switch {
case isUnreserved(b):
buf.WriteByte(b)
default:
fmt.Fprintf(buf, "%%%02X", b)
}
}
return buf.String()
return url.PathEscape(string(data))
}

// EscapeString is like Escape, but taking
// a string as argument.
func EscapeString(s string) string {
return Escape([]byte(s))
}

// isUnreserved return true
// if the byte c is an unreserved char,
// as defined in RFC 2396.
func isUnreserved(c byte) bool {
return (c >= 'a' && c <= 'z') ||
(c >= 'A' && c <= 'Z') ||
(c >= '0' && c <= '9') ||
c == '-' ||
c == '_' ||
c == '.' ||
c == '!' ||
c == '~' ||
c == '*' ||
c == '\'' ||
c == '(' ||
c == ')'
}

func isHex(c byte) bool {
switch {
case c >= 'a' && c <= 'f':
return true
case c >= 'A' && c <= 'F':
return true
case c >= '0' && c <= '9':
return true
}
return false
}

// borrowed from net/url/url.go
func unhex(c byte) byte {
switch {
case '0' <= c && c <= '9':
return c - '0'
case 'a' <= c && c <= 'f':
return c - 'a' + 10
case 'A' <= c && c <= 'F':
return c - 'A' + 10
}
return 0
return url.PathEscape(s)
}

// Unescape unescapes a character sequence
// escaped with Escape(String?).
func Unescape(s string) ([]byte, error) {
var buf = new(bytes.Buffer)
reader := strings.NewReader(s)

for {
r, size, err := reader.ReadRune()
if err == io.EOF {
break
}
if err != nil {
return nil, err
}
if size > 1 {
return nil, fmt.Errorf("rfc2396: non-ASCII char detected")
}

switch r {
case '%':
eb1, err := reader.ReadByte()
if err == io.EOF {
return nil, fmt.Errorf("rfc2396: unexpected end of unescape sequence")
}
if err != nil {
return nil, err
}
if !isHex(eb1) {
return nil, fmt.Errorf("rfc2396: invalid char 0x%x in unescape sequence", r)
}
eb0, err := reader.ReadByte()
if err == io.EOF {
return nil, fmt.Errorf("rfc2396: unexpected end of unescape sequence")
}
if err != nil {
return nil, err
}
if !isHex(eb0) {
return nil, fmt.Errorf("rfc2396: invalid char 0x%x in unescape sequence", r)
}
buf.WriteByte(unhex(eb0) + unhex(eb1)*16)
default:
buf.WriteByte(byte(r))
}
}
return buf.Bytes(), nil
res, err := url.PathUnescape(s)
return []byte(res), err
}

// UnescapeToString is like Unescape, but returning
// a string.
func UnescapeToString(s string) (string, error) {
b, err := Unescape(s)
return string(b), err
return url.PathUnescape(s)
}
2 changes: 1 addition & 1 deletion rfc2396_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ var tests = []struct {
unescaped []byte
}{
{"A%20brief%20note%0A", []byte("A brief note\n")},
{"%7B%5B%5Dbyte(%22A%2520brief%2520note%22)%2C%20%5B%5Dbyte(%22A%20brief%20note%22)%7D", []byte(`{[]byte("A%20brief%20note"), []byte("A brief note")}`)},
{"%7B%5B%5Dbyte%28%22A%2520brief%2520note%22%29%2C%20%5B%5Dbyte%28%22A%20brief%20note%22%29%7D", []byte(`{[]byte("A%20brief%20note"), []byte("A brief note")}`)},
}

func TestEscape(t *testing.T) {
Expand Down

0 comments on commit d28ab02

Please sign in to comment.