hive-c0re: refuse an account name for the disk path, not just the store one
`token_path`'s doc claimed the compiler was the check and that nothing had to remember to perform one. True of `agent`, which is an `Ident`. Not true of `account`, a bare `&str` concatenated into the filename — safe only because `deliver` happened to validate it first, which is the caller-must-remember pattern the comment denied. Observably a no-op today: the one call site already rejects a bad account before reaching here. What changes is that the signature now enforces what the comment asserted, so a second caller cannot skip it. The check is `path::checked_segment`, made public rather than reimplemented. Two copies of a charset are two charsets: they agree until one is edited, and the day they diverge a name is legal in the store and not on disk. An account name cannot simply become an `Ident` the way an agent name is: it is an attribute name in `hyperhive.matrixAccounts`, so uppercase and underscore are already configurable, and narrowing that is a decision rather than a refactor. The new test's controls pin both. Found by argus reviewing the merged PR.
This commit is contained in:
parent
247ff4498d
commit
6de6bd5d87
2 changed files with 53 additions and 13 deletions
|
|
@ -23,7 +23,17 @@ pub const AGENT_PREFIX: &str = "swarm/agents";
|
|||
/// out of the prefix entirely. Both are names this crate receives from
|
||||
/// elsewhere — an agent name from the topology, an account name from an
|
||||
/// agent's own config — so neither is trusted to be well-formed here.
|
||||
fn checked_segment(kind: &'static str, value: &str) -> Result<(), Error> {
|
||||
///
|
||||
/// Public because the same name is also used to build a path **on disk**, and
|
||||
/// that guard must accept exactly what this one does. Two copies of a charset
|
||||
/// are two charsets: they agree until one is edited, and the day they diverge
|
||||
/// is the day a name is legal in the store and not on the filesystem, or the
|
||||
/// reverse.
|
||||
///
|
||||
/// # Errors
|
||||
/// [`Error::PathSegment`] when `value` is empty or holds anything outside
|
||||
/// `[A-Za-z0-9_-]`.
|
||||
pub fn checked_segment(kind: &'static str, value: &str) -> Result<(), Error> {
|
||||
if value.is_empty() {
|
||||
return Err(Error::PathSegment {
|
||||
kind,
|
||||
|
|
|
|||
Loading…
Reference in a new issue