danger.go 1.6 KB

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