diff --git a/CHANGELOG.md b/CHANGELOG.md index 8550a2aa2639..06a4f2c19203 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - `datadogexporter`: Replace HistogramMode defined as string with enum. - `pkg/translator/signalfx`: Change signalfx translator to expose To/From translator structs. (#9740) +- `transformprocessor`: Add parameter validation to `truncate_all` and `limit` functions. The `limit` parameter can no longer be negative. (#9783) ### 🚩 Deprecations 🚩 diff --git a/processor/transformprocessor/README.md b/processor/transformprocessor/README.md index 4ee779495705..cd2cf1051128 100644 --- a/processor/transformprocessor/README.md +++ b/processor/transformprocessor/README.md @@ -22,9 +22,9 @@ it references an unset map value, there will be no action. - `keep_keys(target, string...)` - `target` is a path expression to a map type field. The map will be mutated to only contain the fields specified by the list of strings. e.g., `keep_keys(attributes, "http.method")`, `keep_keys(attributes, "http.method", "http.route")` -- `truncate_all(target, limit)` - `target` is a path expression to a map type field. `limit` is an integer. The map will be mutated such that all string values are truncated to the limit. e.g., `truncate_all(attributes, 100)` will truncate all string values in `attributes` such that all string values have less than or equal to 100 characters. Non-string values are ignored. +- `truncate_all(target, limit)` - `target` is a path expression to a map type field. `limit` is a non-negative integer. The map will be mutated such that all string values are truncated to the limit. e.g., `truncate_all(attributes, 100)` will truncate all string values in `attributes` such that all string values have less than or equal to 100 characters. Non-string values are ignored. -- `limit(target, limit)` - `target` is a path expression to a map type field. `limit` is an integer. The map will be mutated such that the number of items does not exceed the limit. e.g., `limit(attributes, 100)` will limit `attributes` to no more than 100 items. Which items are dropped is random. +- `limit(target, limit)` - `target` is a path expression to a map type field. `limit` is a non-negative integer. The map will be mutated such that the number of items does not exceed the limit. e.g., `limit(attributes, 100)` will limit `attributes` to no more than 100 items. Which items are dropped is random. Supported where operations: - `==` - matches telemetry where the values are equal to each other diff --git a/processor/transformprocessor/internal/common/functions.go b/processor/transformprocessor/internal/common/functions.go index 77f87f1674d1..8b51064872d3 100644 --- a/processor/transformprocessor/internal/common/functions.go +++ b/processor/transformprocessor/internal/common/functions.go @@ -73,6 +73,9 @@ func keepKeys(target GetSetter, keys []string) (ExprFunc, error) { } func truncateAll(target GetSetter, limit int64) (ExprFunc, error) { + if limit < 0 { + return nil, fmt.Errorf("invalid limit for truncate_all function, %d cannot be negative", limit) + } return func(ctx TransformContext) interface{} { if limit < 0 { return nil @@ -104,6 +107,9 @@ func truncateAll(target GetSetter, limit int64) (ExprFunc, error) { } func limit(target GetSetter, limit int64) (ExprFunc, error) { + if limit < 0 { + return nil, fmt.Errorf("invalid limit for limit function, %d cannot be negative", limit) + } return func(ctx TransformContext) interface{} { val := target.Get(ctx) if val == nil { diff --git a/processor/transformprocessor/internal/common/functions_test.go b/processor/transformprocessor/internal/common/functions_test.go index a916e61770e3..0ef99122f98b 100644 --- a/processor/transformprocessor/internal/common/functions_test.go +++ b/processor/transformprocessor/internal/common/functions_test.go @@ -94,7 +94,7 @@ func Test_newFunctionCall_invalid(t *testing.T) { }, }, { - name: "not matching slice type", + name: "keep_keys not matching slice type", inv: Invocation{ Function: "keep_keys", Arguments: []Value{ @@ -114,7 +114,7 @@ func Test_newFunctionCall_invalid(t *testing.T) { }, }, { - name: "not int", + name: "truncate_all not int", inv: Invocation{ Function: "truncate_all", Arguments: []Value{ @@ -134,7 +134,27 @@ func Test_newFunctionCall_invalid(t *testing.T) { }, }, { - name: "not int", + name: "truncate_all negative limit", + inv: Invocation{ + Function: "truncate_all", + Arguments: []Value{ + { + Path: &Path{ + Fields: []Field{ + { + Name: "name", + }, + }, + }, + }, + { + Int: intp(-1), + }, + }, + }, + }, + { + name: "limit not int", inv: Invocation{ Function: "limit", Arguments: []Value{ @@ -153,6 +173,26 @@ func Test_newFunctionCall_invalid(t *testing.T) { }, }, }, + { + name: "limit negative limit", + inv: Invocation{ + Function: "limit", + Arguments: []Value{ + { + Path: &Path{ + Fields: []Field{ + { + Name: "name", + }, + }, + }, + }, + { + Int: intp(-1), + }, + }, + }, + }, { name: "function call returns error", inv: Invocation{ diff --git a/processor/transformprocessor/internal/traces/functions_test.go b/processor/transformprocessor/internal/traces/functions_test.go index c2be448d23d0..9a376eadf1ab 100644 --- a/processor/transformprocessor/internal/traces/functions_test.go +++ b/processor/transformprocessor/internal/traces/functions_test.go @@ -316,38 +316,6 @@ func Test_newFunctionCall(t *testing.T) { attrs.CopyTo(span.Attributes()) }, }, - { - name: "truncate resource negative", - inv: common.Invocation{ - Function: "truncate_all", - Arguments: []common.Value{ - { - Path: &common.Path{ - Fields: []common.Field{ - { - Name: "resource", - }, - { - Name: "attributes", - }, - }, - }, - }, - { - Int: intp(-1), - }, - }, - }, - want: func(span ptrace.Span) { - input.CopyTo(span) - span.Attributes().Clear() - attrs := pcommon.NewMap() - attrs.InsertString("test", "hello world") - attrs.InsertInt("test2", 3) - attrs.InsertBool("test3", true) - attrs.CopyTo(span.Attributes()) - }, - }, { name: "limit attributes", inv: common.Invocation{