From 6d7950bddc3733b02e8ba8968c8264cf115a52dc Mon Sep 17 00:00:00 2001 From: Shadowghost Date: Thu, 27 Mar 2025 16:10:20 +0100 Subject: [PATCH 1/4] Fix container parameter validation --- Jellyfin.Api/Controllers/AudioController.cs | 2 +- Jellyfin.Api/Controllers/DynamicHlsController.cs | 4 ++-- Jellyfin.Api/Controllers/LiveTvController.cs | 4 +++- Jellyfin.Api/Controllers/VideosController.cs | 2 +- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Jellyfin.Api/Controllers/AudioController.cs b/Jellyfin.Api/Controllers/AudioController.cs index 272b4034ed..33f21db714 100644 --- a/Jellyfin.Api/Controllers/AudioController.cs +++ b/Jellyfin.Api/Controllers/AudioController.cs @@ -259,7 +259,7 @@ public class AudioController : BaseJellyfinApiController [ProducesAudioFile] public async Task GetAudioStreamByContainer( [FromRoute, Required] Guid itemId, - [FromRoute, Required] string container, + [FromRoute, Required] [RegularExpression(EncodingHelper.ValidationRegex)] string container, [FromQuery] bool? @static, [FromQuery] string? @params, [FromQuery] string? tag, diff --git a/Jellyfin.Api/Controllers/DynamicHlsController.cs b/Jellyfin.Api/Controllers/DynamicHlsController.cs index ca8ab0ef75..90dcbd59e2 100644 --- a/Jellyfin.Api/Controllers/DynamicHlsController.cs +++ b/Jellyfin.Api/Controllers/DynamicHlsController.cs @@ -1106,7 +1106,7 @@ public class DynamicHlsController : BaseJellyfinApiController [FromRoute, Required] Guid itemId, [FromRoute, Required] string playlistId, [FromRoute, Required] int segmentId, - [FromRoute, Required] string container, + [FromRoute, Required] [RegularExpression(EncodingHelper.ValidationRegex)] string container, [FromQuery, Required] long runtimeTicks, [FromQuery, Required] long actualSegmentLengthTicks, [FromQuery] bool? @static, @@ -1291,7 +1291,7 @@ public class DynamicHlsController : BaseJellyfinApiController [FromRoute, Required] Guid itemId, [FromRoute, Required] string playlistId, [FromRoute, Required] int segmentId, - [FromRoute, Required] string container, + [FromRoute, Required] [RegularExpression(EncodingHelper.ValidationRegex)] string container, [FromQuery, Required] long runtimeTicks, [FromQuery, Required] long actualSegmentLengthTicks, [FromQuery] bool? @static, diff --git a/Jellyfin.Api/Controllers/LiveTvController.cs b/Jellyfin.Api/Controllers/LiveTvController.cs index 5461d12fa2..172686cadb 100644 --- a/Jellyfin.Api/Controllers/LiveTvController.cs +++ b/Jellyfin.Api/Controllers/LiveTvController.cs @@ -1190,7 +1190,9 @@ public class LiveTvController : BaseJellyfinApiController [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesVideoFile] - public ActionResult GetLiveStreamFile([FromRoute, Required] string streamId, [FromRoute, Required] string container) + public ActionResult GetLiveStreamFile( + [FromRoute, Required] string streamId, + [FromRoute, Required] [RegularExpression(EncodingHelper.ValidationRegex)] string container) { var liveStreamInfo = _mediaSourceManager.GetLiveStreamInfoByUniqueId(streamId); if (liveStreamInfo is null) diff --git a/Jellyfin.Api/Controllers/VideosController.cs b/Jellyfin.Api/Controllers/VideosController.cs index 6f18c1603b..685d502e42 100644 --- a/Jellyfin.Api/Controllers/VideosController.cs +++ b/Jellyfin.Api/Controllers/VideosController.cs @@ -556,7 +556,7 @@ public class VideosController : BaseJellyfinApiController [ProducesVideoFile] public Task GetVideoStreamByContainer( [FromRoute, Required] Guid itemId, - [FromRoute, Required] string container, + [FromRoute, Required] [RegularExpression(EncodingHelper.ValidationRegex)] string container, [FromQuery] bool? @static, [FromQuery] string? @params, [FromQuery] string? tag, From 1fcc79316dc236e0b070c3d695477d6e87f4c229 Mon Sep 17 00:00:00 2001 From: Shadowghost Date: Thu, 27 Mar 2025 16:11:24 +0100 Subject: [PATCH 2/4] Rename ValidationRegex to ContainerValidationRegex --- Jellyfin.Api/Controllers/AudioController.cs | 20 +++--- .../Controllers/DynamicHlsController.cs | 62 +++++++++---------- Jellyfin.Api/Controllers/LiveTvController.cs | 2 +- .../Controllers/UniversalAudioController.cs | 4 +- Jellyfin.Api/Controllers/VideosController.cs | 20 +++--- .../MediaEncoding/EncodingHelper.cs | 10 +-- 6 files changed, 59 insertions(+), 59 deletions(-) diff --git a/Jellyfin.Api/Controllers/AudioController.cs b/Jellyfin.Api/Controllers/AudioController.cs index 33f21db714..9e3065824f 100644 --- a/Jellyfin.Api/Controllers/AudioController.cs +++ b/Jellyfin.Api/Controllers/AudioController.cs @@ -92,18 +92,18 @@ public class AudioController : BaseJellyfinApiController [ProducesAudioFile] public async Task GetAudioStream( [FromRoute, Required] Guid itemId, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? container, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? container, [FromQuery] bool? @static, [FromQuery] string? @params, [FromQuery] string? tag, [FromQuery, ParameterObsolete] string? deviceProfileId, [FromQuery] string? playSessionId, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? segmentContainer, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? segmentContainer, [FromQuery] int? segmentLength, [FromQuery] int? minSegments, [FromQuery] string? mediaSourceId, [FromQuery] string? deviceId, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? audioCodec, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? audioCodec, [FromQuery] bool? enableAutoStreamCopy, [FromQuery] bool? allowVideoStreamCopy, [FromQuery] bool? allowAudioStreamCopy, @@ -133,8 +133,8 @@ public class AudioController : BaseJellyfinApiController [FromQuery] int? cpuCoreLimit, [FromQuery] string? liveStreamId, [FromQuery] bool? enableMpegtsM2TsMode, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? videoCodec, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? subtitleCodec, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? videoCodec, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? subtitleCodec, [FromQuery] string? transcodeReasons, [FromQuery] int? audioStreamIndex, [FromQuery] int? videoStreamIndex, @@ -259,18 +259,18 @@ public class AudioController : BaseJellyfinApiController [ProducesAudioFile] public async Task GetAudioStreamByContainer( [FromRoute, Required] Guid itemId, - [FromRoute, Required] [RegularExpression(EncodingHelper.ValidationRegex)] string container, + [FromRoute, Required] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string container, [FromQuery] bool? @static, [FromQuery] string? @params, [FromQuery] string? tag, [FromQuery, ParameterObsolete] string? deviceProfileId, [FromQuery] string? playSessionId, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? segmentContainer, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? segmentContainer, [FromQuery] int? segmentLength, [FromQuery] int? minSegments, [FromQuery] string? mediaSourceId, [FromQuery] string? deviceId, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? audioCodec, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? audioCodec, [FromQuery] bool? enableAutoStreamCopy, [FromQuery] bool? allowVideoStreamCopy, [FromQuery] bool? allowAudioStreamCopy, @@ -300,8 +300,8 @@ public class AudioController : BaseJellyfinApiController [FromQuery] int? cpuCoreLimit, [FromQuery] string? liveStreamId, [FromQuery] bool? enableMpegtsM2TsMode, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? videoCodec, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? subtitleCodec, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? videoCodec, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? subtitleCodec, [FromQuery] string? transcodeReasons, [FromQuery] int? audioStreamIndex, [FromQuery] int? videoStreamIndex, diff --git a/Jellyfin.Api/Controllers/DynamicHlsController.cs b/Jellyfin.Api/Controllers/DynamicHlsController.cs index 90dcbd59e2..f59ce3834b 100644 --- a/Jellyfin.Api/Controllers/DynamicHlsController.cs +++ b/Jellyfin.Api/Controllers/DynamicHlsController.cs @@ -166,18 +166,18 @@ public class DynamicHlsController : BaseJellyfinApiController [ProducesPlaylistFile] public async Task GetLiveHlsStream( [FromRoute, Required] Guid itemId, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? container, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? container, [FromQuery] bool? @static, [FromQuery] string? @params, [FromQuery] string? tag, [FromQuery, ParameterObsolete] string? deviceProfileId, [FromQuery] string? playSessionId, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? segmentContainer, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? segmentContainer, [FromQuery] int? segmentLength, [FromQuery] int? minSegments, [FromQuery] string? mediaSourceId, [FromQuery] string? deviceId, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? audioCodec, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? audioCodec, [FromQuery] bool? enableAutoStreamCopy, [FromQuery] bool? allowVideoStreamCopy, [FromQuery] bool? allowAudioStreamCopy, @@ -207,8 +207,8 @@ public class DynamicHlsController : BaseJellyfinApiController [FromQuery] int? cpuCoreLimit, [FromQuery] string? liveStreamId, [FromQuery] bool? enableMpegtsM2TsMode, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? videoCodec, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? subtitleCodec, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? videoCodec, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? subtitleCodec, [FromQuery] string? transcodeReasons, [FromQuery] int? audioStreamIndex, [FromQuery] int? videoStreamIndex, @@ -415,12 +415,12 @@ public class DynamicHlsController : BaseJellyfinApiController [FromQuery] string? tag, [FromQuery, ParameterObsolete] string? deviceProfileId, [FromQuery] string? playSessionId, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? segmentContainer, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? segmentContainer, [FromQuery] int? segmentLength, [FromQuery] int? minSegments, [FromQuery, Required] string mediaSourceId, [FromQuery] string? deviceId, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? audioCodec, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? audioCodec, [FromQuery] bool? enableAutoStreamCopy, [FromQuery] bool? allowVideoStreamCopy, [FromQuery] bool? allowAudioStreamCopy, @@ -452,8 +452,8 @@ public class DynamicHlsController : BaseJellyfinApiController [FromQuery] int? cpuCoreLimit, [FromQuery] string? liveStreamId, [FromQuery] bool? enableMpegtsM2TsMode, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? videoCodec, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? subtitleCodec, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? videoCodec, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? subtitleCodec, [FromQuery] string? transcodeReasons, [FromQuery] int? audioStreamIndex, [FromQuery] int? videoStreamIndex, @@ -591,12 +591,12 @@ public class DynamicHlsController : BaseJellyfinApiController [FromQuery] string? tag, [FromQuery, ParameterObsolete] string? deviceProfileId, [FromQuery] string? playSessionId, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? segmentContainer, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? segmentContainer, [FromQuery] int? segmentLength, [FromQuery] int? minSegments, [FromQuery, Required] string mediaSourceId, [FromQuery] string? deviceId, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? audioCodec, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? audioCodec, [FromQuery] bool? enableAutoStreamCopy, [FromQuery] bool? allowVideoStreamCopy, [FromQuery] bool? allowAudioStreamCopy, @@ -627,8 +627,8 @@ public class DynamicHlsController : BaseJellyfinApiController [FromQuery] int? cpuCoreLimit, [FromQuery] string? liveStreamId, [FromQuery] bool? enableMpegtsM2TsMode, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? videoCodec, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? subtitleCodec, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? videoCodec, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? subtitleCodec, [FromQuery] string? transcodeReasons, [FromQuery] int? audioStreamIndex, [FromQuery] int? videoStreamIndex, @@ -761,12 +761,12 @@ public class DynamicHlsController : BaseJellyfinApiController [FromQuery] string? tag, [FromQuery, ParameterObsolete] string? deviceProfileId, [FromQuery] string? playSessionId, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? segmentContainer, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? segmentContainer, [FromQuery] int? segmentLength, [FromQuery] int? minSegments, [FromQuery] string? mediaSourceId, [FromQuery] string? deviceId, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? audioCodec, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? audioCodec, [FromQuery] bool? enableAutoStreamCopy, [FromQuery] bool? allowVideoStreamCopy, [FromQuery] bool? allowAudioStreamCopy, @@ -798,8 +798,8 @@ public class DynamicHlsController : BaseJellyfinApiController [FromQuery] int? cpuCoreLimit, [FromQuery] string? liveStreamId, [FromQuery] bool? enableMpegtsM2TsMode, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? videoCodec, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? subtitleCodec, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? videoCodec, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? subtitleCodec, [FromQuery] string? transcodeReasons, [FromQuery] int? audioStreamIndex, [FromQuery] int? videoStreamIndex, @@ -933,12 +933,12 @@ public class DynamicHlsController : BaseJellyfinApiController [FromQuery] string? tag, [FromQuery, ParameterObsolete] string? deviceProfileId, [FromQuery] string? playSessionId, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? segmentContainer, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? segmentContainer, [FromQuery] int? segmentLength, [FromQuery] int? minSegments, [FromQuery] string? mediaSourceId, [FromQuery] string? deviceId, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? audioCodec, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? audioCodec, [FromQuery] bool? enableAutoStreamCopy, [FromQuery] bool? allowVideoStreamCopy, [FromQuery] bool? allowAudioStreamCopy, @@ -969,8 +969,8 @@ public class DynamicHlsController : BaseJellyfinApiController [FromQuery] int? cpuCoreLimit, [FromQuery] string? liveStreamId, [FromQuery] bool? enableMpegtsM2TsMode, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? videoCodec, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? subtitleCodec, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? videoCodec, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? subtitleCodec, [FromQuery] string? transcodeReasons, [FromQuery] int? audioStreamIndex, [FromQuery] int? videoStreamIndex, @@ -1106,7 +1106,7 @@ public class DynamicHlsController : BaseJellyfinApiController [FromRoute, Required] Guid itemId, [FromRoute, Required] string playlistId, [FromRoute, Required] int segmentId, - [FromRoute, Required] [RegularExpression(EncodingHelper.ValidationRegex)] string container, + [FromRoute, Required] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string container, [FromQuery, Required] long runtimeTicks, [FromQuery, Required] long actualSegmentLengthTicks, [FromQuery] bool? @static, @@ -1114,12 +1114,12 @@ public class DynamicHlsController : BaseJellyfinApiController [FromQuery] string? tag, [FromQuery, ParameterObsolete] string? deviceProfileId, [FromQuery] string? playSessionId, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? segmentContainer, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? segmentContainer, [FromQuery] int? segmentLength, [FromQuery] int? minSegments, [FromQuery] string? mediaSourceId, [FromQuery] string? deviceId, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? audioCodec, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? audioCodec, [FromQuery] bool? enableAutoStreamCopy, [FromQuery] bool? allowVideoStreamCopy, [FromQuery] bool? allowAudioStreamCopy, @@ -1151,8 +1151,8 @@ public class DynamicHlsController : BaseJellyfinApiController [FromQuery] int? cpuCoreLimit, [FromQuery] string? liveStreamId, [FromQuery] bool? enableMpegtsM2TsMode, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? videoCodec, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? subtitleCodec, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? videoCodec, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? subtitleCodec, [FromQuery] string? transcodeReasons, [FromQuery] int? audioStreamIndex, [FromQuery] int? videoStreamIndex, @@ -1291,7 +1291,7 @@ public class DynamicHlsController : BaseJellyfinApiController [FromRoute, Required] Guid itemId, [FromRoute, Required] string playlistId, [FromRoute, Required] int segmentId, - [FromRoute, Required] [RegularExpression(EncodingHelper.ValidationRegex)] string container, + [FromRoute, Required] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string container, [FromQuery, Required] long runtimeTicks, [FromQuery, Required] long actualSegmentLengthTicks, [FromQuery] bool? @static, @@ -1299,12 +1299,12 @@ public class DynamicHlsController : BaseJellyfinApiController [FromQuery] string? tag, [FromQuery, ParameterObsolete] string? deviceProfileId, [FromQuery] string? playSessionId, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? segmentContainer, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? segmentContainer, [FromQuery] int? segmentLength, [FromQuery] int? minSegments, [FromQuery] string? mediaSourceId, [FromQuery] string? deviceId, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? audioCodec, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? audioCodec, [FromQuery] bool? enableAutoStreamCopy, [FromQuery] bool? allowVideoStreamCopy, [FromQuery] bool? allowAudioStreamCopy, @@ -1335,8 +1335,8 @@ public class DynamicHlsController : BaseJellyfinApiController [FromQuery] int? cpuCoreLimit, [FromQuery] string? liveStreamId, [FromQuery] bool? enableMpegtsM2TsMode, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? videoCodec, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? subtitleCodec, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? videoCodec, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? subtitleCodec, [FromQuery] string? transcodeReasons, [FromQuery] int? audioStreamIndex, [FromQuery] int? videoStreamIndex, diff --git a/Jellyfin.Api/Controllers/LiveTvController.cs b/Jellyfin.Api/Controllers/LiveTvController.cs index 172686cadb..10f1789ad8 100644 --- a/Jellyfin.Api/Controllers/LiveTvController.cs +++ b/Jellyfin.Api/Controllers/LiveTvController.cs @@ -1192,7 +1192,7 @@ public class LiveTvController : BaseJellyfinApiController [ProducesVideoFile] public ActionResult GetLiveStreamFile( [FromRoute, Required] string streamId, - [FromRoute, Required] [RegularExpression(EncodingHelper.ValidationRegex)] string container) + [FromRoute, Required] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string container) { var liveStreamInfo = _mediaSourceManager.GetLiveStreamInfoByUniqueId(streamId); if (liveStreamInfo is null) diff --git a/Jellyfin.Api/Controllers/UniversalAudioController.cs b/Jellyfin.Api/Controllers/UniversalAudioController.cs index a5b5fde626..fd63347030 100644 --- a/Jellyfin.Api/Controllers/UniversalAudioController.cs +++ b/Jellyfin.Api/Controllers/UniversalAudioController.cs @@ -102,13 +102,13 @@ public class UniversalAudioController : BaseJellyfinApiController [FromQuery] string? mediaSourceId, [FromQuery] string? deviceId, [FromQuery] Guid? userId, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? audioCodec, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? audioCodec, [FromQuery] int? maxAudioChannels, [FromQuery] int? transcodingAudioChannels, [FromQuery] int? maxStreamingBitrate, [FromQuery] int? audioBitRate, [FromQuery] long? startTimeTicks, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? transcodingContainer, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? transcodingContainer, [FromQuery] MediaStreamProtocol? transcodingProtocol, [FromQuery] int? maxAudioSampleRate, [FromQuery] int? maxAudioBitDepth, diff --git a/Jellyfin.Api/Controllers/VideosController.cs b/Jellyfin.Api/Controllers/VideosController.cs index 685d502e42..714d4ba72a 100644 --- a/Jellyfin.Api/Controllers/VideosController.cs +++ b/Jellyfin.Api/Controllers/VideosController.cs @@ -315,18 +315,18 @@ public class VideosController : BaseJellyfinApiController [ProducesVideoFile] public async Task GetVideoStream( [FromRoute, Required] Guid itemId, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? container, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? container, [FromQuery] bool? @static, [FromQuery] string? @params, [FromQuery] string? tag, [FromQuery, ParameterObsolete] string? deviceProfileId, [FromQuery] string? playSessionId, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? segmentContainer, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? segmentContainer, [FromQuery] int? segmentLength, [FromQuery] int? minSegments, [FromQuery] string? mediaSourceId, [FromQuery] string? deviceId, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? audioCodec, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? audioCodec, [FromQuery] bool? enableAutoStreamCopy, [FromQuery] bool? allowVideoStreamCopy, [FromQuery] bool? allowAudioStreamCopy, @@ -358,8 +358,8 @@ public class VideosController : BaseJellyfinApiController [FromQuery] int? cpuCoreLimit, [FromQuery] string? liveStreamId, [FromQuery] bool? enableMpegtsM2TsMode, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? videoCodec, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? subtitleCodec, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? videoCodec, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? subtitleCodec, [FromQuery] string? transcodeReasons, [FromQuery] int? audioStreamIndex, [FromQuery] int? videoStreamIndex, @@ -556,18 +556,18 @@ public class VideosController : BaseJellyfinApiController [ProducesVideoFile] public Task GetVideoStreamByContainer( [FromRoute, Required] Guid itemId, - [FromRoute, Required] [RegularExpression(EncodingHelper.ValidationRegex)] string container, + [FromRoute, Required] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string container, [FromQuery] bool? @static, [FromQuery] string? @params, [FromQuery] string? tag, [FromQuery] string? deviceProfileId, [FromQuery] string? playSessionId, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? segmentContainer, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? segmentContainer, [FromQuery] int? segmentLength, [FromQuery] int? minSegments, [FromQuery] string? mediaSourceId, [FromQuery] string? deviceId, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? audioCodec, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? audioCodec, [FromQuery] bool? enableAutoStreamCopy, [FromQuery] bool? allowVideoStreamCopy, [FromQuery] bool? allowAudioStreamCopy, @@ -599,8 +599,8 @@ public class VideosController : BaseJellyfinApiController [FromQuery] int? cpuCoreLimit, [FromQuery] string? liveStreamId, [FromQuery] bool? enableMpegtsM2TsMode, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? videoCodec, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? subtitleCodec, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? videoCodec, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? subtitleCodec, [FromQuery] string? transcodeReasons, [FromQuery] int? audioStreamIndex, [FromQuery] int? videoStreamIndex, diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index cf76f336c8..ed80de6355 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -37,7 +37,7 @@ namespace MediaBrowser.Controller.MediaEncoding /// periods, underscores, commas, and vertical bars, with a length between 0 and 40 characters. /// This should matches all common valid codecs. /// - public const string ValidationRegex = @"^[a-zA-Z0-9\-\._,|]{0,40}$"; + public const string ContainerValidationRegex = @"^[a-zA-Z0-9\-\._,|]{0,40}$"; private const string _defaultMjpegEncoder = "mjpeg"; @@ -77,7 +77,7 @@ namespace MediaBrowser.Controller.MediaEncoding private readonly Version _minFFmpegVaapiDeviceVendorId = new Version(7, 0, 1); private readonly Version _minFFmpegQsvVppScaleModeOption = new Version(6, 0); - private static readonly Regex _validationRegex = new(ValidationRegex, RegexOptions.Compiled); + private static readonly Regex _containerValidationRegex = new(ContainerValidationRegex, RegexOptions.Compiled); private static readonly string[] _videoProfilesH264 = [ @@ -452,7 +452,7 @@ namespace MediaBrowser.Controller.MediaEncoding return GetMjpegEncoder(state, encodingOptions); } - if (_validationRegex.IsMatch(codec)) + if (_containerValidationRegex.IsMatch(codec)) { return codec.ToLowerInvariant(); } @@ -493,7 +493,7 @@ namespace MediaBrowser.Controller.MediaEncoding public static string GetInputFormat(string container) { - if (string.IsNullOrEmpty(container) || !_validationRegex.IsMatch(container)) + if (string.IsNullOrEmpty(container) || !_containerValidationRegex.IsMatch(container)) { return null; } @@ -711,7 +711,7 @@ namespace MediaBrowser.Controller.MediaEncoding { var codec = state.OutputAudioCodec; - if (!_validationRegex.IsMatch(codec)) + if (!_containerValidationRegex.IsMatch(codec)) { codec = "aac"; } From 3df7d7a809d14e3ab89001d4c98203e20cad9082 Mon Sep 17 00:00:00 2001 From: Shadowghost Date: Thu, 27 Mar 2025 16:13:07 +0100 Subject: [PATCH 3/4] Add validation for level input --- Jellyfin.Api/Controllers/AudioController.cs | 4 ++-- Jellyfin.Api/Controllers/DynamicHlsController.cs | 14 +++++++------- Jellyfin.Api/Controllers/VideosController.cs | 4 ++-- .../MediaEncoding/EncodingHelper.cs | 6 ++++++ 4 files changed, 17 insertions(+), 11 deletions(-) diff --git a/Jellyfin.Api/Controllers/AudioController.cs b/Jellyfin.Api/Controllers/AudioController.cs index 9e3065824f..e334e12640 100644 --- a/Jellyfin.Api/Controllers/AudioController.cs +++ b/Jellyfin.Api/Controllers/AudioController.cs @@ -114,7 +114,7 @@ public class AudioController : BaseJellyfinApiController [FromQuery] int? audioChannels, [FromQuery] int? maxAudioChannels, [FromQuery] string? profile, - [FromQuery] string? level, + [FromQuery] [RegularExpression(EncodingHelper.LevelValidationRegex)] string? level, [FromQuery] float? framerate, [FromQuery] float? maxFramerate, [FromQuery] bool? copyTimestamps, @@ -281,7 +281,7 @@ public class AudioController : BaseJellyfinApiController [FromQuery] int? audioChannels, [FromQuery] int? maxAudioChannels, [FromQuery] string? profile, - [FromQuery] string? level, + [FromQuery] [RegularExpression(EncodingHelper.LevelValidationRegex)] string? level, [FromQuery] float? framerate, [FromQuery] float? maxFramerate, [FromQuery] bool? copyTimestamps, diff --git a/Jellyfin.Api/Controllers/DynamicHlsController.cs b/Jellyfin.Api/Controllers/DynamicHlsController.cs index f59ce3834b..a351c1be15 100644 --- a/Jellyfin.Api/Controllers/DynamicHlsController.cs +++ b/Jellyfin.Api/Controllers/DynamicHlsController.cs @@ -188,7 +188,7 @@ public class DynamicHlsController : BaseJellyfinApiController [FromQuery] int? audioChannels, [FromQuery] int? maxAudioChannels, [FromQuery] string? profile, - [FromQuery] string? level, + [FromQuery] [RegularExpression(EncodingHelper.LevelValidationRegex)] string? level, [FromQuery] float? framerate, [FromQuery] float? maxFramerate, [FromQuery] bool? copyTimestamps, @@ -431,7 +431,7 @@ public class DynamicHlsController : BaseJellyfinApiController [FromQuery] int? audioChannels, [FromQuery] int? maxAudioChannels, [FromQuery] string? profile, - [FromQuery] string? level, + [FromQuery] [RegularExpression(EncodingHelper.LevelValidationRegex)] string? level, [FromQuery] float? framerate, [FromQuery] float? maxFramerate, [FromQuery] bool? copyTimestamps, @@ -608,7 +608,7 @@ public class DynamicHlsController : BaseJellyfinApiController [FromQuery] int? audioChannels, [FromQuery] int? maxAudioChannels, [FromQuery] string? profile, - [FromQuery] string? level, + [FromQuery] [RegularExpression(EncodingHelper.LevelValidationRegex)] string? level, [FromQuery] float? framerate, [FromQuery] float? maxFramerate, [FromQuery] bool? copyTimestamps, @@ -777,7 +777,7 @@ public class DynamicHlsController : BaseJellyfinApiController [FromQuery] int? audioChannels, [FromQuery] int? maxAudioChannels, [FromQuery] string? profile, - [FromQuery] string? level, + [FromQuery] [RegularExpression(EncodingHelper.LevelValidationRegex)] string? level, [FromQuery] float? framerate, [FromQuery] float? maxFramerate, [FromQuery] bool? copyTimestamps, @@ -950,7 +950,7 @@ public class DynamicHlsController : BaseJellyfinApiController [FromQuery] int? audioChannels, [FromQuery] int? maxAudioChannels, [FromQuery] string? profile, - [FromQuery] string? level, + [FromQuery] [RegularExpression(EncodingHelper.LevelValidationRegex)] string? level, [FromQuery] float? framerate, [FromQuery] float? maxFramerate, [FromQuery] bool? copyTimestamps, @@ -1130,7 +1130,7 @@ public class DynamicHlsController : BaseJellyfinApiController [FromQuery] int? audioChannels, [FromQuery] int? maxAudioChannels, [FromQuery] string? profile, - [FromQuery] string? level, + [FromQuery] [RegularExpression(EncodingHelper.LevelValidationRegex)] string? level, [FromQuery] float? framerate, [FromQuery] float? maxFramerate, [FromQuery] bool? copyTimestamps, @@ -1316,7 +1316,7 @@ public class DynamicHlsController : BaseJellyfinApiController [FromQuery] int? audioChannels, [FromQuery] int? maxAudioChannels, [FromQuery] string? profile, - [FromQuery] string? level, + [FromQuery] [RegularExpression(EncodingHelper.LevelValidationRegex)] string? level, [FromQuery] float? framerate, [FromQuery] float? maxFramerate, [FromQuery] bool? copyTimestamps, diff --git a/Jellyfin.Api/Controllers/VideosController.cs b/Jellyfin.Api/Controllers/VideosController.cs index 714d4ba72a..97f3239bbc 100644 --- a/Jellyfin.Api/Controllers/VideosController.cs +++ b/Jellyfin.Api/Controllers/VideosController.cs @@ -337,7 +337,7 @@ public class VideosController : BaseJellyfinApiController [FromQuery] int? audioChannels, [FromQuery] int? maxAudioChannels, [FromQuery] string? profile, - [FromQuery] string? level, + [FromQuery] [RegularExpression(EncodingHelper.LevelValidationRegex)] string? level, [FromQuery] float? framerate, [FromQuery] float? maxFramerate, [FromQuery] bool? copyTimestamps, @@ -578,7 +578,7 @@ public class VideosController : BaseJellyfinApiController [FromQuery] int? audioChannels, [FromQuery] int? maxAudioChannels, [FromQuery] string? profile, - [FromQuery] string? level, + [FromQuery] [RegularExpression(EncodingHelper.LevelValidationRegex)] string? level, [FromQuery] float? framerate, [FromQuery] float? maxFramerate, [FromQuery] bool? copyTimestamps, diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index ed80de6355..17fb42fccc 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -39,6 +39,12 @@ namespace MediaBrowser.Controller.MediaEncoding /// public const string ContainerValidationRegex = @"^[a-zA-Z0-9\-\._,|]{0,40}$"; + /// + /// The level validation regex. + /// This regular expression matches strings representing a double. + /// + public const string LevelValidationRegex = @"-?\d+(?:\.\d+)?"; + private const string _defaultMjpegEncoder = "mjpeg"; private const string QsvAlias = "qs"; From d0c1ef80027fabb4109e8131a950a2468fa9befd Mon Sep 17 00:00:00 2001 From: Tim Eisele Date: Thu, 3 Apr 2025 20:42:33 +0200 Subject: [PATCH 4/4] Update MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs Co-authored-by: Cody Robibero --- MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 17fb42fccc..268549612d 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -43,7 +43,7 @@ namespace MediaBrowser.Controller.MediaEncoding /// The level validation regex. /// This regular expression matches strings representing a double. /// - public const string LevelValidationRegex = @"-?\d+(?:\.\d+)?"; + public const string LevelValidationRegex = @"-?[0-9]+(?:\.[0-9]+)?"; private const string _defaultMjpegEncoder = "mjpeg";