From 423460489571e99d8ab3b1f27115d216eb8ed52a Mon Sep 17 00:00:00 2001 From: Michael Bolin Date: Sun, 5 Oct 2025 11:54:45 -0700 Subject: [PATCH] fix: use low-level stdin read logic to avoid a BufReader --- .../responses-api-proxy/src/read_api_key.rs | 52 ++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/codex-rs/responses-api-proxy/src/read_api_key.rs b/codex-rs/responses-api-proxy/src/read_api_key.rs index 1dda92f380..21f4278c5c 100644 --- a/codex-rs/responses-api-proxy/src/read_api_key.rs +++ b/codex-rs/responses-api-proxy/src/read_api_key.rs @@ -1,7 +1,6 @@ use anyhow::Context; use anyhow::Result; use anyhow::anyhow; -use std::io::Read; use zeroize::Zeroize; /// Use a generous buffer size to avoid truncation and to allow for longer API @@ -13,10 +12,61 @@ const AUTH_HEADER_PREFIX: &[u8] = b"Bearer "; /// value with the auth token used with `Bearer`. The header value is returned /// as a `&'static str` whose bytes are locked in memory to avoid accidental /// exposure. +#[cfg(unix)] pub(crate) fn read_auth_header_from_stdin() -> Result<&'static str> { + read_auth_header_with(read_from_unix_stdin) +} + +#[cfg(windows)] +pub(crate) fn read_auth_header_from_stdin() -> Result<&'static str> { + use std::io::Read; + + // Note that stdio::io::stdin() has an internal BufReader: + // https://github.com/rust-lang/rust/blob/bcbbdcb8522fd3cb4a8dde62313b251ab107694d/library/std/src/io/stdio.rs#L250-L252 + // which can end up retaining a copy of stdin data in memory longer than + // necessary. This should be replaced with Windows equivalents if this is + // a concern, though note we do not have an equivalent of mlock() on + // Windows right now, either. read_auth_header_with(|buffer| std::io::stdin().read(buffer)) } +#[cfg(unix)] +fn read_from_unix_stdin(buffer: &mut [u8]) -> std::io::Result { + use libc::c_void; + use libc::read; + + let mut total = 0; + while total < buffer.len() { + let slice = &mut buffer[total..]; + let result = unsafe { + read( + libc::STDIN_FILENO, + slice.as_mut_ptr().cast::(), + slice.len(), + ) + }; + + if result == 0 { + break; + } + + if result < 0 { + let err = std::io::Error::last_os_error(); + if err.kind() == std::io::ErrorKind::Interrupted { + continue; + } + return Err(err); + } + + total += result as usize; + if result as usize != slice.len() { + break; + } + } + + Ok(total) +} + fn read_auth_header_with(read_fn: F) -> Result<&'static str> where F: FnOnce(&mut [u8]) -> std::io::Result,