diff --git a/src/modes/get.rs b/src/modes/get.rs index c7d6297..d3686e4 100644 --- a/src/modes/get.rs +++ b/src/modes/get.rs @@ -43,6 +43,17 @@ pub fn mode_get( let mut item_path = data_path.clone(); item_path.push(item_id.to_string()); + // Check if this is a binary item and we're outputting to a TTY + if !args.options.force { + if let Some(binary_meta) = item.meta.get("binary") { + if binary_meta == "true" { + if is_stdout_tty() { + return Err(anyhow!("Refusing to output binary data to TTY, use --force to override")); + } + } + } + } + let compression_type = CompressionType::from_str(&item.compression)?; let compression_engine = get_compression_engine(compression_type)?; compression_engine.cat(item_path.clone())?; @@ -52,3 +63,21 @@ pub fn mode_get( Err(anyhow!("Unable to find matching item in database")) } } + +fn is_stdout_tty() -> bool { + #[cfg(unix)] + unsafe { + libc::isatty(libc::STDOUT_FILENO) != 0 + } + + #[cfg(windows)] + unsafe { + let stdout_handle = winapi::um::processenv::GetStdHandle(winapi::um::winbase::STD_OUTPUT_HANDLE); + let mut console_mode: winapi::shared::minwindef::DWORD = 0; + winapi::um::consoleapi::GetConsoleMode(stdout_handle, &mut console_mode) != 0 + } + + // Fallback for non-unix platforms or if we can't determine + #[cfg(not(any(unix, windows)))] + false +}