Skip to content

Commit

Permalink
Add Script validators
Browse files Browse the repository at this point in the history
  • Loading branch information
maxkofler committed Dec 8, 2023
1 parent ab6f1b3 commit a3e0f1d
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/validators.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

pub mod elf;
pub mod indexed_package;
pub mod scripts;

mod error;
pub use error::*;
Expand All @@ -27,12 +28,15 @@ pub struct ValidationResult<T> {
pub enum ValidatorAction<'a> {
/// Perform an action on a `ELF` file
ELF(elf::ELFAction<'a>),
/// Perform an action on a `Script` file
Script(scripts::ScriptAction<'a>),
}

impl<'a> std::fmt::Display for ValidatorAction<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::ELF(action) => action.fmt(f),
Self::Script(action) => action.fmt(f),
}
}
}
17 changes: 17 additions & 0 deletions src/validators/indexed_package.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,23 @@ pub fn validate_indexed_package<'a>(
});
}
}
crate::util::fs::FSEntry::Script(script) => {
let path = path.to_path_buf().join(entry.name());
let v_res = script.validate(input);

// If there are some results, append them to the return value
if !(v_res.actions.is_empty() && v_res.errors.is_empty()) {
res.push(FileValidationResult {
path,
actions: v_res
.actions
.into_iter()
.map(ValidatorAction::Script)
.collect(),
errors: v_res.errors,
});
}
}
_ => {}
}

Expand Down
82 changes: 82 additions & 0 deletions src/validators/scripts.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
//! Validators for `Script`s
use std::path::PathBuf;

use crate::{
error::{Error, Throwable},
package::IndexedPackage,
util::fs::{ScriptFile, SearchType, ToPathBuf},
};

use super::{ValidationError, ValidationInput, ValidationResult};

impl ScriptFile {
/// Validate an `Script`:
/// - Make sure the `interpreter` is linkable and modify the path for the correct location
/// # Arguments
/// * `input` - The `ValidationInput` to work correctly
pub fn validate<'a>(&self, input: &'a ValidationInput) -> ValidationResult<ScriptAction<'a>> {
let mut actions: Vec<ScriptAction> = Vec::new();
let mut errors: Vec<Error> = Vec::new();

// Validate the interpreter
if let Some(old_interpreter) = &self.interpreter {
if let Some(filename) = old_interpreter.0.file_name() {
if let Some(result) = input
.package_index
.find_fs_entry(&SearchType::ELF(filename))
{
actions.push(ScriptAction::ReplaceInterpreter {
interpreter: (old_interpreter.0.clone(), result.0.to_path_buf()),
package: result.1,
})
} else {
errors.push(
ValidationError::UnresolvedDependency {
filename: old_interpreter.0.as_os_str().to_owned(),
}
.throw("Resolving script interpreter".to_string()),
)
}
}
}

ValidationResult { actions, errors }
}
}

/// An action to perform on a Script file
#[derive(Clone)]
pub enum ScriptAction<'a> {
/// Set the `interpreter` available in `package`
ReplaceInterpreter {
/// The old and the new interpreter
interpreter: (PathBuf, PathBuf),
/// The package holding the interpreter (the dependency)
package: &'a dyn IndexedPackage,
},
}

impl<'a> std::fmt::Display for ScriptAction<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::ReplaceInterpreter {
interpreter,
package,
} => {
write!(
f,
"Replace SCRIPT interpreter '{}' with '{}' of package '{}' (args: '{}')",
interpreter.0.to_string_lossy(),
interpreter.1.to_string_lossy(),
package.get_full_name(),
interpreter
.1
.iter()
.map(|s| s.to_string_lossy().to_string())
.collect::<Vec<String>>()
.join(" "),
)
}
}
}
}

0 comments on commit a3e0f1d

Please sign in to comment.