diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7c36733..190aaff 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,7 +8,7 @@ jobs: Tests: strategy: matrix: - go-version: [1.18.x, 1.19.x, 1.20.x] + go-version: [1.19.x, 1.20.x] platform: [ubuntu-latest, windows-latest, macos-latest] runs-on: ${{ matrix.platform }} steps: diff --git a/bytes.go b/bytes.go index e5b5488..e24b5fe 100644 --- a/bytes.go +++ b/bytes.go @@ -4,7 +4,7 @@ package utils -// ToLowerBytes converts ascii slice to lower-case in-place. +// ToLowerBytes converts ascii slice to lower-case func ToLowerBytes(b []byte) []byte { for i := 0; i < len(b); i++ { b[i] = toLowerTable[b[i]] @@ -12,7 +12,7 @@ func ToLowerBytes(b []byte) []byte { return b } -// ToUpperBytes converts ascii slice to upper-case in-place. +// ToUpperBytes converts ascii slice to upper-case func ToUpperBytes(b []byte) []byte { for i := 0; i < len(b); i++ { b[i] = toUpperTable[b[i]] diff --git a/convert.go b/convert.go index 9b456f1..36f015d 100644 --- a/convert.go +++ b/convert.go @@ -13,6 +13,8 @@ import ( "unsafe" ) +const MaxStringLen = 0x7fff0000 // Maximum string length for UnsafeBytes. (decimal: 2147418112) + // #nosec G103 // UnsafeString returns a string pointer without allocation func UnsafeString(b []byte) string { @@ -20,14 +22,16 @@ func UnsafeString(b []byte) string { } // #nosec G103 -// UnsafeBytes returns a byte pointer without allocation -func UnsafeBytes(s string) (bs []byte) { - sh := (*reflect.StringHeader)(unsafe.Pointer(&s)) - bh := (*reflect.SliceHeader)(unsafe.Pointer(&bs)) - bh.Data = sh.Data - bh.Len = sh.Len - bh.Cap = sh.Len - return +// UnsafeBytes returns a byte pointer without allocation. +// String length shouldn't be more than 2147418112. +func UnsafeBytes(s string) []byte { + if s == "" { + return nil + } + + return (*[MaxStringLen]byte)(unsafe.Pointer( + (*reflect.StringHeader)(unsafe.Pointer(&s)).Data), + )[:len(s):len(s)] } // CopyString copies a string to make it immutable diff --git a/http.go b/http.go index 7aacd39..b2b0e6b 100644 --- a/http.go +++ b/http.go @@ -4,24 +4,37 @@ package utils -import "strings" +import ( + "mime" + "strings" +) const MIMEOctetStream = "application/octet-stream" // GetMIME returns the content-type of a file extension -func GetMIME(extension string) (mime string) { +func GetMIME(extension string) string { if len(extension) == 0 { - return mime + return "" } + var foundMime string if extension[0] == '.' { - mime = mimeExtensions[extension[1:]] + foundMime = mimeExtensions[extension[1:]] } else { - mime = mimeExtensions[extension] + foundMime = mimeExtensions[extension] } - if len(mime) == 0 { - return MIMEOctetStream + + if len(foundMime) == 0 { + if extension[0] != '.' { + foundMime = mime.TypeByExtension("." + extension) + } else { + foundMime = mime.TypeByExtension(extension) + } + + if foundMime == "" { + return MIMEOctetStream + } } - return mime + return foundMime } // ParseVendorSpecificContentType check if content type is vendor specific and diff --git a/http_test.go b/http_test.go index e06e890..d826bfc 100644 --- a/http_test.go +++ b/http_test.go @@ -25,9 +25,18 @@ func Test_GetMIME(t *testing.T) { res = GetMIME("unknown") require.Equal(t, MIMEOctetStream, res) + // empty case res = GetMIME("") require.Equal(t, "", res) + + err := mime.AddExtensionType(".mjs", "application/javascript") + if err == nil { + res = GetMIME(".mjs") + require.Equal(t, "application/javascript", res) + } + require.NoError(t, err) + } // go test -v -run=^$ -bench=Benchmark_GetMIME -benchmem -count=2 diff --git a/ips.go b/ips.go index 6d24464..333054f 100644 --- a/ips.go +++ b/ips.go @@ -26,7 +26,7 @@ func IsIPv4(s string) bool { } } - if ci == 0 || n > 0xFF || (ci > 1 && s[0] == '0') { + if ci == 0 || (ci > 1 && s[0] == '0') { return false } diff --git a/ips_test.go b/ips_test.go index ce9109c..7c392eb 100644 --- a/ips_test.go +++ b/ips_test.go @@ -27,6 +27,12 @@ func Test_IsIPv4(t *testing.T) { require.Equal(t, false, IsIPv4("")) require.Equal(t, false, IsIPv4("2345:0425:2CA1::0567:5673:23b5")) require.Equal(t, false, IsIPv4("invalid")) + require.Equal(t, false, IsIPv4("189.12.34.260")) + require.Equal(t, false, IsIPv4("189.12.260.260")) + require.Equal(t, false, IsIPv4("189.260.260.260")) + require.Equal(t, false, IsIPv4("999.999.999.999")) + require.Equal(t, false, IsIPv4("9999.9999.9999.9999")) + } // go test -v -run=^$ -bench=UnsafeString -benchmem -count=2