From: Elias Rohrer Date: Mon, 21 Aug 2023 12:39:24 +0000 (+0200) Subject: f Check `namespace`/`key` for control characters X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=commitdiff_plain;h=89103ab01cdc24352dfca565a50f4407ccfe5676;p=rust-lightning f Check `namespace`/`key` for control characters ... and use `PrintableString` --- diff --git a/lightning-persister/src/fs_store.rs b/lightning-persister/src/fs_store.rs index cd3e9dda5..5ccc4d8c3 100644 --- a/lightning-persister/src/fs_store.rs +++ b/lightning-persister/src/fs_store.rs @@ -1,5 +1,6 @@ //! Objects related to [`FilesystemStore`] live here. use lightning::util::persist::KVStore; +use lightning::util::string::PrintableString; use std::collections::HashMap; use std::fs; @@ -53,7 +54,17 @@ impl KVStore for FilesystemStore { fn read(&self, namespace: &str, key: &str) -> std::io::Result { if key.is_empty() { - let msg = format!("Failed to read {}/{}: key may not be empty.", namespace, key); + let msg = format!("Failed to read {}/{}: key may not be empty.", + PrintableString(namespace), PrintableString(key)); + return Err(std::io::Error::new(std::io::ErrorKind::Other, msg)); + } + + if namespace.chars().any(|c| !c.is_ascii() || c.is_control()) || + key.chars().any(|c| !c.is_ascii() || c.is_control()) { + debug_assert!(false, "Failed to read {}/{}: namespace and key must be valid ASCII + strings.", PrintableString(namespace), PrintableString(key)); + let msg = format!("Failed to read {}/{}: namespace and key must be valid ASCII strings.", + PrintableString(namespace), PrintableString(key)); return Err(std::io::Error::new(std::io::ErrorKind::Other, msg)); } @@ -69,7 +80,17 @@ impl KVStore for FilesystemStore { fn write(&self, namespace: &str, key: &str, buf: &[u8]) -> std::io::Result<()> { if key.is_empty() { - let msg = format!("Failed to write {}/{}: key may not be empty.", namespace, key); + let msg = format!("Failed to write {}/{}: key may not be empty.", + PrintableString(namespace), PrintableString(key)); + return Err(std::io::Error::new(std::io::ErrorKind::Other, msg)); + } + + if namespace.chars().any(|c| !c.is_ascii() || c.is_control()) || + key.chars().any(|c| !c.is_ascii() || c.is_control()) { + debug_assert!(false, "Failed to write {}/{}: namespace and key must be valid ASCII + strings.", PrintableString(namespace), PrintableString(key)); + let msg = format!("Failed to write {}/{}: namespace and key must be valid ASCII strings.", + PrintableString(namespace), PrintableString(key)); return Err(std::io::Error::new(std::io::ErrorKind::Other, msg)); } @@ -144,7 +165,17 @@ impl KVStore for FilesystemStore { fn remove(&self, namespace: &str, key: &str) -> std::io::Result<()> { if key.is_empty() { - let msg = format!("Failed to remove {}/{}: key may not be empty.", namespace, key); + let msg = format!("Failed to remove {}/{}: key may not be empty.", + PrintableString(namespace), PrintableString(key)); + return Err(std::io::Error::new(std::io::ErrorKind::Other, msg)); + } + + if namespace.chars().any(|c| !c.is_ascii() || c.is_control()) || + key.chars().any(|c| !c.is_ascii() || c.is_control()) { + debug_assert!(false, "Failed to remove {}/{}: namespace and key must be valid ASCII + strings.", PrintableString(namespace), PrintableString(key)); + let msg = format!("Failed to remove {}/{}: namespace and key must be valid ASCII strings.", + PrintableString(namespace), PrintableString(key)); return Err(std::io::Error::new(std::io::ErrorKind::Other, msg)); }