Skip to content

Commit

Permalink
Add test for UnicodeString Limit
Browse files Browse the repository at this point in the history
Signed-off-by: Amit Barve <[email protected]>
  • Loading branch information
ambarve committed Aug 27, 2021
1 parent 0afb0c9 commit 587be85
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 5 deletions.
10 changes: 5 additions & 5 deletions internal/winapi/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ type UnicodeString struct {
}

// NTSTRSAFE_UNICODE_STRING_MAX_CCH is a constant defined in ntstrsafe.h. This value
// denotes the maximum number of bytes a path can have.
// denotes the maximum number of wide chars a path can have.
const NTSTRSAFE_UNICODE_STRING_MAX_CCH = 32767

//String converts a UnicodeString to a golang string
Expand All @@ -42,15 +42,15 @@ func (uni UnicodeString) String() string {
// NewUnicodeString allocates a new UnicodeString and copies `s` into
// the buffer of the new UnicodeString.
func NewUnicodeString(s string) (*UnicodeString, error) {
if len(s) > NTSTRSAFE_UNICODE_STRING_MAX_CCH {
return nil, syscall.ENAMETOOLONG
}

buf, err := windows.UTF16FromString(s)
if err != nil {
return nil, err
}

if len(buf) > NTSTRSAFE_UNICODE_STRING_MAX_CCH {
return nil, syscall.ENAMETOOLONG
}

uni := &UnicodeString{
// The length is in bytes and should not include the trailing null character.
Length: uint16((len(buf) - 1) * 2),
Expand Down
33 changes: 33 additions & 0 deletions internal/winapi/winapi_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package winapi

import (
"strings"
"testing"
"unicode/utf16"
)
Expand Down Expand Up @@ -59,3 +60,35 @@ func TestUnicodeToString(t *testing.T) {
}
}
}

func TestUnicodeStringLimit(t *testing.T) {
var sb strings.Builder

// limit in bytes of how long the input string can be
// -1 to account for null character.
limit := NTSTRSAFE_UNICODE_STRING_MAX_CCH - 1

lengths := []int{limit - 1, limit, limit + 1}
testStrings := []string{}
for _, len := range lengths {
sb.Reset()
for i := 0; i < len; i++ {
// We are deliberately writing byte 41 here as it takes only 8
// bits in UTF-8 encoding. If we use non-ASCII chars the limit
// calculations used above won't work.
if err := sb.WriteByte(41); err != nil {
t.Fatalf("string creation failed: %s", err)
}
}
testStrings = append(testStrings, sb.String())
}

for i, testStr := range testStrings {
_, err := NewUnicodeString(testStr)
if lengths[i] > limit && err == nil {
t.Fatalf("input string of length %d should throw ENAMETOOLONG error", lengths[i])
} else if lengths[i] <= limit && err != nil {
t.Fatalf("unexpected error for length %d: %s", lengths[i], err)
}
}
}

0 comments on commit 587be85

Please sign in to comment.