gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

danger.go (1684B)


      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 }