unix: allow non-padded SockaddrIUCV

This was the intention from the start, but due to a logic error in the
handling of slices the implementation only handled minimum 8 character
strings.

This commit also improves the tests.

Change-Id: I6b0ed00bbd8a2faf90ca4a3ebe6218d3c5d6e8bf
GitHub-Last-Rev: 5b6dbc0682
GitHub-Pull-Request: golang/sys#77
Reviewed-on: https://go-review.googlesource.com/c/sys/+/248778
Reviewed-by: Matt Layher <mdlayher@gmail.com>
Run-TryBot: Matt Layher <mdlayher@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
Christian Svensson
2020-08-17 15:34:28 +00:00
committed by Matt Layher
parent 3ff754bf58
commit cc1be6b9e0
2 changed files with 75 additions and 2 deletions

View File

@@ -474,6 +474,76 @@ func TestSockaddrUnix_sockaddr(t *testing.T) {
}
}
func TestSockaddrIUCV_sockaddr(t *testing.T) {
tests := []struct {
name string
sa *SockaddrIUCV
raw *RawSockaddrIUCV
err error
}{
{
name: "no fields set",
sa: &SockaddrIUCV{},
raw: &RawSockaddrIUCV{
Family: AF_IUCV,
Nodeid: [8]int8{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
User_id: [8]int8{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
Name: [8]int8{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
},
},
{
name: "both fields set",
sa: &SockaddrIUCV{
UserID: "USERID",
Name: "NAME",
},
raw: &RawSockaddrIUCV{
Family: AF_IUCV,
Nodeid: [8]int8{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
User_id: [8]int8{'U', 'S', 'E', 'R', 'I', 'D', ' ', ' '},
Name: [8]int8{'N', 'A', 'M', 'E', ' ', ' ', ' ', ' '},
},
},
{
name: "too long userid",
sa: &SockaddrIUCV{
UserID: "123456789",
},
err: EINVAL,
},
{
name: "too long name",
sa: &SockaddrIUCV{
Name: "123456789",
},
err: EINVAL,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
out, l, err := tt.sa.sockaddr()
if err != tt.err {
t.Fatalf("unexpected error: %v, want: %v", err, tt.err)
}
// Must be 0 on error or a fixed size otherwise.
if (tt.err != nil && l != 0) || (tt.raw != nil && l != SizeofSockaddrIUCV) {
t.Fatalf("unexpected Socklen: %d", l)
}
if out == nil {
// No pointer to cast, return early.
return
}
raw := (*RawSockaddrIUCV)(out)
if !reflect.DeepEqual(raw, tt.raw) {
t.Fatalf("unexpected RawSockaddrIUCV:\n got: %#v\nwant: %#v", raw, tt.raw)
}
})
}
}
// These helpers explicitly copy the contents of in into out to produce
// the correct sockaddr structure, without relying on unsafe casting to
// a type of a larger size.

View File

@@ -902,10 +902,13 @@ func (sa *SockaddrIUCV) sockaddr() (unsafe.Pointer, _Socklen, error) {
sa.raw.User_id[i] = ' '
sa.raw.Name[i] = ' '
}
for i, b := range []byte(sa.UserID[:8]) {
if len(sa.UserID) > 8 || len(sa.Name) > 8 {
return nil, 0, EINVAL
}
for i, b := range []byte(sa.UserID[:]) {
sa.raw.User_id[i] = int8(b)
}
for i, b := range []byte(sa.Name[:8]) {
for i, b := range []byte(sa.Name[:]) {
sa.raw.Name[i] = int8(b)
}
return unsafe.Pointer(&sa.raw), SizeofSockaddrIUCV, nil