aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCody Robibero <cody@robibe.ro>2026-08-22 08:43:07 -0400
committerGitHub <noreply@github.com>2026-08-22 08:43:07 -0400
commitc04f11bd76acd19a1440bbb4351160642a09ef9c (patch)
tree8063f43084f6c7ba1ad2a50fb5a0bc084a08dad4 /src
parent6617a27de30f595617b372d53910c35e49d76364 (diff)
parent9ba91d4583f3671eaacae8e073fb53288f9b8715 (diff)
Merge pull request #17685 from jellyfin/GHSA-wwwm-px48-fpvq-v12
Fix GHSA-wwwm-px48-fpvq
Diffstat (limited to 'src')
-rw-r--r--src/Jellyfin.Extensions/StringExtensions.cs37
-rw-r--r--src/Jellyfin.LiveTv/IO/EncodedRecorder.cs4
2 files changed, 39 insertions, 2 deletions
diff --git a/src/Jellyfin.Extensions/StringExtensions.cs b/src/Jellyfin.Extensions/StringExtensions.cs
index 906efbcbcc..38f1cf738f 100644
--- a/src/Jellyfin.Extensions/StringExtensions.cs
+++ b/src/Jellyfin.Extensions/StringExtensions.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Text;
using System.Text.RegularExpressions;
using ICU4N.Text;
@@ -173,5 +174,41 @@ namespace Jellyfin.Extensions
return cleaned;
}
+
+ /// <summary>
+ /// Escapes an argument so that it survives command line parsing as a single argument when it is wrapped in double quotes by the caller.
+ /// </summary>
+ /// <param name="value">The argument to escape.</param>
+ /// <returns>The escaped argument.</returns>
+ public static string EscapeProcessArgument(this string value)
+ {
+ ArgumentNullException.ThrowIfNull(value);
+
+ var span = value.AsSpan();
+ if (!span.Contains('"'))
+ {
+ var trailing = span.Length - span.TrimEnd('\\').Length;
+ return trailing == 0 ? value : string.Concat(value, new string('\\', trailing));
+ }
+
+ var escaped = new StringBuilder(value.Length + 8);
+ var backslashes = 0;
+
+ foreach (var character in span)
+ {
+ if (character == '\\')
+ {
+ backslashes++;
+ continue;
+ }
+
+ escaped
+ .Append('\\', character == '"' ? (backslashes * 2) + 1 : backslashes)
+ .Append(character);
+ backslashes = 0;
+ }
+
+ return escaped.Append('\\', backslashes * 2).ToString();
+ }
}
}
diff --git a/src/Jellyfin.LiveTv/IO/EncodedRecorder.cs b/src/Jellyfin.LiveTv/IO/EncodedRecorder.cs
index 19c4514766..633c4f95ed 100644
--- a/src/Jellyfin.LiveTv/IO/EncodedRecorder.cs
+++ b/src/Jellyfin.LiveTv/IO/EncodedRecorder.cs
@@ -188,8 +188,8 @@ namespace Jellyfin.LiveTv.IO
var commandLineArgs = string.Format(
CultureInfo.InvariantCulture,
"-i \"{0}\" {2} -map_metadata -1 -threads {6} {3}{4}{5} -y \"{1}\"",
- inputTempFile,
- targetFile.Replace("\"", "\\\"", StringComparison.Ordinal), // Escape quotes in filename
+ inputTempFile.EscapeProcessArgument(),
+ targetFile.EscapeProcessArgument(),
videoArgs,
GetAudioArgs(mediaSource),
subtitleArgs,