diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2024-04-16 08:18:47 +0200 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2024-04-16 14:20:36 +0000 |
| commit | 0e05124fa8b99e403da71f699481bf4096fa6997 (patch) | |
| tree | a809ff7ad8be208dc5d4a2ce03103af644a9708d /prog/decodeexec.go | |
| parent | f8f619e676a9c568c10ac690b37f8b414cd0d52b (diff) | |
prog: include number of calls into exec encoding
Prepend total number of calls to the exec encoding.
This will allow pkg/ipc to better parse executor response
without full parsing of the encoded program.
Diffstat (limited to 'prog/decodeexec.go')
| -rw-r--r-- | prog/decodeexec.go | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/prog/decodeexec.go b/prog/decodeexec.go index 2356e051b..81c70cb2b 100644 --- a/prog/decodeexec.go +++ b/prog/decodeexec.go @@ -72,6 +72,17 @@ type ExecCsumChunk struct { Size uint64 } +func ExecCallCount(exec []byte) (int, error) { + v, n := binary.Varint(exec) + if n <= 0 { + return 0, fmt.Errorf("not enough data in the buffer") + } + if v > MaxCalls { + return 0, fmt.Errorf("too many calls (%v)", v) + } + return int(v), nil +} + func (target *Target) DeserializeExec(exec []byte, stats map[string]int) (ExecProg, error) { dec := &execDecoder{target: target, data: exec, stats: stats} dec.parse() @@ -101,6 +112,7 @@ type execDecoder struct { } func (dec *execDecoder) parse() { + ncalls := dec.read("header") for dec.err == nil { switch instr := dec.read("instr/opcode"); instr { case execInstrCopyin: @@ -117,6 +129,9 @@ func (dec *execDecoder) parse() { }) case execInstrEOF: dec.commitCall() + if ncalls != uint64(len(dec.calls)) { + dec.err = fmt.Errorf("bad number of calls: %v/%v", ncalls, len(dec.calls)) + } return case execInstrSetProps: dec.commitCall() |
