|
1 package danger |
|
2 |
|
3 import ( |
|
4 "fmt" |
|
5 "reflect" |
|
6 "unsafe" |
|
7 ) |
|
8 |
|
9 const maxInt = uintptr(int(^uint(0) >> 1)) |
|
10 |
|
11 func SubsliceOffset(data []byte, subslice []byte) int { |
|
12 datap := (*reflect.SliceHeader)(unsafe.Pointer(&data)) |
|
13 hlp := (*reflect.SliceHeader)(unsafe.Pointer(&subslice)) |
|
14 |
|
15 if hlp.Data < datap.Data { |
|
16 panic(fmt.Errorf("subslice address (%d) is before data address (%d)", hlp.Data, datap.Data)) |
|
17 } |
|
18 offset := hlp.Data - datap.Data |
|
19 |
|
20 if offset > maxInt { |
|
21 panic(fmt.Errorf("slice offset larger than int (%d)", offset)) |
|
22 } |
|
23 |
|
24 intoffset := int(offset) |
|
25 |
|
26 if intoffset > datap.Len { |
|
27 panic(fmt.Errorf("slice offset (%d) is farther than data length (%d)", intoffset, datap.Len)) |
|
28 } |
|
29 |
|
30 if intoffset+hlp.Len > datap.Len { |
|
31 panic(fmt.Errorf("slice ends (%d+%d) is farther than data length (%d)", intoffset, hlp.Len, datap.Len)) |
|
32 } |
|
33 |
|
34 return intoffset |
|
35 } |
|
36 |
|
37 func BytesRange(start []byte, end []byte) []byte { |
|
38 if start == nil || end == nil { |
|
39 panic("cannot call BytesRange with nil") |
|
40 } |
|
41 startp := (*reflect.SliceHeader)(unsafe.Pointer(&start)) |
|
42 endp := (*reflect.SliceHeader)(unsafe.Pointer(&end)) |
|
43 |
|
44 if startp.Data > endp.Data { |
|
45 panic(fmt.Errorf("start pointer address (%d) is after end pointer address (%d)", startp.Data, endp.Data)) |
|
46 } |
|
47 |
|
48 l := startp.Len |
|
49 endLen := int(endp.Data-startp.Data) + endp.Len |
|
50 if endLen > l { |
|
51 l = endLen |
|
52 } |
|
53 |
|
54 if l > startp.Cap { |
|
55 panic(fmt.Errorf("range length is larger than capacity")) |
|
56 } |
|
57 |
|
58 return start[:l] |
|
59 } |
|
60 |
|
61 func Stride(ptr unsafe.Pointer, size uintptr, offset int) unsafe.Pointer { |
|
62 // TODO: replace with unsafe.Add when Go 1.17 is released |
|
63 // https://github.com/golang/go/issues/40481 |
|
64 return unsafe.Pointer(uintptr(ptr) + uintptr(int(size)*offset)) |
|
65 } |