diff --git a/crates/boot/src/actions/chainload.rs b/crates/boot/src/actions/chainload.rs index 359a992..6d5a8a7 100644 --- a/crates/boot/src/actions/chainload.rs +++ b/crates/boot/src/actions/chainload.rs @@ -21,7 +21,7 @@ pub fn chainload(context: Rc, configuration: &ChainloadConfigurat // Resolve the path to the image to chainload. let resolved = eficore::path::resolve_path( Some(context.root().loaded_image_path()?), - &context.stamp(&configuration.path), + context.stamp(&configuration.path), ) .context("unable to resolve chainload path")?; @@ -38,8 +38,7 @@ pub fn chainload(context: Rc, configuration: &ChainloadConfigurat .context("unable to open loaded image protocol")?; // Stamp and combine the options to pass to the image. - let options = - utils::combine_options(configuration.options.iter().map(|item| context.stamp(item))); + let options = utils::combine_options(context.stamp_iter(configuration.options.iter())); // Pass the load options to the image. // If no options are provided, the resulting string will be empty. @@ -50,6 +49,7 @@ pub fn chainload(context: Rc, configuration: &ChainloadConfigurat .context("unable to convert chainloader options to CString16")?, ); + // Ensure the chainloader options limit is not exceeded. if options.num_bytes() > u32::MAX as usize { bail!("chainloader options too large"); } diff --git a/crates/boot/src/actions/edera.rs b/crates/boot/src/actions/edera.rs index 1acb94c..bf92cf1 100644 --- a/crates/boot/src/actions/edera.rs +++ b/crates/boot/src/actions/edera.rs @@ -20,20 +20,11 @@ use uefi::Guid; /// Builds a configuration string for the Xen EFI stub using the specified `configuration`. fn build_xen_config(context: Rc, configuration: &EderaConfiguration) -> String { // Stamp xen options and combine them. - let xen_options = utils::combine_options( - configuration - .xen_options - .iter() - .map(|item| context.stamp(item)), - ); + let xen_options = utils::combine_options(context.stamp_iter(configuration.xen_options.iter())); // Stamp kernel options and combine them. - let kernel_options = utils::combine_options( - configuration - .kernel_options - .iter() - .map(|item| context.stamp(item)), - ); + let kernel_options = + utils::combine_options(context.stamp_iter(configuration.kernel_options.iter())); // xen config file format is ini-like [ diff --git a/crates/boot/src/context.rs b/crates/boot/src/context.rs index ea33c64..7dd9c84 100644 --- a/crates/boot/src/context.rs +++ b/crates/boot/src/context.rs @@ -269,6 +269,15 @@ impl SproutContext { Self::stamp_values(&self.all_values(), text.as_ref()).1 } + /// Stamps all the items from the iterator `input` with all the values in this [SproutContext] + /// and it's parents. This calls [self.stamp] on each item. + pub fn stamp_iter( + &self, + input: impl Iterator>, + ) -> impl Iterator { + input.map(|item| self.stamp(item)) + } + /// Unloads a [SproutContext] back into an owned context. This /// may not succeed if something else is holding onto the value. pub fn unload(self: Rc) -> Option { diff --git a/crates/boot/src/drivers.rs b/crates/boot/src/drivers.rs index 1f95abc..62d9b90 100644 --- a/crates/boot/src/drivers.rs +++ b/crates/boot/src/drivers.rs @@ -18,7 +18,7 @@ fn load_driver(context: Rc, driver: &DriverDeclaration) -> Result // Resolve the path to the driver image. let resolved = eficore::path::resolve_path( Some(context.root().loaded_image_path()?), - &context.stamp(&driver.path), + context.stamp(&driver.path), ) .context("unable to resolve path to driver")?; diff --git a/crates/boot/src/generators/list.rs b/crates/boot/src/generators/list.rs index 290440a..9716c09 100644 --- a/crates/boot/src/generators/list.rs +++ b/crates/boot/src/generators/list.rs @@ -22,11 +22,10 @@ pub fn generate( // Stamp the entry title and actions from the template. let mut entry = list.entry.clone(); - entry.actions = entry - .actions - .into_iter() - .map(|action| context.stamp(action)) - .collect(); + + // Stamp all the actions this entry references. + entry.actions = context.stamp_iter(entry.actions.into_iter()).collect(); + // Push the entry into the list with the new context. entries.push(BootableEntry::new( index.to_string(), diff --git a/crates/eficore/src/path.rs b/crates/eficore/src/path.rs index 02b82b9..a263117 100644 --- a/crates/eficore/src/path.rs +++ b/crates/eficore/src/path.rs @@ -48,8 +48,8 @@ fn cstring16_contains_char(string: &CString16, c: char) -> bool { /// Parses the input `path` as a [DevicePath]. /// Uses the [DevicePathFromText] protocol exclusively, and will fail if it cannot acquire the protocol. -pub fn text_to_device_path(path: &str) -> Result { - let path = CString16::try_from(path).context("unable to convert path to CString16")?; +pub fn text_to_device_path(path: impl AsRef) -> Result { + let path = CString16::try_from(path.as_ref()).context("unable to convert path to CString16")?; let device_path_from_text = uefi::boot::open_protocol_exclusive::( uefi::boot::get_handle_for_protocol::() .context("no device path from text protocol")?, @@ -113,8 +113,13 @@ pub fn device_path_subpath(path: &DevicePath) -> Result { /// Resolve a path specified by `input` to its various components. /// Uses `default_root_path` as the base root if one is not specified in the path. /// Returns [ResolvedPath] which contains the resolved components. -pub fn resolve_path(default_root_path: Option<&DevicePath>, input: &str) -> Result { - let mut path = text_to_device_path(input).context("unable to convert text to path")?; +pub fn resolve_path( + default_root_path: Option<&DevicePath>, + input: impl ToString, +) -> Result { + let mut input = input.to_string(); + + let mut path = text_to_device_path(&input).context("unable to convert text to path")?; let path_has_device = path .node_iter() .next() @@ -125,7 +130,6 @@ pub fn resolve_path(default_root_path: Option<&DevicePath>, input: &str) -> Resu .map(|it| it.to_string().contains('(')) .unwrap_or(false); if !path_has_device { - let mut input = input.to_string(); if !input.starts_with('\\') { input.insert(0, '\\'); } diff --git a/crates/eficore/src/shim.rs b/crates/eficore/src/shim.rs index bd8e1c5..49affa2 100644 --- a/crates/eficore/src/shim.rs +++ b/crates/eficore/src/shim.rs @@ -84,7 +84,7 @@ impl<'a> ShimInput<'a> { let path = path .to_string(DisplayOnly(false), AllowShortcuts(false)) .context("unable to convert device path to string")?; - let path = crate::path::resolve_path(None, &path.to_string()) + let path = crate::path::resolve_path(None, path.to_string()) .context("unable to resolve path")?; // Read the file path. let data = path.read_file()?;