src/runtime: fix nil map dereference
Operations on nil maps are accepted and shouldn't panic. The base hashmapGet/hashmapDelete handled nil-maps correctly, but the hashmapBinary versions could segfault accessing the nil map while trying to hash the key. Fixes #2341
Этот коммит содержится в:
родитель
cfe6b9765f
коммит
d6c892fe7b
3 изменённых файлов: 13 добавлений и 0 удалений
|
@ -307,16 +307,24 @@ func hashmapNext(m *hashmap, it *hashmapIterator, key, value unsafe.Pointer) boo
|
||||||
// Hashmap with plain binary data keys (not containing strings etc.).
|
// Hashmap with plain binary data keys (not containing strings etc.).
|
||||||
|
|
||||||
func hashmapBinarySet(m *hashmap, key, value unsafe.Pointer) {
|
func hashmapBinarySet(m *hashmap, key, value unsafe.Pointer) {
|
||||||
|
// TODO: detect nil map here and throw a better panic message?
|
||||||
hash := hashmapHash(key, uintptr(m.keySize))
|
hash := hashmapHash(key, uintptr(m.keySize))
|
||||||
hashmapSet(m, key, value, hash, memequal)
|
hashmapSet(m, key, value, hash, memequal)
|
||||||
}
|
}
|
||||||
|
|
||||||
func hashmapBinaryGet(m *hashmap, key, value unsafe.Pointer, valueSize uintptr) bool {
|
func hashmapBinaryGet(m *hashmap, key, value unsafe.Pointer, valueSize uintptr) bool {
|
||||||
|
if m == nil {
|
||||||
|
memzero(value, uintptr(valueSize))
|
||||||
|
return false
|
||||||
|
}
|
||||||
hash := hashmapHash(key, uintptr(m.keySize))
|
hash := hashmapHash(key, uintptr(m.keySize))
|
||||||
return hashmapGet(m, key, value, valueSize, hash, memequal)
|
return hashmapGet(m, key, value, valueSize, hash, memequal)
|
||||||
}
|
}
|
||||||
|
|
||||||
func hashmapBinaryDelete(m *hashmap, key unsafe.Pointer) {
|
func hashmapBinaryDelete(m *hashmap, key unsafe.Pointer) {
|
||||||
|
if m == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
hash := hashmapHash(key, uintptr(m.keySize))
|
hash := hashmapHash(key, uintptr(m.keySize))
|
||||||
hashmapDelete(m, key, hash, memequal)
|
hashmapDelete(m, key, hash, memequal)
|
||||||
}
|
}
|
||||||
|
|
4
testdata/map.go
предоставленный
4
testdata/map.go
предоставленный
|
@ -57,6 +57,10 @@ func main() {
|
||||||
println(k) // unreachable
|
println(k) // unreachable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var nilbinmap map[uint16]int
|
||||||
|
delete(nilbinmap, 4)
|
||||||
|
println("nilbinmap:", nilbinmap[5])
|
||||||
|
|
||||||
arrKey := ArrayKey([4]byte{4, 3, 2, 1})
|
arrKey := ArrayKey([4]byte{4, 3, 2, 1})
|
||||||
println(testMapArrayKey[arrKey])
|
println(testMapArrayKey[arrKey])
|
||||||
testMapArrayKey[arrKey] = 5555
|
testMapArrayKey[arrKey] = 5555
|
||||||
|
|
1
testdata/map.txt
предоставленный
1
testdata/map.txt
предоставленный
|
@ -53,6 +53,7 @@ true false 0
|
||||||
nilmap: 0
|
nilmap: 0
|
||||||
4
|
4
|
||||||
42
|
42
|
||||||
|
nilbinmap: 0
|
||||||
4321
|
4321
|
||||||
5555
|
5555
|
||||||
itfMap[3]: 0
|
itfMap[3]: 0
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче