aboutsummaryrefslogtreecommitdiffstats
path: root/prog/encoding.go
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2020-09-20 13:22:28 +0200
committerDmitry Vyukov <dvyukov@google.com>2020-09-20 15:12:12 +0200
commit5620c9c4dbbce2d97e92839afd66ba7c32f4bf0c (patch)
tree9092d7d77c21e31ef4771ff329e6dbf757e41bbd /prog/encoding.go
parent43f95803e9c3f5a951867d363b6f48ffb3c82d94 (diff)
prog: allow arbitrary long lines in serialized programs
We use bufio.Scanner and it has mandatory limit on line length. The file system tests (sys/linux/test/syz_mount_image_*) has very long lines (megabytes). Remove the restriction on line length.
Diffstat (limited to 'prog/encoding.go')
-rw-r--r--prog/encoding.go44
1 files changed, 23 insertions, 21 deletions
diff --git a/prog/encoding.go b/prog/encoding.go
index 77c2356b8..140636865 100644
--- a/prog/encoding.go
+++ b/prog/encoding.go
@@ -4,7 +4,6 @@
package prog
import (
- "bufio"
"bytes"
"encoding/hex"
"fmt"
@@ -721,7 +720,6 @@ func (p *parser) eatExcessive(stopAtComma bool, what string, args ...interface{}
const (
encodingAddrBase = 0x7f0000000000
- maxLineLen = 1 << 20
)
func (target *Target) serializeAddr(arg *PointerArg) string {
@@ -979,11 +977,11 @@ type parser struct {
autos map[Arg]bool
comment string
- r *bufio.Scanner
- s string
- i int
- l int
- e error
+ data []byte
+ s string
+ i int
+ l int
+ e error
}
func newParser(target *Target, data []byte, strict bool) *parser {
@@ -991,9 +989,8 @@ func newParser(target *Target, data []byte, strict bool) *parser {
target: target,
strict: strict,
vars: make(map[string]*ResultArg),
- r: bufio.NewScanner(bytes.NewReader(data)),
+ data: data,
}
- p.r.Buffer(nil, maxLineLen)
return p
}
@@ -1032,14 +1029,17 @@ func (p *parser) fixupAutos(prog *Prog) {
}
func (p *parser) Scan() bool {
- if p.e != nil {
+ if p.e != nil || len(p.data) == 0 {
return false
}
- if !p.r.Scan() {
- p.e = p.r.Err()
- return false
+ nextLine := bytes.IndexByte(p.data, '\n')
+ if nextLine != -1 {
+ p.s = string(p.data[:nextLine])
+ p.data = p.data[nextLine+1:]
+ } else {
+ p.s = string(p.data)
+ p.data = nil
}
- p.s = p.r.Text()
p.i = 0
p.l++
return true
@@ -1138,10 +1138,15 @@ func (p *parser) strictFailf(msg string, args ...interface{}) {
func CallSet(data []byte) (map[string]struct{}, int, error) {
calls := make(map[string]struct{})
ncalls := 0
- s := bufio.NewScanner(bytes.NewReader(data))
- s.Buffer(nil, maxLineLen)
- for s.Scan() {
- ln := s.Bytes()
+ for len(data) > 0 {
+ ln := data
+ nextLine := bytes.IndexByte(data, '\n')
+ if nextLine != -1 {
+ ln = data[:nextLine]
+ data = data[nextLine+1:]
+ } else {
+ data = nil
+ }
if len(ln) == 0 || ln[0] == '#' {
continue
}
@@ -1163,9 +1168,6 @@ func CallSet(data []byte) (map[string]struct{}, int, error) {
calls[string(call)] = struct{}{}
ncalls++
}
- if err := s.Err(); err != nil {
- return nil, 0, err
- }
if len(calls) == 0 {
return nil, 0, fmt.Errorf("program does not contain any calls")
}