diff --git a/condition/number_equal_to.go b/condition/number_equal_to.go index f5accfff..465ed04d 100644 --- a/condition/number_equal_to.go +++ b/condition/number_equal_to.go @@ -39,13 +39,22 @@ func (insp *numberEqualTo) Condition(ctx context.Context, msg *message.Message) return insp.match(f, compare), nil } + + val := msg.GetValue(insp.conf.Object.SourceKey) + + // for gjson's GetValue, if the path is empty string (indicating source key or target key is not present), + // the Result.Exists() will return false + // If source or target key is present but value cannot be found, always return false + if !val.Exists() { + return false, nil + } + target := msg.GetValue(insp.conf.Object.TargetKey) if target.Exists() { compare = target.Float() } - v := msg.GetValue(insp.conf.Object.SourceKey) - return insp.match(v.Float(), compare), nil + return insp.match(val.Float(), compare), nil } func (c *numberEqualTo) match(f float64, t float64) bool { diff --git a/condition/number_equal_to_test.go b/condition/number_equal_to_test.go index 91f264b0..3813baca 100644 --- a/condition/number_equal_to_test.go +++ b/condition/number_equal_to_test.go @@ -134,6 +134,70 @@ var numberEqualToTests = []struct { []byte(`{"foo": 100, "bar": 200}`), false, }, + { + "fail", + config.Config{ + Settings: map[string]interface{}{ + "object": map[string]interface{}{ + "source_key": "baz", + }, + "value": 0, + }, + }, + []byte(`{"foo": 100, "bar": 200}`), + false, + }, + { + "fail", + config.Config{ + Settings: map[string]interface{}{ + "object": map[string]interface{}{ + "source_key": "baz", + "target_key": "bar", + }, + }, + }, + []byte(`{"foo": 100, "bar": 200}`), + false, + }, + { + "fail", + config.Config{ + Settings: map[string]interface{}{ + "object": map[string]interface{}{ + "target_key": "abc", + }, + }, + }, + []byte(`100`), + false, + }, + { + "fail", + config.Config{ + Settings: map[string]interface{}{ + "object": map[string]interface{}{ + "source_key": "foo", + "target_key": "baz", + }, + }, + }, + []byte(`{"foo": 100, "bar": 200}`), + false, + }, + { + "fail", + config.Config{ + Settings: map[string]interface{}{ + "object": map[string]interface{}{ + "source_key": "baz", + "target_key": "abc", + }, + }, + }, + []byte(`{"foo": 100, "bar": 200}`), + false, + }, } func TestNumberEqualTo(t *testing.T) { diff --git a/condition/string_equal_to.go b/condition/string_equal_to.go index 562ee614..7aa89eb3 100644 --- a/condition/string_equal_to.go +++ b/condition/string_equal_to.go @@ -40,14 +40,21 @@ func (insp *stringEqualTo) Condition(ctx context.Context, msg *message.Message) return bytes.Equal(msg.Data(), compare), nil } - target := msg.GetValue(insp.conf.Object.TargetKey) + val := msg.GetValue(insp.conf.Object.SourceKey) + // for gjson's GetValue, if the path is empty string (indicating source key or target key is not present), + // the Result.Exists() will return false + // If source or target key is present but value cannot be found, always return false + if !val.Exists() { + return false, nil + } + + target := msg.GetValue(insp.conf.Object.TargetKey) if target.Exists() { compare = target.Bytes() } - value := msg.GetValue(insp.conf.Object.SourceKey) - return bytes.Equal(value.Bytes(), compare), nil + return bytes.Equal(val.Bytes(), compare), nil } func (c *stringEqualTo) String() string { diff --git a/condition/string_equal_to_test.go b/condition/string_equal_to_test.go index 33785ca3..e6f004b6 100644 --- a/condition/string_equal_to_test.go +++ b/condition/string_equal_to_test.go @@ -73,6 +73,70 @@ var stringEqualToTests = []struct { []byte(`{"foo":"abc", "bar":"def"}`), false, }, + { + "fail", + config.Config{ + Settings: map[string]interface{}{ + "object": map[string]interface{}{ + "source_key": "foo", + }, + "value": "abc", + }, + }, + []byte(`{"bar": "abc", "baz": "0"}`), + false, + }, + { + "fail", + config.Config{ + Settings: map[string]interface{}{ + "object": map[string]interface{}{ + "source_key": "foo", + }, + "value": "", + }, + }, + []byte(`{"bar": "abc", "baz": "0"}`), + false, + }, + { + "fail", + config.Config{ + Settings: map[string]interface{}{ + "object": map[string]interface{}{ + "source_key": "foo", + "target_key": "baz", + }, + }, + }, + []byte(`{"bar": "abc", "baz": "0"}`), + false, + }, + { + "fail", + config.Config{ + Settings: map[string]interface{}{ + "object": map[string]interface{}{ + "target_key": "foo", + }, + }, + }, + []byte(`{"bar": "abc", "baz": "0"}`), + false, + }, + { + "fail", + config.Config{ + Settings: map[string]interface{}{ + "object": map[string]interface{}{ + "source_key": "bar", + "target_key": "foo", + }, + }, + }, + []byte(`{"bar": "abc", "baz": "0"}`), + false, + }, } func TestStringEqualTo(t *testing.T) {