fix: misuse of reflect.SliceHeader (#19875)
Currently, unsafeBytesToString function violates the 6th rule of unsafe pointer usage. That is, reflect.SliceHeader/String header should never be used as plain struct. This misuse can make to silent memory corruption, which can be difficult to track down when problem occurred. Instead, use the more (right) idiom to convert slice of byte to string without heap allocation. goos: linux goarch: amd64 cpu: Intel(R) Core(TM) i7-8665U CPU @ 1.90GHz BenchmarkInvalid-8 1000000000 0.497 ns/op 0 B/op 0 allocs/op BenchmarkValid-8 1000000000 0.239 ns/op 0 B/op 0 allocs/op PASS ok command-line-arguments 0.815spull/19939/head
parent
ee390ddfd3
commit
51ff6f7b5c
9
id.go
9
id.go
|
@ -3,7 +3,6 @@ package influxdb
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"reflect"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
@ -83,13 +82,7 @@ func (i *ID) Decode(b []byte) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func unsafeBytesToString(in []byte) string {
|
func unsafeBytesToString(in []byte) string {
|
||||||
src := *(*reflect.SliceHeader)(unsafe.Pointer(&in))
|
return *(*string)(unsafe.Pointer(&in))
|
||||||
dst := reflect.StringHeader{
|
|
||||||
Data: src.Data,
|
|
||||||
Len: src.Len,
|
|
||||||
}
|
|
||||||
s := *(*string)(unsafe.Pointer(&dst))
|
|
||||||
return s
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DecodeFromString parses s as a hex-encoded string.
|
// DecodeFromString parses s as a hex-encoded string.
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package models // import "github.com/influxdata/influxdb/models"
|
package models // import "github.com/influxdata/influxdb/models"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"reflect"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
@ -30,15 +29,6 @@ func parseBoolBytes(b []byte) (bool, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// unsafeBytesToString converts a []byte to a string without a heap allocation.
|
// unsafeBytesToString converts a []byte to a string without a heap allocation.
|
||||||
//
|
|
||||||
// It is unsafe, and is intended to prepare input to short-lived functions
|
|
||||||
// that require strings.
|
|
||||||
func unsafeBytesToString(in []byte) string {
|
func unsafeBytesToString(in []byte) string {
|
||||||
src := *(*reflect.SliceHeader)(unsafe.Pointer(&in))
|
return *(*string)(unsafe.Pointer(&in))
|
||||||
dst := reflect.StringHeader{
|
|
||||||
Data: src.Data,
|
|
||||||
Len: src.Len,
|
|
||||||
}
|
|
||||||
s := *(*string)(unsafe.Pointer(&dst))
|
|
||||||
return s
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue