fix: truncate in runes rather than bytes
truncate measures and slices by byte, so a string cut inside a multi-byte rune both mis-measures the fixed-width column it is being laid out against and emits a broken character. Everything it is handed is server-supplied — alert names, label values, annotations — and none of that is guaranteed to be ASCII. Identical behaviour for the ASCII case.
This commit is contained in:
@@ -808,12 +808,19 @@ func renderBarWidth(count, maxCount, maxWidth int) int {
|
|||||||
return w
|
return w
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// truncate shortens s to max terminal cells, marking the cut with an ellipsis.
|
||||||
|
//
|
||||||
|
// Counted in runes rather than bytes: these strings are laid out against
|
||||||
|
// fixed-width columns, and a byte cut through a multi-byte rune would both
|
||||||
|
// mis-measure the column and emit a broken character. Server-supplied text —
|
||||||
|
// labels, annotations, delivery errors — is not guaranteed to be ASCII.
|
||||||
func truncate(s string, max int) string {
|
func truncate(s string, max int) string {
|
||||||
if max < 1 {
|
if max < 1 {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
if len(s) <= max {
|
r := []rune(s)
|
||||||
|
if len(r) <= max {
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
return s[:max-1] + "…"
|
return string(r[:max-1]) + "…"
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user