Skip to content

Commit 570f619

Browse files
authored
[pkg/ottl] Fix empty string matching (#37071)
1 parent 5c38c98 commit 570f619

File tree

5 files changed

+99
-2
lines changed

5 files changed

+99
-2
lines changed

.chloggen/ottl-empty-string-fix.yaml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Use this changelog template to create an entry for release notes.
2+
3+
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
4+
change_type: bug_fix
5+
6+
# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver)
7+
component: pkg/ottl
8+
9+
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
10+
note: Fix bug with `replace_all_matches` and `replace_all_patterns` that caused non-string values to be changed to empty string when matching against empty string.
11+
12+
# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists.
13+
issues: [37071]
14+
15+
# (Optional) One or more lines of additional information to render under the primary note.
16+
# These lines will be padded with 2 spaces and then inserted directly into the document.
17+
# Use pipe (|) for multiline entries.
18+
subtext:
19+
20+
# If your change doesn't affect end users or the exported elements of any package,
21+
# you should instead start your pull request title with [chore] or use the "Skip Changelog" label.
22+
# Optional: The change log or logs in which this entry should be included.
23+
# e.g. '[user]' or '[user, api]'
24+
# Include 'user' if the change is relevant to end users.
25+
# Include 'api' if there is a change to a library API.
26+
# Default: '[user]'
27+
change_logs: []

pkg/ottl/ottlfuncs/func_replace_all_matches.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ func replaceAllMatches[K any](target ottl.PMapGetter[K], pattern string, replace
7575
}
7676
}
7777
val.Range(func(_ string, value pcommon.Value) bool {
78-
if glob.Match(value.Str()) {
78+
if value.Type() == pcommon.ValueTypeStr && glob.Match(value.Str()) {
7979
value.SetStr(replacementVal)
8080
}
8181
return true

pkg/ottl/ottlfuncs/func_replace_all_matches_test.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ func Test_replaceAllMatches(t *testing.T) {
2020
input.PutStr("test", "hello world")
2121
input.PutStr("test2", "hello")
2222
input.PutStr("test3", "goodbye")
23+
input.PutStr("test4", "")
24+
input.PutInt("test5", 123)
2325

2426
ottlValue := ottl.StandardFunctionGetter[pcommon.Map]{
2527
FCtx: ottl.FunctionContext{
@@ -64,6 +66,8 @@ func Test_replaceAllMatches(t *testing.T) {
6466
expectedMap.PutStr("test", "prefix=hash(hello {universe})")
6567
expectedMap.PutStr("test2", "prefix=hash(hello {universe})")
6668
expectedMap.PutStr("test3", "goodbye")
69+
expectedMap.PutStr("test4", "")
70+
expectedMap.PutInt("test5", 123)
6771
},
6872
},
6973
{
@@ -81,6 +85,8 @@ func Test_replaceAllMatches(t *testing.T) {
8185
expectedMap.PutStr("test", "hello {universe}")
8286
expectedMap.PutStr("test2", "hello {universe}")
8387
expectedMap.PutStr("test3", "goodbye")
88+
expectedMap.PutStr("test4", "")
89+
expectedMap.PutInt("test5", 123)
8490
},
8591
},
8692
{
@@ -98,6 +104,27 @@ func Test_replaceAllMatches(t *testing.T) {
98104
expectedMap.PutStr("test", "hello world")
99105
expectedMap.PutStr("test2", "hello")
100106
expectedMap.PutStr("test3", "goodbye")
107+
expectedMap.PutStr("test4", "")
108+
expectedMap.PutInt("test5", 123)
109+
},
110+
},
111+
{
112+
name: "replace empty string",
113+
target: target,
114+
pattern: "",
115+
replacement: ottl.StandardStringGetter[pcommon.Map]{
116+
Getter: func(context.Context, pcommon.Map) (any, error) {
117+
return "empty_string_replacement", nil
118+
},
119+
},
120+
function: ottl.Optional[ottl.FunctionGetter[pcommon.Map]]{},
121+
replacementFormat: ottl.Optional[ottl.StringGetter[pcommon.Map]]{},
122+
want: func(expectedMap pcommon.Map) {
123+
expectedMap.PutStr("test", "hello world")
124+
expectedMap.PutStr("test2", "hello")
125+
expectedMap.PutStr("test3", "goodbye")
126+
expectedMap.PutStr("test4", "empty_string_replacement")
127+
expectedMap.PutInt("test5", 123)
101128
},
102129
},
103130
}

pkg/ottl/ottlfuncs/func_replace_all_patterns.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ func replaceAllPatterns[K any](target ottl.PMapGetter[K], mode string, regexPatt
6565
val.Range(func(key string, originalValue pcommon.Value) bool {
6666
switch mode {
6767
case modeValue:
68-
if compiledPattern.MatchString(originalValue.Str()) {
68+
if originalValue.Type() == pcommon.ValueTypeStr && compiledPattern.MatchString(originalValue.Str()) {
6969
if !fn.IsEmpty() {
7070
updatedString, err := applyOptReplaceFunction(ctx, tCtx, compiledPattern, fn, originalValue.Str(), replacementVal, replacementFormat)
7171
if err != nil {

pkg/ottl/ottlfuncs/func_replace_all_patterns_test.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ func Test_replaceAllPatterns(t *testing.T) {
2323
input.PutInt("test4", 1234)
2424
input.PutDouble("test5", 1234)
2525
input.PutBool("test6", true)
26+
input.PutStr("test7", "")
2627

2728
ottlValue := ottl.StandardFunctionGetter[pcommon.Map]{
2829
FCtx: ottl.FunctionContext{
@@ -77,6 +78,7 @@ func Test_replaceAllPatterns(t *testing.T) {
7778
expectedMap.PutInt("test4", 1234)
7879
expectedMap.PutDouble("test5", 1234)
7980
expectedMap.PutBool("test6", true)
81+
expectedMap.PutStr("test7", "")
8082
},
8183
},
8284
{
@@ -97,6 +99,7 @@ func Test_replaceAllPatterns(t *testing.T) {
9799
expectedMap.PutInt("test4", 1234)
98100
expectedMap.PutDouble("test5", 1234)
99101
expectedMap.PutBool("test6", true)
102+
expectedMap.PutStr("test7", "")
100103
},
101104
},
102105
{
@@ -117,6 +120,7 @@ func Test_replaceAllPatterns(t *testing.T) {
117120
expectedMap.PutInt("test4", 1234)
118121
expectedMap.PutDouble("test5", 1234)
119122
expectedMap.PutBool("test6", true)
123+
expectedMap.PutStr("test7", "")
120124
},
121125
},
122126
{
@@ -137,6 +141,7 @@ func Test_replaceAllPatterns(t *testing.T) {
137141
expectedMap.PutInt("test4", 1234)
138142
expectedMap.PutDouble("test5", 1234)
139143
expectedMap.PutBool("test6", true)
144+
expectedMap.PutStr("test7", "")
140145
},
141146
},
142147
{
@@ -158,6 +163,7 @@ func Test_replaceAllPatterns(t *testing.T) {
158163
expectedMap.PutInt("test4", 1234)
159164
expectedMap.PutDouble("test5", 1234)
160165
expectedMap.PutBool("test6", true)
166+
expectedMap.PutStr("test7", "")
161167
},
162168
},
163169
{
@@ -196,6 +202,7 @@ func Test_replaceAllPatterns(t *testing.T) {
196202
expectedMap.PutInt("test4", 1234)
197203
expectedMap.PutDouble("test5", 1234)
198204
expectedMap.PutBool("test6", true)
205+
expectedMap.PutStr("test7", "")
199206
},
200207
},
201208
{
@@ -217,6 +224,7 @@ func Test_replaceAllPatterns(t *testing.T) {
217224
expectedMap.PutInt("test4", 1234)
218225
expectedMap.PutDouble("test5", 1234)
219226
expectedMap.PutBool("test6", true)
227+
expectedMap.PutStr("test7", "")
220228
},
221229
},
222230
{
@@ -238,6 +246,7 @@ func Test_replaceAllPatterns(t *testing.T) {
238246
expectedMap.PutInt("test4", 1234)
239247
expectedMap.PutDouble("test5", 1234)
240248
expectedMap.PutBool("test6", true)
249+
expectedMap.PutStr("test7", "")
241250
},
242251
},
243252
{
@@ -258,6 +267,7 @@ func Test_replaceAllPatterns(t *testing.T) {
258267
expectedMap.PutInt("test4", 1234)
259268
expectedMap.PutDouble("test5", 1234)
260269
expectedMap.PutBool("test6", true)
270+
expectedMap.PutStr("test7", "")
261271
},
262272
},
263273
{
@@ -278,6 +288,7 @@ func Test_replaceAllPatterns(t *testing.T) {
278288
expectedMap.PutInt("test4", 1234)
279289
expectedMap.PutDouble("test5", 1234)
280290
expectedMap.PutBool("test6", true)
291+
expectedMap.PutStr("test7", "")
281292
},
282293
},
283294
{
@@ -298,6 +309,7 @@ func Test_replaceAllPatterns(t *testing.T) {
298309
expectedMap.PutInt("test4", 1234)
299310
expectedMap.PutDouble("test5", 1234)
300311
expectedMap.PutBool("test6", true)
312+
expectedMap.PutStr("test7", "")
301313
},
302314
},
303315
{
@@ -318,6 +330,7 @@ func Test_replaceAllPatterns(t *testing.T) {
318330
expectedMap.PutInt("test4", 1234)
319331
expectedMap.PutDouble("test5", 1234)
320332
expectedMap.PutBool("test6", true)
333+
expectedMap.PutStr("test7", "")
321334
},
322335
},
323336
{
@@ -338,6 +351,7 @@ func Test_replaceAllPatterns(t *testing.T) {
338351
expectedMap.PutInt("test4", 1234)
339352
expectedMap.PutDouble("test5", 1234)
340353
expectedMap.PutBool("test6", true)
354+
expectedMap.PutStr("test7", "")
341355
},
342356
},
343357
{
@@ -360,6 +374,7 @@ func Test_replaceAllPatterns(t *testing.T) {
360374
expectedMap.PutInt("test4", 1234)
361375
expectedMap.PutDouble("test5", 1234)
362376
expectedMap.PutBool("test6", true)
377+
expectedMap.PutStr("test7", "")
363378
},
364379
},
365380
{
@@ -382,6 +397,7 @@ func Test_replaceAllPatterns(t *testing.T) {
382397
expectedMap.PutInt("test4", 1234)
383398
expectedMap.PutDouble("test5", 1234)
384399
expectedMap.PutBool("test6", true)
400+
expectedMap.PutStr("test7", "")
385401
},
386402
},
387403
{
@@ -404,6 +420,7 @@ func Test_replaceAllPatterns(t *testing.T) {
404420
expectedMap.PutInt("test.4", 1234)
405421
expectedMap.PutDouble("test.5", 1234)
406422
expectedMap.PutBool("test.6", true)
423+
expectedMap.PutStr("test.7", "")
407424
},
408425
},
409426
{
@@ -426,6 +443,7 @@ func Test_replaceAllPatterns(t *testing.T) {
426443
expectedMap.PutInt("test4", 1234)
427444
expectedMap.PutDouble("test5", 1234)
428445
expectedMap.PutBool("test6", true)
446+
expectedMap.PutStr("test7", "")
429447
},
430448
},
431449
{
@@ -447,6 +465,7 @@ func Test_replaceAllPatterns(t *testing.T) {
447465
expectedMap.PutInt("test-4", 1234)
448466
expectedMap.PutDouble("test-5", 1234)
449467
expectedMap.PutBool("test-6", true)
468+
expectedMap.PutStr("test-7", "")
450469
},
451470
},
452471
{
@@ -469,6 +488,30 @@ func Test_replaceAllPatterns(t *testing.T) {
469488
expectedMap.PutInt("test4", 1234)
470489
expectedMap.PutDouble("test5", 1234)
471490
expectedMap.PutBool("test6", true)
491+
expectedMap.PutStr("test7", "")
492+
},
493+
},
494+
{
495+
name: "replacement for empty string",
496+
target: target,
497+
mode: modeValue,
498+
pattern: `^$`,
499+
replacement: ottl.StandardStringGetter[pcommon.Map]{
500+
Getter: func(context.Context, pcommon.Map) (any, error) {
501+
return "empty_string_replacement", nil
502+
},
503+
},
504+
replacementFormat: ottl.Optional[ottl.StringGetter[pcommon.Map]]{},
505+
function: ottl.Optional[ottl.FunctionGetter[pcommon.Map]]{},
506+
want: func(expectedMap pcommon.Map) {
507+
expectedMap.Clear()
508+
expectedMap.PutStr("test", "hello world")
509+
expectedMap.PutStr("test2", "hello")
510+
expectedMap.PutStr("test3", "goodbye world1 and world2")
511+
expectedMap.PutInt("test4", 1234)
512+
expectedMap.PutDouble("test5", 1234)
513+
expectedMap.PutBool("test6", true)
514+
expectedMap.PutStr("test7", "empty_string_replacement")
472515
},
473516
},
474517
}

0 commit comments

Comments
 (0)