mirror of
https://github.com/lukaszraczylo/filepuff-mcp.git
synced 2026-10-18 05:48:00 +00:00
fix(util): rune-safe truncation across formatters
firstLineOf (query) and truncateString (edit) sliced strings at a raw byte offset, splitting a multibyte UTF-8 character into invalid bytes in LLM-facing output (ast_query compact format and edit not-found errors are hot paths). Extract the rune-boundary backoff already used by search's truncateLine into util.RuneBoundary and route all three sites through it. Adds table-driven tests for the primitive and a multibyte case for firstLineOf.
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
package util
|
||||
|
||||
import "unicode/utf8"
|
||||
|
||||
// RuneBoundary returns the largest index j <= i such that s[:j] is valid UTF-8
|
||||
// (j falls on a rune start, never inside a multibyte sequence). i is clamped to
|
||||
// [0, len(s)]. Callers slicing s[:i] for truncation should slice s[:RuneBoundary(s, i)]
|
||||
// instead so a multibyte character is never split into an invalid encoding.
|
||||
func RuneBoundary(s string, i int) int {
|
||||
if i <= 0 {
|
||||
return 0
|
||||
}
|
||||
if i >= len(s) {
|
||||
return len(s)
|
||||
}
|
||||
for i > 0 && !utf8.RuneStart(s[i]) {
|
||||
i--
|
||||
}
|
||||
return i
|
||||
}
|
||||
Reference in New Issue
Block a user