From fa2a14ccd262f102ca04e47529d5f79a556a1692 Mon Sep 17 00:00:00 2001 From: Zhuoxun Yang Date: Fri, 6 Oct 2023 22:55:30 +0800 Subject: [PATCH 01/11] expr: unify debug message --- src/uu/expr/src/syntax_tree.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uu/expr/src/syntax_tree.rs b/src/uu/expr/src/syntax_tree.rs index b3cd329ba..335405d06 100644 --- a/src/uu/expr/src/syntax_tree.rs +++ b/src/uu/expr/src/syntax_tree.rs @@ -52,7 +52,7 @@ impl AstNode { operands, } => { println!( - "Node( {} ) at #{} (evaluate -> {:?})", + "Node( {} ) at #{} ( evaluate -> {:?} )", op_type, token_idx, self.evaluate() From 2c2e01205cfbe4b6337a207102485fd2dc64e443 Mon Sep 17 00:00:00 2001 From: Zhuoxun Yang Date: Fri, 6 Oct 2023 23:50:22 +0800 Subject: [PATCH 02/11] expr: short-circuit evaluation for | --- src/uu/expr/src/syntax_tree.rs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/uu/expr/src/syntax_tree.rs b/src/uu/expr/src/syntax_tree.rs index 335405d06..ad421edb7 100644 --- a/src/uu/expr/src/syntax_tree.rs +++ b/src/uu/expr/src/syntax_tree.rs @@ -155,8 +155,24 @@ impl AstNode { } } pub fn operand_values(&self) -> Result, String> { - if let Self::Node { operands, .. } = self { + if let Self::Node { + operands, op_type, .. + } = self + { let mut out = Vec::with_capacity(operands.len()); + let mut operands = operands.iter(); + + if op_type == "|" { + if let Some(value) = operands.next() { + let value = value.evaluate()?; + out.push(value.clone()); + if value_as_bool(&value) { + out.push(String::from("dummy")); + return Ok(out); + } + } + } + for operand in operands { let value = operand.evaluate()?; out.push(value); From 5a732dd21a9aa0987f973eda4ffe919b9985be29 Mon Sep 17 00:00:00 2001 From: Zhuoxun Yang Date: Fri, 6 Oct 2023 23:50:44 +0800 Subject: [PATCH 03/11] tests/expr: add test expr 1 \| a / 5 --- tests/by-util/test_expr.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/by-util/test_expr.rs b/tests/by-util/test_expr.rs index ea5a964d9..99445d566 100644 --- a/tests/by-util/test_expr.rs +++ b/tests/by-util/test_expr.rs @@ -123,6 +123,11 @@ fn test_or() { .args(&["-14", "|", "1"]) .succeeds() .stdout_only("-14\n"); + + new_ucmd!() + .args(&["1", "|", "a", "/", "5"]) + .succeeds() + .stdout_only("1\n"); } #[test] From 0df561e256905c9477bd316b68a9fb56d36a47c6 Mon Sep 17 00:00:00 2001 From: Luv_Ray Date: Sat, 7 Oct 2023 00:19:56 +0800 Subject: [PATCH 04/11] expr: add comment in syntax_tree.rs --- src/uu/expr/src/syntax_tree.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/uu/expr/src/syntax_tree.rs b/src/uu/expr/src/syntax_tree.rs index ad421edb7..eaa6be1f5 100644 --- a/src/uu/expr/src/syntax_tree.rs +++ b/src/uu/expr/src/syntax_tree.rs @@ -161,7 +161,8 @@ impl AstNode { { let mut out = Vec::with_capacity(operands.len()); let mut operands = operands.iter(); - + // check the first value before `|`, stop evaluate and return directly if it is true. + // push dummy to pass the check of `len() == 2` if op_type == "|" { if let Some(value) = operands.next() { let value = value.evaluate()?; From 7bf4b7f6748812e29daf3fb91180e4dfceb6ce30 Mon Sep 17 00:00:00 2001 From: Luv_Ray Date: Sat, 7 Oct 2023 00:42:04 +0800 Subject: [PATCH 05/11] tests/expr: add tests in test_expr.rs --- tests/by-util/test_expr.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/by-util/test_expr.rs b/tests/by-util/test_expr.rs index 99445d566..a463f086b 100644 --- a/tests/by-util/test_expr.rs +++ b/tests/by-util/test_expr.rs @@ -128,6 +128,16 @@ fn test_or() { .args(&["1", "|", "a", "/", "5"]) .succeeds() .stdout_only("1\n"); + + new_ucmd!() + .args(&["foo", "|", "a", "/", "5"]) + .succeeds() + .stdout_only("foo\n"); + + new_ucmd!() + .args(&["0", "|", "10", "/", "5"]) + .succeeds() + .stdout_only("2\n"); } #[test] From e5d70d444ae7ca3a3100190ea87c22edfecab121 Mon Sep 17 00:00:00 2001 From: Zhuoxun Yang Date: Sat, 7 Oct 2023 10:41:10 +0800 Subject: [PATCH 06/11] tests/expr: format --- tests/by-util/test_expr.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/by-util/test_expr.rs b/tests/by-util/test_expr.rs index a463f086b..4637d51c7 100644 --- a/tests/by-util/test_expr.rs +++ b/tests/by-util/test_expr.rs @@ -128,7 +128,7 @@ fn test_or() { .args(&["1", "|", "a", "/", "5"]) .succeeds() .stdout_only("1\n"); - + new_ucmd!() .args(&["foo", "|", "a", "/", "5"]) .succeeds() From 7e08562ee6bc71fb5e6b6d0aa19a80549627f5eb Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Sun, 8 Oct 2023 15:02:01 +0200 Subject: [PATCH 07/11] expr: add some empty lines --- src/uu/expr/src/syntax_tree.rs | 8 ++++++++ src/uu/expr/src/tokens.rs | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/src/uu/expr/src/syntax_tree.rs b/src/uu/expr/src/syntax_tree.rs index eaa6be1f5..4ca723a4d 100644 --- a/src/uu/expr/src/syntax_tree.rs +++ b/src/uu/expr/src/syntax_tree.rs @@ -31,10 +31,12 @@ pub enum AstNode { operands: OperandsList, }, } + impl AstNode { fn debug_dump(&self) { self.debug_dump_impl(1); } + fn debug_dump_impl(&self, depth: usize) { for _ in 0..depth { print!("\t",); @@ -71,12 +73,14 @@ impl AstNode { operands, }) } + fn new_leaf(token_idx: usize, value: &str) -> Box { Box::new(Self::Leaf { token_idx, value: value.into(), }) } + pub fn evaluate(&self) -> Result { match self { Self::Leaf { value, .. } => Ok(value.clone()), @@ -154,6 +158,7 @@ impl AstNode { }, } } + pub fn operand_values(&self) -> Result, String> { if let Self::Node { operands, op_type, .. @@ -257,6 +262,7 @@ fn ast_from_rpn(rpn: &mut TokenStack) -> Result, String> { } } } + fn maybe_ast_node( token_idx: usize, op_type: &str, @@ -520,6 +526,7 @@ fn prefix_operator_substr(values: &[String]) -> String { fn bool_as_int(b: bool) -> u8 { u8::from(b) } + fn bool_as_string(b: bool) -> String { if b { "1".to_string() @@ -527,6 +534,7 @@ fn bool_as_string(b: bool) -> String { "0".to_string() } } + fn value_as_bool(s: &str) -> bool { if s.is_empty() { return false; diff --git a/src/uu/expr/src/tokens.rs b/src/uu/expr/src/tokens.rs index b4e4c7da5..3c5cac060 100644 --- a/src/uu/expr/src/tokens.rs +++ b/src/uu/expr/src/tokens.rs @@ -38,6 +38,7 @@ pub enum Token { value: String, }, } + impl Token { fn new_infix_op(v: &str, left_assoc: bool, precedence: u8) -> Self { Self::InfixOp { @@ -46,6 +47,7 @@ impl Token { value: v.into(), } } + fn new_value(v: &str) -> Self { Self::Value { value: v.into() } } @@ -56,12 +58,14 @@ impl Token { _ => false, } } + fn is_a_number(&self) -> bool { match self { Self::Value { value, .. } => value.parse::().is_ok(), _ => false, } } + fn is_a_close_paren(&self) -> bool { matches!(*self, Self::ParClose) } From 5ac1aef20ec3d639db72207e537d84750c828c87 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sun, 8 Oct 2023 17:34:37 +0200 Subject: [PATCH 08/11] github action: move the fuzzing action into it own file/task --- .github/workflows/CICD.yml | 50 --------------------------- .github/workflows/fuzzing.yml | 64 +++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 50 deletions(-) create mode 100644 .github/workflows/fuzzing.yml diff --git a/.github/workflows/CICD.yml b/.github/workflows/CICD.yml index 61c12dad0..39eea1593 100644 --- a/.github/workflows/CICD.yml +++ b/.github/workflows/CICD.yml @@ -125,56 +125,6 @@ jobs: S=$(cargo fmt -- --check) && printf "%s\n" "$S" || { printf "%s\n" "$S" ; printf "%s\n" "$S" | sed -E -n -e "s/^Diff[[:space:]]+in[[:space:]]+${PWD//\//\\/}\/(.*)[[:space:]]+at[[:space:]]+[^0-9]+([0-9]+).*$/::${fault_type} file=\1,line=\2::${fault_prefix}: \`cargo fmt\`: style violation (file:'\1', line:\2; use \`cargo fmt -- \"\1\"\`)/p" ; fault=true ; } if [ -n "${{ steps.vars.outputs.FAIL_ON_FAULT }}" ] && [ -n "$fault" ]; then exit 1 ; fi - fuzz: - name: Run the fuzzers - runs-on: ubuntu-latest - env: - RUN_FOR: 60 - steps: - - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@nightly - - name: Install `cargo-fuzz` - run: cargo install cargo-fuzz - - uses: Swatinem/rust-cache@v2 - - name: Run fuzz_date for XX seconds - shell: bash - run: | - ## Run it - cd fuzz - cargo +nightly fuzz run fuzz_date -- -max_total_time=${{ env.RUN_FOR }} -detect_leaks=0 - - name: Run fuzz_test for XX seconds - continue-on-error: true - shell: bash - run: | - ## Run it - cd fuzz - cargo +nightly fuzz run fuzz_test -- -max_total_time=${{ env.RUN_FOR }} -detect_leaks=0 - - name: Run fuzz_expr for XX seconds - continue-on-error: true - shell: bash - run: | - ## Run it - cd fuzz - cargo +nightly fuzz run fuzz_expr -- -max_total_time=${{ env.RUN_FOR }} -detect_leaks=0 - - name: Run fuzz_parse_glob for XX seconds - shell: bash - run: | - ## Run it - cd fuzz - cargo +nightly fuzz run fuzz_parse_glob -- -max_total_time=${{ env.RUN_FOR }} -detect_leaks=0 - - name: Run fuzz_parse_size for XX seconds - shell: bash - run: | - ## Run it - cd fuzz - cargo +nightly fuzz run fuzz_parse_size -- -max_total_time=${{ env.RUN_FOR }} -detect_leaks=0 - - name: Run fuzz_parse_time for XX seconds - shell: bash - run: | - ## Run it - cd fuzz - cargo +nightly fuzz run fuzz_parse_time -- -max_total_time=${{ env.RUN_FOR }} -detect_leaks=0 - style_lint: name: Style/lint runs-on: ${{ matrix.job.os }} diff --git a/.github/workflows/fuzzing.yml b/.github/workflows/fuzzing.yml new file mode 100644 index 000000000..677df2c9f --- /dev/null +++ b/.github/workflows/fuzzing.yml @@ -0,0 +1,64 @@ +name: Fuzzing + +# spell-checker:ignore fuzzer + +on: [push, pull_request] + +permissions: + contents: read # to fetch code (actions/checkout) + +# End the current execution if there is a new changeset in the PR. +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} + +jobs: + fuzz: + name: Run the fuzzers + runs-on: ubuntu-latest + env: + RUN_FOR: 60 + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@nightly + - name: Install `cargo-fuzz` + run: cargo install cargo-fuzz + - uses: Swatinem/rust-cache@v2 + - name: Run fuzz_date for XX seconds + shell: bash + run: | + ## Run it + cd fuzz + cargo +nightly fuzz run fuzz_date -- -max_total_time=${{ env.RUN_FOR }} -detect_leaks=0 + - name: Run fuzz_test for XX seconds + continue-on-error: true + shell: bash + run: | + ## Run it + cd fuzz + cargo +nightly fuzz run fuzz_test -- -max_total_time=${{ env.RUN_FOR }} -detect_leaks=0 + - name: Run fuzz_expr for XX seconds + continue-on-error: true + shell: bash + run: | + ## Run it + cd fuzz + cargo +nightly fuzz run fuzz_expr -- -max_total_time=${{ env.RUN_FOR }} -detect_leaks=0 + - name: Run fuzz_parse_glob for XX seconds + shell: bash + run: | + ## Run it + cd fuzz + cargo +nightly fuzz run fuzz_parse_glob -- -max_total_time=${{ env.RUN_FOR }} -detect_leaks=0 + - name: Run fuzz_parse_size for XX seconds + shell: bash + run: | + ## Run it + cd fuzz + cargo +nightly fuzz run fuzz_parse_size -- -max_total_time=${{ env.RUN_FOR }} -detect_leaks=0 + - name: Run fuzz_parse_time for XX seconds + shell: bash + run: | + ## Run it + cd fuzz + cargo +nightly fuzz run fuzz_parse_time -- -max_total_time=${{ env.RUN_FOR }} -detect_leaks=0 From 2c9e091ebee4e9d5b85ac46015d8727ae654ffdc Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Mon, 9 Oct 2023 07:07:38 +0200 Subject: [PATCH 09/11] Bump errno from 0.3.1 to 0.3.5 --- Cargo.lock | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 197368abf..d4da11736 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -783,25 +783,14 @@ dependencies = [ [[package]] name = "errno" -version = "0.3.1" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" dependencies = [ - "errno-dragonfly", "libc", "windows-sys 0.48.0", ] -[[package]] -name = "errno-dragonfly" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" -dependencies = [ - "cc", - "libc", -] - [[package]] name = "exacl" version = "0.11.0" From 2883c0a9689ead143ae4a8b38536447939d890fd Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Mon, 9 Oct 2023 15:16:50 +0200 Subject: [PATCH 10/11] uucore: remove commented out import --- src/uucore/src/lib/features/tokenize/sub.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/uucore/src/lib/features/tokenize/sub.rs b/src/uucore/src/lib/features/tokenize/sub.rs index 447616ae6..c65a37a68 100644 --- a/src/uucore/src/lib/features/tokenize/sub.rs +++ b/src/uucore/src/lib/features/tokenize/sub.rs @@ -18,7 +18,6 @@ use std::iter::Peekable; use std::process::exit; use std::slice::Iter; use std::str::Chars; -// use std::collections::HashSet; use super::num_format::format_field::{FieldType, FormatField}; use super::num_format::num_format; From b38ac2cb7488e0006c5a98f87bc36b9ce07dc150 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Mon, 9 Oct 2023 15:28:12 +0200 Subject: [PATCH 11/11] uucore: remove commented out enum FChar --- .../tokenize/num_format/format_field.rs | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/src/uucore/src/lib/features/tokenize/num_format/format_field.rs b/src/uucore/src/lib/features/tokenize/num_format/format_field.rs index 036ee286d..bd57b0ecd 100644 --- a/src/uucore/src/lib/features/tokenize/num_format/format_field.rs +++ b/src/uucore/src/lib/features/tokenize/num_format/format_field.rs @@ -17,23 +17,6 @@ pub enum FieldType { Charf, } -// #[allow(non_camel_case_types)] -// pub enum FChar { -// d, -// e, -// E, -// i, -// f, -// F, -// g, -// G, -// u, -// x, -// X, -// o -// } -// - // a Sub Tokens' fields are stored // as a single object so they can be more simply // passed by ref to num_format in a Sub method