Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 5 additions & 22 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1002,23 +1002,8 @@ impl Config {
if !m.path.is_dir() {
anyhow::bail!("[[filesys]] path {} is not a directory", m.path.display());
}
// The volume name becomes an AmigaDOS volume label (a DosList
// BSTR): 1-30 bytes, and no ':' '/' or NUL.
let vol = &m.volume;
if vol.is_empty() {
anyhow::bail!("[[filesys]] volume name must not be empty");
}
if vol.len() > 30 {
anyhow::bail!(
"[[filesys]] volume name {vol:?} is too long ({} bytes; max 30)",
vol.len()
);
}
if vol.contains([':', '/', '\0']) {
anyhow::bail!(
"[[filesys]] volume name {vol:?} contains an invalid \
character (no ':' '/' or NUL)"
);
if let Some(err) = crate::filesys::volume_name_error(&m.volume) {
anyhow::bail!("[[filesys]] {err}");
}
}
chain.add_board_with_rom(
Expand Down Expand Up @@ -1631,10 +1616,8 @@ fn drive_image(raw: RawDrive) -> Result<DriveImage> {
let trimmed = name.trim();
if trimmed.is_empty() {
None
} else if trimmed.contains([':', '/']) {
bail!("drive name {name:?} must not contain ':' or '/'");
} else if trimmed.chars().count() > 30 {
bail!("drive name {name:?} is too long (AmigaDOS volume names hold 30 characters)");
} else if let Some(err) = crate::filesys::volume_name_error(trimmed) {
bail!("drive name: {err}");
} else {
Some(trimmed.to_string())
}
Expand Down Expand Up @@ -3689,7 +3672,7 @@ mod tests {
"#,
)
.unwrap_err();
assert!(err.to_string().contains("must not contain"), "{err:#}");
assert!(err.to_string().contains("invalid character"), "{err:#}");

// Over the 30-character FFS volume-label limit.
let err = parse_config(&format!(
Expand Down
22 changes: 22 additions & 0 deletions src/filesys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,28 @@ pub const MOUNT_ENTRY_SIZE: usize = 32;
/// Maximum host mounts (units), and the divisor for each unit's fixed
/// board-window lock-pool slice.
pub const MOUNT_MAX_COUNT: usize = 8;
/// Longest AmigaDOS volume label: a DosList BSTR holds 30 bytes.
pub const VOLUME_NAME_MAX: usize = 30;

/// Why `name` would not work as an AmigaDOS volume label, or `None` if it
/// would. Shared by the config validator and the launcher's name editor so
/// the GUI cannot save a name the config would reject.
pub fn volume_name_error(name: &str) -> Option<String> {
if name.is_empty() {
Some("volume name must not be empty".to_string())
} else if name.len() > VOLUME_NAME_MAX {
Some(format!(
"volume name {name:?} is too long ({} bytes; max {VOLUME_NAME_MAX})",
name.len()
))
} else if name.contains([':', '/', '\0']) {
Some(format!(
"volume name {name:?} contains an invalid character (no ':' '/' or NUL)"
))
} else {
None
}
}
/// The DiagArea (`BoardSpec::copperline_services` points er_InitDiagVec
/// here): embedded in the handler ROM at +0x40, like real autoboot boards
/// carry theirs in the device ROM (see `_diag_area` in entry.s).
Expand Down
Loading
Loading