diff options
| author | Jiao, Joey <quic_jiangenj@quicinc.com> | 2024-11-06 13:41:21 +0800 |
|---|---|---|
| committer | Aleksandr Nogikh <nogikh@google.com> | 2024-11-13 11:16:59 +0000 |
| commit | 4dfba277487a7023ab9f5783302da4a9b5e9bef8 (patch) | |
| tree | 72c5a0b86f7e38922230b4421ebe50c5654e5cdc /prog | |
| parent | bb3f84250514d5990939e57b5d1ff8badc566033 (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.go | 5 | ||||
| -rw-r--r-- | prog/expr_test.go | 23 | ||||
| -rw-r--r-- | prog/types.go | 1 |
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 { |
