14 Commits

Author SHA1 Message Date
f0d7ec56b3 test
Some checks failed
Gentoo Utils / build-oci-image (push) Successful in 8s
Gentoo Utils / grep (push) Failing after 3s
Gentoo Utils / check-format (push) Successful in 7s
Gentoo Utils / docs (push) Successful in 13s
Gentoo Utils / build (push) Successful in 21s
Gentoo Utils / test (push) Successful in 26s
Gentoo Utils / fuzz (push) Successful in 5m58s
2025-12-14 19:58:58 -06:00
e34b7546a4 test 2025-12-14 19:58:58 -06:00
e12212cd2c ci: fix jobs not exiting on failure 2025-12-14 19:58:58 -06:00
104cb98d9e ci: build: remove debugging echos
ci: build: remove redundant source
2025-12-14 19:58:58 -06:00
7f59bb7c02 ci: add fuzz job
ci: fuzz: add timeout

ci: fuzz: add fuzzer timeout
2025-12-14 19:58:58 -06:00
6c0b368f6b scripts: add fuzzer helper script 2025-12-14 19:58:58 -06:00
52ce39d579 Merge pull request 'feature/remove-statics-from-parser-fuzzer' (#13) from feature/remove-statics-from-parser-fuzzer into master
All checks were successful
Gentoo Utils / check-format (push) Successful in 8s
Gentoo Utils / build (push) Successful in 20s
Gentoo Utils / test (push) Successful in 26s
Gentoo Utils / grep (push) Successful in 3s
Gentoo Utils / docs (push) Successful in 12s
Gentoo Utils / build-oci-image (push) Successful in 7s
Reviewed-on: #13
Reviewed-by: penguin <penguin@epenguin.net>
2025-12-14 19:42:50 -06:00
7348681b65 gate atom parser fuzzer debug printing
All checks were successful
Gentoo Utils / build-oci-image (push) Successful in 25s
Gentoo Utils / grep (push) Successful in 4s
Gentoo Utils / check-format (push) Successful in 22s
Gentoo Utils / docs (push) Successful in 26s
Gentoo Utils / build (push) Successful in 36s
Gentoo Utils / test (push) Successful in 40s
2025-12-15 01:09:16 +00:00
5178a7b8ea check for duplicate flags in usedeps, instead of duplicate usedeps 2025-12-15 00:37:47 +00:00
a3ff953e50 except InvalidAtom in atom.py 2025-12-15 00:36:12 +00:00
b0f68fa7e0 remove static variables from atom parser fuzzer
Stdin and Stdout are already synchronized and available to multiple
threads as needed, we don't need to hold onto instances in a static variable.
2025-12-15 00:33:35 +00:00
c25294333b use -E flag in git grep
All checks were successful
Gentoo Utils / build-oci-image (push) Successful in 17s
Gentoo Utils / grep (push) Successful in 4s
Gentoo Utils / check-format (push) Successful in 25s
Gentoo Utils / docs (push) Successful in 30s
Gentoo Utils / build (push) Successful in 40s
Gentoo Utils / test (push) Successful in 33s
2025-12-14 23:14:41 +00:00
08fac67f73 fill in todo! in match arm
All checks were successful
Gentoo Utils / build-oci-image (push) Successful in 7s
Gentoo Utils / grep (push) Successful in 3s
Gentoo Utils / test (push) Successful in 27s
Gentoo Utils / check-format (push) Successful in 8s
Gentoo Utils / docs (push) Successful in 12s
Gentoo Utils / build (push) Successful in 20s
2025-12-14 04:38:33 +00:00
06deeb3ae7 grep for todo! and dbg! in check_commands and in CI 2025-12-14 04:38:33 +00:00
6 changed files with 96 additions and 35 deletions

View File

@@ -4,7 +4,7 @@ on: [push]
defaults: defaults:
run: run:
shell: bash -l {0} shell: bash -le -o pipefail {0}
jobs: jobs:
build-oci-image: build-oci-image:
@@ -98,10 +98,6 @@ jobs:
- name: build and check - name: build and check
run: | run: |
echo $USER
echo "CC=$CC"
echo "CXX=$CXX"
source /etc/profile
meson setup -Dfuzz=enabled -Dtests=enabled -Dbuildtype=debugoptimized -Ddocs=enabled build meson setup -Dfuzz=enabled -Dtests=enabled -Dbuildtype=debugoptimized -Ddocs=enabled build
meson compile -C build meson compile -C build
@@ -125,6 +121,37 @@ jobs:
meson compile -C build meson compile -C build
ninja test -C build ninja test -C build
fuzz:
runs-on: brutalisk
env:
CC: 'clang'
CXX: 'clang++'
FUZZER_TIMEOUT_S: 300
needs: [build-oci-image, build]
container:
image: ${{ vars.REGISTRY_URL }}/${{ gitea.repository }}:${{ needs.build-oci-image.outputs.image_tag }}
steps:
- name: Checkout repo
uses: actions/checkout@v5
# FIXME: Get rid of this step when portage has fixes merged?
# needed because portage has fixes upstream we need that arent stable yet
- name: Checkout tip of portage
run: |
git clone https://github.com/gentoo/portage.git
cd portage
python -m venv .venv && ./.venv/bin/pip install -e .
source ./.venv/bin/activate
which emerge
- name: build and fuzz
run: |
source ./portage/.venv/bin/activate
which emerge
meson setup -Dfuzz=enabled -Dtests=enabled -Dbuildtype=debugoptimized build
meson compile atom_parser_fuzzer:alias -C build
timeout 10m ./scripts/fuzz.sh
check-format: check-format:
runs-on: brutalisk runs-on: brutalisk
needs: [build-oci-image] needs: [build-oci-image]
@@ -153,3 +180,16 @@ jobs:
run: | run: |
meson setup -Ddocs=enabled docs meson setup -Ddocs=enabled docs
ninja rustdoc -C docs ninja rustdoc -C docs
grep:
runs-on: brutalisk
needs: [build-oci-image]
container:
image: ${{ vars.REGISTRY_URL }}/${{ gitea.repository }}:${{ needs.build-oci-image.outputs.image_tag }}
steps:
- name: Checkout repo
uses: actions/checkout@v5
- name: grep for patterns
run: |
git grep -E 'todo!|dbg!' -- '*.rs' && exit 1 || exit 0

View File

@@ -3,3 +3,4 @@ ninja rustfmt -C build
ninja rustdoc -C build ninja rustdoc -C build
ninja clippy -C build ninja clippy -C build
ninja test -C build ninja test -C build
git grep -E 'todo!|dbg!' -- '*.rs' && exit 1 || exit 0

View File

@@ -4,25 +4,12 @@
use core::slice; use core::slice;
use gentoo_utils::{Parseable, atom::Atom}; use gentoo_utils::{Parseable, atom::Atom};
use std::{ use std::{
env::{self},
io::{self, Write}, io::{self, Write},
sync::{LazyLock, Mutex},
}; };
#[derive(Debug)]
struct State {
input: io::Stdin,
output: io::Stdout,
}
#[unsafe(no_mangle)] #[unsafe(no_mangle)]
pub unsafe extern "C" fn LLVMFuzzerTestOneInput(input: *const u8, len: usize) -> i32 { pub unsafe extern "C" fn LLVMFuzzerTestOneInput(input: *const u8, len: usize) -> i32 {
static PIPES: LazyLock<Mutex<State>> = LazyLock::new(|| {
Mutex::new(State {
input: io::stdin(),
output: io::stdout(),
})
});
let slice = unsafe { slice::from_raw_parts(input, len) }; let slice = unsafe { slice::from_raw_parts(input, len) };
let str = str::from_utf8(slice).expect("expected ascii input"); let str = str::from_utf8(slice).expect("expected ascii input");
@@ -30,13 +17,13 @@ pub unsafe extern "C" fn LLVMFuzzerTestOneInput(input: *const u8, len: usize) ->
return -1; return -1;
} }
let mut state = PIPES.lock().unwrap(); let stdin = io::stdin();
let mut stdout = io::stdout();
writeln!(&mut state.output, "{str}").unwrap();
let mut buffer = String::new(); let mut buffer = String::new();
state.input.read_line(&mut buffer).unwrap(); writeln!(&mut stdout, "{str}").unwrap();
stdin.read_line(&mut buffer).unwrap();
let control = match buffer.as_str().trim() { let control = match buffer.as_str().trim() {
"0" => Ok(()), "0" => Ok(()),
@@ -48,23 +35,32 @@ pub unsafe extern "C" fn LLVMFuzzerTestOneInput(input: *const u8, len: usize) ->
match (control, gentoo_utils) { match (control, gentoo_utils) {
(Ok(_), Ok(_)) => { (Ok(_), Ok(_)) => {
eprintln!("agreement that {str} is valid"); if env::var("FUZZER_LOG").is_ok() {
eprintln!("agreement that {str} is valid");
}
} }
(Err(_), Err(_)) => { (Err(_), Err(_)) => {
eprintln!("agreement that {str} is invalid"); if env::var("FUZZER_LOG").is_ok() {
eprintln!("agreement that {str} is invalid");
}
} }
(Ok(_), Err(rest)) => { (Ok(_), Err(rest)) => {
panic!("disagreement on {str}\ncontrol:Ok\ngentoo-utils:Err({rest})"); panic!("disagreement on {str}\ncontrol:Ok\ngentoo-utils:Err({rest})");
} }
(Err(_), Ok(atom)) (Err(_), Ok(atom))
if atom if atom.usedeps().iter().any(|usedep| {
.usedeps() atom.usedeps()
.iter() .iter()
.any(|usedep| atom.usedeps().iter().filter(|u| usedep == *u).count() > 1) => .filter(|u| *usedep.flag() == *u.flag())
.count()
> 1
}) =>
{ {
eprintln!( if env::var("FUZZER_LOG").is_ok() {
"disagreement, but we will allow it since its probably because of duplicated usdeps" eprintln!(
); "disagreement, but we will allow it since its probably because of duplicated usdeps"
);
}
} }
(Err(_), Ok(_)) => { (Err(_), Ok(_)) => {
panic!("disagreement on {str}\ncontrol:Err\ngentoo-utils:Ok") panic!("disagreement on {str}\ncontrol:Err\ngentoo-utils:Ok")

View File

@@ -2,12 +2,13 @@
import sys import sys
from portage.dep import Atom from portage.dep import Atom
from portage.exception import InvalidAtom
for line in sys.stdin.buffer: for line in sys.stdin.buffer:
try: try:
Atom(line.decode().strip()) Atom(line.decode().strip())
sys.stdout.buffer.write(b"0\n") sys.stdout.buffer.write(b"0\n")
except: except InvalidAtom:
sys.stdout.buffer.write(b"1\n") sys.stdout.buffer.write(b"1\n")
finally: finally:
sys.stdout.buffer.flush() sys.stdout.buffer.flush()

23
scripts/fuzz.sh Executable file
View File

@@ -0,0 +1,23 @@
#!/bin/bash
CWD="$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")"
PROJECT_DIR=$(realpath "${CWD}/../")
in=$(mktemp -u) || exit $?
out=$(mktemp -u) || exit $?
mkfifo ${in} ${out} || exit $?
if [[ -z "$FUZZER_TIMEOUT_S" ]]; then
FUZZER_TIMEOUT_S=600
fi
${PROJECT_DIR}/scripts/atom.py <${in} >${out} \
| ${PROJECT_DIR}/build/fuzz/atom/parser/fuzzer -max_total_time=$FUZZER_TIMEOUT_S >${in} <${out} \
${PROJECT_DIR}/build/atom_parser_fuzzer_corpus \
-only_ascii=1 \
-fork=2 \
-timeout=2 \
-max_total_time=$FUZZER_TIMEOUT_S \
-timeout_exitcode=0 \
"$@"

View File

@@ -102,7 +102,7 @@ impl Iterator for Ebuilds {
Ok(ebuild) => break Some(Ok(ebuild)), Ok(ebuild) => break Some(Ok(ebuild)),
Err(e) => break Some(Err(e)), Err(e) => break Some(Err(e)),
}, },
_ => todo!(), Err(e) => break Some(Err(Error::ReadDir(self.0.clone(), e))),
} }
} }
} }