aboutsummaryrefslogtreecommitdiffstats
path: root/prog
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 /prog
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 'prog')
-rw-r--r--prog/expr.go5
-rw-r--r--prog/expr_test.go23
-rw-r--r--prog/types.go1
3 files changed, 21 insertions, 8 deletions
diff --git a/prog/expr.go b/prog/expr.go
index e9446ab2c..87fb056a9 100644
--- a/prog/expr.go
+++ b/prog/expr.go
@@ -30,6 +30,11 @@ func (bo *BinaryExpression) Evaluate(finder ArgFinder) (uint64, bool) {
return 0, true
case OperatorBinaryAnd:
return left & right, true
+ case OperatorOr:
+ if left != 0 || right != 0 {
+ return 1, true
+ }
+ return 0, true
}
panic(fmt.Sprintf("unknown operator %q", bo.Operator))
}
diff --git a/prog/expr_test.go b/prog/expr_test.go
index 74818ea55..1558248f5 100644
--- a/prog/expr_test.go
+++ b/prog/expr_test.go
@@ -92,13 +92,20 @@ func TestEvaluateConditionalFields(t *testing.T) {
}{
{
good: []string{
- `test$conditional_struct(&AUTO={0x0, @void, @void})`,
- `test$conditional_struct(&AUTO={0x4, @void, @value=0x123})`,
- `test$conditional_struct(&AUTO={0x6, @value={AUTO}, @value=0x123})`,
+ `test$conditional_struct(&AUTO={0x0, @void, @void, @void})`,
+ `test$conditional_struct(&AUTO={0x2, @value={AUTO}, @void, @value=0x456})`,
+ `test$conditional_struct(&AUTO={0x4, @void, @value=0x123, @value=0x456})`,
+ `test$conditional_struct(&AUTO={0x6, @value={AUTO}, @value=0x123, @void})`,
},
bad: []string{
- `test$conditional_struct(&AUTO={0x0, @void, @value=0x123})`,
- `test$conditional_struct(&AUTO={0x0, @value={AUTO}, @value=0x123})`,
+ `test$conditional_struct(&AUTO={0x0, @void, @void, @value=0x123})`,
+ `test$conditional_struct(&AUTO={0x0, @value={AUTO}, @void, @value=0x123})`,
+ `test$conditional_struct(&AUTO={0x0, @void, @value=0x123, @void})`,
+ `test$conditional_struct(&AUTO={0x0, @void, @void, @value=0x123})`,
+ `test$conditional_struct(&AUTO={0x2, @value={AUTO}, @void, @void})`,
+ `test$conditional_struct(&AUTO={0x2, @value={AUTO}, @value=0x123, @void})`,
+ `test$conditional_struct(&AUTO={0x4, @void, @value=0x123, @void})`,
+ `test$conditional_struct(&AUTO={0x4, @void, @void, @value=0x123})`,
},
},
{
@@ -141,14 +148,14 @@ func TestConditionalMinimize(t *testing.T) {
output string
}{
{
- input: `test$conditional_struct(&AUTO={0x6, @value={AUTO}, @value=0x123})`,
+ input: `test$conditional_struct(&AUTO={0x6, @value={AUTO}, @value=0x123, @void})`,
pred: func(p *Prog, _ int) bool {
return len(p.Calls) == 1 && p.Calls[0].Meta.Name == `test$conditional_struct`
},
output: `test$conditional_struct(0x0)`,
},
{
- input: `test$conditional_struct(&(0x7f0000000040)={0x6, @value, @value=0x123})`,
+ input: `test$conditional_struct(&(0x7f0000000040)={0x6, @value, @value=0x123, @void})`,
pred: func(p *Prog, _ int) bool {
return bytes.Contains(p.Serialize(), []byte("0x123"))
},
@@ -236,7 +243,7 @@ func parseConditionalStructCall(t *testing.T, c *Call) (bool, bool) {
if !ok {
t.Fatalf("expected GroupArg: %v", va.Res)
}
- if len(ga.Inner) != 3 {
+ if len(ga.Inner) != 4 {
t.Fatalf("wrong number of struct args %v", len(ga.Inner))
}
mask := ga.Inner[0].(*ConstArg).Val
diff --git a/prog/types.go b/prog/types.go
index 0d6fa1596..5f2360946 100644
--- a/prog/types.go
+++ b/prog/types.go
@@ -110,6 +110,7 @@ const (
OperatorCompareEq BinaryOperator = iota
OperatorCompareNeq
OperatorBinaryAnd
+ OperatorOr
)
type BinaryExpression struct {