Skip to content

Commit

Permalink
Make sure paths are always escaped
Browse files Browse the repository at this point in the history
  • Loading branch information
AngheloAlf committed Aug 12, 2024
1 parent eb3d3b2 commit f552917
Show file tree
Hide file tree
Showing 11 changed files with 208 additions and 113 deletions.
11 changes: 7 additions & 4 deletions slinky-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::{error::Error, path::PathBuf};

use clap::Parser;
use regex::Regex;
use slinky::ScriptGenerator;
use slinky::{RuntimeSettings, ScriptGenerator};

// TODO: Add program description to cli

Expand Down Expand Up @@ -69,13 +69,16 @@ fn create_runtime_settings(cli: &Cli) -> slinky::RuntimeSettings {
fn write_script(
writer: &mut impl ScriptGenerator,
document: &slinky::Document,
rs: &RuntimeSettings,
output: &Option<PathBuf>,
) {
writer.add_whole_document(document).expect("ah?");

if let Some(output_path) = output {
writer
.export_linker_script_to_file(output_path)
.export_linker_script_to_file(
&rs.escape_path(output_path).expect("Error escaping path"),
)
.expect("Error writing the linker script");
} else {
println!(
Expand Down Expand Up @@ -104,10 +107,10 @@ fn main() {
if cli.partial_linking {
let mut writer = slinky::PartialLinkerWriter::new(&document, &rs);

write_script(&mut writer, &document, &cli.output);
write_script(&mut writer, &document, &rs, &cli.output);
} else {
let mut writer = slinky::LinkerWriter::new(&document, &rs);

write_script(&mut writer, &document, &cli.output);
write_script(&mut writer, &document, &rs, &cli.output);
}
}
51 changes: 51 additions & 0 deletions slinky/src/escaped_path.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/* SPDX-FileCopyrightText: © 2024 decompals */
/* SPDX-License-Identifier: MIT */

use std::path::{Path, PathBuf};

#[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
pub struct EscapedPath(pub PathBuf);

impl AsRef<PathBuf> for EscapedPath {
fn as_ref(&self) -> &PathBuf {
&self.0
}
}

impl AsRef<Path> for EscapedPath {
fn as_ref(&self) -> &Path {
&self.0
}
}

impl AsMut<PathBuf> for EscapedPath {
fn as_mut(&mut self) -> &mut PathBuf {
&mut self.0
}
}

impl From<String> for EscapedPath {
fn from(value: String) -> Self {
Self(PathBuf::from(value))
}
}

impl Default for EscapedPath {
fn default() -> Self {
Self::new()
}
}

impl EscapedPath {
pub fn new() -> Self {
Self(PathBuf::new())
}

pub fn push(&mut self, path: EscapedPath) {
self.0.push(path.0)
}

pub fn display(&self) -> std::path::Display {
self.0.display()
}
}
15 changes: 14 additions & 1 deletion slinky/src/file_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ use std::{
path::{Path, PathBuf},
};

use crate::{absent_nullable::AbsentNullable, file_kind::FileKind, Settings, SlinkyError};
use crate::{
absent_nullable::AbsentNullable, file_kind::FileKind, EscapedPath, RuntimeSettings, Settings,
SlinkyError,
};

#[derive(PartialEq, Debug, Clone)]
pub struct FileInfo {
Expand Down Expand Up @@ -55,6 +58,16 @@ impl FileInfo {
}
}

impl FileInfo {
pub fn path_escaped(&self, rs: &RuntimeSettings) -> Result<EscapedPath, SlinkyError> {
rs.escape_path(&self.path)
}

pub fn dir_escaped(&self, rs: &RuntimeSettings) -> Result<EscapedPath, SlinkyError> {
rs.escape_path(&self.dir)
}
}

#[derive(Deserialize, PartialEq, Debug)]
#[serde(deny_unknown_fields)]
pub(crate) struct FileInfoSerial {
Expand Down
2 changes: 2 additions & 0 deletions slinky/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

mod absent_nullable;
mod error;
mod escaped_path;
mod traits;
mod utils;

Expand All @@ -28,6 +29,7 @@ mod runtime_settings;
pub mod version;

pub use error::SlinkyError;
pub use escaped_path::EscapedPath;

pub use linker_symbols_style::LinkerSymbolsStyle;
pub use settings::Settings;
Expand Down
98 changes: 41 additions & 57 deletions slinky/src/linker_writer.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
/* SPDX-FileCopyrightText: © 2024 decompals */
/* SPDX-License-Identifier: MIT */

use std::path::PathBuf;
use std::{io::Write, path::Path};
use std::io::Write;

use crate::{
utils, version, Document, FileInfo, FileKind, RuntimeSettings, ScriptExporter, ScriptGenerator,
ScriptImporter, Segment, SlinkyError, SymbolAssignment, VramClass,
utils, version, Document, EscapedPath, FileInfo, FileKind, RuntimeSettings, ScriptExporter,
ScriptGenerator, ScriptImporter, Segment, SlinkyError, SymbolAssignment, VramClass,
};

use crate::script_buffer::ScriptBuffer;
Expand All @@ -15,7 +14,7 @@ pub struct LinkerWriter<'a> {
buffer: ScriptBuffer,

// Used for dependency generation
files_paths: indexmap::IndexSet<PathBuf>,
files_paths: indexmap::IndexSet<EscapedPath>,

vram_classes: indexmap::IndexMap<String, VramClass>,

Expand Down Expand Up @@ -115,8 +114,8 @@ impl ScriptImporter for LinkerWriter<'_> {
}

impl ScriptExporter for LinkerWriter<'_> {
fn export_linker_script_to_file(&self, path: &Path) -> Result<(), SlinkyError> {
let mut f = utils::create_file_and_parents(path)?;
fn export_linker_script_to_file(&self, path: &EscapedPath) -> Result<(), SlinkyError> {
let mut f = utils::create_file_and_parents(path.as_ref())?;

self.export_linker_script(&mut f)
}
Expand All @@ -135,17 +134,14 @@ impl ScriptExporter for LinkerWriter<'_> {
}

fn save_other_files(&self) -> Result<(), SlinkyError> {
if let Some(d_path) = &self.d.settings.d_path {
if let Some(target_path) = &self.d.settings.target_path {
self.export_dependencies_file_to_file(
&self.rs.escape_path(d_path)?,
&self.rs.escape_path(target_path)?,
)?;
if let Some(d_path) = &self.d.settings.d_path_escaped(self.rs)? {
if let Some(target_path) = &self.d.settings.target_path_escaped(self.rs)? {
self.export_dependencies_file_to_file(d_path, target_path)?;
}
}

if let Some(symbols_header_path) = &self.d.settings.symbols_header_path {
self.export_symbol_header_to_file(&self.rs.escape_path(symbols_header_path)?)?;
if let Some(symbols_header_path) = &self.d.settings.symbols_header_path_escaped(self.rs)? {
self.export_symbol_header_to_file(symbols_header_path)?;
}

Ok(())
Expand Down Expand Up @@ -173,7 +169,7 @@ impl LinkerWriter<'_> {
pub fn export_dependencies_file(
&self,
dst: &mut impl Write,
target_path: &Path,
target_path: &EscapedPath,
) -> Result<(), SlinkyError> {
if self.rs.emit_version_comment() {
if let Err(e) = write!(
Expand All @@ -190,20 +186,18 @@ impl LinkerWriter<'_> {
}
}

let escaped_target_path = self.rs.escape_path(target_path)?;
if let Err(e) = write!(dst, "{}:", escaped_target_path.display()) {
if let Err(e) = write!(dst, "{}:", target_path.display()) {
return Err(SlinkyError::FailedWrite {
description: e.to_string(),
contents: escaped_target_path.display().to_string(),
contents: target_path.display().to_string(),
});
}

for p in &self.files_paths {
let escaped_p = self.rs.escape_path(p)?;
if let Err(e) = write!(dst, " \\\n {}", escaped_p.display()) {
if let Err(e) = write!(dst, " \\\n {}", p.display()) {
return Err(SlinkyError::FailedWrite {
description: e.to_string(),
contents: escaped_p.display().to_string(),
contents: p.display().to_string(),
});
}
}
Expand All @@ -216,11 +210,10 @@ impl LinkerWriter<'_> {
}

for p in &self.files_paths {
let escaped_p = self.rs.escape_path(p)?;
if let Err(e) = writeln!(dst, "{}:", escaped_p.display()) {
if let Err(e) = writeln!(dst, "{}:", p.display()) {
return Err(SlinkyError::FailedWrite {
description: e.to_string(),
contents: escaped_p.display().to_string(),
contents: p.display().to_string(),
});
}
}
Expand All @@ -230,17 +223,17 @@ impl LinkerWriter<'_> {

pub fn export_dependencies_file_to_file(
&self,
path: &Path,
target_path: &Path,
path: &EscapedPath,
target_path: &EscapedPath,
) -> Result<(), SlinkyError> {
let mut f = utils::create_file_and_parents(path)?;
let mut f = utils::create_file_and_parents(path.as_ref())?;

self.export_dependencies_file(&mut f, target_path)
}

pub fn export_dependencies_file_to_string(
&self,
target_path: &Path,
target_path: &EscapedPath,
) -> Result<String, SlinkyError> {
let mut s = Vec::new();

Expand Down Expand Up @@ -311,8 +304,8 @@ impl LinkerWriter<'_> {
Ok(())
}

pub fn export_symbol_header_to_file(&self, path: &Path) -> Result<(), SlinkyError> {
let mut f = utils::create_file_and_parents(path)?;
pub fn export_symbol_header_to_file(&self, path: &EscapedPath) -> Result<(), SlinkyError> {
let mut f = utils::create_file_and_parents(path.as_ref())?;

self.export_symbol_header(&mut f)
}
Expand Down Expand Up @@ -756,7 +749,7 @@ impl LinkerWriter<'_> {
segment: &Segment,
section: &str,
sections: &[String],
base_path: &Path,
base_path: &EscapedPath,
) -> Result<(), SlinkyError> {
if !self.rs.should_emit_entry(
&file.exclude_if_any,
Expand All @@ -774,36 +767,28 @@ impl LinkerWriter<'_> {
// TODO: figure out glob support
match file.kind {
FileKind::Object => {
let mut path = base_path.to_path_buf();
path.extend(&file.path);
let mut path = base_path.clone();
path.push(file.path_escaped(self.rs)?);

let escaped_path = self.rs.escape_path(&path)?;

self.buffer.writeln(&format!(
"{}({}{});",
escaped_path.display(),
section,
wildcard
));
if !self.files_paths.contains(&escaped_path) {
self.files_paths.insert(escaped_path);
self.buffer
.writeln(&format!("{}({}{});", path.display(), section, wildcard));
if !self.files_paths.contains(&path) {
self.files_paths.insert(path);
}
}
FileKind::Archive => {
let mut path = base_path.to_path_buf();
path.extend(&file.path);

let escaped_path = self.rs.escape_path(&path)?;
let mut path = base_path.clone();
path.push(file.path_escaped(self.rs)?);

self.buffer.writeln(&format!(
"{}:{}({}{});",
escaped_path.display(),
path.display(),
file.subfile,
section,
wildcard
));
if !self.files_paths.contains(&escaped_path) {
self.files_paths.insert(escaped_path);
if !self.files_paths.contains(&path) {
self.files_paths.insert(path);
}
}
FileKind::Pad => {
Expand All @@ -819,9 +804,9 @@ impl LinkerWriter<'_> {
}
}
FileKind::Group => {
let mut new_base_path = base_path.to_path_buf();
let mut new_base_path = base_path.clone();

new_base_path.extend(&file.dir);
new_base_path.push(file.dir_escaped(self.rs)?);

for file_of_group in &file.files {
//self.emit_file(file_of_group, segment, section, sections, &new_base_path)?;
Expand All @@ -845,7 +830,7 @@ impl LinkerWriter<'_> {
segment: &Segment,
section: &str,
sections: &[String],
base_path: &Path,
base_path: &EscapedPath,
) -> Result<(), SlinkyError> {
if !file.section_order.is_empty() {
// Keys specify the section and value specify where it will be put.
Expand Down Expand Up @@ -886,11 +871,10 @@ impl LinkerWriter<'_> {
section: &str,
sections: &[String],
) -> Result<(), SlinkyError> {
let mut base_path = PathBuf::new();
let mut base_path = self.d.settings.base_path_escaped(self.rs)?;

base_path.extend(&self.d.settings.base_path);
if !self.reference_partial_objects {
base_path.extend(&segment.dir);
base_path.push(segment.dir_escaped(self.rs)?);
}

for file in &segment.files {
Expand Down
Loading

0 comments on commit f552917

Please sign in to comment.