about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorRen Kararou <[email protected]>2023-11-28 16:55:05 -0600
committerRen Kararou <[email protected]>2023-11-28 16:55:05 -0600
commitc7de1c312c66ce7216f3fddff02daeac657790f9 (patch)
tree7ffcac302ff3a5e0858db896c3fa872af19b7097
parent6a8f7dce846fabbf71881d9f2beba5504133730d (diff)
downloadk2spice-mei/echo.tar.gz
k2spice-mei/echo.tar.bz2
k2spice-mei/echo.zip
out of bounds error during \0nnn checks mei/echo
-rw-r--r--usr/src/mei/echo/src/echo.rs104
1 files changed, 50 insertions, 54 deletions
diff --git a/usr/src/mei/echo/src/echo.rs b/usr/src/mei/echo/src/echo.rs
index ad5eee9..6522788 100644
--- a/usr/src/mei/echo/src/echo.rs
+++ b/usr/src/mei/echo/src/echo.rs
@@ -27,64 +27,60 @@
 
 use std::env;
 
-fn main() {
-    let print: String = env::args().skip(1).collect::<Vec<String>>().join(" ");
-    // This does not currently mimic functionality of illumos echo
-    if print.is_empty() {
-        println!("");
-    } else {
-        println!("{print}");
+fn escape(escstr: String) -> String {
+    let escmap = vec![
+        ("\\\\", "\\"),
+        //("\\a", "\a"),
+        //("\\b", "\b"),
+        //("\\f", "\f"),
+        ("\\n", "\n"),
+        ("\\r", "\r"),
+        ("\\t", "\t"),
+        //("\\v", "\v"),
+    ];
+    let mut im = escstr.to_owned();
+    for esc in escmap {
+        im = str::replace(im.as_str(), esc.0, esc.1);
     }
-
-    // This mimics illumos echo functionality, or it should
-    /*
-    let mut esc: bool = false;
-    let mut is_num: bool = false;
-    let mut oct: String = "".to_string();
-    let mut oc: u8 = 0;
-
-    for c in print.chars() {
-        if !esc {
-            if c == '\\' {
-                esc = true;
-            } else {
-                print!("{c}");
+    // TODO: Handle octal esc \0n where n is 1-, 2-, or 3-digit octal number
+    let mut octstr: String = String::new();
+    let escb = im.as_bytes();
+    let mut i = 0;
+    while i < escb.len() {
+        if !(i + 1 >= escb.len()) {
+            let mut xe = i + 1;
+            if !(escb[i] == b'\\' && escb[xe] == b'0') {
+                octstr += &im[i..i + 1];
+                i += 1;
+                continue;
             }
-        } else {
-            match c {
-                // "unknown character escape" wtf rust these are valid.
-                //'a' => print!("\a"),
-                //'b' => print!("\b"),
-                //'c' => print!("\c"),
-                //'f' => print!("\f"),
-                'n' => print!("\n"),
-                'r' => print!("\r"),
-                't' => print!("\t"),
-                //'v' => print!("\v"),
-                '\\' => print!("\\"),
-                '0' => is_num = true,
-                _ => print!("\\{c}"),
+            i = xe + 1;
+            while char::from(escb[xe + 1]).is_digit(8) && i - xe < 3 {
+                xe += 1;
             }
-            if is_num {
-                if oc < 3 {
-                    oct.push(c);
-                    oc = oc + 1;
-                }
-                if oc == 2 {
-                    match u32::from_str_radix(oct.as_str(), 8) {
-                        Ok(chr) => print!("{}", chr),
-                        Err(_) => print!("\\0{}", oct),
-                    }
-                    is_num = false;
-                    oct = "".to_string();
-                    oc = 0;
-                    esc = false;
-                }
+            let c: u8 = if let Ok(x) = u8::from_str_radix(&im[i..xe], 8) {
+                x
             } else {
-                esc = false;
-            }
+                continue;
+            };
+            octstr += char::from(c).to_string().as_str();
+            i = xe;
         }
     }
-    print!("\n");
-    */
+    // TODO: find and handle \c
+    let mut retitr = octstr.split("\\c").peekable();
+    if let Some(retstr) = retitr.next() {
+        if retitr.peek().is_none() {
+            (retstr.to_owned() + "\n").clone()
+        } else {
+            retstr.to_string().clone()
+        }
+    } else {
+        String::from("\n")
+    }
+}
+
+fn main() {
+    let print: String = env::args().skip(1).collect::<Vec<String>>().join(" ");
+    print!("{}", escape(print));
 }