feat(core): trim strings to specific bytes' limit
What changed, and why it matters
This commit adds a new helper function that shortens text strings so they do not exceed a specified byte size. It is a routine feature addition with no obvious security bug, and there is no disclosed security issue tied to it.
No security action required. Treat as normal feature code; future callers should validate that max_bytes is sensible and that truncation does not alter security-critical semantics.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch introduces trim_str(s: str, max_bytes: int) in core/src/trezor/strings.py, which iterates over Unicode characters, measures each character’s UTF-8 byte length, and returns the longest prefix whose total byte size is <= max_bytes. Unit tests cover ASCII and multi-byte (➀➁➂) cases. No callers are added in this commit, and no security relevance is stated.
Changed components
core/src/trezor/strings.pycore/tests/test_trezor.strings.pyInspect captured patch +34 / −0
diff --git a/core/src/trezor/strings.py b/core/src/trezor/strings.py
index 4d880096c..f9823a36d 100644
--- a/core/src/trezor/strings.py
+++ b/core/src/trezor/strings.py
@@ -153,3 +153,16 @@ def format_autolock_duration(auto_lock_ms: int) -> str:
auto_lock_label = TR.plurals__lock_after_x_seconds
return format_plural("{count} {plural}", auto_lock_num, auto_lock_label)
+
+
+def trim_str(s: str, max_bytes: int) -> str:
+ """
+ Trim a string, so the result's byte size will be less or equal to `max_bytes`.
+ """
+ assert max_bytes >= 0
+ for i, char in enumerate(s):
+ char_size = len(char.encode())
+ if max_bytes < char_size:
+ return s[:i]
+ max_bytes -= char_size
+ return s
diff --git a/core/tests/test_trezor.strings.py b/core/tests/test_trezor.strings.py
index 721d491be..69d6ab15e 100644
--- a/core/tests/test_trezor.strings.py
+++ b/core/tests/test_trezor.strings.py
@@ -222,6 +222,27 @@ class TestStrings(unittest.TestCase):
strings.format_timestamp(1616057224)
+ def test_trim_str(self):
+ # test ASCII
+ self.assertEqual(strings.trim_str("123", 4), "123")
+ self.assertEqual(strings.trim_str("123", 3), "123")
+ self.assertEqual(strings.trim_str("123", 2), "12")
+ self.assertEqual(strings.trim_str("123", 1), "1")
+ self.assertEqual(strings.trim_str("123", 0), "")
+
+ # test non-ASCII
+ self.assertEqual(strings.trim_str("➀➁➂", 10), "➀➁➂")
+ self.assertEqual(strings.trim_str("➀➁➂", 9), "➀➁➂")
+ self.assertEqual(strings.trim_str("➀➁➂", 8), "➀➁")
+ self.assertEqual(strings.trim_str("➀➁➂", 7), "➀➁")
+ self.assertEqual(strings.trim_str("➀➁➂", 6), "➀➁")
+ self.assertEqual(strings.trim_str("➀➁➂", 5), "➀")
+ self.assertEqual(strings.trim_str("➀➁➂", 4), "➀")
+ self.assertEqual(strings.trim_str("➀➁➂", 3), "➀")
+ self.assertEqual(strings.trim_str("➀➁➂", 2), "")
+ self.assertEqual(strings.trim_str("➀➁➂", 1), "")
+ self.assertEqual(strings.trim_str("➀➁➂", 0), "")
+
if __name__ == "__main__":
unittest.main()
Why this scored 12/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.