From c898a1499c650b89002faa15696a043d94eef3ec Mon Sep 17 00:00:00 2001 From: Alex Zenla Date: Sat, 26 Sep 2026 20:16:09 -0700 Subject: [PATCH] fix(bls): combine the options of every options line The Boot Loader Specification allows the options key to appear more than once, with all of the options combined in order. Each options line replaced the previous one instead, so an entry that set root= on one line and other options on the next booted without its root filesystem. --- crates/bls/src/lib.rs | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/crates/bls/src/lib.rs b/crates/bls/src/lib.rs index 6d2a26d..97c97eb 100644 --- a/crates/bls/src/lib.rs +++ b/crates/bls/src/lib.rs @@ -66,9 +66,17 @@ impl FromStr for BlsEntry { title = Some(value.trim().to_string()); } - // The options to pass to the entry. + // The options to pass to the entry. The options key can appear more than once, + // and all the options are combined in the order they appear. "options" => { - options = Some(value.trim().to_string()); + let value = value.trim(); + match options.as_mut() { + Some(options) => { + options.push(' '); + options.push_str(value); + } + None => options = Some(value.to_string()), + } } // The path to the linux kernel. @@ -571,6 +579,13 @@ efi /EFI/fedora/shimx64.efi assert_eq!(entry.initrd, ["/intel-ucode.img", "/initramfs.img"]); } + #[test] + fn parse_multiple_options_lines_combined_in_order() { + let input = "linux /vmlinuz\noptions root=/dev/sda1 ro\noptions quiet\n"; + let entry: BlsEntry = input.parse().unwrap(); + assert_eq!(entry.options().as_deref(), Some("root=/dev/sda1 ro quiet")); + } + #[test] fn initrd_paths_normalises_slashes() { let entry: BlsEntry = "linux /vmlinuz\ninitrd /boot/initrd.img\n".parse().unwrap();