From 6849666d5fc4892d75ca84190e27d6786df5ab56 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 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. --- 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, },