Add additional validations

This commit is contained in:
Shadowghost
2026-03-30 10:48:51 +02:00
parent e12d933531
commit d3907afde7
8 changed files with 102 additions and 69 deletions
+10 -10
View File
@@ -92,18 +92,18 @@ public class AudioController : BaseJellyfinApiController
[ProducesAudioFile] [ProducesAudioFile]
public async Task<ActionResult> GetAudioStream( public async Task<ActionResult> GetAudioStream(
[FromRoute, Required] Guid itemId, [FromRoute, Required] Guid itemId,
[FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? container, [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegexStr)] string? container,
[FromQuery] bool? @static, [FromQuery] bool? @static,
[FromQuery] string? @params, [FromQuery] string? @params,
[FromQuery] string? tag, [FromQuery] string? tag,
[FromQuery, ParameterObsolete] string? deviceProfileId, [FromQuery, ParameterObsolete] string? deviceProfileId,
[FromQuery] string? playSessionId, [FromQuery] string? playSessionId,
[FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? segmentContainer, [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegexStr)] string? segmentContainer,
[FromQuery] int? segmentLength, [FromQuery] int? segmentLength,
[FromQuery] int? minSegments, [FromQuery] int? minSegments,
[FromQuery] string? mediaSourceId, [FromQuery] string? mediaSourceId,
[FromQuery] string? deviceId, [FromQuery] string? deviceId,
[FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? audioCodec, [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegexStr)] string? audioCodec,
[FromQuery] bool? enableAutoStreamCopy, [FromQuery] bool? enableAutoStreamCopy,
[FromQuery] bool? allowVideoStreamCopy, [FromQuery] bool? allowVideoStreamCopy,
[FromQuery] bool? allowAudioStreamCopy, [FromQuery] bool? allowAudioStreamCopy,
@@ -133,8 +133,8 @@ public class AudioController : BaseJellyfinApiController
[FromQuery] int? cpuCoreLimit, [FromQuery] int? cpuCoreLimit,
[FromQuery] string? liveStreamId, [FromQuery] string? liveStreamId,
[FromQuery] bool? enableMpegtsM2TsMode, [FromQuery] bool? enableMpegtsM2TsMode,
[FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? videoCodec, [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegexStr)] string? videoCodec,
[FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? subtitleCodec, [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegexStr)] string? subtitleCodec,
[FromQuery] string? transcodeReasons, [FromQuery] string? transcodeReasons,
[FromQuery] int? audioStreamIndex, [FromQuery] int? audioStreamIndex,
[FromQuery] int? videoStreamIndex, [FromQuery] int? videoStreamIndex,
@@ -259,18 +259,18 @@ public class AudioController : BaseJellyfinApiController
[ProducesAudioFile] [ProducesAudioFile]
public async Task<ActionResult> GetAudioStreamByContainer( public async Task<ActionResult> GetAudioStreamByContainer(
[FromRoute, Required] Guid itemId, [FromRoute, Required] Guid itemId,
[FromRoute, Required] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string container, [FromRoute, Required] [RegularExpression(EncodingHelper.ContainerValidationRegexStr)] string container,
[FromQuery] bool? @static, [FromQuery] bool? @static,
[FromQuery] string? @params, [FromQuery] string? @params,
[FromQuery] string? tag, [FromQuery] string? tag,
[FromQuery, ParameterObsolete] string? deviceProfileId, [FromQuery, ParameterObsolete] string? deviceProfileId,
[FromQuery] string? playSessionId, [FromQuery] string? playSessionId,
[FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? segmentContainer, [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegexStr)] string? segmentContainer,
[FromQuery] int? segmentLength, [FromQuery] int? segmentLength,
[FromQuery] int? minSegments, [FromQuery] int? minSegments,
[FromQuery] string? mediaSourceId, [FromQuery] string? mediaSourceId,
[FromQuery] string? deviceId, [FromQuery] string? deviceId,
[FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? audioCodec, [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegexStr)] string? audioCodec,
[FromQuery] bool? enableAutoStreamCopy, [FromQuery] bool? enableAutoStreamCopy,
[FromQuery] bool? allowVideoStreamCopy, [FromQuery] bool? allowVideoStreamCopy,
[FromQuery] bool? allowAudioStreamCopy, [FromQuery] bool? allowAudioStreamCopy,
@@ -300,8 +300,8 @@ public class AudioController : BaseJellyfinApiController
[FromQuery] int? cpuCoreLimit, [FromQuery] int? cpuCoreLimit,
[FromQuery] string? liveStreamId, [FromQuery] string? liveStreamId,
[FromQuery] bool? enableMpegtsM2TsMode, [FromQuery] bool? enableMpegtsM2TsMode,
[FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? videoCodec, [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegexStr)] string? videoCodec,
[FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? subtitleCodec, [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegexStr)] string? subtitleCodec,
[FromQuery] string? transcodeReasons, [FromQuery] string? transcodeReasons,
[FromQuery] int? audioStreamIndex, [FromQuery] int? audioStreamIndex,
[FromQuery] int? videoStreamIndex, [FromQuery] int? videoStreamIndex,
@@ -167,18 +167,18 @@ public class DynamicHlsController : BaseJellyfinApiController
[ProducesPlaylistFile] [ProducesPlaylistFile]
public async Task<ActionResult> GetLiveHlsStream( public async Task<ActionResult> GetLiveHlsStream(
[FromRoute, Required] Guid itemId, [FromRoute, Required] Guid itemId,
[FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? container, [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegexStr)] string? container,
[FromQuery] bool? @static, [FromQuery] bool? @static,
[FromQuery] string? @params, [FromQuery] string? @params,
[FromQuery] string? tag, [FromQuery] string? tag,
[FromQuery, ParameterObsolete] string? deviceProfileId, [FromQuery, ParameterObsolete] string? deviceProfileId,
[FromQuery] string? playSessionId, [FromQuery] string? playSessionId,
[FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? segmentContainer, [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegexStr)] string? segmentContainer,
[FromQuery] int? segmentLength, [FromQuery] int? segmentLength,
[FromQuery] int? minSegments, [FromQuery] int? minSegments,
[FromQuery] string? mediaSourceId, [FromQuery] string? mediaSourceId,
[FromQuery] string? deviceId, [FromQuery] string? deviceId,
[FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? audioCodec, [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegexStr)] string? audioCodec,
[FromQuery] bool? enableAutoStreamCopy, [FromQuery] bool? enableAutoStreamCopy,
[FromQuery] bool? allowVideoStreamCopy, [FromQuery] bool? allowVideoStreamCopy,
[FromQuery] bool? allowAudioStreamCopy, [FromQuery] bool? allowAudioStreamCopy,
@@ -208,8 +208,8 @@ public class DynamicHlsController : BaseJellyfinApiController
[FromQuery] int? cpuCoreLimit, [FromQuery] int? cpuCoreLimit,
[FromQuery] string? liveStreamId, [FromQuery] string? liveStreamId,
[FromQuery] bool? enableMpegtsM2TsMode, [FromQuery] bool? enableMpegtsM2TsMode,
[FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? videoCodec, [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegexStr)] string? videoCodec,
[FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? subtitleCodec, [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegexStr)] string? subtitleCodec,
[FromQuery] string? transcodeReasons, [FromQuery] string? transcodeReasons,
[FromQuery] int? audioStreamIndex, [FromQuery] int? audioStreamIndex,
[FromQuery] int? videoStreamIndex, [FromQuery] int? videoStreamIndex,
@@ -416,12 +416,12 @@ public class DynamicHlsController : BaseJellyfinApiController
[FromQuery] string? tag, [FromQuery] string? tag,
[FromQuery, ParameterObsolete] string? deviceProfileId, [FromQuery, ParameterObsolete] string? deviceProfileId,
[FromQuery] string? playSessionId, [FromQuery] string? playSessionId,
[FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? segmentContainer, [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegexStr)] string? segmentContainer,
[FromQuery] int? segmentLength, [FromQuery] int? segmentLength,
[FromQuery] int? minSegments, [FromQuery] int? minSegments,
[FromQuery, Required] string mediaSourceId, [FromQuery, Required] string mediaSourceId,
[FromQuery] string? deviceId, [FromQuery] string? deviceId,
[FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? audioCodec, [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegexStr)] string? audioCodec,
[FromQuery] bool? enableAutoStreamCopy, [FromQuery] bool? enableAutoStreamCopy,
[FromQuery] bool? allowVideoStreamCopy, [FromQuery] bool? allowVideoStreamCopy,
[FromQuery] bool? allowAudioStreamCopy, [FromQuery] bool? allowAudioStreamCopy,
@@ -453,8 +453,8 @@ public class DynamicHlsController : BaseJellyfinApiController
[FromQuery] int? cpuCoreLimit, [FromQuery] int? cpuCoreLimit,
[FromQuery] string? liveStreamId, [FromQuery] string? liveStreamId,
[FromQuery] bool? enableMpegtsM2TsMode, [FromQuery] bool? enableMpegtsM2TsMode,
[FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? videoCodec, [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegexStr)] string? videoCodec,
[FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? subtitleCodec, [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegexStr)] string? subtitleCodec,
[FromQuery] string? transcodeReasons, [FromQuery] string? transcodeReasons,
[FromQuery] int? audioStreamIndex, [FromQuery] int? audioStreamIndex,
[FromQuery] int? videoStreamIndex, [FromQuery] int? videoStreamIndex,
@@ -592,12 +592,12 @@ public class DynamicHlsController : BaseJellyfinApiController
[FromQuery] string? tag, [FromQuery] string? tag,
[FromQuery, ParameterObsolete] string? deviceProfileId, [FromQuery, ParameterObsolete] string? deviceProfileId,
[FromQuery] string? playSessionId, [FromQuery] string? playSessionId,
[FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? segmentContainer, [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegexStr)] string? segmentContainer,
[FromQuery] int? segmentLength, [FromQuery] int? segmentLength,
[FromQuery] int? minSegments, [FromQuery] int? minSegments,
[FromQuery, Required] string mediaSourceId, [FromQuery, Required] string mediaSourceId,
[FromQuery] string? deviceId, [FromQuery] string? deviceId,
[FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? audioCodec, [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegexStr)] string? audioCodec,
[FromQuery] bool? enableAutoStreamCopy, [FromQuery] bool? enableAutoStreamCopy,
[FromQuery] bool? allowVideoStreamCopy, [FromQuery] bool? allowVideoStreamCopy,
[FromQuery] bool? allowAudioStreamCopy, [FromQuery] bool? allowAudioStreamCopy,
@@ -628,8 +628,8 @@ public class DynamicHlsController : BaseJellyfinApiController
[FromQuery] int? cpuCoreLimit, [FromQuery] int? cpuCoreLimit,
[FromQuery] string? liveStreamId, [FromQuery] string? liveStreamId,
[FromQuery] bool? enableMpegtsM2TsMode, [FromQuery] bool? enableMpegtsM2TsMode,
[FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? videoCodec, [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegexStr)] string? videoCodec,
[FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? subtitleCodec, [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegexStr)] string? subtitleCodec,
[FromQuery] string? transcodeReasons, [FromQuery] string? transcodeReasons,
[FromQuery] int? audioStreamIndex, [FromQuery] int? audioStreamIndex,
[FromQuery] int? videoStreamIndex, [FromQuery] int? videoStreamIndex,
@@ -762,12 +762,12 @@ public class DynamicHlsController : BaseJellyfinApiController
[FromQuery] string? tag, [FromQuery] string? tag,
[FromQuery, ParameterObsolete] string? deviceProfileId, [FromQuery, ParameterObsolete] string? deviceProfileId,
[FromQuery] string? playSessionId, [FromQuery] string? playSessionId,
[FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? segmentContainer, [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegexStr)] string? segmentContainer,
[FromQuery] int? segmentLength, [FromQuery] int? segmentLength,
[FromQuery] int? minSegments, [FromQuery] int? minSegments,
[FromQuery] string? mediaSourceId, [FromQuery] string? mediaSourceId,
[FromQuery] string? deviceId, [FromQuery] string? deviceId,
[FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? audioCodec, [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegexStr)] string? audioCodec,
[FromQuery] bool? enableAutoStreamCopy, [FromQuery] bool? enableAutoStreamCopy,
[FromQuery] bool? allowVideoStreamCopy, [FromQuery] bool? allowVideoStreamCopy,
[FromQuery] bool? allowAudioStreamCopy, [FromQuery] bool? allowAudioStreamCopy,
@@ -799,8 +799,8 @@ public class DynamicHlsController : BaseJellyfinApiController
[FromQuery] int? cpuCoreLimit, [FromQuery] int? cpuCoreLimit,
[FromQuery] string? liveStreamId, [FromQuery] string? liveStreamId,
[FromQuery] bool? enableMpegtsM2TsMode, [FromQuery] bool? enableMpegtsM2TsMode,
[FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? videoCodec, [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegexStr)] string? videoCodec,
[FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? subtitleCodec, [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegexStr)] string? subtitleCodec,
[FromQuery] string? transcodeReasons, [FromQuery] string? transcodeReasons,
[FromQuery] int? audioStreamIndex, [FromQuery] int? audioStreamIndex,
[FromQuery] int? videoStreamIndex, [FromQuery] int? videoStreamIndex,
@@ -934,12 +934,12 @@ public class DynamicHlsController : BaseJellyfinApiController
[FromQuery] string? tag, [FromQuery] string? tag,
[FromQuery, ParameterObsolete] string? deviceProfileId, [FromQuery, ParameterObsolete] string? deviceProfileId,
[FromQuery] string? playSessionId, [FromQuery] string? playSessionId,
[FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? segmentContainer, [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegexStr)] string? segmentContainer,
[FromQuery] int? segmentLength, [FromQuery] int? segmentLength,
[FromQuery] int? minSegments, [FromQuery] int? minSegments,
[FromQuery] string? mediaSourceId, [FromQuery] string? mediaSourceId,
[FromQuery] string? deviceId, [FromQuery] string? deviceId,
[FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? audioCodec, [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegexStr)] string? audioCodec,
[FromQuery] bool? enableAutoStreamCopy, [FromQuery] bool? enableAutoStreamCopy,
[FromQuery] bool? allowVideoStreamCopy, [FromQuery] bool? allowVideoStreamCopy,
[FromQuery] bool? allowAudioStreamCopy, [FromQuery] bool? allowAudioStreamCopy,
@@ -970,8 +970,8 @@ public class DynamicHlsController : BaseJellyfinApiController
[FromQuery] int? cpuCoreLimit, [FromQuery] int? cpuCoreLimit,
[FromQuery] string? liveStreamId, [FromQuery] string? liveStreamId,
[FromQuery] bool? enableMpegtsM2TsMode, [FromQuery] bool? enableMpegtsM2TsMode,
[FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? videoCodec, [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegexStr)] string? videoCodec,
[FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? subtitleCodec, [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegexStr)] string? subtitleCodec,
[FromQuery] string? transcodeReasons, [FromQuery] string? transcodeReasons,
[FromQuery] int? audioStreamIndex, [FromQuery] int? audioStreamIndex,
[FromQuery] int? videoStreamIndex, [FromQuery] int? videoStreamIndex,
@@ -1107,7 +1107,7 @@ public class DynamicHlsController : BaseJellyfinApiController
[FromRoute, Required] Guid itemId, [FromRoute, Required] Guid itemId,
[FromRoute, Required] string playlistId, [FromRoute, Required] string playlistId,
[FromRoute, Required] int segmentId, [FromRoute, Required] int segmentId,
[FromRoute, Required] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string container, [FromRoute, Required] [RegularExpression(EncodingHelper.ContainerValidationRegexStr)] string container,
[FromQuery, Required] long runtimeTicks, [FromQuery, Required] long runtimeTicks,
[FromQuery, Required] long actualSegmentLengthTicks, [FromQuery, Required] long actualSegmentLengthTicks,
[FromQuery] bool? @static, [FromQuery] bool? @static,
@@ -1115,12 +1115,12 @@ public class DynamicHlsController : BaseJellyfinApiController
[FromQuery] string? tag, [FromQuery] string? tag,
[FromQuery, ParameterObsolete] string? deviceProfileId, [FromQuery, ParameterObsolete] string? deviceProfileId,
[FromQuery] string? playSessionId, [FromQuery] string? playSessionId,
[FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? segmentContainer, [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegexStr)] string? segmentContainer,
[FromQuery] int? segmentLength, [FromQuery] int? segmentLength,
[FromQuery] int? minSegments, [FromQuery] int? minSegments,
[FromQuery] string? mediaSourceId, [FromQuery] string? mediaSourceId,
[FromQuery] string? deviceId, [FromQuery] string? deviceId,
[FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? audioCodec, [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegexStr)] string? audioCodec,
[FromQuery] bool? enableAutoStreamCopy, [FromQuery] bool? enableAutoStreamCopy,
[FromQuery] bool? allowVideoStreamCopy, [FromQuery] bool? allowVideoStreamCopy,
[FromQuery] bool? allowAudioStreamCopy, [FromQuery] bool? allowAudioStreamCopy,
@@ -1152,8 +1152,8 @@ public class DynamicHlsController : BaseJellyfinApiController
[FromQuery] int? cpuCoreLimit, [FromQuery] int? cpuCoreLimit,
[FromQuery] string? liveStreamId, [FromQuery] string? liveStreamId,
[FromQuery] bool? enableMpegtsM2TsMode, [FromQuery] bool? enableMpegtsM2TsMode,
[FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? videoCodec, [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegexStr)] string? videoCodec,
[FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? subtitleCodec, [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegexStr)] string? subtitleCodec,
[FromQuery] string? transcodeReasons, [FromQuery] string? transcodeReasons,
[FromQuery] int? audioStreamIndex, [FromQuery] int? audioStreamIndex,
[FromQuery] int? videoStreamIndex, [FromQuery] int? videoStreamIndex,
@@ -1292,7 +1292,7 @@ public class DynamicHlsController : BaseJellyfinApiController
[FromRoute, Required] Guid itemId, [FromRoute, Required] Guid itemId,
[FromRoute, Required] string playlistId, [FromRoute, Required] string playlistId,
[FromRoute, Required] int segmentId, [FromRoute, Required] int segmentId,
[FromRoute, Required] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string container, [FromRoute, Required] [RegularExpression(EncodingHelper.ContainerValidationRegexStr)] string container,
[FromQuery, Required] long runtimeTicks, [FromQuery, Required] long runtimeTicks,
[FromQuery, Required] long actualSegmentLengthTicks, [FromQuery, Required] long actualSegmentLengthTicks,
[FromQuery] bool? @static, [FromQuery] bool? @static,
@@ -1300,12 +1300,12 @@ public class DynamicHlsController : BaseJellyfinApiController
[FromQuery] string? tag, [FromQuery] string? tag,
[FromQuery, ParameterObsolete] string? deviceProfileId, [FromQuery, ParameterObsolete] string? deviceProfileId,
[FromQuery] string? playSessionId, [FromQuery] string? playSessionId,
[FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? segmentContainer, [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegexStr)] string? segmentContainer,
[FromQuery] int? segmentLength, [FromQuery] int? segmentLength,
[FromQuery] int? minSegments, [FromQuery] int? minSegments,
[FromQuery] string? mediaSourceId, [FromQuery] string? mediaSourceId,
[FromQuery] string? deviceId, [FromQuery] string? deviceId,
[FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? audioCodec, [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegexStr)] string? audioCodec,
[FromQuery] bool? enableAutoStreamCopy, [FromQuery] bool? enableAutoStreamCopy,
[FromQuery] bool? allowVideoStreamCopy, [FromQuery] bool? allowVideoStreamCopy,
[FromQuery] bool? allowAudioStreamCopy, [FromQuery] bool? allowAudioStreamCopy,
@@ -1336,8 +1336,8 @@ public class DynamicHlsController : BaseJellyfinApiController
[FromQuery] int? cpuCoreLimit, [FromQuery] int? cpuCoreLimit,
[FromQuery] string? liveStreamId, [FromQuery] string? liveStreamId,
[FromQuery] bool? enableMpegtsM2TsMode, [FromQuery] bool? enableMpegtsM2TsMode,
[FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? videoCodec, [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegexStr)] string? videoCodec,
[FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? subtitleCodec, [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegexStr)] string? subtitleCodec,
[FromQuery] string? transcodeReasons, [FromQuery] string? transcodeReasons,
[FromQuery] int? audioStreamIndex, [FromQuery] int? audioStreamIndex,
[FromQuery] int? videoStreamIndex, [FromQuery] int? videoStreamIndex,
+1 -1
View File
@@ -1192,7 +1192,7 @@ public class LiveTvController : BaseJellyfinApiController
[ProducesVideoFile] [ProducesVideoFile]
public ActionResult GetLiveStreamFile( public ActionResult GetLiveStreamFile(
[FromRoute, Required] string streamId, [FromRoute, Required] string streamId,
[FromRoute, Required] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string container) [FromRoute, Required] [RegularExpression(EncodingHelper.ContainerValidationRegexStr)] string container)
{ {
var liveStreamInfo = _mediaSourceManager.GetLiveStreamInfoByUniqueId(streamId); var liveStreamInfo = _mediaSourceManager.GetLiveStreamInfoByUniqueId(streamId);
if (liveStreamInfo is null) if (liveStreamInfo is null)
@@ -102,13 +102,13 @@ public class UniversalAudioController : BaseJellyfinApiController
[FromQuery] string? mediaSourceId, [FromQuery] string? mediaSourceId,
[FromQuery] string? deviceId, [FromQuery] string? deviceId,
[FromQuery] Guid? userId, [FromQuery] Guid? userId,
[FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? audioCodec, [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegexStr)] string? audioCodec,
[FromQuery] int? maxAudioChannels, [FromQuery] int? maxAudioChannels,
[FromQuery] int? transcodingAudioChannels, [FromQuery] int? transcodingAudioChannels,
[FromQuery] int? maxStreamingBitrate, [FromQuery] int? maxStreamingBitrate,
[FromQuery] int? audioBitRate, [FromQuery] int? audioBitRate,
[FromQuery] long? startTimeTicks, [FromQuery] long? startTimeTicks,
[FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? transcodingContainer, [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegexStr)] string? transcodingContainer,
[FromQuery] MediaStreamProtocol? transcodingProtocol, [FromQuery] MediaStreamProtocol? transcodingProtocol,
[FromQuery] int? maxAudioSampleRate, [FromQuery] int? maxAudioSampleRate,
[FromQuery] int? maxAudioBitDepth, [FromQuery] int? maxAudioBitDepth,
+10 -10
View File
@@ -315,18 +315,18 @@ public class VideosController : BaseJellyfinApiController
[ProducesVideoFile] [ProducesVideoFile]
public async Task<ActionResult> GetVideoStream( public async Task<ActionResult> GetVideoStream(
[FromRoute, Required] Guid itemId, [FromRoute, Required] Guid itemId,
[FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? container, [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegexStr)] string? container,
[FromQuery] bool? @static, [FromQuery] bool? @static,
[FromQuery] string? @params, [FromQuery] string? @params,
[FromQuery] string? tag, [FromQuery] string? tag,
[FromQuery, ParameterObsolete] string? deviceProfileId, [FromQuery, ParameterObsolete] string? deviceProfileId,
[FromQuery] string? playSessionId, [FromQuery] string? playSessionId,
[FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? segmentContainer, [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegexStr)] string? segmentContainer,
[FromQuery] int? segmentLength, [FromQuery] int? segmentLength,
[FromQuery] int? minSegments, [FromQuery] int? minSegments,
[FromQuery] string? mediaSourceId, [FromQuery] string? mediaSourceId,
[FromQuery] string? deviceId, [FromQuery] string? deviceId,
[FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? audioCodec, [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegexStr)] string? audioCodec,
[FromQuery] bool? enableAutoStreamCopy, [FromQuery] bool? enableAutoStreamCopy,
[FromQuery] bool? allowVideoStreamCopy, [FromQuery] bool? allowVideoStreamCopy,
[FromQuery] bool? allowAudioStreamCopy, [FromQuery] bool? allowAudioStreamCopy,
@@ -358,8 +358,8 @@ public class VideosController : BaseJellyfinApiController
[FromQuery] int? cpuCoreLimit, [FromQuery] int? cpuCoreLimit,
[FromQuery] string? liveStreamId, [FromQuery] string? liveStreamId,
[FromQuery] bool? enableMpegtsM2TsMode, [FromQuery] bool? enableMpegtsM2TsMode,
[FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? videoCodec, [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegexStr)] string? videoCodec,
[FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? subtitleCodec, [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegexStr)] string? subtitleCodec,
[FromQuery] string? transcodeReasons, [FromQuery] string? transcodeReasons,
[FromQuery] int? audioStreamIndex, [FromQuery] int? audioStreamIndex,
[FromQuery] int? videoStreamIndex, [FromQuery] int? videoStreamIndex,
@@ -556,18 +556,18 @@ public class VideosController : BaseJellyfinApiController
[ProducesVideoFile] [ProducesVideoFile]
public Task<ActionResult> GetVideoStreamByContainer( public Task<ActionResult> GetVideoStreamByContainer(
[FromRoute, Required] Guid itemId, [FromRoute, Required] Guid itemId,
[FromRoute, Required] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string container, [FromRoute, Required] [RegularExpression(EncodingHelper.ContainerValidationRegexStr)] string container,
[FromQuery] bool? @static, [FromQuery] bool? @static,
[FromQuery] string? @params, [FromQuery] string? @params,
[FromQuery] string? tag, [FromQuery] string? tag,
[FromQuery] string? deviceProfileId, [FromQuery] string? deviceProfileId,
[FromQuery] string? playSessionId, [FromQuery] string? playSessionId,
[FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? segmentContainer, [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegexStr)] string? segmentContainer,
[FromQuery] int? segmentLength, [FromQuery] int? segmentLength,
[FromQuery] int? minSegments, [FromQuery] int? minSegments,
[FromQuery] string? mediaSourceId, [FromQuery] string? mediaSourceId,
[FromQuery] string? deviceId, [FromQuery] string? deviceId,
[FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? audioCodec, [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegexStr)] string? audioCodec,
[FromQuery] bool? enableAutoStreamCopy, [FromQuery] bool? enableAutoStreamCopy,
[FromQuery] bool? allowVideoStreamCopy, [FromQuery] bool? allowVideoStreamCopy,
[FromQuery] bool? allowAudioStreamCopy, [FromQuery] bool? allowAudioStreamCopy,
@@ -599,8 +599,8 @@ public class VideosController : BaseJellyfinApiController
[FromQuery] int? cpuCoreLimit, [FromQuery] int? cpuCoreLimit,
[FromQuery] string? liveStreamId, [FromQuery] string? liveStreamId,
[FromQuery] bool? enableMpegtsM2TsMode, [FromQuery] bool? enableMpegtsM2TsMode,
[FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? videoCodec, [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegexStr)] string? videoCodec,
[FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? subtitleCodec, [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegexStr)] string? subtitleCodec,
[FromQuery] string? transcodeReasons, [FromQuery] string? transcodeReasons,
[FromQuery] int? audioStreamIndex, [FromQuery] int? audioStreamIndex,
[FromQuery] int? videoStreamIndex, [FromQuery] int? videoStreamIndex,
+17 -4
View File
@@ -422,14 +422,18 @@ public static class StreamingHelpers
request.Static = string.Equals("true", val, StringComparison.OrdinalIgnoreCase); request.Static = string.Equals("true", val, StringComparison.OrdinalIgnoreCase);
break; break;
case 4: case 4:
if (videoRequest is not null) if (videoRequest is not null && IsValidCodecName(val))
{ {
videoRequest.VideoCodec = val; videoRequest.VideoCodec = val;
} }
break; break;
case 5: case 5:
request.AudioCodec = val; if (IsValidCodecName(val))
{
request.AudioCodec = val;
}
break; break;
case 6: case 6:
if (videoRequest is not null) if (videoRequest is not null)
@@ -504,7 +508,7 @@ public static class StreamingHelpers
break; break;
case 18: case 18:
if (videoRequest is not null) if (videoRequest is not null && IsValidCodecName(val))
{ {
videoRequest.Profile = val; videoRequest.Profile = val;
} }
@@ -563,7 +567,11 @@ public static class StreamingHelpers
break; break;
case 30: case 30:
request.SubtitleCodec = val; if (IsValidCodecName(val))
{
request.SubtitleCodec = val;
}
break; break;
case 31: case 31:
if (videoRequest is not null) if (videoRequest is not null)
@@ -586,6 +594,11 @@ public static class StreamingHelpers
} }
} }
private static bool IsValidCodecName(string val)
{
return EncodingHelper.ContainerValidationRegex().IsMatch(val);
}
/// <summary> /// <summary>
/// Parses the container into its file extension. /// Parses the container into its file extension.
/// </summary> /// </summary>
@@ -33,12 +33,12 @@ namespace MediaBrowser.Controller.MediaEncoding
public partial class EncodingHelper public partial class EncodingHelper
{ {
/// <summary> /// <summary>
/// The codec validation regex. /// The codec validation regex string.
/// This regular expression matches strings that consist of alphanumeric characters, hyphens, /// This regular expression matches strings that consist of alphanumeric characters, hyphens,
/// periods, underscores, commas, and vertical bars, with a length between 0 and 40 characters. /// periods, underscores, commas, and vertical bars, with a length between 0 and 40 characters.
/// This should matches all common valid codecs. /// This should matches all common valid codecs.
/// </summary> /// </summary>
public const string ContainerValidationRegex = @"^[a-zA-Z0-9\-\._,|]{0,40}$"; public const string ContainerValidationRegexStr = @"^[a-zA-Z0-9\-\._,|]{0,40}$";
/// <summary> /// <summary>
/// The level validation regex. /// The level validation regex.
@@ -87,8 +87,6 @@ namespace MediaBrowser.Controller.MediaEncoding
private readonly Version _minFFmpegRkmppHevcDecDoviRpu = new Version(7, 1, 1); private readonly Version _minFFmpegRkmppHevcDecDoviRpu = new Version(7, 1, 1);
private readonly Version _minFFmpegReadrateCatchupOption = new Version(8, 0); private readonly Version _minFFmpegReadrateCatchupOption = new Version(8, 0);
private static readonly Regex _containerValidationRegex = new(ContainerValidationRegex, RegexOptions.Compiled);
private static readonly string[] _videoProfilesH264 = private static readonly string[] _videoProfilesH264 =
[ [
"ConstrainedBaseline", "ConstrainedBaseline",
@@ -181,6 +179,15 @@ namespace MediaBrowser.Controller.MediaEncoding
RemoveHdr10Plus, RemoveHdr10Plus,
} }
/// <summary>
/// The codec validation regex.
/// This regular expression matches strings that consist of alphanumeric characters, hyphens,
/// periods, underscores, commas, and vertical bars, with a length between 0 and 40 characters.
/// This should matches all common valid codecs.
/// </summary>
[GeneratedRegex(@"^[a-zA-Z0-9\-\._,|]{0,40}$")]
public static partial Regex ContainerValidationRegex();
[GeneratedRegex(@"\s+")] [GeneratedRegex(@"\s+")]
private static partial Regex WhiteSpaceRegex(); private static partial Regex WhiteSpaceRegex();
@@ -477,7 +484,7 @@ namespace MediaBrowser.Controller.MediaEncoding
return GetMjpegEncoder(state, encodingOptions); return GetMjpegEncoder(state, encodingOptions);
} }
if (_containerValidationRegex.IsMatch(codec)) if (ContainerValidationRegex().IsMatch(codec))
{ {
return codec.ToLowerInvariant(); return codec.ToLowerInvariant();
} }
@@ -518,7 +525,7 @@ namespace MediaBrowser.Controller.MediaEncoding
public static string GetInputFormat(string container) public static string GetInputFormat(string container)
{ {
if (string.IsNullOrEmpty(container) || !_containerValidationRegex.IsMatch(container)) if (string.IsNullOrEmpty(container) || !ContainerValidationRegex().IsMatch(container))
{ {
return null; return null;
} }
@@ -736,7 +743,7 @@ namespace MediaBrowser.Controller.MediaEncoding
{ {
var codec = state.OutputAudioCodec; var codec = state.OutputAudioCodec;
if (!_containerValidationRegex.IsMatch(codec)) if (!ContainerValidationRegex().IsMatch(codec))
{ {
codec = "aac"; codec = "aac";
} }
@@ -205,7 +205,13 @@ namespace MediaBrowser.Providers.Subtitles
} }
var savePaths = new List<string>(); var savePaths = new List<string>();
var saveFileName = Path.GetFileNameWithoutExtension(video.Path) + "." + response.Language.ToLowerInvariant(); var language = response.Language.ToLowerInvariant();
if (language.AsSpan().IndexOfAny(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar) >= 0)
{
throw new ArgumentException("Language contains invalid characters.");
}
var saveFileName = Path.GetFileNameWithoutExtension(video.Path) + "." + language;
if (response.IsForced) if (response.IsForced)
{ {
@@ -233,6 +239,11 @@ namespace MediaBrowser.Providers.Subtitles
private async Task TrySaveToFiles(Stream stream, List<string> savePaths, Video video, string extension) private async Task TrySaveToFiles(Stream stream, List<string> savePaths, Video video, string extension)
{ {
if (!_allowedSubtitleFormats.Contains("." + extension, StringComparison.OrdinalIgnoreCase))
{
throw new ArgumentException($"Invalid subtitle format: {extension}");
}
List<Exception>? exs = null; List<Exception>? exs = null;
foreach (var savePath in savePaths) foreach (var savePath in savePaths)
@@ -240,15 +251,17 @@ namespace MediaBrowser.Providers.Subtitles
var path = Path.GetFullPath(savePath + "." + extension); var path = Path.GetFullPath(savePath + "." + extension);
try try
{ {
if (path.StartsWith(video.ContainingFolderPath, StringComparison.Ordinal) var containingFolder = video.ContainingFolderPath + Path.DirectorySeparatorChar;
|| path.StartsWith(video.GetInternalMetadataPath(), StringComparison.Ordinal)) var metadataFolder = video.GetInternalMetadataPath() + Path.DirectorySeparatorChar;
if (path.StartsWith(containingFolder, StringComparison.Ordinal)
|| path.StartsWith(metadataFolder, StringComparison.Ordinal))
{ {
var fileExists = File.Exists(path); var fileExists = File.Exists(path);
var counter = 0; var counter = 0;
while (fileExists) while (fileExists)
{ {
path = Path.GetFullPath(string.Format(CultureInfo.InvariantCulture, "{0}.{1}.{2}", savePath, counter, extension)); path = string.Format(CultureInfo.InvariantCulture, "{0}.{1}.{2}", savePath, counter, extension);
fileExists = File.Exists(path); fileExists = File.Exists(path);
counter++; counter++;
} }