diff --git a/src/converter.rs b/src/converter.rs index 30b8785..fc3e49e 100644 --- a/src/converter.rs +++ b/src/converter.rs @@ -1,14 +1,14 @@ use anyhow::{Context, Result}; -use ::image::{DynamicImage, ImageFormat, Rgba, RgbaImage}; +use ::image::{ImageFormat}; use printpdf::*; use dotext::MsDoc; -use ::lopdf::{self as lopdf_crate, dictionary, Object, ObjectId, Document as LoDocument}; +use ::lopdf::{dictionary, Object, ObjectId, Document as LoDocument}; use std::fs::{self, File}; -use std::io::{BufWriter, Read, Write}; +use std::io::{BufWriter, Read}; use std::path::{Path, PathBuf}; use std::process::Command; use tempfile::NamedTempFile; -use tracing::{debug, info, warn}; +use tracing::{debug, info}; use crate::pure_converter::PureRustConverter; diff --git a/src/docx_handler.rs b/src/docx_handler.rs index ff22f0e..47cbbec 100644 --- a/src/docx_handler.rs +++ b/src/docx_handler.rs @@ -1,13 +1,11 @@ use anyhow::{Context, Result}; use docx_rs::*; use std::fs::{self, File}; -use std::io::{Read, Write}; use std::path::{Path, PathBuf}; -use tempfile::NamedTempFile; use uuid::Uuid; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; -use tracing::{debug, info, warn}; +use tracing::{info, warn}; #[derive(Debug, Clone, Serialize, Deserialize)] pub struct DocxMetadata { diff --git a/src/pure_converter.rs b/src/pure_converter.rs index f4521b3..1987b16 100644 --- a/src/pure_converter.rs +++ b/src/pure_converter.rs @@ -2,14 +2,13 @@ use anyhow::{Context, Result}; use ::image::{DynamicImage, ImageFormat, Rgba, RgbaImage}; use printpdf::*; use std::fs::{self, File}; -use std::io::{BufReader, BufWriter, Read, Write}; +use std::io::{BufReader, BufWriter, Read}; use std::path::{Path, PathBuf}; use tempfile::NamedTempFile; -use tracing::{debug, info, warn}; +use tracing::{info}; use roxmltree; use zip::ZipArchive; -use rusttype::{Font, Scale}; -use ::lopdf::{self as lopdf_crate, dictionary, Object}; +use ::lopdf::{dictionary, Object}; pub struct PureRustConverter; @@ -31,7 +30,9 @@ impl PureRustConverter { let name = file.name().to_string(); if name == "word/document.xml" { - file.read_to_string(&mut document_xml)?; + let mut buf = Vec::new(); + file.read_to_end(&mut buf)?; + document_xml = String::from_utf8_lossy(&buf).to_string(); break; } } diff --git a/src/security.rs b/src/security.rs index da4a469..9fa5a61 100644 --- a/src/security.rs +++ b/src/security.rs @@ -243,15 +243,18 @@ impl SecurityConfig { return false; } - // Check whitelist (if set, only whitelisted commands are allowed) + // Check whitelist (if set, only whitelisted commands are allowed); + // Whitelist takes precedence over blacklist. if let Some(ref whitelist) = self.command_whitelist { - if !whitelist.contains(command) { + if whitelist.contains(command) { + return true; + } else { debug!("Command '{}' blocked: not in whitelist", command); return false; } } - - // Check blacklist (if set, blacklisted commands are blocked) + + // If no whitelist, enforce blacklist if present if let Some(ref blacklist) = self.command_blacklist { if blacklist.contains(command) { debug!("Command '{}' blocked: in blacklist", command); @@ -374,7 +377,17 @@ impl SecurityConfig { // In sandbox mode, only allow operations in temp directory let temp_dir = std::env::temp_dir(); - if let Ok(canonical_path) = path.canonicalize() { + // Fast-path for non-existent paths under common temp prefixes + if !path.exists() { + if let Some(s) = path.to_str() { + if s.starts_with("/tmp/") || s.starts_with("/private/tmp/") { + return true; + } + } + } + // Avoid requiring the file to exist. Use parent directory for canonicalization when needed. + let candidate = if path.exists() { path.to_path_buf() } else { path.parent().unwrap_or(path).to_path_buf() }; + if let Ok(canonical_path) = candidate.canonicalize() { if let Ok(canonical_temp) = temp_dir.canonicalize() { if canonical_path.starts_with(&canonical_temp) { return true;