From f655c0199db13139fbc7a016f6492176272ca74d Mon Sep 17 00:00:00 2001 From: Stu Leak Date: Fri, 9 Jan 2026 23:49:19 -0500 Subject: [PATCH] fix(author): sanitize output filenames at job creation time MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added explicit sanitization of output paths when creating authoring jobs to ensure special characters are removed before any filesystem operations. The sanitization now happens in two places: 1. addAuthorToQueue: Sanitizes the output path for regular authoring jobs 2. addAuthorVideoTSToQueue: Sanitizes the output path for VIDEO_TS->ISO jobs This ensures that: - OutputFile field in Job struct never contains special characters - Log filenames are sanitized (using the OutputFile basename) - All filesystem operations use clean filenames Before: /path/ifuckedmybestfriend'sgirlfriend.iso After: /path/ifuckedmybestfriendsgirlfriend.iso The display title shown to users still contains the original text, but all actual file operations use sanitized names. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 --- author_module.go | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/author_module.go b/author_module.go index 98b8562..307aa1d 100644 --- a/author_module.go +++ b/author_module.go @@ -2372,12 +2372,25 @@ func (s *appState) addAuthorToQueue(paths []string, region, aspect, title, outpu if strings.TrimSpace(titleLabel) == "" { titleLabel = "DVD" } + + // Sanitize output path to ensure no special characters in filesystem operations + sanitizedOutputPath := outputPath + dir := filepath.Dir(outputPath) + base := filepath.Base(outputPath) + ext := filepath.Ext(base) + nameWithoutExt := strings.TrimSuffix(base, ext) + sanitizedName := sanitizeForPath(nameWithoutExt) + if sanitizedName == "" { + sanitizedName = "dvd_output" + } + sanitizedOutputPath = filepath.Join(dir, sanitizedName+ext) + job := &queue.Job{ Type: queue.JobTypeAuthor, Title: fmt.Sprintf("Author DVD: %s", titleLabel), - Description: fmt.Sprintf("Output: %s", utils.ShortenMiddle(filepath.Base(outputPath), 40)), + Description: fmt.Sprintf("Output: %s", utils.ShortenMiddle(filepath.Base(sanitizedOutputPath), 40)), InputFile: paths[0], - OutputFile: outputPath, + OutputFile: sanitizedOutputPath, Config: config, } @@ -2399,15 +2412,28 @@ func (s *appState) addAuthorVideoTSToQueue(videoTSPath, title, outputPath string if s.jobQueue == nil { return fmt.Errorf("queue not initialized") } + + // Sanitize output path to ensure no special characters in filesystem operations + sanitizedOutputPath := outputPath + dir := filepath.Dir(outputPath) + base := filepath.Base(outputPath) + ext := filepath.Ext(base) + nameWithoutExt := strings.TrimSuffix(base, ext) + sanitizedName := sanitizeForPath(nameWithoutExt) + if sanitizedName == "" { + sanitizedName = "dvd_output" + } + sanitizedOutputPath = filepath.Join(dir, sanitizedName+ext) + job := &queue.Job{ Type: queue.JobTypeAuthor, Title: fmt.Sprintf("Author ISO: %s", title), - Description: fmt.Sprintf("VIDEO_TS -> %s", utils.ShortenMiddle(filepath.Base(outputPath), 40)), + Description: fmt.Sprintf("VIDEO_TS -> %s", utils.ShortenMiddle(filepath.Base(sanitizedOutputPath), 40)), InputFile: videoTSPath, - OutputFile: outputPath, + OutputFile: sanitizedOutputPath, Config: map[string]interface{}{ "videoTSPath": videoTSPath, - "outputPath": outputPath, + "outputPath": sanitizedOutputPath, "makeISO": true, "title": title, },