aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bin/tp.rs27
-rw-r--r--src/bin/tpd.rs4
-rw-r--r--src/daemon.rs10
3 files changed, 30 insertions, 11 deletions
diff --git a/src/bin/tp.rs b/src/bin/tp.rs
index 860d1c9..5c4c473 100644
--- a/src/bin/tp.rs
+++ b/src/bin/tp.rs
@@ -110,14 +110,27 @@ fn main() {
std::process::exit(1);
}
};
+ // Read at most MAX_PASTE + 1 byte so we can detect
+ // oversized input without unbounded allocation.
+ const MAX_PASTE: usize = 64 * 1024;
let mut content = Vec::new();
- if let Err(e) = std::io::stdin().read_to_end(&mut content) {
- eprintln!("error: reading stdin: {e}");
- std::process::exit(1);
- }
- if content.is_empty() {
- eprintln!("error: empty input");
- std::process::exit(1);
+ match std::io::stdin()
+ .take((MAX_PASTE + 1) as u64)
+ .read_to_end(&mut content)
+ {
+ Ok(0) => {
+ eprintln!("error: empty input");
+ std::process::exit(1);
+ }
+ Ok(n) if n > MAX_PASTE => {
+ eprintln!("error: input exceeds 64 KiB limit");
+ std::process::exit(1);
+ }
+ Err(e) => {
+ eprintln!("error: reading stdin: {e}");
+ std::process::exit(1);
+ }
+ _ => {}
}
let cmd = if public { "PUTP" } else { "PUT" };
format!("{cmd} {ttl_secs} {}\n", base58::encode(&content))
diff --git a/src/bin/tpd.rs b/src/bin/tpd.rs
index a1edf79..e1ebc7b 100644
--- a/src/bin/tpd.rs
+++ b/src/bin/tpd.rs
@@ -256,7 +256,9 @@ fn main() {
let shutdown = Arc::new(AtomicBool::new(false));
- // Signal handler
+ // Signal handler — Arc::into_raw intentionally leaks the
+ // refcount so the pointer remains valid for the process
+ // lifetime. No matching Arc::from_raw needed.
let sig = Arc::clone(&shutdown);
unsafe {
SHUTDOWN_PTR.store(
diff --git a/src/daemon.rs b/src/daemon.rs
index f12efd9..12757a3 100644
--- a/src/daemon.rs
+++ b/src/daemon.rs
@@ -298,9 +298,13 @@ fn handle_client(
"request too large".into(),
));
writer.write_all(resp.as_bytes())?;
- // Drain remaining bytes until newline
- let mut discard = String::new();
- let _ = reader.read_line(&mut discard);
+ // Drain remaining bytes until newline (bounded to
+ // prevent a client without newlines from blocking
+ // indefinitely beyond the read timeout).
+ let mut discard = Vec::new();
+ let _ = (&mut reader)
+ .take(MAX_LINE_SIZE as u64)
+ .read_until(b'\n', &mut discard);
continue;
}
let line = line.trim();