mini-static 0.38.5

A secure, async static file server with streaming, traversal protection, and connection limits.
Documentation
//! The threat model cites tests by name. This checks those names still exist.
//!
//! A security document that confidently cites a test someone renamed two months ago is
//! worse than no document: it reads as evidence and is not. `verify-guarantees.sh` proves
//! each cited test *catches* its mutation, but it is run by hand; this runs in the normal
//! suite and fails the moment a citation goes stale.
//!
//! Only the "Defended" table is checked — it is the one making the three-cell
//! guarantee/test/mutation claim. Names cited in prose elsewhere in the document are not
//! scanned, since they are not claiming to be verified evidence.

use std::collections::BTreeSet;
use std::fs;

/// Pull the `` `test_name` `` cells out of the "Defended" table.
///
/// The table's rows are `| guarantee | \`test\` | \`mutation-id\` |`, so the second
/// backticked cell of a three-cell row is the test name. Mutation ids are skipped: they
/// name entries in the shell script, not Rust functions.
fn cited_test_names(doc: &str) -> BTreeSet<String> {
	let mut names = BTreeSet::new();
	for line in doc.lines() {
		if !line.starts_with('|') {
			continue;
		}
		let cells: Vec<&str> = line.split('|').map(str::trim).collect();
		// `| a | b | c |` splits to ["", "a", "b", "c", ""] — five parts for three cells.
		if cells.len() != 5 {
			continue;
		}
		let test_cell = cells[2];
		if let Some(name) = test_cell.strip_prefix('`').and_then(|c| c.strip_suffix('`')) {
			// Skip the header row and anything that is not an identifier.
			if name.chars().all(|c| c.is_ascii_alphanumeric() || c == '_') && name.contains('_') {
				names.insert(name.to_string());
			}
		}
	}
	names
}

#[test]
fn every_test_cited_by_the_threat_model_exists() {
	let doc = fs::read_to_string("THREAT_MODEL.md").expect("THREAT_MODEL.md is missing");
	let cited = cited_test_names(&doc);

	assert!(
		cited.len() >= 15,
		"only {} citations parsed — the table format probably changed and this check has \
		 stopped guarding anything: {cited:?}",
		cited.len()
	);

	// Every test function in the suite, by name, from the sources rather than a listing —
	// no test harness introspection is available at compile time.
	let mut defined = BTreeSet::new();
	let dirs = ["tests", "tests/unit", "tests/unit/server", "src"];
	for dir in dirs {
		let Ok(entries) = fs::read_dir(dir) else {
			continue;
		};
		for entry in entries.flatten() {
			let path = entry.path();
			if path.extension().is_none_or(|e| e != "rs") {
				continue;
			}
			let Ok(source) = fs::read_to_string(&path) else {
				continue;
			};
			for line in source.lines() {
				let line = line.trim();
				let Some(rest) = line.strip_prefix("async fn ").or_else(|| line.strip_prefix("fn ")) else {
					continue;
				};
				if let Some(name) = rest.split('(').next() {
					defined.insert(name.trim().to_string());
				}
			}
		}
	}

	let missing: Vec<&String> = cited.iter().filter(|name| !defined.contains(*name)).collect();
	assert!(
		missing.is_empty(),
		"THREAT_MODEL.md cites tests that no longer exist: {missing:?}\n\
		 Either restore the test or remove the guarantee's row — a cited test that is gone \
		 means the guarantee is no longer proven."
	);
}