Skip to content
Snippets Groups Projects
Commit 99286faf authored by Sjoerd Simons's avatar Sjoerd Simons Committed by Apertis package maintainers
Browse files

Fix tr hack to not leak


Rather then leaking a boxed value to keep the upstream code working wrap
the unescape string into a cow. This causes a bunch of allocations
to happen if the upper/lower character classes are used but at least
there are no allocations leaked.

Signed-off-by: default avatarSjoerd Simons <sjoerd@collabora.com>
parent 05dd754f
No related branches found
No related tags found
1 merge request!1Allow using rust-coreutils as a coreutils replacement
......@@ -21,33 +21,59 @@ Signed-off-by: Arnaud Ferraris <arnaud.ferraris@collabora.com>
Forwarded: not-needed
Bug: https://github.com/uutils/coreutils/issues/556
---
src/uu/tr/src/expand.rs | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
src/uu/tr/src/expand.rs | 26 +++++++++++++++++++++++---
1 file changed, 23 insertions(+), 3 deletions(-)
diff --git a/src/uu/tr/src/expand.rs b/src/uu/tr/src/expand.rs
index e71cf26..9be9df8 100644
index e71cf26..c65a77b 100644
--- a/src/uu/tr/src/expand.rs
+++ b/src/uu/tr/src/expand.rs
@@ -61,6 +61,18 @@ struct Unescape<'a> {
string: &'a str,
@@ -9,6 +9,7 @@
// spell-checker:ignore (ToDO) allocs slen unesc
+use std::borrow::Cow;
use std::char::from_u32;
use std::cmp::min;
use std::iter::Peekable;
@@ -58,7 +59,22 @@ fn parse_sequence(s: &str) -> (char, usize) {
}
struct Unescape<'a> {
- string: &'a str,
+ string: Cow<'a, str>,
+}
+
+impl<'a> Unescape<'a> {
+ #[inline]
+ pub fn new(s: &'a str) -> Unescape<'a> {
+ Unescape {
+ string: Box::leak(
+ s.replace("[:upper:]", "A-Z").as_str()
+ .replace("[:lower:]", "a-z").into_boxed_str()
+ ),
+ }
+ }
+}
+ let string = if s.contains("[:upper:]") || s.contains("[:lower:]") {
+ s.replace("[:upper:]", "A-Z")
+ .replace("[:lower:]", "a-z")
+ .into()
+ } else {
+ s.into()
+ };
+
+ Unescape { string }
+ }
}
impl<'a> Iterator for Unescape<'a> {
type Item = char;
@@ -88,7 +104,11 @@ impl<'a> Iterator for Unescape<'a> {
c => (Some(c), c.len_utf8()), // not an escape char
};
@@ -139,7 +151,7 @@ impl<'a> ExpandSet<'a> {
- self.string = &self.string[idx..]; // advance the pointer to the next char
+ // advance the pointer to the next char
+ self.string = match &mut self.string {
+ Cow::Borrowed(s) => s[idx..].into(),
+ Cow::Owned(ref mut s) => s.split_off(idx).into(),
+ };
ret
}
}
@@ -139,7 +159,7 @@ impl<'a> ExpandSet<'a> {
pub fn new(s: &'a str) -> ExpandSet<'a> {
ExpandSet {
range: 0..=0,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment