Skip to content

Commit 02ab962

Browse files
authored
Store only the 4 mask bytes in AccessControlMask.RawBytes (Fixes #120) (#121)
1 parent c93fc0d commit 02ab962

2 files changed

Lines changed: 39 additions & 2 deletions

File tree

ace/mask/AccessControlMask.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,12 @@ func (acm *AccessControlMask) Unmarshal(marshalledData []byte) (int, error) {
2929
return 0, fmt.Errorf("AccessControlMask unmarshal requires at least 4 bytes, got %d", len(marshalledData))
3030
}
3131

32-
// Store the raw bytes and set the size
33-
acm.RawBytes = marshalledData
32+
// Store exactly the 4 bytes of the ACCESS_MASK (MS-DTYP 2.4.3). The caller
33+
// passes the whole remaining ACE body (mask + SID + application data), so
34+
// slicing to [:4] avoids aliasing the variable-length remainder into
35+
// RawBytes — which otherwise made Equal (a byte comparison of RawBytes)
36+
// report two identical masks as unequal when their ACE tails differed.
37+
acm.RawBytes = marshalledData[:4]
3438
acm.RawBytesSize = 4
3539

3640
// Convert raw bytes to a uint32 value using little-endian format
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package mask
2+
3+
import (
4+
"testing"
5+
)
6+
7+
// TestAccessControlMask_Unmarshal_RawBytesFourBytes is a regression test for
8+
// Unmarshal aliasing the whole remaining ACE body into RawBytes. The ACCESS_MASK
9+
// is a fixed 4-byte field (MS-DTYP 2.4.3), so RawBytes must hold exactly those 4
10+
// bytes; otherwise Equal (a byte comparison of RawBytes) reports two masks with
11+
// the same value but different ACE tails as unequal.
12+
func TestAccessControlMask_Unmarshal_RawBytesFourBytes(t *testing.T) {
13+
// 0x000f01ff followed by trailing bytes that belong to the SID / app data.
14+
a := AccessControlMask{}
15+
if _, err := a.Unmarshal([]byte{0xff, 0x01, 0x0f, 0x00, 0xaa, 0xbb, 0xcc, 0xdd}); err != nil {
16+
t.Fatalf("Unmarshal error = %v", err)
17+
}
18+
b := AccessControlMask{}
19+
if _, err := b.Unmarshal([]byte{0xff, 0x01, 0x0f, 0x00, 0x11, 0x22}); err != nil {
20+
t.Fatalf("Unmarshal error = %v", err)
21+
}
22+
23+
if len(a.RawBytes) != 4 {
24+
t.Fatalf("RawBytes length = %d, want 4", len(a.RawBytes))
25+
}
26+
if a.RawValue != 0x000f01ff || b.RawValue != 0x000f01ff {
27+
t.Fatalf("RawValue mismatch: 0x%08x / 0x%08x", a.RawValue, b.RawValue)
28+
}
29+
if !a.Equal(&b) {
30+
t.Fatalf("masks with identical value 0x%08x but different ACE tails compare unequal (RawBytes %x vs %x)",
31+
a.RawValue, a.RawBytes, b.RawBytes)
32+
}
33+
}

0 commit comments

Comments
 (0)