diff --git a/Cargo.toml b/Cargo.toml index 263a1842..e953f212 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -56,6 +56,16 @@ license = "MIT OR Apache-2.0" authors = ["unom"] repository = "https://git.unom.io/unom/punktfunk" +# The `unsafe` discipline the `packaging/windows/drivers/*` crates already run, extended to the +# workspace. `unsafe fn` marks a CONTRACT the caller must uphold; it is not a licence for the whole +# body to skip checking. Without this lint an `unsafe fn` body is unchecked end to end, so a 600-line +# function hides which handful of lines are actually the unsafe ones — exactly the reviewer-hostile +# shape we are working down. `warn` while the remaining sites are cleared crate by crate; flip to +# `deny` once they are, so it can never regress. (This is the Rust 2024 default; adopting it early +# also pays off the edition migration.) +[workspace.lints.rust] +unsafe_op_in_unsafe_fn = "warn" + [profile.release] opt-level = 3 lto = "thin" diff --git a/clients/android/native/Cargo.toml b/clients/android/native/Cargo.toml index fd8bedc8..320f4745 100644 --- a/clients/android/native/Cargo.toml +++ b/clients/android/native/Cargo.toml @@ -64,3 +64,6 @@ libc = "0.2" # host + Linux client use. audiopus_sys vendors libopus (pure C) and builds it static via cmake — # the cargo-ndk build sets LIBOPUS_STATIC=1/LIBOPUS_NO_PKG=1 so it links the bundled lib, not the host's. opus = "0.3" + +[lints] +workspace = true diff --git a/clients/linux/Cargo.toml b/clients/linux/Cargo.toml index 8a613486..0a2128d7 100644 --- a/clients/linux/Cargo.toml +++ b/clients/linux/Cargo.toml @@ -32,3 +32,6 @@ anyhow = "1" tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } relm4 = { version = "0.11", features = ["libadwaita"] } + +[lints] +workspace = true diff --git a/clients/linux/src/main.rs b/clients/linux/src/main.rs index 90e6244d..7925386d 100644 --- a/clients/linux/src/main.rs +++ b/clients/linux/src/main.rs @@ -3,6 +3,7 @@ //! Hosts, pairing/trust, settings, and the desktop library page; every stream (and the //! console game library) runs in the spawned `punktfunk-session` Vulkan binary — the //! shell never touches video (punktfunk-planning `linux-client-rearchitecture.md`). +#![forbid(unsafe_code)] // The UI-agnostic plumbing lives in `pf-client-core`, shared with the session binary. // Root re-exports keep every `crate::trust`-style path resolving unchanged. diff --git a/clients/probe/Cargo.toml b/clients/probe/Cargo.toml index 9c84589a..ca485037 100644 --- a/clients/probe/Cargo.toml +++ b/clients/probe/Cargo.toml @@ -22,3 +22,6 @@ mdns-sd = "0.20" # encoder. libopus is already in the graph via `punktfunk-core`'s quic feature; this exposes the # name directly. Cross-platform (cmake-vendored), so the probe builds + validates everywhere. opus = "0.3" + +[lints] +workspace = true diff --git a/clients/probe/src/main.rs b/clients/probe/src/main.rs index 3831f6ab..d8760bfe 100644 --- a/clients/probe/src/main.rs +++ b/clients/probe/src/main.rs @@ -45,6 +45,7 @@ //! [--input-test | --mic-test [--mic-burst] | --touch-test | --rich-input-test] //! [--pin HEX | --pair PIN] [--compositor NAME] [--gamepad NAME] | --discover [SECS]` //! Env: `PUNKTFUNK_CLIENT_10BIT=1` / `PUNKTFUNK_CLIENT_444=1` advertise the 10-bit / 4:4:4 caps. +#![forbid(unsafe_code)] use anyhow::{anyhow, Context, Result}; use punktfunk_core::config::GamepadPref; diff --git a/clients/session/Cargo.toml b/clients/session/Cargo.toml index c4cc7ec2..6bb29d7c 100644 --- a/clients/session/Cargo.toml +++ b/clients/session/Cargo.toml @@ -45,3 +45,6 @@ tracing-subscriber = { version = "0.3", features = ["env-filter"] } # the SDK); same pattern as clients/windows. [target.'cfg(windows)'.build-dependencies] winresource = "0.1" + +[lints] +workspace = true diff --git a/clients/session/src/main.rs b/clients/session/src/main.rs index 715129be..3d32640f 100644 --- a/clients/session/src/main.rs +++ b/clients/session/src/main.rs @@ -13,6 +13,7 @@ //! the first presented frame, `stats:` lines per 1 s window, one `{"error": …}` / //! `{"ended": …}` JSON line on the way out. Logs go to stderr. Exit codes: 0 clean end, //! 2 connect failed, 3 trust rejected / pairing required, 4 presenter init failed. +#![forbid(unsafe_code)] #[cfg(all(any(target_os = "linux", windows), feature = "ui"))] mod console; diff --git a/clients/windows/Cargo.toml b/clients/windows/Cargo.toml index 0114c7a4..d5222651 100644 --- a/clients/windows/Cargo.toml +++ b/clients/windows/Cargo.toml @@ -95,3 +95,6 @@ tracing-subscriber = { version = "0.3", features = ["env-filter"] } [target.'cfg(windows)'.build-dependencies] winresource = "0.1" windows-reactor-setup = { git = "https://github.com/microsoft/windows-rs", rev = "a4f7b2cb7c63c6bb7fc77a2affe57145be1d8c4f" } + +[lints] +workspace = true diff --git a/crates/libvpl-sys/Cargo.toml b/crates/libvpl-sys/Cargo.toml index 3eb222de..4c5e5a65 100644 --- a/crates/libvpl-sys/Cargo.toml +++ b/crates/libvpl-sys/Cargo.toml @@ -15,3 +15,6 @@ links = "vpl" cmake = "0.1" # Same bindgen configuration as pyrowave-sys (runtime = dlopen libclang). bindgen = { version = "0.72", features = ["runtime"], default-features = false } + +[lints] +workspace = true diff --git a/crates/pf-capture/Cargo.toml b/crates/pf-capture/Cargo.toml index a2c7e27e..c2ea5cba 100644 --- a/crates/pf-capture/Cargo.toml +++ b/crates/pf-capture/Cargo.toml @@ -58,3 +58,6 @@ windows = { version = "0.62", features = [ "Win32_UI_Input_KeyboardAndMouse", "Win32_UI_WindowsAndMessaging", ] } + +[lints] +workspace = true diff --git a/crates/pf-client-core/Cargo.toml b/crates/pf-client-core/Cargo.toml index f8750dec..51376757 100644 --- a/crates/pf-client-core/Cargo.toml +++ b/crates/pf-client-core/Cargo.toml @@ -79,3 +79,6 @@ windows = { git = "https://github.com/microsoft/windows-rs", rev = "a4f7b2cb7c63 # still strictly per-session opt-in (Settings codec pick / PUNKTFUNK_PREFER_PYROWAVE=1). default = ["pyrowave"] pyrowave = ["dep:pyrowave-sys", "dep:ash"] + +[lints] +workspace = true diff --git a/crates/pf-clipboard/Cargo.toml b/crates/pf-clipboard/Cargo.toml index 6dfb7604..62cd2a71 100644 --- a/crates/pf-clipboard/Cargo.toml +++ b/crates/pf-clipboard/Cargo.toml @@ -52,3 +52,6 @@ windows = { version = "0.62", features = [ "Win32_System_Ole", "Win32_UI_WindowsAndMessaging", ] } + +[lints] +workspace = true diff --git a/crates/pf-console-ui/Cargo.toml b/crates/pf-console-ui/Cargo.toml index 70a72c69..e3293660 100644 --- a/crates/pf-console-ui/Cargo.toml +++ b/crates/pf-console-ui/Cargo.toml @@ -33,3 +33,6 @@ sdl3 = { version = "0.18", features = ["hidapi", "ash"] } [target.'cfg(windows)'.dependencies] sdl3 = { version = "0.18", features = ["hidapi", "ash", "build-from-source"] } + +[lints] +workspace = true diff --git a/crates/pf-driver-proto/Cargo.toml b/crates/pf-driver-proto/Cargo.toml index f5ae8a3b..f814fa23 100644 --- a/crates/pf-driver-proto/Cargo.toml +++ b/crates/pf-driver-proto/Cargo.toml @@ -18,3 +18,6 @@ publish = false [dependencies] # `min_const_generics`: Pod/Zeroable for `[u8; N]` of any N (the gamepad SHM reserved tails are >32). bytemuck = { version = "1.19", features = ["derive", "min_const_generics"] } + +[lints] +workspace = true diff --git a/crates/pf-driver-proto/src/lib.rs b/crates/pf-driver-proto/src/lib.rs index ad2576c4..f4c9b559 100644 --- a/crates/pf-driver-proto/src/lib.rs +++ b/crates/pf-driver-proto/src/lib.rs @@ -20,7 +20,7 @@ //! //! The GUID and LUID are carried as plain integers; the host converts to `windows::core::GUID` / //! `windows::Win32::Foundation::LUID` and the driver to its own bindgen types via the same constants. - +#![forbid(unsafe_code)] #![cfg_attr(not(test), no_std)] extern crate alloc; diff --git a/crates/pf-encode/Cargo.toml b/crates/pf-encode/Cargo.toml index 736c5d35..82818060 100644 --- a/crates/pf-encode/Cargo.toml +++ b/crates/pf-encode/Cargo.toml @@ -92,3 +92,6 @@ pyrowave = ["dep:pyrowave-sys"] # (design/native-qsv-encoder.md). ⚠ Like `nvenc`: hand builds need this feature or # Intel boxes fall through to the ffmpeg path / software. qsv = ["dep:libvpl-sys"] + +[lints] +workspace = true diff --git a/crates/pf-ffvk/Cargo.toml b/crates/pf-ffvk/Cargo.toml index 19c83390..d6e53dde 100644 --- a/crates/pf-ffvk/Cargo.toml +++ b/crates/pf-ffvk/Cargo.toml @@ -20,3 +20,6 @@ ash = { version = "0.38", features = ["loaded"] } # Same bindgen configuration as ffmpeg-sys-next (runtime = dlopen libclang). bindgen = { version = "0.72", features = ["runtime"], default-features = false } pkg-config = "0.3" + +[lints] +workspace = true diff --git a/crates/pf-frame/Cargo.toml b/crates/pf-frame/Cargo.toml index 43a1343e..d388cfe1 100644 --- a/crates/pf-frame/Cargo.toml +++ b/crates/pf-frame/Cargo.toml @@ -35,3 +35,6 @@ windows = { version = "0.62", features = [ "Win32_System_LibraryLoader", "Win32_System_Threading", ] } + +[lints] +workspace = true diff --git a/crates/pf-gpu/Cargo.toml b/crates/pf-gpu/Cargo.toml index 1a737d64..9602dfc1 100644 --- a/crates/pf-gpu/Cargo.toml +++ b/crates/pf-gpu/Cargo.toml @@ -26,3 +26,6 @@ windows = { version = "0.62", features = [ [dev-dependencies] tempfile = "3" + +[lints] +workspace = true diff --git a/crates/pf-host-config/Cargo.toml b/crates/pf-host-config/Cargo.toml index 8622d261..0cecefa6 100644 --- a/crates/pf-host-config/Cargo.toml +++ b/crates/pf-host-config/Cargo.toml @@ -10,3 +10,6 @@ description = "Process-wide punktfunk host configuration (env-parsed HostConfig publish = false [dependencies] + +[lints] +workspace = true diff --git a/crates/pf-host-config/src/lib.rs b/crates/pf-host-config/src/lib.rs index bdf2f2c8..471d66e9 100644 --- a/crates/pf-host-config/src/lib.rs +++ b/crates/pf-host-config/src/lib.rs @@ -31,6 +31,7 @@ //! = off, anything else = on, so the old presence-style `=1` keeps working). The Linux `zerocopy` //! module keeps its own *truthy* parser (`1|true|yes|on`) — the two are independent features that //! share a name; do NOT conflate them. +#![forbid(unsafe_code)] use std::sync::OnceLock; diff --git a/crates/pf-inject/Cargo.toml b/crates/pf-inject/Cargo.toml index 1af5824d..3dc7d463 100644 --- a/crates/pf-inject/Cargo.toml +++ b/crates/pf-inject/Cargo.toml @@ -75,3 +75,6 @@ windows = { version = "0.62", features = [ "Win32_UI_Input_Pointer", "Win32_UI_WindowsAndMessaging", ] } + +[lints] +workspace = true diff --git a/crates/pf-paths/Cargo.toml b/crates/pf-paths/Cargo.toml index ea4668ae..e6b05887 100644 --- a/crates/pf-paths/Cargo.toml +++ b/crates/pf-paths/Cargo.toml @@ -11,3 +11,6 @@ publish = false [dependencies] tracing = "0.1" + +[lints] +workspace = true diff --git a/crates/pf-paths/src/lib.rs b/crates/pf-paths/src/lib.rs index 9789308f..fbbfc8a8 100644 --- a/crates/pf-paths/src/lib.rs +++ b/crates/pf-paths/src/lib.rs @@ -6,6 +6,7 @@ //! - [`config_dir`] resolves the per-host config directory (XDG / `%ProgramData%`, `PUNKTFUNK_CONFIG_DIR` override). //! - [`create_private_dir`] makes it owner-private (0700 / restrictive DACL). //! - [`write_secret_file`] writes an owner-only secret (0600 / SYSTEM+Admins DACL). +#![forbid(unsafe_code)] use std::path::PathBuf; diff --git a/crates/pf-presenter/Cargo.toml b/crates/pf-presenter/Cargo.toml index a98156c6..d0e175c3 100644 --- a/crates/pf-presenter/Cargo.toml +++ b/crates/pf-presenter/Cargo.toml @@ -53,3 +53,6 @@ windows-sys = { version = "0.61", features = [ # backend in pf-client-core; ON by default, matching pf-client-core's default. default = ["pyrowave"] pyrowave = ["pf-client-core/pyrowave"] + +[lints] +workspace = true diff --git a/crates/pf-vdisplay/Cargo.toml b/crates/pf-vdisplay/Cargo.toml index 6090c64d..451e1417 100644 --- a/crates/pf-vdisplay/Cargo.toml +++ b/crates/pf-vdisplay/Cargo.toml @@ -65,3 +65,6 @@ windows = { version = "0.62", features = [ "Win32_System_IO", "Win32_System_Threading", ] } + +[lints] +workspace = true diff --git a/crates/pf-vdisplay/src/vdisplay/linux/gamescope.rs b/crates/pf-vdisplay/src/vdisplay/linux/gamescope.rs index 6a5f510a..ef7f533d 100644 --- a/crates/pf-vdisplay/src/vdisplay/linux/gamescope.rs +++ b/crates/pf-vdisplay/src/vdisplay/linux/gamescope.rs @@ -604,8 +604,7 @@ pub fn managed_session_available() -> bool { /// walking each candidate's ppid chain — so one client's nested gamescope never makes the next /// client attach to it. pub fn foreign_gamescope_running() -> bool { - // SAFETY: `getuid()` is a parameterless POSIX call that always succeeds and touches no memory. - let uid = unsafe { libc::getuid() }; + let uid = crate::proc::current_uid(); let our_pid = std::process::id(); let Ok(entries) = std::fs::read_dir("/proc") else { return false; @@ -708,8 +707,7 @@ pub fn launch_into_session(cmd: &str) -> Result { /// when a process exposes it. Empty when no gamescope session is running / none exposes a `DISPLAY`. #[cfg(target_os = "linux")] pub(crate) fn xwayland_cursor_targets() -> Vec<(String, Option)> { - // SAFETY: `getuid()` is a parameterless POSIX call that always succeeds and touches no memory. - let uid = unsafe { libc::getuid() }; + let uid = crate::proc::current_uid(); let mut out: Vec<(String, Option)> = Vec::new(); let Ok(entries) = std::fs::read_dir("/proc") else { return out; @@ -765,8 +763,7 @@ pub(crate) fn xwayland_cursor_targets() -> Vec<(String, Option)> { /// gamescope socket; `DISPLAY` is the nested Xwayland; `XAUTHORITY` is its auth file (for X /// clients that aren't gamescope children). Any one can be individually absent. fn discover_session_display_env() -> Option<(Option, Option, Option)> { - // SAFETY: `getuid()` is a parameterless POSIX call that always succeeds and touches no memory. - let uid = unsafe { libc::getuid() }; + let uid = crate::proc::current_uid(); for e in std::fs::read_dir("/proc").ok()?.flatten() { let name = e.file_name(); let Some(pid_str) = name.to_str() else { @@ -1441,8 +1438,7 @@ fn cgroup_under_user_manager(cgroup: &str) -> bool { /// Our uid as a string — what `loginctl` wants for a user argument. fn uid_string() -> String { - // SAFETY: `getuid()` is a parameterless POSIX call that always succeeds and touches no memory. - unsafe { libc::getuid() }.to_string() + crate::proc::current_uid().to_string() } /// Is lingering on for this user (logind keeps the `--user` manager alive with no session)? diff --git a/crates/pf-vdisplay/src/vdisplay/linux/gamescope/discovery.rs b/crates/pf-vdisplay/src/vdisplay/linux/gamescope/discovery.rs index 7be486c2..4b90cabb 100644 --- a/crates/pf-vdisplay/src/vdisplay/linux/gamescope/discovery.rs +++ b/crates/pf-vdisplay/src/vdisplay/linux/gamescope/discovery.rs @@ -106,8 +106,7 @@ pub(crate) fn wait_for_steam_game_exit( /// `AppId=57` never matches appid 570) — specific to the game reaper, so Steam's own shader-precompile /// step (not reaper-wrapped) can't be mistaken for the game. fn steam_game_running(appid: u32) -> bool { - // SAFETY: `getuid()` is a parameterless POSIX call that always succeeds and touches no memory. - let uid = unsafe { libc::getuid() }; + let uid = crate::proc::current_uid(); let appid_tok = format!("AppId={appid}"); let Ok(entries) = std::fs::read_dir("/proc") else { return false; diff --git a/crates/pf-vdisplay/src/vdisplay/proc.rs b/crates/pf-vdisplay/src/vdisplay/proc.rs index 6c8377ed..6572c4c7 100644 --- a/crates/pf-vdisplay/src/vdisplay/proc.rs +++ b/crates/pf-vdisplay/src/vdisplay/proc.rs @@ -78,6 +78,21 @@ fn timed_out(cmd: &Command, budget: Duration) -> Error { ) } +/// The calling process's real uid. +/// +/// Every session/gamescope lookup that derives `/run/user/` (or filters `/proc` to "our" +/// processes) needs this, and each one used to open its own `unsafe` block carrying a verbatim +/// copy of the same SAFETY note. `getuid()` is parameterless, always succeeds, and touches no +/// memory, so there is no contract for a caller to uphold — which makes it exactly the shape that +/// belongs behind a safe wrapper instead of being restated at every call site. One `unsafe` here, +/// none at the callers. +#[cfg(target_os = "linux")] +pub(crate) fn current_uid() -> u32 { + // SAFETY: parameterless POSIX call that always succeeds and touches no memory — it just + // returns the calling process's real uid. Nothing is aliased, read, or freed. + unsafe { libc::getuid() } +} + // `unix` gate, not `test` alone: this module is compiled on every platform (lib.rs declares it // unconditionally), but the cases below spawn `sleep`/`true`/`echo` as EXECUTABLES. On Windows // `echo` is a shell builtin and there is no `sleep.exe`, so an ungated module turns a green suite diff --git a/crates/pf-vdisplay/src/vdisplay/session.rs b/crates/pf-vdisplay/src/vdisplay/session.rs index 0c25b574..d95e6cc9 100644 --- a/crates/pf-vdisplay/src/vdisplay/session.rs +++ b/crates/pf-vdisplay/src/vdisplay/session.rs @@ -280,9 +280,7 @@ pub(crate) fn runtime_dir() -> String { #[cfg(target_os = "linux")] fn default_runtime_dir(env: &EnvProbe) -> String { env.xdg_runtime_dir.clone().unwrap_or_else(|| { - // SAFETY: `getuid()` is a parameterless POSIX call that always succeeds and touches no - // memory — it just returns the calling process's real uid. Nothing is aliased or freed. - let uid = unsafe { libc::getuid() }; + let uid = crate::proc::current_uid(); format!("/run/user/{uid}") }) } @@ -305,9 +303,7 @@ fn default_bus(env: &EnvProbe, runtime: &str) -> String { #[cfg(target_os = "linux")] pub fn detect_active_session() -> ActiveSession { use std::os::unix::fs::MetadataExt; - // SAFETY: `getuid()` is a parameterless POSIX call that always succeeds and touches no memory — - // it just returns the calling process's real uid. Nothing is aliased or freed. - let uid = unsafe { libc::getuid() }; + let uid = crate::proc::current_uid(); // ONE sample of the session-scoped env, before any scanning — see [`EnvProbe`]. Everything // below reads this snapshot, never the process env. let env = EnvProbe::sample(); @@ -712,8 +708,7 @@ mod tests { impl FakeRuntime { fn new(tag: &str, pids: &[u32]) -> FakeRuntime { - // SAFETY: parameterless POSIX call, returns the calling process's uid; touches no memory. - let uid = unsafe { libc::getuid() }; + let uid = crate::proc::current_uid(); let dir = std::env::temp_dir().join(format!("pf-swaysock-{tag}-{}", std::process::id())); let _ = std::fs::remove_dir_all(&dir); diff --git a/crates/pf-win-display/Cargo.toml b/crates/pf-win-display/Cargo.toml index ebcc6e3b..6b8142ce 100644 --- a/crates/pf-win-display/Cargo.toml +++ b/crates/pf-win-display/Cargo.toml @@ -36,3 +36,6 @@ windows = { version = "0.62", features = [ "Win32_System_StationsAndDesktops", "Win32_System_Threading", ] } + +[lints] +workspace = true diff --git a/crates/pf-zerocopy/Cargo.toml b/crates/pf-zerocopy/Cargo.toml index 6efba664..6ad8048e 100644 --- a/crates/pf-zerocopy/Cargo.toml +++ b/crates/pf-zerocopy/Cargo.toml @@ -34,3 +34,6 @@ serde_json = "1" # Linux-only like the code under test: the render-node scan is exercised against a fixture tree. [target.'cfg(target_os = "linux")'.dev-dependencies] tempfile = "3" + +[lints] +workspace = true diff --git a/crates/punktfunk-core/Cargo.toml b/crates/punktfunk-core/Cargo.toml index 3f1ca1d9..3714d5db 100644 --- a/crates/punktfunk-core/Cargo.toml +++ b/crates/punktfunk-core/Cargo.toml @@ -107,3 +107,6 @@ harness = false [build-dependencies] cbindgen = "0.29" + +[lints] +workspace = true diff --git a/crates/punktfunk-host/Cargo.toml b/crates/punktfunk-host/Cargo.toml index b1ba5d57..45e7d97d 100644 --- a/crates/punktfunk-host/Cargo.toml +++ b/crates/punktfunk-host/Cargo.toml @@ -310,3 +310,6 @@ pyrowave = ["pf-encode/pyrowave"] # builds of this crate never execute the winresource block). [target.'cfg(windows)'.build-dependencies] winresource = "0.1" + +[lints] +workspace = true diff --git a/crates/punktfunk-tray/Cargo.toml b/crates/punktfunk-tray/Cargo.toml index f51ac5b4..9bdd98c2 100644 --- a/crates/punktfunk-tray/Cargo.toml +++ b/crates/punktfunk-tray/Cargo.toml @@ -58,3 +58,6 @@ libc = "0.2" # Windows client's build.rs — cross-builds from Linux CI runners skip it. [target.'cfg(windows)'.build-dependencies] winresource = "0.1" + +[lints] +workspace = true diff --git a/crates/pyrowave-sys/Cargo.toml b/crates/pyrowave-sys/Cargo.toml index 3c0723dd..ac4e9f8e 100644 --- a/crates/pyrowave-sys/Cargo.toml +++ b/crates/pyrowave-sys/Cargo.toml @@ -15,3 +15,6 @@ links = "pyrowave" cmake = "0.1" # Same bindgen configuration as pf-ffvk (runtime = dlopen libclang). bindgen = { version = "0.72", features = ["runtime"], default-features = false } + +[lints] +workspace = true diff --git a/tools/display-disturb/Cargo.toml b/tools/display-disturb/Cargo.toml index 2bcd5242..7c85c22e 100644 --- a/tools/display-disturb/Cargo.toml +++ b/tools/display-disturb/Cargo.toml @@ -14,3 +14,6 @@ windows = { version = "0.62", features = [ "Win32_Graphics_Gdi", "Win32_Foundation", ] } + +[lints] +workspace = true diff --git a/tools/latency-probe/Cargo.toml b/tools/latency-probe/Cargo.toml index 7fa005ac..5e3e01d7 100644 --- a/tools/latency-probe/Cargo.toml +++ b/tools/latency-probe/Cargo.toml @@ -9,3 +9,6 @@ authors.workspace = true repository.workspace = true [dependencies] + +[lints] +workspace = true diff --git a/tools/latency-probe/src/main.rs b/tools/latency-probe/src/main.rs index 532b2dc9..06e79b77 100644 --- a/tools/latency-probe/src/main.rs +++ b/tools/latency-probe/src/main.rs @@ -5,6 +5,7 @@ //! anything, so regressions are quantifiable. //! //! Status: scaffold. +#![forbid(unsafe_code)] fn main() { println!( diff --git a/tools/loss-harness/Cargo.toml b/tools/loss-harness/Cargo.toml index 3c8e034f..176d37aa 100644 --- a/tools/loss-harness/Cargo.toml +++ b/tools/loss-harness/Cargo.toml @@ -10,3 +10,6 @@ repository.workspace = true [dependencies] punktfunk-core = { path = "../../crates/punktfunk-core" } + +[lints] +workspace = true diff --git a/tools/loss-harness/src/main.rs b/tools/loss-harness/src/main.rs index 04c300aa..b871ac4b 100644 --- a/tools/loss-harness/src/main.rs +++ b/tools/loss-harness/src/main.rs @@ -4,6 +4,7 @@ //! both FEC schemes, and prints how many frames survive. A pure-software stand-in for //! `tc netem` that needs no network and runs anywhere `punktfunk_core` builds. The real punktfunk/1 //! harness adds `tc netem` jitter/reorder on the UDP path. +#![forbid(unsafe_code)] use punktfunk_core::config::{Config, FecConfig, FecScheme, ProtocolPhase, Role}; use punktfunk_core::crypto::SessionKey;