diff --git a/pipeline/doif/do_if_test.go b/pipeline/doif/do_if_test.go index 9e59d2ef2..d6858181b 100644 --- a/pipeline/doif/do_if_test.go +++ b/pipeline/doif/do_if_test.go @@ -1079,7 +1079,10 @@ const userInfoRawJSON = ` { "name": "jack", "age": 120, - "hobbies": ["football", "diving"] + "hobbies": ["football", "diving"], + "obj": { + "a": "b" + } }` func dryJSON(rawJSON string) string { diff --git a/pipeline/doif/len_cmp_op.go b/pipeline/doif/len_cmp_op.go index c3ad043c2..f21f14022 100644 --- a/pipeline/doif/len_cmp_op.go +++ b/pipeline/doif/len_cmp_op.go @@ -129,6 +129,43 @@ func (n *lenCmpOpNode) Type() NodeType { return NodeLengthCmpOp } +func getNodeFieldsBytesSize(node *insaneJSON.Node) int { + size := 0 + fields := node.AsFields() + for _, elemNode := range fields { + // field node is a field name and it is always a string enclosed with double quotes + size += len(elemNode.AsString()) + 2 + 1 // quotes enclosing field name and colon between key and value + + elemNodeVal := elemNode.AsFieldValue() + size += getNodeBytesSize(elemNodeVal) + } + size += len(fields) - 1 // commas between object fields + return size +} + +func getNodeBytesSize(node *insaneJSON.Node) int { + if node == nil { + return 0 + } + size := 0 + switch { + case node.IsArray(): + nodeArr := node.AsArray() + for _, elemNode := range nodeArr { + size += getNodeBytesSize(elemNode) + } + size += len(nodeArr) - 1 + 2 // commas between elements and square brackets enclosing array + case node.IsObject(): + size += getNodeFieldsBytesSize(node) + 2 // curly brackets enclosing object + default: + size += len(node.AsString()) + if node.IsString() { + size += 2 // quotes enclosing string + } + } + return size +} + func (n *lenCmpOpNode) Check(eventRoot *insaneJSON.Root) bool { value := 0 @@ -140,7 +177,7 @@ func (n *lenCmpOpNode) Check(eventRoot *insaneJSON.Root) bool { } if node.IsObject() || node.IsArray() { - value = len(node.EncodeToByte()) + value = getNodeBytesSize(node) } else { value = len(node.AsString()) }