aboutsummaryrefslogtreecommitdiffstats
path: root/pkg
diff options
context:
space:
mode:
authorJiao, Joey <quic_jiangenj@quicinc.com>2024-11-06 13:41:21 +0800
committerAleksandr Nogikh <nogikh@google.com>2024-11-13 11:16:59 +0000
commit4dfba277487a7023ab9f5783302da4a9b5e9bef8 (patch)
tree72c5a0b86f7e38922230b4421ebe50c5654e5cdc /pkg
parentbb3f84250514d5990939e57b5d1ff8badc566033 (diff)
all: support || operator in syzlang if condition
ex. f3 field has logic or operator in if condition: conditional_struct { mask int32 f1 field1 (if[value[mask] & FIELD_FLAG1]) f2 int64 (if[value[mask] & FIELD_FLAG2]) f3 int64 (if[value[mask] == FIELD_FLAG1 || value[mask] == FIELD_FLAG2]) } [packed]
Diffstat (limited to 'pkg')
-rw-r--r--pkg/ast/ast.go1
-rw-r--r--pkg/ast/format.go2
-rw-r--r--pkg/ast/parser.go11
-rw-r--r--pkg/ast/scanner.go4
-rw-r--r--pkg/ast/testdata/all.txt3
-rw-r--r--pkg/ast/testdata/errors.txt8
-rw-r--r--pkg/compiler/gen.go1
-rw-r--r--pkg/fuzzer/job_test.go2
8 files changed, 26 insertions, 6 deletions
diff --git a/pkg/ast/ast.go b/pkg/ast/ast.go
index 2726af602..bd2d97c23 100644
--- a/pkg/ast/ast.go
+++ b/pkg/ast/ast.go
@@ -258,6 +258,7 @@ const (
OperatorCompareEq = iota + 1
OperatorCompareNeq
OperatorBinaryAnd
+ OperatorOr
)
type BinaryExpression struct {
diff --git a/pkg/ast/format.go b/pkg/ast/format.go
index 4b54466c2..b16a62531 100644
--- a/pkg/ast/format.go
+++ b/pkg/ast/format.go
@@ -273,6 +273,8 @@ func fmtExpressionRec(sb *strings.Builder, t *Type, parentPrio int) {
sb.WriteString("!=")
case OperatorBinaryAnd:
sb.WriteString("&")
+ case OperatorOr:
+ sb.WriteString("||")
default:
panic(fmt.Sprintf("unknown operator %q", be.Operator))
}
diff --git a/pkg/ast/parser.go b/pkg/ast/parser.go
index 839d8e6d6..273a4889f 100644
--- a/pkg/ast/parser.go
+++ b/pkg/ast/parser.go
@@ -438,17 +438,18 @@ type operatorInfo struct {
prio int
}
-const maxOperatorPrio = 1
+const maxOperatorPrio = 2
// The highest priority is 0.
var binaryOperators = map[token]operatorInfo{
- tokCmpEq: {op: OperatorCompareEq, prio: 0},
- tokCmpNeq: {op: OperatorCompareNeq, prio: 0},
- tokBinAnd: {op: OperatorBinaryAnd, prio: 1},
+ tokOr: {op: OperatorOr, prio: 0},
+ tokCmpEq: {op: OperatorCompareEq, prio: 1},
+ tokCmpNeq: {op: OperatorCompareNeq, prio: 1},
+ tokBinAnd: {op: OperatorBinaryAnd, prio: 2},
}
// Parse out a single Type object, which can either be a plain object or an expression.
-// For now, only expressions constructed via '(', ')', "==", "!=", '&' are supported.
+// For now, only expressions constructed via '(', ')', "==", "!=", '&', '||' are supported.
func (p *parser) parseType() *Type {
return p.parseBinaryExpr(0)
}
diff --git a/pkg/ast/scanner.go b/pkg/ast/scanner.go
index aaabb5bcc..9a5becf1c 100644
--- a/pkg/ast/scanner.go
+++ b/pkg/ast/scanner.go
@@ -39,6 +39,7 @@ const (
tokBinAnd
tokCmpEq
tokCmpNeq
+ tokOr
tokEOF
)
@@ -73,6 +74,7 @@ var tok2str = [...]string{
tokEOF: "EOF",
tokCmpEq: "==",
tokCmpNeq: "!=",
+ tokOr: "||",
}
func init() {
@@ -192,6 +194,8 @@ func (s *scanner) Scan() (tok token, lit string, pos Pos) {
tok = tokCmpEq
case s.tryConsume("!="):
tok = tokCmpNeq
+ case s.tryConsume("||"):
+ tok = tokOr
default:
tok = punctuation[s.ch]
if tok == tokIllegal {
diff --git a/pkg/ast/testdata/all.txt b/pkg/ast/testdata/all.txt
index a274b3eff..d5587c027 100644
--- a/pkg/ast/testdata/all.txt
+++ b/pkg/ast/testdata/all.txt
@@ -14,6 +14,7 @@ expressions {
f1 int8 (if[X & Y == Z])
f2 int8 (if[X & Y & Z == value[X] & A])
f3 int8 (if[X & (A == B) & Z != C])
+ f5 int8 (if[value[X] == A || value[X] == B])
}
intflags = 1, 2, 3, 4
@@ -29,4 +30,6 @@ condFields {
f2 int16 (out, if[val[mask] & SOME_CONST == OTHER_CONST])
f3 int16 (out, if[val[mask] & SOME_CONST & OTHER_CONST == val[mask] & CONST_X])
f4 int16 (out, if[val[flags] & SOME_CONST])
+ f5 int16 (out, if[val[flags] == SOME_CONST || val[flags] == OTHER_CONST])
+ f6 int16 (out, if[val[flags] == SOME_CONST || val[flags] & OTHER_CONST])
}
diff --git a/pkg/ast/testdata/errors.txt b/pkg/ast/testdata/errors.txt
index b3d9e7f52..a8a4aa197 100644
--- a/pkg/ast/testdata/errors.txt
+++ b/pkg/ast/testdata/errors.txt
@@ -75,6 +75,14 @@ sCondFieldsError2 {
f5 int16 (out, if[val[mask] & == val[mask]]) ### unexpected ==, expecting int, identifier, string
} ### unexpected '}', expecting comment, define, include, resource, identifier
+sCondFieldsError3 {
+ f6 int16 (out, if[val[mask] == SOME_CONST] || [val[mask]]) ### unexpected '[', expecting int, identifier, string
+} ### unexpected '}', expecting comment, define, include, resource, identifier
+
+sCondFieldsError4 {
+ f7 int16 (out, if[val[mask] == SOME_CONST || val[mask] ==]) ### unexpected ']', expecting int, identifier, string
+} ### unexpected '}', expecting comment, define, include, resource, identifier
+
type mybool8 int8
type net_port proc[1, 2, int16be]
type mybool16 ### unexpected '\n', expecting '[', identifier
diff --git a/pkg/compiler/gen.go b/pkg/compiler/gen.go
index 891cd1644..104c2899b 100644
--- a/pkg/compiler/gen.go
+++ b/pkg/compiler/gen.go
@@ -608,6 +608,7 @@ var binaryOperatorMap = map[ast.Operator]prog.BinaryOperator{
ast.OperatorCompareEq: prog.OperatorCompareEq,
ast.OperatorCompareNeq: prog.OperatorCompareNeq,
ast.OperatorBinaryAnd: prog.OperatorBinaryAnd,
+ ast.OperatorOr: prog.OperatorOr,
}
func (comp *compiler) genExpression(t *ast.Type) prog.Expression {
diff --git a/pkg/fuzzer/job_test.go b/pkg/fuzzer/job_test.go
index d7c07b9d1..edb68fdc9 100644
--- a/pkg/fuzzer/job_test.go
+++ b/pkg/fuzzer/job_test.go
@@ -77,7 +77,7 @@ func TestDeflake(t *testing.T) {
target, err := prog.GetTarget(targets.TestOS, targets.TestArch64Fuzz)
assert.NoError(t, err)
- const anyTestProg = `syz_compare(&AUTO="00000000", 0x4, &AUTO=@conditional={0x0, @void, @void}, AUTO)`
+ const anyTestProg = `syz_compare(&AUTO="00000000", 0x4, &AUTO=@conditional={0x0, @void, @void, @void}, AUTO)`
prog, err := target.Deserialize([]byte(anyTestProg), prog.NonStrict)
assert.NoError(t, err)