(fuzz_log: &Path)
| 471 | } |
| 472 | |
| 473 | fn parse_artifact_from_log(fuzz_log: &Path) -> Result<Vec<u8>> { |
| 474 | let fuzzer_dir = get_file_dirname(fuzz_log); |
| 475 | let log_vec = std::fs::read(fuzz_log).expect("cannot open fuzz log"); |
| 476 | let log_str = String::from_utf8_lossy(&log_vec).to_string(); |
| 477 | |
| 478 | let mut err_buf = Vec::new(); |
| 479 | for line in log_str.lines().rev() { |
| 480 | if let Some(c) = line.chars().next() { |
| 481 | if c == '#' { |
| 482 | break; |
| 483 | } |
| 484 | } |
| 485 | err_buf.push(line); |
| 486 | } |
| 487 | err_buf.reverse(); |
| 488 | let err_buf = err_buf.join("\n"); |
| 489 | |
| 490 | for line in err_buf.lines().rev() { |
| 491 | if let Some(crash_input) = line.strip_prefix("Base64: ") { |
| 492 | let bytes = base64::engine::general_purpose::STANDARD.decode(crash_input)?; |
| 493 | return Ok(bytes); |
| 494 | } |
| 495 | } |
| 496 | |
| 497 | for line in err_buf.lines().rev() { |
| 498 | if let Some(artifact_file) = |
| 499 | line.strip_prefix("artifact_prefix='./'; Test unit written to ./") |
| 500 | { |
| 501 | let artifact_file: PathBuf = [fuzzer_dir, "work".into(), artifact_file.into()] |
| 502 | .iter() |
| 503 | .collect(); |
| 504 | let bytes = std::fs::read(artifact_file).expect("cannot read artifact"); |
| 505 | return Ok(bytes); |
| 506 | } |
| 507 | } |
| 508 | eyre::bail!("cannot parse artifact from : {fuzz_log:?}") |
| 509 | } |
| 510 | |
| 511 | fn parse_driver_id(artifact: &[u8]) -> Option<u16> { |
| 512 | if artifact.len() < 2 { |
no test coverage detected