From 378711bd83d2b4687b79513a1798e1cceea4e49f Mon Sep 17 00:00:00 2001 From: rishadbaniya Date: Thu, 23 May 2024 09:53:41 +0545 Subject: [PATCH 01/12] fix, refactor: remove uuencode crate fron uuencode.rs, implementing the encoding and fixing the permission symbolss, base64 output --- xform/src/uuencode.rs | 127 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 113 insertions(+), 14 deletions(-) diff --git a/xform/src/uuencode.rs b/xform/src/uuencode.rs index 6816cc054..4911de0c6 100644 --- a/xform/src/uuencode.rs +++ b/xform/src/uuencode.rs @@ -9,15 +9,18 @@ extern crate clap; extern crate plib; -extern crate uuencode; use base64::prelude::*; use clap::Parser; use gettextrs::{bind_textdomain_codeset, textdomain}; use plib::PROJECT_NAME; +use std::fs::{File, Permissions}; use std::io::{self, Read, Write}; +use std::os::unix::fs::PermissionsExt; use std::path::PathBuf; +const PERMISSION_MASK: u32 = 0o7; + /// uuencode - encode a binary file #[derive(Parser, Debug)] #[command(author, version, about, long_about)] @@ -33,26 +36,122 @@ struct Args { decode_path: Option, } -fn encode_file(args: &Args) -> io::Result<()> { - let mut file = plib::io::input_stream_opt(&args.file)?; +enum EncodingType { + Historical, + Base64, +} + +impl EncodingType { + fn get_header(&self) -> String { + match *self { + EncodingType::Historical => "begin", + EncodingType::Base64 => "begin-base64", + } + .to_string() + } +} + +/// mentions the constants ncessary to extract out the permission +/// so we'll use bit masking by shifting 3 bits everytime to ge +fn get_permission_values(perm: Permissions) -> String { + let perm_mode = perm.mode(); - let mut buffer = Vec::new(); - file.read_to_end(&mut buffer)?; + let others_perm = perm_mode & PERMISSION_MASK; + let group_perm = (perm_mode >> 3) & PERMISSION_MASK; + let user_perm = (perm_mode >> 6) & PERMISSION_MASK; + + format!("{user_perm}{group_perm}{others_perm}") +} + +fn encode_base64_line(line: &[u8]) -> Vec { + let mut out = BASE64_STANDARD.encode(&line).as_bytes().to_vec(); + out.push(b'\n'); + out +} + +fn encode_historical_line(line: &[u8]) -> Vec { + let mut out = Vec::new(); + out.push(line.len() as u8 + 0x20); + // in every line we'll take a chunk of 3 bytes and encode it + for in_chunk in line.chunks(3) { + // there could be less than 3 bytes, we need to fill it up with the padding byte + let a = in_chunk[0]; + let b = *in_chunk.get(1).unwrap_or(&0); + let c = *in_chunk.get(2).unwrap_or(&0); + + // https://pubs.opengroup.org/onlinepubs/9699919799/utilities/uuencode.html directly mentions + // the algorithm below(to convert 3 byte to 4 bytes of historical encoding) + // + // btw "uuencode" specification mentions ANDING with 0x3F i.e six 1's + // but we already have shifted 8 bit by 1, so that's not necessary + let out_chunk = [ + 0x20 + (a >> 2), + 0x20 + ((a & 0x03) << 4) | (b >> 4) & 0x0F, + 0x20 + ((b & 0x0F) << 2) | ((c >> 6) & 0x03), + 0x20 + (c & 0x3F), + ]; + + out.extend_from_slice(&out_chunk); + } + out.push(b'\n'); + out +} +/// encodes and puts out on stdout +fn encode(args: &Args) -> io::Result<()> { let decode_path = match &args.decode_path { None => String::from("/dev/stdout"), Some(path) => String::from(path), }; - let output = { - if args.base64 { - BASE64_STANDARD.encode(&buffer[..]) - } else { - uuencode::uuencode(&decode_path, &buffer[..]) - } + let encoding_type = if args.base64 { + EncodingType::Base64 + } else { + EncodingType::Historical }; - io::stdout().write_all(output.as_bytes())?; + let mut buf: Vec = Vec::new(); + let mut out: Vec = Vec::new(); + + let header_init = encoding_type.get_header(); + + let file_p = args + .file + .as_ref() + .unwrap_or(&PathBuf::from("/dev/stdin")) + .clone(); + + if file_p == PathBuf::from("/dev/stdin") { + let header = format!("{header_init} 644 {decode_path}\n"); + io::stdout().write_all(header.as_bytes())?; + io::stdin().lock().read_to_end(&mut buf)?; + } else { + let mut file = File::open(&file_p)?; + let perm = get_permission_values(file.metadata()?.permissions()); + + let header = format!("{header_init} {perm} {decode_path}\n"); + out.extend_from_slice(header.as_bytes()); + file.read_to_end(&mut buf)?; + } + + match encoding_type { + EncodingType::Historical => { + for line in buf.chunks(45) { + out.extend(encode_historical_line(line)); + } + + out.push(b'\n'); + out.extend(b"end"); + } + EncodingType::Base64 => { + for line in buf.chunks(45) { + out.extend(encode_base64_line(line)); + } + out.extend(b"===="); + } + } + + io::stdout().write_all(out.as_slice())?; io::stdout().write_all(b"\n")?; Ok(()) @@ -60,7 +159,7 @@ fn encode_file(args: &Args) -> io::Result<()> { fn pathname_display(path: &Option) -> String { match path { - None => String::from("stdin"), + None => String::from("/dev/stdin"), Some(p) => p.display().to_string(), } } @@ -74,7 +173,7 @@ fn main() -> Result<(), Box> { let mut exit_code = 0; - if let Err(e) = encode_file(&args) { + if let Err(e) = encode(&args) { exit_code = 1; eprintln!("{:?}: {}", pathname_display(&args.file), e); } From ec59a8b725167274dddff153eeeb01eff6712123 Mon Sep 17 00:00:00 2001 From: rishadbaniya Date: Thu, 23 May 2024 10:42:58 +0545 Subject: [PATCH 02/12] fix: correct ending bytes --- xform/src/uuencode.rs | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/xform/src/uuencode.rs b/xform/src/uuencode.rs index 4911de0c6..64b1acf67 100644 --- a/xform/src/uuencode.rs +++ b/xform/src/uuencode.rs @@ -81,12 +81,9 @@ fn encode_historical_line(line: &[u8]) -> Vec { // https://pubs.opengroup.org/onlinepubs/9699919799/utilities/uuencode.html directly mentions // the algorithm below(to convert 3 byte to 4 bytes of historical encoding) - // - // btw "uuencode" specification mentions ANDING with 0x3F i.e six 1's - // but we already have shifted 8 bit by 1, so that's not necessary let out_chunk = [ - 0x20 + (a >> 2), - 0x20 + ((a & 0x03) << 4) | (b >> 4) & 0x0F, + 0x20 + (a >> 2) & 0x3F, + 0x20 + ((a & 0x03) << 4) | ((b >> 4) & 0x0F), 0x20 + ((b & 0x0F) << 2) | ((c >> 6) & 0x03), 0x20 + (c & 0x3F), ]; @@ -114,7 +111,6 @@ fn encode(args: &Args) -> io::Result<()> { let mut out: Vec = Vec::new(); let header_init = encoding_type.get_header(); - let file_p = args .file .as_ref() @@ -140,8 +136,7 @@ fn encode(args: &Args) -> io::Result<()> { out.extend(encode_historical_line(line)); } - out.push(b'\n'); - out.extend(b"end"); + out.extend(b"`\nend"); } EncodingType::Base64 => { for line in buf.chunks(45) { From 4075efcb1f8f3fe3e4a005dfc63ad957976ed3bf Mon Sep 17 00:00:00 2001 From: rishadbaniya Date: Thu, 23 May 2024 21:59:50 +0545 Subject: [PATCH 03/12] refactor: make use of ASCII 96 value instead of 32 for safe transmission --- xform/src/uuencode.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/xform/src/uuencode.rs b/xform/src/uuencode.rs index 64b1acf67..4a6bf62ac 100644 --- a/xform/src/uuencode.rs +++ b/xform/src/uuencode.rs @@ -81,21 +81,26 @@ fn encode_historical_line(line: &[u8]) -> Vec { // https://pubs.opengroup.org/onlinepubs/9699919799/utilities/uuencode.html directly mentions // the algorithm below(to convert 3 byte to 4 bytes of historical encoding) - let out_chunk = [ + let mut out_chunk = [ 0x20 + (a >> 2) & 0x3F, 0x20 + ((a & 0x03) << 4) | ((b >> 4) & 0x0F), 0x20 + ((b & 0x0F) << 2) | ((c >> 6) & 0x03), 0x20 + (c & 0x3F), ]; + for i in out_chunk.iter_mut() { + if *i == 32 { + *i = 96 + } + } out.extend_from_slice(&out_chunk); } out.push(b'\n'); out } -/// encodes and puts out on stdout -fn encode(args: &Args) -> io::Result<()> { +/// encodes the file(it can be standard input too) and outputs on standard output +fn encode_file(args: &Args) -> io::Result<()> { let decode_path = match &args.decode_path { None => String::from("/dev/stdout"), Some(path) => String::from(path), @@ -160,7 +165,6 @@ fn pathname_display(path: &Option) -> String { } fn main() -> Result<(), Box> { - // parse command line arguments let args = Args::parse(); textdomain(PROJECT_NAME)?; @@ -168,7 +172,7 @@ fn main() -> Result<(), Box> { let mut exit_code = 0; - if let Err(e) = encode(&args) { + if let Err(e) = encode_file(&args) { exit_code = 1; eprintln!("{:?}: {}", pathname_display(&args.file), e); } From ff8783a0a9fb541e1dd63a2fd7f7e4220ad23fd6 Mon Sep 17 00:00:00 2001 From: rishadbaniya Date: Fri, 24 May 2024 23:52:51 +0545 Subject: [PATCH 04/12] fix: remove uudecode crate and implement uudecode with base64 --- Cargo.lock | 7 -- xform/Cargo.toml | 1 - xform/src/uudecode.rs | 157 +++++++++++++++++++++++++++++++++++------- 3 files changed, 131 insertions(+), 34 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 588201665..b3859ddc9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -835,7 +835,6 @@ dependencies = [ "clap", "gettext-rs", "plib", - "uuencode", ] [[package]] @@ -1128,12 +1127,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" -[[package]] -name = "uuencode" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce87414615a82bde6978712c15b79bf056d16827930ff779f1e40ed74c692ac0" - [[package]] name = "version_check" version = "0.9.4" diff --git a/xform/Cargo.toml b/xform/Cargo.toml index d86f5d951..01ce870d6 100644 --- a/xform/Cargo.toml +++ b/xform/Cargo.toml @@ -10,7 +10,6 @@ repository = "https://github.com/rustcoreutils/posixutils-rs.git" plib = { path = "../plib" } clap.workspace = true gettext-rs.workspace = true -uuencode = "0.1" base64 = "0.21" [[bin]] diff --git a/xform/src/uudecode.rs b/xform/src/uudecode.rs index 318c6ff7f..37ae587db 100644 --- a/xform/src/uudecode.rs +++ b/xform/src/uudecode.rs @@ -15,10 +15,17 @@ use base64::prelude::*; use clap::Parser; use gettextrs::{bind_textdomain_codeset, textdomain}; use plib::PROJECT_NAME; -use std::fs::OpenOptions; +use std::fs::{remove_file, File, OpenOptions, Permissions}; use std::io::{self, Error, ErrorKind, Read, Write}; +use std::os::unix::fs::PermissionsExt; use std::path::PathBuf; +macro_rules! reduce { + ($e : expr) => { + $e - 0x20 + }; +} + /// uudecode - decode a binary file #[derive(Parser, Debug)] #[command(author, version, about, long_about)] @@ -48,35 +55,133 @@ fn write_file(pathname: &PathBuf, bindata: &[u8]) -> io::Result<()> { } } +#[derive(Debug)] +enum DecodingType { + Historical, + + Base64, +} + +#[derive(Debug)] +struct Header { + dec_type: DecodingType, + + lower_perm_bits: u32, + + out: PathBuf, +} + +impl Header { + fn parse(line: &str) -> Self { + // split with spaces + let split: Vec<&str> = line.split(' ').collect(); + let dec_type = if split[0] == "begin" { + DecodingType::Historical + } else if split[0] == "base64-begin" { + DecodingType::Base64 + } else { + panic!("Invalid encoding type"); + }; + + let lower_perm_bits = u32::from_str_radix(split[1], 8).expect("Invalid permission value"); + let out = PathBuf::from(split[2]); + + Self { + dec_type, + lower_perm_bits, + out, + } + } +} + +fn decode_historical_line(line: &str) -> Vec { + let mut out = Vec::new(); + + for chunk in line.as_bytes().chunks(4) { + let chunk = chunk.to_vec(); + + let out_chunk = [ + reduce!(chunk[0]) << 2 | (reduce!(chunk[1])) >> 4, + reduce!(chunk[1]) << 4 | reduce!(chunk[2]) >> 2, + reduce!(chunk[2]) << 6 | reduce!(chunk[3]), + ]; + + out.extend_from_slice(&out_chunk); + } + + out +} + +fn decode_base64_line(line: &str) -> io::Result> { + BASE64_STANDARD + .decode(&line) + .map_err(|_| Error::from(io::ErrorKind::InvalidInput)) +} + fn decode_file(args: &Args) -> io::Result<()> { - let mut file = plib::io::input_stream_opt(&args.file)?; - - // read entire file into memory. - // ugly but necessary due to uudecode crate implementation. - let mut buffer = String::new(); - file.read_to_string(&mut buffer)?; - - // attempt base64 decode - let b64_res = BASE64_STANDARD.decode(buffer.as_bytes()); - match b64_res { - // fall through to uudecode format - Err(_e) => {} - - // decode succeeded. exit here. - Ok(bindata) => match &args.outfile { - None => return write_file(&PathBuf::from("bindata.out"), &bindata[..]), - Some(outfn) => return write_file(outfn, &bindata[..]), - }, + let mut buf: Vec = Vec::new(); + let mut out: Vec = Vec::new(); + + let file_p = args + .file + .as_ref() + .unwrap_or(&PathBuf::from("/dev/stdin")) + .clone(); + + if file_p == PathBuf::from("/dev/stdin") { + io::stdin().lock().read_to_end(&mut buf)?; + } else { + let mut file = File::open(&file_p)?; + file.read_to_end(&mut buf)?; } - // attempt to decode using uudecode format - match uuencode::uudecode(&buffer) { - None => return Err(Error::new(ErrorKind::Other, "invalid input data")), - Some((bindata, filename)) => match &args.outfile { - None => write_file(&PathBuf::from(filename), &bindata[..]), - Some(outfn) => write_file(outfn, &bindata[..]), - }, + let buf = String::from_utf8(buf).unwrap(); + let mut lines = buf.lines(); + let header = Header::parse(lines.next().expect("No header line")); + + match header.dec_type { + DecodingType::Historical => { + while let Some(line) = lines.next() { + let line = line.replace("`", " "); + if line.len() == 1 && line == " " { + let end_line = lines.next().expect("No end line"); + if end_line == "end" || end_line == "end\r" { + break; + } else { + panic!("Invalid ending") + } + } + + out.extend_from_slice(&decode_historical_line(&line[1..])); + } + } + DecodingType::Base64 => { + while let Some(line) = lines.next() { + if line == "====" || line == "====\n" { + break; + } + out.extend_from_slice(&decode_base64_line(line)?); + } + } } + + let out_file = args.file.as_ref().unwrap_or(&header.out); + + if out_file == &PathBuf::from("/dev/stdout") { + io::stdout().write_all(&out)?; + } else { + if out_file.exists() { + remove_file(&out_file)?; + } + + let out_file = File::create(&out_file)?; + let mut out_file_perm = out_file.metadata()?.permissions(); + let out_file_raw_perm = out_file_perm.mode(); + let new_out_file_raw_perm = ((out_file_raw_perm >> 9) << 9) | header.lower_perm_bits; + out_file_perm.set_mode(new_out_file_raw_perm); + } + + Ok(()) } fn pathname_display(path: &Option) -> String { From 4bd536d8f7e181a2362a9a51aaf7009abb3121ed Mon Sep 17 00:00:00 2001 From: rishadbaniya Date: Fri, 24 May 2024 23:58:06 +0545 Subject: [PATCH 05/12] chore: remove warnings --- xform/src/uudecode.rs | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/xform/src/uudecode.rs b/xform/src/uudecode.rs index 37ae587db..01a6df94b 100644 --- a/xform/src/uudecode.rs +++ b/xform/src/uudecode.rs @@ -9,14 +9,13 @@ extern crate clap; extern crate plib; -extern crate uuencode; use base64::prelude::*; use clap::Parser; use gettextrs::{bind_textdomain_codeset, textdomain}; use plib::PROJECT_NAME; -use std::fs::{remove_file, File, OpenOptions, Permissions}; -use std::io::{self, Error, ErrorKind, Read, Write}; +use std::fs::{remove_file, File}; +use std::io::{self, Error, Read, Write}; use std::os::unix::fs::PermissionsExt; use std::path::PathBuf; @@ -38,23 +37,6 @@ struct Args { file: Option, } -fn write_file(pathname: &PathBuf, bindata: &[u8]) -> io::Result<()> { - let f_res = OpenOptions::new() - .read(false) - .write(true) - .create(true) - .truncate(true) - .open(pathname); - - match f_res { - Err(e) => { - eprintln!("{}: {}", pathname.display(), e); - return Err(e); - } - Ok(mut file) => file.write_all(bindata), - } -} - #[derive(Debug)] enum DecodingType { Historical, From aa128d2182bcc8ba718697c684517f91ce1402f0 Mon Sep 17 00:00:00 2001 From: rishadbaniya Date: Sat, 25 May 2024 00:22:30 +0545 Subject: [PATCH 06/12] fix: output to file and and permission --- xform/src/uudecode.rs | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/xform/src/uudecode.rs b/xform/src/uudecode.rs index 01a6df94b..e665c66bf 100644 --- a/xform/src/uudecode.rs +++ b/xform/src/uudecode.rs @@ -59,7 +59,7 @@ impl Header { let split: Vec<&str> = line.split(' ').collect(); let dec_type = if split[0] == "begin" { DecodingType::Historical - } else if split[0] == "base64-begin" { + } else if split[0] == "begin-base64" { DecodingType::Base64 } else { panic!("Invalid encoding type"); @@ -147,20 +147,21 @@ fn decode_file(args: &Args) -> io::Result<()> { } } - let out_file = args.file.as_ref().unwrap_or(&header.out); - - if out_file == &PathBuf::from("/dev/stdout") { + if header.out == PathBuf::from("/dev/stdout") { io::stdout().write_all(&out)?; } else { - if out_file.exists() { - remove_file(&out_file)?; + if header.out.exists() { + remove_file(&header.out)?; } - let out_file = File::create(&out_file)?; - let mut out_file_perm = out_file.metadata()?.permissions(); - let out_file_raw_perm = out_file_perm.mode(); - let new_out_file_raw_perm = ((out_file_raw_perm >> 9) << 9) | header.lower_perm_bits; - out_file_perm.set_mode(new_out_file_raw_perm); + let mut o_file = File::create(&header.out)?; + let mut o_file_perm = o_file.metadata()?.permissions(); + let o_file_perm_mode = o_file_perm.mode(); + let new_o_file_perm_mode = ((o_file_perm_mode >> 9) << 9) | header.lower_perm_bits; + o_file_perm.set_mode(new_o_file_perm_mode); + + o_file.write_all(&out)?; + o_file.set_permissions(o_file_perm)?; } Ok(()) From 9ba51fe082f6ead388ea9af47f452a629f7ade7e Mon Sep 17 00:00:00 2001 From: rishadbaniya Date: Sat, 25 May 2024 00:34:36 +0545 Subject: [PATCH 07/12] fix: make use of output file through -o flag --- xform/src/uudecode.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/xform/src/uudecode.rs b/xform/src/uudecode.rs index e665c66bf..c1df47aca 100644 --- a/xform/src/uudecode.rs +++ b/xform/src/uudecode.rs @@ -147,14 +147,16 @@ fn decode_file(args: &Args) -> io::Result<()> { } } - if header.out == PathBuf::from("/dev/stdout") { + let out_path = args.outfile.as_ref().unwrap_or(&header.out); + + if out_path == &PathBuf::from("/dev/stdout") { io::stdout().write_all(&out)?; } else { - if header.out.exists() { - remove_file(&header.out)?; + if out_path.exists() { + remove_file(&out_path)?; } - let mut o_file = File::create(&header.out)?; + let mut o_file = File::create(&out_path)?; let mut o_file_perm = o_file.metadata()?.permissions(); let o_file_perm_mode = o_file_perm.mode(); let new_o_file_perm_mode = ((o_file_perm_mode >> 9) << 9) | header.lower_perm_bits; From 93b8006119ff2138a73e2dae0adba844272edcdf Mon Sep 17 00:00:00 2001 From: rishadbaniya Date: Sat, 25 May 2024 16:29:23 +0545 Subject: [PATCH 08/12] fix: add bracket for precedence --- xform/src/uuencode.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/xform/src/uuencode.rs b/xform/src/uuencode.rs index 4a6bf62ac..3ccd8b5c2 100644 --- a/xform/src/uuencode.rs +++ b/xform/src/uuencode.rs @@ -75,19 +75,19 @@ fn encode_historical_line(line: &[u8]) -> Vec { // in every line we'll take a chunk of 3 bytes and encode it for in_chunk in line.chunks(3) { // there could be less than 3 bytes, we need to fill it up with the padding byte + // those are simply the null ASCII character i.e 0 let a = in_chunk[0]; let b = *in_chunk.get(1).unwrap_or(&0); let c = *in_chunk.get(2).unwrap_or(&0); - - // https://pubs.opengroup.org/onlinepubs/9699919799/utilities/uuencode.html directly mentions - // the algorithm below(to convert 3 byte to 4 bytes of historical encoding) let mut out_chunk = [ - 0x20 + (a >> 2) & 0x3F, - 0x20 + ((a & 0x03) << 4) | ((b >> 4) & 0x0F), - 0x20 + ((b & 0x0F) << 2) | ((c >> 6) & 0x03), + 0x20 + ((a >> 2) & 0x3F), + 0x20 + (((a & 0x03) << 4) | ((b >> 4) & 0x0F)), + 0x20 + (((b & 0x0F) << 2) | ((c >> 6) & 0x03)), 0x20 + (c & 0x3F), ]; + // https://pubs.opengroup.org/onlinepubs/9699919799/utilities/uuencode.html directly mentions + // the algorithm below(to convert 3 byte to 4 bytes of historical encoding) for i in out_chunk.iter_mut() { if *i == 32 { *i = 96 From 7c60a2f19bd83000bd7766519903ee22f72d0308 Mon Sep 17 00:00:00 2001 From: rishadbaniya Date: Sat, 25 May 2024 18:03:11 +0545 Subject: [PATCH 09/12] feat: add binary testing in stdout --- plib/src/testing.rs | 51 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/plib/src/testing.rs b/plib/src/testing.rs index e865ddd77..08ea953dc 100644 --- a/plib/src/testing.rs +++ b/plib/src/testing.rs @@ -19,6 +19,16 @@ pub struct TestPlan { pub expected_exit_code: i32, } +/// [TestPlan] but for binary data on standard output +pub struct BinaryTestPlan { + pub cmd: String, + pub args: Vec, + pub stdin_data: String, + pub expected_out: Vec, + pub expected_err: String, + pub expected_exit_code: i32, +} + fn run_test_base(plan: TestPlan) -> (TestPlan, Output) { let relpath = format!("target/release/{}", plan.cmd); let test_bin_path = std::env::current_dir() @@ -45,6 +55,47 @@ fn run_test_base(plan: TestPlan) -> (TestPlan, Output) { (plan, output) } +fn run_binary_test_base(plan: BinaryTestPlan) -> (BinaryTestPlan, Output) { + let relpath = format!("target/release/{}", plan.cmd); + let test_bin_path = std::env::current_dir() + .unwrap() + .parent() + .unwrap() // Move up to the workspace root from the current package directory + .join(relpath); // Adjust the path to the binary + + let mut command = Command::new(test_bin_path); + let mut child = command + .args(&plan.args) + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .stderr(Stdio::piped()) + .spawn() + .expect("failed to spawn head"); + + let stdin = child.stdin.as_mut().expect("failed to get stdin"); + stdin + .write_all(plan.stdin_data.as_bytes()) + .expect("failed to write to stdin"); + + let output = child.wait_with_output().expect("failed to wait for child"); + (plan, output) +} + +pub fn run_binary_test(plan: BinaryTestPlan) { + let (plan, output) = run_binary_test_base(plan); + + let stdout = output.stdout; + assert_eq!(stdout, plan.expected_out); + + let stderr = String::from_utf8_lossy(&output.stderr); + assert_eq!(stderr, plan.expected_err); + + assert_eq!(output.status.code(), Some(plan.expected_exit_code)); + if plan.expected_exit_code == 0 { + assert!(output.status.success()); + } +} + pub fn run_test(plan: TestPlan) { let (plan, output) = run_test_base(plan); From 1308bf892cdac051d38045cb28d5c8e63668bed8 Mon Sep 17 00:00:00 2001 From: rishadbaniya Date: Sat, 25 May 2024 18:04:02 +0545 Subject: [PATCH 10/12] feat: add integration testing for both uuencode and uudecode with jpg and text file as the binary input --- xform/src/uudecode.rs | 6 +- xform/tests/integration.rs | 155 ++++++++++++++- xform/tests/uucode/image.jpg | Bin 0 -> 8117 bytes xform/tests/uucode/image_base64_encoded.txt | 183 +++++++++++++++++ .../tests/uucode/image_historical_encoded.txt | 184 ++++++++++++++++++ xform/tests/uucode/sample.txt | 10 + xform/tests/uucode/sample_base64_encoded.txt | 78 ++++++++ .../uucode/sample_historical_encoded.txt | 79 ++++++++ 8 files changed, 692 insertions(+), 3 deletions(-) create mode 100644 xform/tests/uucode/image.jpg create mode 100644 xform/tests/uucode/image_base64_encoded.txt create mode 100644 xform/tests/uucode/image_historical_encoded.txt create mode 100644 xform/tests/uucode/sample.txt create mode 100644 xform/tests/uucode/sample_base64_encoded.txt create mode 100644 xform/tests/uucode/sample_historical_encoded.txt diff --git a/xform/src/uudecode.rs b/xform/src/uudecode.rs index c1df47aca..8a38917cf 100644 --- a/xform/src/uudecode.rs +++ b/xform/src/uudecode.rs @@ -134,9 +134,13 @@ fn decode_file(args: &Args) -> io::Result<()> { } } - out.extend_from_slice(&decode_historical_line(&line[1..])); + let len = (line[..1].as_bytes()[0] - 32) as usize; + let mut dec_out = decode_historical_line(&line[1..]); + dec_out.truncate(len); + out.extend_from_slice(&dec_out); } } + DecodingType::Base64 => { while let Some(line) = lines.next() { if line == "====" || line == "====\n" { diff --git a/xform/tests/integration.rs b/xform/tests/integration.rs index fc8b0dacb..4f6dc3286 100644 --- a/xform/tests/integration.rs +++ b/xform/tests/integration.rs @@ -7,13 +7,12 @@ // SPDX-License-Identifier: MIT // +use plib::{run_binary_test, run_test, BinaryTestPlan, TestPlan}; use std::{ fs::{remove_file, File}, io::Read, }; -use plib::{run_test, TestPlan}; - fn cksum_test(test_data: &str, expected_output: &str) { run_test(TestPlan { cmd: String::from("cksum"), @@ -51,6 +50,32 @@ fn uncompress_test(args: &[&str], expected_output: &str, expected_error: &str) { }); } +fn uuencode_test(args: &[&str], expected_output: &str, expected_error: &str) { + let str_args: Vec = args.iter().map(|s| String::from(*s)).collect(); + + run_test(TestPlan { + cmd: String::from("uuencode"), + args: str_args, + stdin_data: String::new(), + expected_out: String::from(expected_output), + expected_err: String::from(expected_error), + expected_exit_code: 0, + }) +} + +fn uudecode_test(args: &[&str], expected_output: &Vec, expected_error: &str) { + let str_args: Vec = args.iter().map(|s| String::from(*s)).collect(); + + run_binary_test(BinaryTestPlan { + cmd: String::from("uudecode"), + args: str_args, + stdin_data: String::new(), + expected_out: expected_output.clone(), + expected_err: String::from(expected_error), + expected_exit_code: 0, + }); +} + #[test] fn test_cksum() { cksum_test("foo\n", "3915528286 4\n"); @@ -136,3 +161,129 @@ fn test_compression_compress_file() { remove_file(&compressed_file_path).unwrap(); } } + +#[test] +fn test_uuencode_uudecode_with_historical_encoding_text_file() { + use std::env; + use std::path::PathBuf; + + let cargo_manifest_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()); + let source_file = cargo_manifest_dir.join("tests/uucode/sample.txt"); + + // the "sample_historical_encoded.txt" is generated from the GNU uuencode sharutils + let encoded_file = cargo_manifest_dir.join("tests/uucode/sample_historical_encoded.txt"); + + let mut encoded_file_content = String::new(); + File::open(&encoded_file) + .unwrap() + .read_to_string(&mut encoded_file_content) + .unwrap(); + + uuencode_test( + &[source_file.to_str().unwrap(), "/dev/stdout"], + &encoded_file_content, + "", + ); + + let mut source_file_content = Vec::new(); + File::open(&source_file) + .unwrap() + .read_to_end(&mut source_file_content) + .unwrap(); + + // Decode the encoded file using uudecode + uudecode_test(&[encoded_file.to_str().unwrap()], &source_file_content, ""); +} + +#[test] +fn test_uuencode_uudecode_with_base64_encoding_text_file() { + use std::env; + use std::path::PathBuf; + + let cargo_manifest_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()); + let source_file = cargo_manifest_dir.join("tests/uucode/sample.txt"); + let encoded_file = cargo_manifest_dir.join("tests/uucode/sample_base64_encoded.txt"); + + let mut encoded_file_content = String::new(); + File::open(&encoded_file) + .unwrap() + .read_to_string(&mut encoded_file_content) + .unwrap(); + + uuencode_test( + &["-m", source_file.to_str().unwrap(), "/dev/stdout"], + &encoded_file_content, + "", + ); + + let mut source_file_content = Vec::new(); + File::open(&source_file) + .unwrap() + .read_to_end(&mut source_file_content) + .unwrap(); + + // Decode the encoded file using uudecode + uudecode_test(&[encoded_file.to_str().unwrap()], &source_file_content, ""); +} + +#[test] +fn test_uuencode_uudecode_with_historical_encoding_jpg_file() { + use std::env; + use std::path::PathBuf; + + let cargo_manifest_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()); + let source_file = cargo_manifest_dir.join("tests/uucode/image.jpg"); + let encoded_file = cargo_manifest_dir.join("tests/uucode/image_historical_encoded.txt"); + + let mut encoded_file_content = String::new(); + File::open(&encoded_file) + .unwrap() + .read_to_string(&mut encoded_file_content) + .unwrap(); + + uuencode_test( + &[source_file.to_str().unwrap(), "/dev/stdout"], + &encoded_file_content, + "", + ); + + let mut source_file_content = Vec::new(); + File::open(&source_file) + .unwrap() + .read_to_end(&mut source_file_content) + .unwrap(); + + // Decode the encoded file using uudecode + uudecode_test(&[encoded_file.to_str().unwrap()], &source_file_content, ""); +} + +#[test] +fn test_uuencode_uudecode_with_base64_encoding_jpg_file() { + use std::env; + use std::path::PathBuf; + + let cargo_manifest_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()); + let source_file = cargo_manifest_dir.join("tests/uucode/image.jpg"); + let encoded_file = cargo_manifest_dir.join("tests/uucode/image_base64_encoded.txt"); + + let mut encoded_file_content = String::new(); + File::open(&encoded_file) + .unwrap() + .read_to_string(&mut encoded_file_content) + .unwrap(); + + uuencode_test( + &["-m", source_file.to_str().unwrap(), "/dev/stdout"], + &encoded_file_content, + "", + ); + + let mut source_file_content = Vec::new(); + File::open(&source_file) + .unwrap() + .read_to_end(&mut source_file_content) + .unwrap(); + + // Decode the encoded file using uudecode + uudecode_test(&[encoded_file.to_str().unwrap()], &source_file_content, ""); +} diff --git a/xform/tests/uucode/image.jpg b/xform/tests/uucode/image.jpg new file mode 100644 index 0000000000000000000000000000000000000000..5e9c3d64ddfe7f006a0ec0e85e6beadfeef77c1a GIT binary patch literal 8117 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 literal 0 HcmV?d00001 diff --git a/xform/tests/uucode/image_base64_encoded.txt b/xform/tests/uucode/image_base64_encoded.txt new file mode 100644 index 000000000..9179dc552 --- /dev/null +++ b/xform/tests/uucode/image_base64_encoded.txt @@ -0,0 +1,183 @@ +begin-base64 644 /dev/stdout +/9j/2wCEAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4n +ICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDIBCQkJDAsMGA0NGDIhHCEyMjIy +MjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy +Mv/AABEIAMgAyAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQID +BAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQy +gZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElK +U1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Sl +pqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz +9PX29/j5+gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAME +BwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEK +FiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlq +c3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrC +w8TFxsfIycrS09TV1tfY2dri4+Tl5ufo6ery8/T19vf4+fr/2gAMAwEAAhED +EQA/AOeAp4WlC04LXceeAFSAUBakVaABVqQLSqtSqtAhFSpAtOVKkVaCWxoS +nhaeFqRUoJuRhM1IFp4WnbaBEYSl2VKFpdtAiIJS7KlC1DdXEFlbtPcOEjXv +6n0A7n2oDfRAUppSqUd5fag4+wWpER/5aFGkJ/BeB+Jz9K27XR719pllcDv5 +loY8/Qlv6VzSxdKL7nXHA1pK9rGaVpjJXUyeGhIv7mVkkxnbJyPzwCPyNYV7 +ZT2Fx5NxGUYjKnsw9j3q6deFTZmdShUp/EjPZaiZatlaiZa2M0yoy1Gy1aZa +hZaCiswpuKnZabtoGQAU8LShc09VpFAFqVVoValVaBAq1Kq0KtSqtBIgWpQt +Kq1Iq0EsRVp4WnKtPC0EjQtOC08LShaBDAtLtqTbRimIZjAJPYeleTanr1xr +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 +LtVQB6AYp2KWlrnuztsj/9k= +==== diff --git a/xform/tests/uucode/image_historical_encoded.txt b/xform/tests/uucode/image_historical_encoded.txt new file mode 100644 index 000000000..4c3227b3b --- /dev/null +++ b/xform/tests/uucode/image_historical_encoded.txt @@ -0,0 +1,184 @@ +begin 644 /dev/stdout +M_]C_VP"$``@&!@<&!0@'!P<)"0@*#!0-#`L+#!D2$P\4'1H?'AT:'!P@)"XG +M("(L(QP<*#'EZ@X2%AH>(B8J2DY25EI>8F9JBHZ2E +MIJ>HJ:JRL[2UMK>XN;K"P\3%QL?(R;GZ.GJ\?+S +M]/7V]_CY^@$``P$!`0$!`0$!`0````````$"`P0%!@<("0H+$0`"`0($!`,$ +M!P4$!``!`G<``0(#$00%(3$&$D%1!V%Q$R(R@0@40I&AL<$)(S-2\!5B7J"@X2%AH>(B8J2DY25EI>8F9JBHZ2EIJ>HJ:JRL[2UMK>XN;K" +MP\3%QL?(RKR\_3U]O?X^?K_V@`,`P$``A$# +M$0`_`.>`IX6E"TX+7<>>`%2`4!:D5:`!5J0+2JM2JM`A%2I`M.5*D5:"6QH2 +MGA:>%J14H)N1A,U(%IX6G;:!$82EV5*%I=M`B()2[*E"U#=7$%E;M/<.$C7O +MZGT`[GVH#?1`4II2J4=Y?:@X^P6I$1_Y:%&D)_!>!^)S]*V[71[U]IEE<#OY +MEH8\_0EOZ5S2Q=*+[G7'`UI*]K&:5IC)74R>&A(O[F5DDQG;)R/SP"/R-85[ +M93V%QY-Q&48C*GLP]CWJZ=>%39F=2A4I_$C/9:B9:ME:B9:V,TRHRU&RU:9: +MA9:"BLPIN*G9:;MH&0`4\+2AE>3:GKUQK +M.LR2-CR86*0H"2H&>ON?>NW\O.SH1<^()H]MA<73.BYV1]`/7CH*6/6_'^EK=7$NH74`M +M0-Z2;2>1D?*>V`><8X-;W@[5[6RO?,GW=.&4]/8C_/\`CTWB/4-,UR%%MXR+ +MP?()%4;BHYQZ$9Y]L5Y]W>UCTIZ:W.+TOXQ^(XI8XKBWLKW.WYDC*-SCCCC/ +MX5[/FP\1>%;;^TY%LI[M-T09P'C<#.5SU(')]@:XK2;30="LA--HL@=5^>:1 +M%"XZ\$G`%8WBCQMI>IRVSQ*ZM;JRHQ8[0#CHOW2>.#R/;IC!3J2J\L(67<4K +M*%V[F_=6DEG.T,C*S+CYEZ-QU'UJJRU0T?Q);:M"EN-HG0[1@8W+@D?EM-:C +M+7NQO;4\2:Y9.Q59:A9:MLM1,M4"*C+3<5.RTS;049+W!L*M2JM-B(E177H>:L +M*M:7.1B*M2JM*JU*JTKDB*M2A:55J0+3(8T+3PM*%IP6@0FVE"T\+2A:"1NV +M@@`$DX`ZDU)BN7\1:P)TDTFP/FW$@VNJ=2.XSV']YN@''4\3.:@KLNG3=27+ +M$\_\57W_``D6KO=PLS6T*E(@1@!!_%]68G'?&*J00#RE7!^;M7^?R +MK=]2M[6,@,$'E7$_3KTVKV!^OM77>&?#VG75G;Q2W%A-/9G?2>?K7E3KW9[M.DH*R/(+>QN9)_+@C>20<[5'0#N:]S\&:1]TNUAQ=,2TJC._GG!]*TW`&6QD=<4G+F!VV/( +M?%'BO4[2_P#L$"E"QQDI]_G`QZUDVW@?3I/])OX2]W(=S^6Y103Z;<5Z!XK\ +M-QZG=VFL9P]DP)4#JO./R)S^%9F*[<+3C;F/-QE22ERHX_P[X2_LC4KN^E;! +M>1Q;Q!L[(\\;CW./\GMTK+5EA43+74DELF*Y""4 +MQG!Y7^5=5I;^=9J<1P/DR,'=\Y+'OZ_K6-2MRZ(ZJ&%<_>EL:E[XDU[ +M7'837;00-_RP@&!CT]_QS19Z=&77<-SD?Q-DFDAA",N[;2UQ$H]<``$D_3->/0&2YO8XX8R997"HBX'.>/I +M7:^"O"NN:U,M]KX>"SE]=;>:BMKK.F:>/F:99&8^RK_`%)KC?%OB2Q\):(F +MD:($6XE)3Y#GRE/5B>[&I[J[EL/`TWB2_'_$T-H5A)ZJI^[Q[G!-1YC=C7U: +M]E>YFMH$#-`5$J'HT;JVT_\`?:X_.NB>4BNRU"PJTRU$ZT%HJL*;MJ9A2;:!G)/;K)R.&J`Q +MLAPPQ5Y14GEJXPPR*YE.VY[$J2EJBG;V\EQ*L42[G/:NOTS3ELH!%ORS'+L> +MF:K:'%"D4BHA\P?>8]Q6RJ5K>Z//K-J7*R2:U:`C)#(WW74Y5OI3%6ID=UC: +M,'*-R5/3/K]:`M*-[:F4K7T$5:>%I5%/`J[F;&!:X[QUXN&AVHL;)E;4)QS@ +M\PH?XOKZ?G]>S=DBC:21@J*"69C@`#N:^?M-_L<=>@%<>K/622)8PVXQK\D'!C +M'SA,K$EN2/Z>U07%W"2%*;>I(4\"BP +M[Z&UX?N=/M=^/J?:NBFO/%7B*"73=-L;J*PAG,(P +M-F[O\['_`/5R*B^%^B6U[=2ZQ=QAFC.RWC89"?[7UKM!XI-_XBN?#^E+OE2) +MR;D_ZN.0#@$>F>"?7BN.I53JNRO8TC'W%?J5E\+Z#HUG:MJEZM[J5B$=K1&& +MTL1QD=2.#UZXZ50TJ^N_'_BR\6[$BZ)#$8V0$A?;GU)Y^@J;2K"/P6MYX@\5 +MW"7E[.0JPI\[;B<]\9;CMT`-6=8M]0MM=TS1]$LC:64TQEE>WC*QJO(.XCZG +M.?043*-_P"@BN^TV*TT4Z8=(>6=;N\N1>S8.URBON7_`&?F``QUV]Z\ +M?UZ5(/%=Y!&VZ.W98"?4JH#'\6!/XUI124GZ5'XDOM\HLXV^5>9,=SV%<_BDV=-. +MBFKR.IET?='Y^F2>?!WC)^9?IG^1JDAR2.01P01@BG6\\MO('B=D8>AZUK?: +M;/5!MO4$$X^[/'Q^?_UZPNGN=]IT_-!HG_'S(OJF?U_^O6^J5DV&G7-G?@G; +M)`5.)5./S'^&:V@M7'1'#B&I3O$0+3PM."T\+57,+"!7(UI-LW.R2 +M.0&)'`Q4VJZDNMZG>WL[F-Y)&DCW<_+V7\``!]*JB*V'E8F)5B,<<^Y/IS7- +M.7,STJ,.2-C4^T6$E$7F[N8\J_0YJ.4UYF6[BZCM[5=N3<.<^P':F:3:/JEVD*DX)!D;/;-4 +M;B0RWFW`)`VC:*Z&QE&@01/%")KB9PNTG'7M_GUJ*DFE9;L<5=W>QZ%X'BC\ +M.V,5M?W"+?7DQ*(&)R>!@8]`!^==)/'8^!_#&I7>F0$S8\S,F7+2$X4'O@$C +MC^M_)'XBNQLM76YL8))HPC2(CLAYVG`./P +M->/4F^;F[[G?_K&N3TZ[>RL5AE?=.[-))M.^I-> +M;0Y)VCOQ7L86+Y.=[LX:SM+E['KWPOM)9(;K47/R,HB7@]"] +M.;3O"EC$ZE7=/-8'_:Y'Z8K>*UZ,%:-CR:LN:;979:S-7OETZS:4X,A^6-?4 +MUK2$(I8]!Z"N7\01,--:YG4":5U0+G.Q>3@>_&3_`/6%5<(1O)7.4=F=V=CE +MF))/J:93C28-*YWV-E14J]:C%2J.:Y;G?8T],O)HKB*$.3&S!2IY')[5U`6N +M+A;RYD?^ZP-=T%JZ1CRQ/4FIE+H:4J:OS,&"`X\P$GKP>*='$SMMC8,V#@`]A5=5]:>CLC!D.U +MAWK,ZBQ'(0Z[XD*J.2<\^_6I&NT6)F1MTA&`,@'';-6(P%`W,,5G+"W*6(.B_X2!H2K +MAB3T']:JS^)CW) +MBA6V0GU^T@'FS^A'9?Q/Z9KE(XVDD5%5F9C@`#))KZ*\">&5\-^'(HY(PM[<`2 +MW)[@]E_`^V"U +MB_O,S?D`/ZUUS+7$>,'SJ<,?98L_B2?\!113^E<*M=OI9W:9;G_8`_+BJ@]3EQ4=$RSBE` +MIX%17,\-G;2W-Q(L4,2EW=C@*HY)K6YPV/+_`(@VKW=P^IZW,;?1[3,=E;1\ +MRW4I'/\`N@D=3_".!S7D;OND+8"Y/1>@]JZ'QOXLF\4:X\P9ELH +M(]3_`(#M7,G.,TF:P32U'J"[``<]JG%L690#R#SZ4ZTA8C)!R>E:<<0B4$CF +MD5S$`X[?YS^M8MP^7R!WZ5N^'"4D;R1O+MDY/?O +M7-B7[K-Z"U.BBLKG[1>F>4+;%`(@IY'')_,UR5Q-BZF?=\K.V/7&:[7484BA +MEN6:03-:D!0>!M^:O.]1MKNUA@DDB:*.<%HBW!=?4>W\ZRP?O7D7B=+(F>^6 +M/[QY_,U5GO9IXD"(I9V.!78^%?`ESK.HPBY#1VBG,I`YQ@G +MCZX`_&NISUL8WC-SJ%_)D1P(7?#GPBFH:FWB2Y +M@:.TB;;I\;#&X+\H<_0`<]VR>U>M;*?%!';PI#"BI&BA411@*!P`*4BJV,Y/ +MF=R$K3"M3$4PBDV"B0E:\[\5.#KTXSPBJN?^`@_UKT"YDG4K';0[W;JSG"(/ +M4GO]!^G6O,M5+2ZO=R2.)&\UANQ@'!QP.U"9T4(^\4"6;[HP/4TFU_[_`.@J +M4TE',=7*;0IX%,6I%'-4_%/QB$5_#UC(#N_X_77L.HC!]3W]N/6MDS@L>7ZNFG)>E-.!^R0C8DKYW +M3$=9".V3T`Z#'?)-2.(,0Q''9:7:&.6P3Z=A]*E#*O?'O3`MP@)GU%:]IH5_ +MJ%A/?+&8K2)?]=(#AV/`1/[S$^G3O76^!?AQ]O2/5=@275TCG4)@6M[4#Y +MPJ_,[L/0`8Q_M5E^'[@17!51CH>?>OH]K.V>X:=H4:5H_*+$<[,D[?IS7@"> +M$]4L]3U"%(6)M;KR(@>LV>5`]]IW?0'TK&M#GC9&U&7*]3L[.TN+R.&(F-VE +M<*!I4^T7&GWRE; +MZUDP1V!!P<'N*[W4]1M='TR?4+V3R[>!-SMC/T`]R<#\:Y,!)*4Z;W1IC4_= +MDCYTMM+O-&\1MI=XABN5;8/E+;L]"/4&O=/#-F;>"4M&Z$[1\ZX)X_\`KBN< +M\1QV_B_1[?5]/LY8+^!U:W>=XT:1"V&4X8\#)//<>_/3:9K=K#9Q07\\4-VJ +MD&-G"DD'!QG'?'YBE+$4XXF*337Y,KVD<2%W(]<*"<>_2O156#3=]CA=* +M2M=;EJFD55TW5;/5H7DM'9A&Y1U9"I5@<$$'Z'\JN$4[B42(K32*F(IA%*Y7 +M*0N0B%CT`R:\B9B[EVZLE*+U(K1_=LM^._%\?A;1SY+(VI3_+!$>WJY'H/U-?/3N\\K2RNS.Q+ +M,S')8GJ3]:M^(-?N_$.L3ZC=D;Y.%0=(T'11[5DEV;JQQ76E8\MNY:.P=3@_ +M6O5/AK\/UN_*UW5X/W`.ZVMI%SYGH[`_P^@[]>G7FO!?A$W-C<>(]1M3+IUK +M@Q0,=HN7R`>?[H[^O3UKM+GQSK,_RPM#:H.`(DR)5#INY., +M$=>.M>3:IX@U37HQ_:%W)<$%FP>%4G^Z.PQ5%-59=$N-/E8C!62$]<,#_@37 +MGXK!.K)3CH_T.FC74(\KU.EOO$^O+>RV%S/_`&;$IVE85WL1S@@GM@]B.U<[ +M=BZ=VN(;RY=L!B\G5B/6JHU&Z41S78\]4R%)/S`$YZ_7G\_6O0/#L&D:IIAF +M\EY9/NO&YPH_`,*5"_*"@" +M@YW<9*YJ]I5IK%[9F+4+Z>!(47`D.0%8<9Z..WMDMHD"11CY8 +MT`55^@%9]K;);AXU(:1SEG5`H[```=.`/UJFDR4VC.\*";PUXWMU+N;2]WH8 +M^2QPO#8'`RW;V%>JOK5M$S"573'9L9_(&O-)(R%M9`=LT-RBLXZE1P!GZ']3 +M70&0,@8?B?Z53$=WUI"*JZ5/]HTV%SU`VG\.*MUDY6-E&YC>)Y/*\/W6.K!5 +M'XD?TS7FF*[_`,:/MTF)!_',,_0`_P#UJX0K0I'32A:)"5I-M3;:-M5S&G*: +MN*A:N;G^S98K +M/_CYF'EQG^Z3U8GM@9/X5Y]=>#;A]7CTZR#.$16N+EQA0Q]/H,< +M1S8I3:Y8HYBVM)KR3RX4+$`LQZ!0.I)["NK\#>!;CQ/>K<7"M'I43XEDS@R8 +M_A7^I[?6NUTWPUI^G:8;(1"57(:5G',A'//M[=*]`T8(-*@1%554%0JC`&": +MMU[Z1,'A'%)R$U"SA@\,75G;Q+'!%:LL<:]%"KP/TKRD)7L5TOF6DT?]Z-A^ +M8KR0+6F'>C,JL=46-)^74HO?(_0UU(.2,D'T!KDH9X[>X20MM`/;FK&I:I+% +M9M,\DD<)X#@+ECC\A^)_"G4U81=DSO=-U*&QL;J28MB/Y]J@LS<'@#J3Q7C7 +MB_Q2_BO48[LVWV:*.(1I%YF_N23G`Y.?TJK'XE\D7"0Q,6GC,>XR9VY'7IC( +MK*"C&*N$;;F-25R>W?8G//!J%7DC+M$V`ZE&]U/44O4<]J,8'3BK(([C:Z"* +M%&5"!G<WI72>"+TVFJ&T))29<`?[0!Q_7\ZY\!<98@`"K6E.8-3@F$ +MB)Y;;OFSSCG''K2:`]2D+$9;!"\D`5!($MI`CL%7J">.*HZ=KD.LI<"-Y(3' +MCY-@)8'N"3@?D:N0""-2#:AYMN$FG;S6&/3/RC\!6913F%Q<3YT^V69=P;S6 +M.U%88/)]?\*U#.;58O/"`2OM.P_=/..3R<\#\::9F?;N)SR.>W:JNI2>9I<[ +M88M"!(H3&21R/UH`[7P[?Q"P$WCF5@0ZAN*QJZ:G11UT.;\:OF.SC]2S?R_P`:Y#::Z7Q;)YFI1(.B +M1#\R3_\`6KG]M9J1Z$(>Z1;:3::FVTF*KF*Y33VTN*?BC%<7.=7*)BEQ2XI0 +M*7,'((!6QI]\MGIK,RLV),`#WQ7/7NIV>GQE[F8(HZ\$X_*L6X^(%JEA/!8V +M4\[R$;97Q&B^^3_]:M:492>B.?$3A&-FSL+SQ7':N))/+C09'S'_`.O7F]WX +MALH9&2%6F([KPOYFN=O;NXO)VDN9HE8]0I+']./UJDS(I.)&8>N,$_SKT:<% +M$\BI4@_.F$5I8 +MQN2JV^0;5VBK`8&JP)`X%*,MWH$6PPSP:D!X&!GZ574A5YY-2+<%1T`^@H;! +M(2YRHVA3G(-"L.2.#BFJRN_SY`]JT([2)H]ZC=BDY6W*4&]B;PW?K9ZF-YPD +MJF-B3@#/2NS-Y'YOEHP+`9.#7G,H*2X*[<=JV-)O6,P5AEL$;JF6NHTNAV/G +MEDR&Z`=J8;G"%"PPW!S64LYCE\U&93]X<]#5>^U/:X./G]N`#4CY33MB88!& +M&SM)`],=J[KPQKM@]I!IIG5;M0?W94C.237F"7Q9"$"[_?TJ>RU"UMM9M[FY +MA9C$V?DZFHJ)21K2;C([?7V,FLS^@P!^0K,VU!+X@M+NZDE;?'O8D;Q_A4B7 +MEM(<).A)]ZX]4>O!P:5F/VTFVI=M)MI,R3 +M2)'&.KNP`'XT\5C>*_\`D7+O_=I+5V(J/D@Y%#5=4\,S*?-U2-3ZV\?F2'V# +M$$"N5N]2T8%EM-*D<_\`/>_N&!^NQ37++]Y/K5W4/]9_P$5Z]*BHZ79\_5Q, +MIZV0VX*.W[LLY/95VH/IGD_C48B8CD@"GQ]%^E2-]VNG8Y=R+$2]6S2;U'W5 +M_.HCUH'6C<"4OD=*09)Z4VI$ZB@!0,=:7K2-3ATH&QR2K$0V`S>AZ"KAU8"( +M93+'ISC%9C??IC]5^G]:GE3W&I-;&J]U%MWCMTRK#CG\*PX?XOI +M5_\`@;_KG425M"X2ON:QO1(GRE2!M +M96QA;F-H;VQY('5N<&QE87-I;F<@:6UP2!T:')O=6=H(')E64@;F\@;7(@=6YA9F9E8W1E9"!R96UA2!B971W965N+B!4:&4@2!I9B!C;VYV +M:6-T:6]N(&]N(&)E('5N2!D;RX@061M:7)A=&EO;B!C;VYS:61E +M2!E>'!R97-S +M:6]N+B!!2!D97-I9VX@ +M86YS=V5R(&9O2!E>'1E;G-I=F4@:&%S(&-O;6UA;F1E9"!D:7)E8W1I;VXN(%-H;W)T(&%T +M(&9R;VYT('=H:6-H(&)L:6YD(&%S+B!992!A2X*3V8@2!N;W0N(%!R;VUO=&EO;B!D:60@ +M9&ES<&]S:6YG('EO=2!H;W5S96AO;&0@86YY(&EN2X@2&EL;',@ +M=V4@9&\@=6YD97(@=&EM97,@870@9FER6]U(&UI;G5T97(N($%T(&)Y(&%S:V5D(&)E +M:6YG(&-O=7)T(&AO<&5S+B!&87)T:&5R('-O(&9R:65N9',@86T@=&\@9&5T +M Date: Sat, 25 May 2024 18:09:44 +0545 Subject: [PATCH 11/12] fix: remove binary testing plan --- plib/src/testing.rs | 51 -------------------------------------- xform/tests/integration.rs | 10 +++++--- 2 files changed, 7 insertions(+), 54 deletions(-) diff --git a/plib/src/testing.rs b/plib/src/testing.rs index 08ea953dc..e865ddd77 100644 --- a/plib/src/testing.rs +++ b/plib/src/testing.rs @@ -19,16 +19,6 @@ pub struct TestPlan { pub expected_exit_code: i32, } -/// [TestPlan] but for binary data on standard output -pub struct BinaryTestPlan { - pub cmd: String, - pub args: Vec, - pub stdin_data: String, - pub expected_out: Vec, - pub expected_err: String, - pub expected_exit_code: i32, -} - fn run_test_base(plan: TestPlan) -> (TestPlan, Output) { let relpath = format!("target/release/{}", plan.cmd); let test_bin_path = std::env::current_dir() @@ -55,47 +45,6 @@ fn run_test_base(plan: TestPlan) -> (TestPlan, Output) { (plan, output) } -fn run_binary_test_base(plan: BinaryTestPlan) -> (BinaryTestPlan, Output) { - let relpath = format!("target/release/{}", plan.cmd); - let test_bin_path = std::env::current_dir() - .unwrap() - .parent() - .unwrap() // Move up to the workspace root from the current package directory - .join(relpath); // Adjust the path to the binary - - let mut command = Command::new(test_bin_path); - let mut child = command - .args(&plan.args) - .stdin(Stdio::piped()) - .stdout(Stdio::piped()) - .stderr(Stdio::piped()) - .spawn() - .expect("failed to spawn head"); - - let stdin = child.stdin.as_mut().expect("failed to get stdin"); - stdin - .write_all(plan.stdin_data.as_bytes()) - .expect("failed to write to stdin"); - - let output = child.wait_with_output().expect("failed to wait for child"); - (plan, output) -} - -pub fn run_binary_test(plan: BinaryTestPlan) { - let (plan, output) = run_binary_test_base(plan); - - let stdout = output.stdout; - assert_eq!(stdout, plan.expected_out); - - let stderr = String::from_utf8_lossy(&output.stderr); - assert_eq!(stderr, plan.expected_err); - - assert_eq!(output.status.code(), Some(plan.expected_exit_code)); - if plan.expected_exit_code == 0 { - assert!(output.status.success()); - } -} - pub fn run_test(plan: TestPlan) { let (plan, output) = run_test_base(plan); diff --git a/xform/tests/integration.rs b/xform/tests/integration.rs index 4f6dc3286..ce710ffbf 100644 --- a/xform/tests/integration.rs +++ b/xform/tests/integration.rs @@ -63,14 +63,14 @@ fn uuencode_test(args: &[&str], expected_output: &str, expected_error: &str) { }) } -fn uudecode_test(args: &[&str], expected_output: &Vec, expected_error: &str) { +fn uudecode_test(args: &[&str], expected_output: &str, expected_error: &str) { let str_args: Vec = args.iter().map(|s| String::from(*s)).collect(); - run_binary_test(BinaryTestPlan { + run_test(TestPlan { cmd: String::from("uudecode"), args: str_args, stdin_data: String::new(), - expected_out: expected_output.clone(), + expected_out: String::from(expected_output), expected_err: String::from(expected_error), expected_exit_code: 0, }); @@ -190,6 +190,7 @@ fn test_uuencode_uudecode_with_historical_encoding_text_file() { .unwrap() .read_to_end(&mut source_file_content) .unwrap(); + let source_file_content = String::from_utf8_lossy(&source_file_content); // Decode the encoded file using uudecode uudecode_test(&[encoded_file.to_str().unwrap()], &source_file_content, ""); @@ -221,6 +222,7 @@ fn test_uuencode_uudecode_with_base64_encoding_text_file() { .unwrap() .read_to_end(&mut source_file_content) .unwrap(); + let source_file_content = String::from_utf8_lossy(&source_file_content); // Decode the encoded file using uudecode uudecode_test(&[encoded_file.to_str().unwrap()], &source_file_content, ""); @@ -252,6 +254,7 @@ fn test_uuencode_uudecode_with_historical_encoding_jpg_file() { .unwrap() .read_to_end(&mut source_file_content) .unwrap(); + let source_file_content = String::from_utf8_lossy(&source_file_content); // Decode the encoded file using uudecode uudecode_test(&[encoded_file.to_str().unwrap()], &source_file_content, ""); @@ -283,6 +286,7 @@ fn test_uuencode_uudecode_with_base64_encoding_jpg_file() { .unwrap() .read_to_end(&mut source_file_content) .unwrap(); + let source_file_content = String::from_utf8_lossy(&source_file_content); // Decode the encoded file using uudecode uudecode_test(&[encoded_file.to_str().unwrap()], &source_file_content, ""); From f8ed738692dfc8277c8b142396a35e5dc9101b6f Mon Sep 17 00:00:00 2001 From: rishadbaniya Date: Sat, 25 May 2024 18:13:47 +0545 Subject: [PATCH 12/12] fix: remove unnecessary imports --- xform/tests/integration.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xform/tests/integration.rs b/xform/tests/integration.rs index ce710ffbf..ec7c92940 100644 --- a/xform/tests/integration.rs +++ b/xform/tests/integration.rs @@ -7,7 +7,7 @@ // SPDX-License-Identifier: MIT // -use plib::{run_binary_test, run_test, BinaryTestPlan, TestPlan}; +use plib::{run_test, TestPlan}; use std::{ fs::{remove_file, File}, io::Read,