mirror of
https://github.com/wader/fq.git
synced 2024-11-23 00:57:15 +03:00
decode: change PosLoopDetector to use generics
This commit is contained in:
parent
3232f9cc15
commit
93f2aa5d73
@ -301,7 +301,7 @@ const (
|
||||
)
|
||||
|
||||
func makeDecodeRecord() func(d *decode.D) {
|
||||
var pld apple.PosLoopDetector
|
||||
var pld apple.PosLoopDetector[int64]
|
||||
|
||||
var decodeRecord func(d *decode.D)
|
||||
decodeRecord = func(d *decode.D) {
|
||||
|
@ -197,7 +197,7 @@ func (pl *plist) decodeReference(d *decode.D, idx uint64) bool {
|
||||
}
|
||||
pl.consumed[idx] = true
|
||||
|
||||
defer pl.pld.PushAndPop(int64(idx), func() { d.Fatalf("infinite recursion detected") })()
|
||||
defer pl.pld.PushAndPop(idx, func() { d.Fatalf("infinite recursion detected") })()
|
||||
|
||||
itemOffset := pl.o[idx]
|
||||
if itemOffset >= pl.t.offsetTableStart {
|
||||
@ -224,7 +224,7 @@ type plist struct {
|
||||
t trailer
|
||||
o []uint64
|
||||
consumed map[uint64]bool
|
||||
pld apple.PosLoopDetector
|
||||
pld apple.PosLoopDetector[uint64]
|
||||
}
|
||||
|
||||
func bplistDecode(d *decode.D, _ any) any {
|
||||
|
@ -1,12 +1,16 @@
|
||||
package apple
|
||||
|
||||
import (
|
||||
"golang.org/x/exp/constraints"
|
||||
)
|
||||
|
||||
// PosLoopDetector is used for detecting loops when writing decoders, and can
|
||||
// short-circuit infinite recursion that can cause stack overflows.
|
||||
type PosLoopDetector []int64
|
||||
type PosLoopDetector[T constraints.Integer] []T
|
||||
|
||||
// Push adds the current offset to the stack and executes the supplied
|
||||
// detection function
|
||||
func (pld *PosLoopDetector) Push(offset int64, detect func()) {
|
||||
func (pld *PosLoopDetector[T]) Push(offset T, detect func()) {
|
||||
for _, o := range *pld {
|
||||
if offset == o {
|
||||
detect()
|
||||
@ -16,14 +20,14 @@ func (pld *PosLoopDetector) Push(offset int64, detect func()) {
|
||||
}
|
||||
|
||||
// Pop removes the most recently added offset from the stack.
|
||||
func (pld *PosLoopDetector) Pop() {
|
||||
func (pld *PosLoopDetector[T]) Pop() {
|
||||
*pld = (*pld)[:len(*pld)-1]
|
||||
}
|
||||
|
||||
// PushAndPop adds the current offset to the stack, executes the supplied
|
||||
// detection function, and returns the Pop method. A good usage of this is to
|
||||
// pair this method call with a defer statement.
|
||||
func (pld *PosLoopDetector) PushAndPop(i int64, detect func()) func() {
|
||||
func (pld *PosLoopDetector[T]) PushAndPop(i T, detect func()) func() {
|
||||
pld.Push(i, detect)
|
||||
return pld.Pop
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user