Bug: trim_to truncates delimiters and can panic on empty cutsets

Open Beginner friendly
#1,018 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
88/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
go
Domain
tooling

Research direction

Start with cfg/substitution/trim_to_filter.go and the existing TestFilterApply harness. Reproduce the right- and all-mode multi-byte cases and the empty-delimiter case, then verify the filter preserves the complete delimiter and leaves input unchanged for an empty delimiter. Done when the regression tests pass without the reported panic.

Written by the indexing model from the issue text.

Description

bug

Describe the bug

The modify plugin's trim_to filter keeps only the first byte of the matched delimiter when trimming from the right, including all mode. Multi-byte delimiters are truncated, and a Unicode delimiter can be cut in the middle of a UTF-8 sequence.

An empty delimiter can cause a slice-bounds panic when the input slice has no spare capacity. With spare capacity, the filter can instead include an extra byte from the backing array.

To Reproduce

  1. On upstream commit 5379bc2005906fde3aa0a05f6bf574dcd7111404, run this program from the repository's module:
package main

import (
    "fmt"

    "github.com/ozontech/file.d/cfg/substitution"
    "go.uber.org/zap"
)

func main() {
    for _, tc := range []struct{ delimiter, input string }{
        {"END", "first END second END trailing"},
        {"界", "hello界 trailing"},
        {"", "message"},
    } {
        expr := fmt.Sprintf("${field|trim_to(\"right\",%q)}", tc.delimiter)
        ops, err := substitution.ParseSubstitution(expr, nil, zap.NewNop())
        if err != nil {
            panic(err)
        }
        src := make([]byte, len(tc.input))
        copy(src, tc.input)
        fmt.Printf("%q\n", ops[0].Filters[0].Apply(src, src))
    }
}
  1. Observe "first END second E", then "hello\xe7", followed by panic: runtime error: slice bounds out of range [:8] with capacity 7.

The same right-hand truncation occurs in all mode.

Expected behavior

Preserve the complete matched delimiter: "first END second END" and "hello界". Treat an empty delimiter as leaving the input unchanged, consistently with left trimming.

Additional context

Version: upstream master at 5379bc2005906fde3aa0a05f6bf574dcd7111404.
Platform: macOS arm64, Go 1.27.0.

In cfg/substitution/trim_to_filter.go, bytes.LastIndex returns the beginning of the final match, but the slice ends at idx+1. Using idx+len(f.cutset) preserves the whole delimiter and also handles the empty-delimiter case.

I have reproduced the failures in the existing TestFilterApply harness and prepared a focused fix with regression tests.

Dominant language
Go
Stars
504
Forks
263
Avg merge
5d 21h
Merged PRs (30d)
2

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from ozontech/file.d

All issues in ozontech/file.d

Similar issues

More Go issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.