aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Jellyfin.Api/Controllers/DynamicHlsController.cs12
-rw-r--r--Jellyfin.Api/Controllers/EnvironmentController.cs5
-rw-r--r--Jellyfin.Api/Controllers/GenresController.cs2
-rw-r--r--Jellyfin.Api/Controllers/HlsSegmentController.cs5
-rw-r--r--Jellyfin.Api/Controllers/ImageByNameController.cs2
-rw-r--r--Jellyfin.Api/Controllers/ImageController.cs3
-rw-r--r--Jellyfin.Api/Controllers/ItemLookupController.cs21
-rw-r--r--Jellyfin.Api/Controllers/LibraryController.cs6
-rw-r--r--Jellyfin.Api/Controllers/LiveTvController.cs2
-rw-r--r--Jellyfin.Api/Controllers/MusicGenresController.cs4
-rw-r--r--Jellyfin.Api/Controllers/PackageController.cs5
-rw-r--r--Jellyfin.Api/Controllers/RemoteImageController.cs28
-rw-r--r--Jellyfin.Api/Controllers/SearchController.cs2
-rw-r--r--Jellyfin.Api/Controllers/VideoHlsController.cs8
-rw-r--r--Jellyfin.Api/Helpers/AudioHelper.cs8
-rw-r--r--Jellyfin.Api/Helpers/DynamicHlsHelper.cs11
-rw-r--r--Jellyfin.Api/Helpers/FileStreamResponseHelpers.cs4
-rw-r--r--Jellyfin.Api/Helpers/HlsCodecStringHelpers.cs6
-rw-r--r--Jellyfin.Api/Helpers/HlsHelpers.cs4
-rw-r--r--Jellyfin.Api/Helpers/ProgressiveFileCopier.cs5
-rw-r--r--Jellyfin.Api/Helpers/StreamingHelpers.cs4
-rw-r--r--Jellyfin.Api/Helpers/TranscodingJobHelper.cs26
-rw-r--r--Jellyfin.Api/Models/PlaybackDtos/TranscodingJobDto.cs4
-rw-r--r--Jellyfin.Api/Models/PlaybackDtos/TranscodingThrottler.cs2
-rw-r--r--Jellyfin.Api/WebSocketListeners/ActivityLogWebSocketListener.cs2
-rw-r--r--Jellyfin.Api/WebSocketListeners/ScheduledTasksWebSocketListener.cs6
-rw-r--r--Jellyfin.Api/WebSocketListeners/SessionInfoWebSocketListener.cs14
-rw-r--r--MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs2
-rw-r--r--MediaBrowser.Model/Net/MimeTypes.cs6
29 files changed, 155 insertions, 54 deletions
diff --git a/Jellyfin.Api/Controllers/DynamicHlsController.cs b/Jellyfin.Api/Controllers/DynamicHlsController.cs
index e07690e11..b0d5a7cd8 100644
--- a/Jellyfin.Api/Controllers/DynamicHlsController.cs
+++ b/Jellyfin.Api/Controllers/DynamicHlsController.cs
@@ -1347,7 +1347,13 @@ namespace Jellyfin.Api.Controllers
var mapArgs = state.IsOutputVideo ? _encodingHelper.GetMapArgs(state) : string.Empty;
- var outputTsArg = Path.Combine(Path.GetDirectoryName(outputPath), Path.GetFileNameWithoutExtension(outputPath)) + "%d" + GetSegmentFileExtension(state.Request.SegmentContainer);
+ var directory = Path.GetDirectoryName(outputPath);
+ if (directory == null)
+ {
+ throw new NullReferenceException(nameof(directory));
+ }
+
+ var outputTsArg = Path.Combine(directory, Path.GetFileNameWithoutExtension(outputPath)) + "%d" + GetSegmentFileExtension(state.Request.SegmentContainer);
var segmentFormat = GetSegmentFileExtension(state.Request.SegmentContainer).TrimStart('.');
if (string.Equals(segmentFormat, "ts", StringComparison.OrdinalIgnoreCase))
@@ -1566,6 +1572,10 @@ namespace Jellyfin.Api.Controllers
private string GetSegmentPath(StreamState state, string playlist, int index)
{
var folder = Path.GetDirectoryName(playlist);
+ if (folder == null)
+ {
+ throw new NullReferenceException(nameof(folder));
+ }
var filename = Path.GetFileNameWithoutExtension(playlist);
diff --git a/Jellyfin.Api/Controllers/EnvironmentController.cs b/Jellyfin.Api/Controllers/EnvironmentController.cs
index ce88b0b99..8de217bbf 100644
--- a/Jellyfin.Api/Controllers/EnvironmentController.cs
+++ b/Jellyfin.Api/Controllers/EnvironmentController.cs
@@ -103,6 +103,11 @@ namespace Jellyfin.Api.Controllers
if (validatePathDto.ValidateWritable)
{
+ if (validatePathDto.Path == null)
+ {
+ throw new NullReferenceException(nameof(validatePathDto.Path));
+ }
+
var file = Path.Combine(validatePathDto.Path, Guid.NewGuid().ToString());
try
{
diff --git a/Jellyfin.Api/Controllers/GenresController.cs b/Jellyfin.Api/Controllers/GenresController.cs
index f6e0772ec..9c009d784 100644
--- a/Jellyfin.Api/Controllers/GenresController.cs
+++ b/Jellyfin.Api/Controllers/GenresController.cs
@@ -177,7 +177,7 @@ namespace Jellyfin.Api.Controllers
return _dtoService.GetBaseItemDto(item, dtoOptions);
}
- private T GetItemFromSlugName<T>(ILibraryManager libraryManager, string name, DtoOptions dtoOptions)
+ private T? GetItemFromSlugName<T>(ILibraryManager libraryManager, string name, DtoOptions dtoOptions)
where T : BaseItem, new()
{
var result = libraryManager.GetItemList(new InternalItemsQuery
diff --git a/Jellyfin.Api/Controllers/HlsSegmentController.cs b/Jellyfin.Api/Controllers/HlsSegmentController.cs
index 054e586ce..2cee0e9ef 100644
--- a/Jellyfin.Api/Controllers/HlsSegmentController.cs
+++ b/Jellyfin.Api/Controllers/HlsSegmentController.cs
@@ -136,6 +136,11 @@ namespace Jellyfin.Api.Controllers
string.Equals(Path.GetExtension(i), ".m3u8", StringComparison.OrdinalIgnoreCase)
&& i.IndexOf(normalizedPlaylistId, StringComparison.OrdinalIgnoreCase) != -1);
+ if (playlistPath == null)
+ {
+ throw new NullReferenceException(nameof(playlistPath));
+ }
+
return GetFileResult(file, playlistPath);
}
diff --git a/Jellyfin.Api/Controllers/ImageByNameController.cs b/Jellyfin.Api/Controllers/ImageByNameController.cs
index 980c3273d..198dbc51f 100644
--- a/Jellyfin.Api/Controllers/ImageByNameController.cs
+++ b/Jellyfin.Api/Controllers/ImageByNameController.cs
@@ -161,7 +161,7 @@ namespace Jellyfin.Api.Controllers
/// <param name="theme">Theme to search.</param>
/// <param name="name">File name to search for.</param>
/// <returns>A <see cref="FileStreamResult"/> containing the image contents on success, or a <see cref="NotFoundResult"/> if the image could not be found.</returns>
- private ActionResult GetImageFile(string basePath, string? theme, string? name)
+ private ActionResult GetImageFile(string basePath, string theme, string? name)
{
var themeFolder = Path.Combine(basePath, theme);
if (Directory.Exists(themeFolder))
diff --git a/Jellyfin.Api/Controllers/ImageController.cs b/Jellyfin.Api/Controllers/ImageController.cs
index 4a67c1aed..76e53b9a5 100644
--- a/Jellyfin.Api/Controllers/ImageController.cs
+++ b/Jellyfin.Api/Controllers/ImageController.cs
@@ -5,6 +5,7 @@ using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Linq;
+using System.Net.Mime;
using System.Threading;
using System.Threading.Tasks;
using Jellyfin.Api.Attributes;
@@ -1268,7 +1269,7 @@ namespace Jellyfin.Api.Controllers
Response.Headers.Add(key, value);
}
- Response.ContentType = imageContentType;
+ Response.ContentType = imageContentType ?? MediaTypeNames.Text.Plain;
Response.Headers.Add(HeaderNames.Age, Convert.ToInt64((DateTime.UtcNow - dateImageModified).TotalSeconds).ToString(CultureInfo.InvariantCulture));
Response.Headers.Add(HeaderNames.Vary, HeaderNames.Accept);
diff --git a/Jellyfin.Api/Controllers/ItemLookupController.cs b/Jellyfin.Api/Controllers/ItemLookupController.cs
index ab73aa428..b6cb79716 100644
--- a/Jellyfin.Api/Controllers/ItemLookupController.cs
+++ b/Jellyfin.Api/Controllers/ItemLookupController.cs
@@ -334,10 +334,21 @@ namespace Jellyfin.Api.Controllers
private async Task DownloadImage(string providerName, string url, Guid urlHash, string pointerCachePath)
{
using var result = await _providerManager.GetSearchImage(providerName, url, CancellationToken.None).ConfigureAwait(false);
+ if (result.Content.Headers.ContentType?.MediaType == null)
+ {
+ throw new NullReferenceException(nameof(result.Content.Headers.ContentType));
+ }
+
var ext = result.Content.Headers.ContentType.MediaType.Split('/')[^1];
var fullCachePath = GetFullCachePath(urlHash + "." + ext);
- Directory.CreateDirectory(Path.GetDirectoryName(fullCachePath));
+ var directory = Path.GetDirectoryName(fullCachePath);
+ if (directory == null)
+ {
+ throw new NullReferenceException(nameof(directory));
+ }
+
+ Directory.CreateDirectory(directory);
using (var stream = result.Content)
{
await using var fileStream = new FileStream(
@@ -351,7 +362,13 @@ namespace Jellyfin.Api.Controllers
await stream.CopyToAsync(fileStream).ConfigureAwait(false);
}
- Directory.CreateDirectory(Path.GetDirectoryName(pointerCachePath));
+ var pointerCacheDirectory = Path.GetDirectoryName(pointerCachePath);
+ if (pointerCacheDirectory == null)
+ {
+ throw new NullReferenceException(nameof(pointerCacheDirectory));
+ }
+
+ Directory.CreateDirectory(pointerCacheDirectory);
await System.IO.File.WriteAllTextAsync(pointerCachePath, fullCachePath).ConfigureAwait(false);
}
diff --git a/Jellyfin.Api/Controllers/LibraryController.cs b/Jellyfin.Api/Controllers/LibraryController.cs
index 8a872ae13..60bbc5022 100644
--- a/Jellyfin.Api/Controllers/LibraryController.cs
+++ b/Jellyfin.Api/Controllers/LibraryController.cs
@@ -455,7 +455,7 @@ namespace Jellyfin.Api.Controllers
: null;
var dtoOptions = new DtoOptions().AddClientFields(Request);
- BaseItem parent = item.GetParent();
+ BaseItem? parent = item.GetParent();
while (parent != null)
{
@@ -466,7 +466,7 @@ namespace Jellyfin.Api.Controllers
baseItemDtos.Add(_dtoService.GetBaseItemDto(parent, dtoOptions, user));
- parent = parent.GetParent();
+ parent = parent?.GetParent();
}
return baseItemDtos;
@@ -854,7 +854,7 @@ namespace Jellyfin.Api.Controllers
return _libraryManager.GetItemsResult(query).TotalRecordCount;
}
- private BaseItem TranslateParentItem(BaseItem item, User user)
+ private BaseItem? TranslateParentItem(BaseItem item, User user)
{
return item.GetParent() is AggregateFolder
? _libraryManager.GetUserRootFolder().GetChildren(user, true)
diff --git a/Jellyfin.Api/Controllers/LiveTvController.cs b/Jellyfin.Api/Controllers/LiveTvController.cs
index 31253cbbc..384a48705 100644
--- a/Jellyfin.Api/Controllers/LiveTvController.cs
+++ b/Jellyfin.Api/Controllers/LiveTvController.cs
@@ -1078,7 +1078,7 @@ namespace Jellyfin.Api.Controllers
var client = _httpClientFactory.CreateClient(NamedClient.Default);
// https://json.schedulesdirect.org/20141201/available/countries
// Can't dispose the response as it's required up the call chain.
- var response = await client.GetAsync("https://json.schedulesdirect.org/20141201/available/countries")
+ var response = await client.GetAsync(new Uri("https://json.schedulesdirect.org/20141201/available/countries"))
.ConfigureAwait(false);
return File(await response.Content.ReadAsStreamAsync().ConfigureAwait(false), MediaTypeNames.Application.Json);
diff --git a/Jellyfin.Api/Controllers/MusicGenresController.cs b/Jellyfin.Api/Controllers/MusicGenresController.cs
index e434f190a..989c383fd 100644
--- a/Jellyfin.Api/Controllers/MusicGenresController.cs
+++ b/Jellyfin.Api/Controllers/MusicGenresController.cs
@@ -140,7 +140,7 @@ namespace Jellyfin.Api.Controllers
{
var dtoOptions = new DtoOptions().AddClientFields(Request);
- MusicGenre item;
+ MusicGenre? item;
if (genreName.IndexOf(BaseItem.SlugChar, StringComparison.OrdinalIgnoreCase) != -1)
{
@@ -161,7 +161,7 @@ namespace Jellyfin.Api.Controllers
return _dtoService.GetBaseItemDto(item, dtoOptions);
}
- private T GetItemFromSlugName<T>(ILibraryManager libraryManager, string name, DtoOptions dtoOptions)
+ private T? GetItemFromSlugName<T>(ILibraryManager libraryManager, string name, DtoOptions dtoOptions)
where T : BaseItem, new()
{
var result = libraryManager.GetItemList(new InternalItemsQuery
diff --git a/Jellyfin.Api/Controllers/PackageController.cs b/Jellyfin.Api/Controllers/PackageController.cs
index 1d9de14d2..a104af4e6 100644
--- a/Jellyfin.Api/Controllers/PackageController.cs
+++ b/Jellyfin.Api/Controllers/PackageController.cs
@@ -54,6 +54,11 @@ namespace Jellyfin.Api.Controllers
string.IsNullOrEmpty(assemblyGuid) ? default : Guid.Parse(assemblyGuid))
.FirstOrDefault();
+ if (result == null)
+ {
+ return NotFound();
+ }
+
return result;
}
diff --git a/Jellyfin.Api/Controllers/RemoteImageController.cs b/Jellyfin.Api/Controllers/RemoteImageController.cs
index 5f095443b..ad76b3984 100644
--- a/Jellyfin.Api/Controllers/RemoteImageController.cs
+++ b/Jellyfin.Api/Controllers/RemoteImageController.cs
@@ -157,9 +157,9 @@ namespace Jellyfin.Api.Controllers
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesImageFile]
- public async Task<ActionResult> GetRemoteImage([FromQuery, Required] string imageUrl)
+ public async Task<ActionResult> GetRemoteImage([FromQuery, Required] Uri imageUrl)
{
- var urlHash = imageUrl.GetMD5();
+ var urlHash = imageUrl.ToString().GetMD5();
var pointerCachePath = GetFullCachePath(urlHash.ToString());
string? contentPath = null;
@@ -245,17 +245,35 @@ namespace Jellyfin.Api.Controllers
/// <param name="urlHash">The URL hash.</param>
/// <param name="pointerCachePath">The pointer cache path.</param>
/// <returns>Task.</returns>
- private async Task DownloadImage(string url, Guid urlHash, string pointerCachePath)
+ private async Task DownloadImage(Uri url, Guid urlHash, string pointerCachePath)
{
var httpClient = _httpClientFactory.CreateClient(NamedClient.Default);
using var response = await httpClient.GetAsync(url).ConfigureAwait(false);
+ if (response.Content.Headers.ContentType?.MediaType == null)
+ {
+ throw new NullReferenceException(nameof(response.Content.Headers.ContentType));
+ }
+
var ext = response.Content.Headers.ContentType.MediaType.Split('/').Last();
var fullCachePath = GetFullCachePath(urlHash + "." + ext);
- Directory.CreateDirectory(Path.GetDirectoryName(fullCachePath));
+ var fullCacheDirectory = Path.GetDirectoryName(fullCachePath);
+ if (fullCacheDirectory == null)
+ {
+ throw new NullReferenceException(nameof(fullCacheDirectory));
+ }
+
+ Directory.CreateDirectory(fullCacheDirectory);
await using var fileStream = new FileStream(fullCachePath, FileMode.Create, FileAccess.Write, FileShare.Read, IODefaults.FileStreamBufferSize, true);
await response.Content.CopyToAsync(fileStream).ConfigureAwait(false);
- Directory.CreateDirectory(Path.GetDirectoryName(pointerCachePath));
+
+ var pointerCacheDirectory = Path.GetDirectoryName(pointerCachePath);
+ if (pointerCacheDirectory == null)
+ {
+ throw new NullReferenceException(nameof(pointerCacheDirectory));
+ }
+
+ Directory.CreateDirectory(pointerCacheDirectory);
await System.IO.File.WriteAllTextAsync(pointerCachePath, fullCachePath, CancellationToken.None)
.ConfigureAwait(false);
}
diff --git a/Jellyfin.Api/Controllers/SearchController.cs b/Jellyfin.Api/Controllers/SearchController.cs
index 62c870cb1..e75f0d06b 100644
--- a/Jellyfin.Api/Controllers/SearchController.cs
+++ b/Jellyfin.Api/Controllers/SearchController.cs
@@ -260,7 +260,7 @@ namespace Jellyfin.Api.Controllers
}
}
- private T GetParentWithImage<T>(BaseItem item, ImageType type)
+ private T? GetParentWithImage<T>(BaseItem item, ImageType type)
where T : BaseItem
{
return item.GetParents().OfType<T>().FirstOrDefault(i => i.HasImage(type));
diff --git a/Jellyfin.Api/Controllers/VideoHlsController.cs b/Jellyfin.Api/Controllers/VideoHlsController.cs
index d7bcf79c1..517239966 100644
--- a/Jellyfin.Api/Controllers/VideoHlsController.cs
+++ b/Jellyfin.Api/Controllers/VideoHlsController.cs
@@ -361,7 +361,13 @@ namespace Jellyfin.Api.Controllers
var threads = _encodingHelper.GetNumberOfThreads(state, _encodingOptions, videoCodec);
var inputModifier = _encodingHelper.GetInputModifier(state, _encodingOptions);
var format = !string.IsNullOrWhiteSpace(state.Request.SegmentContainer) ? "." + state.Request.SegmentContainer : ".ts";
- var outputTsArg = Path.Combine(Path.GetDirectoryName(outputPath), Path.GetFileNameWithoutExtension(outputPath)) + "%d" + format;
+ var directory = Path.GetDirectoryName(outputPath);
+ if (directory == null)
+ {
+ throw new NullReferenceException(nameof(directory));
+ }
+
+ var outputTsArg = Path.Combine(directory, Path.GetFileNameWithoutExtension(outputPath)) + "%d" + format;
var segmentFormat = format.TrimStart('.');
if (string.Equals(segmentFormat, "ts", StringComparison.OrdinalIgnoreCase))
diff --git a/Jellyfin.Api/Helpers/AudioHelper.cs b/Jellyfin.Api/Helpers/AudioHelper.cs
index a3f2d88ce..c6d577b19 100644
--- a/Jellyfin.Api/Helpers/AudioHelper.cs
+++ b/Jellyfin.Api/Helpers/AudioHelper.cs
@@ -1,4 +1,5 @@
-using System.Net.Http;
+using System;
+using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Jellyfin.Api.Models.StreamingDtos;
@@ -98,6 +99,11 @@ namespace Jellyfin.Api.Helpers
TranscodingJobType transcodingJobType,
StreamingRequestDto streamingRequest)
{
+ if (_httpContextAccessor.HttpContext == null)
+ {
+ throw new NullReferenceException(nameof(_httpContextAccessor.HttpContext));
+ }
+
bool isHeadRequest = _httpContextAccessor.HttpContext.Request.Method == System.Net.WebRequestMethods.Http.Head;
var cancellationTokenSource = new CancellationTokenSource();
diff --git a/Jellyfin.Api/Helpers/DynamicHlsHelper.cs b/Jellyfin.Api/Helpers/DynamicHlsHelper.cs
index ea012f837..20bca731f 100644
--- a/Jellyfin.Api/Helpers/DynamicHlsHelper.cs
+++ b/Jellyfin.Api/Helpers/DynamicHlsHelper.cs
@@ -113,7 +113,7 @@ namespace Jellyfin.Api.Helpers
StreamingRequestDto streamingRequest,
bool enableAdaptiveBitrateStreaming)
{
- var isHeadRequest = _httpContextAccessor.HttpContext.Request.Method == WebRequestMethods.Http.Head;
+ var isHeadRequest = _httpContextAccessor.HttpContext?.Request.Method == WebRequestMethods.Http.Head;
var cancellationTokenSource = new CancellationTokenSource();
return await GetMasterPlaylistInternal(
streamingRequest,
@@ -130,6 +130,11 @@ namespace Jellyfin.Api.Helpers
TranscodingJobType transcodingJobType,
CancellationTokenSource cancellationTokenSource)
{
+ if (_httpContextAccessor.HttpContext == null)
+ {
+ throw new NullReferenceException(nameof(_httpContextAccessor.HttpContext));
+ }
+
using var state = await StreamingHelpers.GetStreamingState(
streamingRequest,
_httpContextAccessor.HttpContext.Request,
@@ -487,14 +492,14 @@ namespace Jellyfin.Api.Helpers
if (string.Equals(codec, "h264", StringComparison.OrdinalIgnoreCase))
{
- string profile = state.GetRequestedProfiles("h264").FirstOrDefault();
+ string? profile = state.GetRequestedProfiles("h264").FirstOrDefault();
return HlsCodecStringHelpers.GetH264String(profile, level);
}
if (string.Equals(codec, "h265", StringComparison.OrdinalIgnoreCase)
|| string.Equals(codec, "hevc", StringComparison.OrdinalIgnoreCase))
{
- string profile = state.GetRequestedProfiles("h265").FirstOrDefault();
+ string? profile = state.GetRequestedProfiles("h265").FirstOrDefault();
return HlsCodecStringHelpers.GetH265String(profile, level);
}
diff --git a/Jellyfin.Api/Helpers/FileStreamResponseHelpers.cs b/Jellyfin.Api/Helpers/FileStreamResponseHelpers.cs
index 366301d3e..20c94cdda 100644
--- a/Jellyfin.Api/Helpers/FileStreamResponseHelpers.cs
+++ b/Jellyfin.Api/Helpers/FileStreamResponseHelpers.cs
@@ -37,8 +37,8 @@ namespace Jellyfin.Api.Helpers
}
// Can't dispose the response as it's required up the call chain.
- var response = await httpClient.GetAsync(state.MediaPath).ConfigureAwait(false);
- var contentType = response.Content.Headers.ContentType.ToString();
+ var response = await httpClient.GetAsync(new Uri(state.MediaPath)).ConfigureAwait(false);
+ var contentType = response.Content.Headers.ContentType?.ToString();
httpContext.Response.Headers[HeaderNames.AcceptRanges] = "none";
diff --git a/Jellyfin.Api/Helpers/HlsCodecStringHelpers.cs b/Jellyfin.Api/Helpers/HlsCodecStringHelpers.cs
index 95f1906ef..1bd3d67ff 100644
--- a/Jellyfin.Api/Helpers/HlsCodecStringHelpers.cs
+++ b/Jellyfin.Api/Helpers/HlsCodecStringHelpers.cs
@@ -23,7 +23,7 @@ namespace Jellyfin.Api.Helpers
/// </summary>
/// <param name="profile">AAC profile.</param>
/// <returns>AAC codec string.</returns>
- public static string GetAACString(string profile)
+ public static string GetAACString(string? profile)
{
StringBuilder result = new StringBuilder("mp4a", 9);
@@ -46,7 +46,7 @@ namespace Jellyfin.Api.Helpers
/// <param name="profile">H.264 profile.</param>
/// <param name="level">H.264 level.</param>
/// <returns>H.264 string.</returns>
- public static string GetH264String(string profile, int level)
+ public static string GetH264String(string? profile, int level)
{
StringBuilder result = new StringBuilder("avc1", 11);
@@ -80,7 +80,7 @@ namespace Jellyfin.Api.Helpers
/// <param name="profile">H.265 profile.</param>
/// <param name="level">H.265 level.</param>
/// <returns>H.265 string.</returns>
- public static string GetH265String(string profile, int level)
+ public static string GetH265String(string? profile, int level)
{
// The h265 syntax is a bit of a mystery at the time this comment was written.
// This is what I've found through various sources:
diff --git a/Jellyfin.Api/Helpers/HlsHelpers.cs b/Jellyfin.Api/Helpers/HlsHelpers.cs
index 242496697..16fbac7ae 100644
--- a/Jellyfin.Api/Helpers/HlsHelpers.cs
+++ b/Jellyfin.Api/Helpers/HlsHelpers.cs
@@ -45,6 +45,10 @@ namespace Jellyfin.Api.Helpers
while (!reader.EndOfStream)
{
var line = await reader.ReadLineAsync().ConfigureAwait(false);
+ if (line == null)
+ {
+ throw new NullReferenceException(nameof(line));
+ }
if (line.IndexOf("#EXTINF:", StringComparison.OrdinalIgnoreCase) != -1)
{
diff --git a/Jellyfin.Api/Helpers/ProgressiveFileCopier.cs b/Jellyfin.Api/Helpers/ProgressiveFileCopier.cs
index e00ed3304..65c03c710 100644
--- a/Jellyfin.Api/Helpers/ProgressiveFileCopier.cs
+++ b/Jellyfin.Api/Helpers/ProgressiveFileCopier.cs
@@ -90,6 +90,11 @@ namespace Jellyfin.Api.Helpers
allowAsyncFileRead = true;
}
+ if (_path == null)
+ {
+ throw new NullReferenceException(nameof(_path));
+ }
+
await using var inputStream = new FileStream(_path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, IODefaults.FileStreamBufferSize, fileOptions);
var eofCount = 0;
diff --git a/Jellyfin.Api/Helpers/StreamingHelpers.cs b/Jellyfin.Api/Helpers/StreamingHelpers.cs
index f4ec29bde..1d102071c 100644
--- a/Jellyfin.Api/Helpers/StreamingHelpers.cs
+++ b/Jellyfin.Api/Helpers/StreamingHelpers.cs
@@ -83,6 +83,10 @@ namespace Jellyfin.Api.Helpers
}
streamingRequest.StreamOptions = ParseStreamOptions(httpRequest.Query);
+ if (httpRequest.Path.Value == null)
+ {
+ throw new NullReferenceException(nameof(httpRequest.Path));
+ }
var url = httpRequest.Path.Value.Split('.').Last();
diff --git a/Jellyfin.Api/Helpers/TranscodingJobHelper.cs b/Jellyfin.Api/Helpers/TranscodingJobHelper.cs
index 0db1fabff..b72e33af3 100644
--- a/Jellyfin.Api/Helpers/TranscodingJobHelper.cs
+++ b/Jellyfin.Api/Helpers/TranscodingJobHelper.cs
@@ -102,7 +102,7 @@ namespace Jellyfin.Api.Helpers
/// </summary>
/// <param name="playSessionId">Playback session id.</param>
/// <returns>The transcoding job.</returns>
- public TranscodingJobDto GetTranscodingJob(string playSessionId)
+ public TranscodingJobDto? GetTranscodingJob(string playSessionId)
{
lock (_activeTranscodingJobs)
{
@@ -116,7 +116,7 @@ namespace Jellyfin.Api.Helpers
/// <param name="path">Path to the transcoding file.</param>
/// <param name="type">The <see cref="TranscodingJobType"/>.</param>
/// <returns>The transcoding job.</returns>
- public TranscodingJobDto GetTranscodingJob(string path, TranscodingJobType type)
+ public TranscodingJobDto? GetTranscodingJob(string path, TranscodingJobType type)
{
lock (_activeTranscodingJobs)
{
@@ -193,9 +193,13 @@ namespace Jellyfin.Api.Helpers
/// Called when [transcode kill timer stopped].
/// </summary>
/// <param name="state">The state.</param>
- private async void OnTranscodeKillTimerStopped(object state)
+ private async void OnTranscodeKillTimerStopped(object? state)
{
- var job = (TranscodingJobDto)state;
+ var job = (TranscodingJobDto?)state;
+ if (job == null)
+ {
+ throw new NullReferenceException(nameof(job));
+ }
if (!job.HasExited && job.Type != TranscodingJobType.Progressive)
{
@@ -489,7 +493,13 @@ namespace Jellyfin.Api.Helpers
CancellationTokenSource cancellationTokenSource,
string? workingDirectory = null)
{
- Directory.CreateDirectory(Path.GetDirectoryName(outputPath));
+ var directory = Path.GetDirectoryName(outputPath);
+ if (directory == null)
+ {
+ throw new NullReferenceException(nameof(directory));
+ }
+
+ Directory.CreateDirectory(directory);
await AcquireResources(state, cancellationTokenSource).ConfigureAwait(false);
@@ -523,7 +533,7 @@ namespace Jellyfin.Api.Helpers
RedirectStandardInput = true,
FileName = _mediaEncoder.EncoderPath,
Arguments = commandLineArguments,
- WorkingDirectory = string.IsNullOrWhiteSpace(workingDirectory) ? null : workingDirectory,
+ WorkingDirectory = string.IsNullOrWhiteSpace(workingDirectory) ? string.Empty : workingDirectory,
ErrorDialog = false
},
EnableRaisingEvents = true
@@ -827,7 +837,7 @@ namespace Jellyfin.Api.Helpers
{
lock (_transcodingLocks)
{
- if (!_transcodingLocks.TryGetValue(outputPath, out SemaphoreSlim result))
+ if (!_transcodingLocks.TryGetValue(outputPath, out SemaphoreSlim? result))
{
result = new SemaphoreSlim(1, 1);
_transcodingLocks[outputPath] = result;
@@ -837,7 +847,7 @@ namespace Jellyfin.Api.Helpers
}
}
- private void OnPlaybackProgress(object sender, PlaybackProgressEventArgs e)
+ private void OnPlaybackProgress(object? sender, PlaybackProgressEventArgs e)
{
if (!string.IsNullOrWhiteSpace(e.PlaySessionId))
{
diff --git a/Jellyfin.Api/Models/PlaybackDtos/TranscodingJobDto.cs b/Jellyfin.Api/Models/PlaybackDtos/TranscodingJobDto.cs
index b9507a4e5..9edc19bb6 100644
--- a/Jellyfin.Api/Models/PlaybackDtos/TranscodingJobDto.cs
+++ b/Jellyfin.Api/Models/PlaybackDtos/TranscodingJobDto.cs
@@ -196,7 +196,7 @@ namespace Jellyfin.Api.Models.PlaybackDtos
/// Start kill timer.
/// </summary>
/// <param name="callback">Callback action.</param>
- public void StartKillTimer(Action<object> callback)
+ public void StartKillTimer(Action<object?> callback)
{
StartKillTimer(callback, PingTimeout);
}
@@ -206,7 +206,7 @@ namespace Jellyfin.Api.Models.PlaybackDtos
/// </summary>
/// <param name="callback">Callback action.</param>
/// <param name="intervalMs">Callback interval.</param>
- public void StartKillTimer(Action<object> callback, int intervalMs)
+ public void StartKillTimer(Action<object?> callback, int intervalMs)
{
if (HasExited)
{
diff --git a/Jellyfin.Api/Models/PlaybackDtos/TranscodingThrottler.cs b/Jellyfin.Api/Models/PlaybackDtos/TranscodingThrottler.cs
index b5e42ea29..872a46824 100644
--- a/Jellyfin.Api/Models/PlaybackDtos/TranscodingThrottler.cs
+++ b/Jellyfin.Api/Models/PlaybackDtos/TranscodingThrottler.cs
@@ -101,7 +101,7 @@ namespace Jellyfin.Api.Models.PlaybackDtos
return _config.GetConfiguration<EncodingOptions>("encoding");
}
- private async void TimerCallback(object state)
+ private async void TimerCallback(object? state)
{
if (_job.HasExited)
{
diff --git a/Jellyfin.Api/WebSocketListeners/ActivityLogWebSocketListener.cs b/Jellyfin.Api/WebSocketListeners/ActivityLogWebSocketListener.cs
index 77d55828d..ce5465116 100644
--- a/Jellyfin.Api/WebSocketListeners/ActivityLogWebSocketListener.cs
+++ b/Jellyfin.Api/WebSocketListeners/ActivityLogWebSocketListener.cs
@@ -56,7 +56,7 @@ namespace Jellyfin.Api.WebSocketListeners
base.Dispose(dispose);
}
- private void OnEntryCreated(object sender, GenericEventArgs<ActivityLogEntry> e)
+ private void OnEntryCreated(object? sender, GenericEventArgs<ActivityLogEntry> e)
{
SendData(true);
}
diff --git a/Jellyfin.Api/WebSocketListeners/ScheduledTasksWebSocketListener.cs b/Jellyfin.Api/WebSocketListeners/ScheduledTasksWebSocketListener.cs
index 80314b923..94df23e56 100644
--- a/Jellyfin.Api/WebSocketListeners/ScheduledTasksWebSocketListener.cs
+++ b/Jellyfin.Api/WebSocketListeners/ScheduledTasksWebSocketListener.cs
@@ -64,19 +64,19 @@ namespace Jellyfin.Api.WebSocketListeners
base.Dispose(dispose);
}
- private void OnTaskCompleted(object sender, TaskCompletionEventArgs e)
+ private void OnTaskCompleted(object? sender, TaskCompletionEventArgs e)
{
SendData(true);
e.Task.TaskProgress -= OnTaskProgress;
}
- private void OnTaskExecuting(object sender, GenericEventArgs<IScheduledTaskWorker> e)
+ private void OnTaskExecuting(object? sender, GenericEventArgs<IScheduledTaskWorker> e)
{
SendData(true);
e.Argument.TaskProgress += OnTaskProgress;
}
- private void OnTaskProgress(object sender, GenericEventArgs<double> e)
+ private void OnTaskProgress(object? sender, GenericEventArgs<double> e)
{
SendData(false);
}
diff --git a/Jellyfin.Api/WebSocketListeners/SessionInfoWebSocketListener.cs b/Jellyfin.Api/WebSocketListeners/SessionInfoWebSocketListener.cs
index 1cf43a005..d996ac69f 100644
--- a/Jellyfin.Api/WebSocketListeners/SessionInfoWebSocketListener.cs
+++ b/Jellyfin.Api/WebSocketListeners/SessionInfoWebSocketListener.cs
@@ -66,37 +66,37 @@ namespace Jellyfin.Api.WebSocketListeners
base.Dispose(dispose);
}
- private async void OnSessionManagerSessionActivity(object sender, SessionEventArgs e)
+ private async void OnSessionManagerSessionActivity(object? sender, SessionEventArgs e)
{
await SendData(false).ConfigureAwait(false);
}
- private async void OnSessionManagerCapabilitiesChanged(object sender, SessionEventArgs e)
+ private async void OnSessionManagerCapabilitiesChanged(object? sender, SessionEventArgs e)
{
await SendData(true).ConfigureAwait(false);
}
- private async void OnSessionManagerPlaybackProgress(object sender, PlaybackProgressEventArgs e)
+ private async void OnSessionManagerPlaybackProgress(object? sender, PlaybackProgressEventArgs e)
{
await SendData(!e.IsAutomated).ConfigureAwait(false);
}
- private async void OnSessionManagerPlaybackStopped(object sender, PlaybackStopEventArgs e)
+ private async void OnSessionManagerPlaybackStopped(object? sender, PlaybackStopEventArgs e)
{
await SendData(true).ConfigureAwait(false);
}
- private async void OnSessionManagerPlaybackStart(object sender, PlaybackProgressEventArgs e)
+ private async void OnSessionManagerPlaybackStart(object? sender, PlaybackProgressEventArgs e)
{
await SendData(true).ConfigureAwait(false);
}
- private async void OnSessionManagerSessionEnded(object sender, SessionEventArgs e)
+ private async void OnSessionManagerSessionEnded(object? sender, SessionEventArgs e)
{
await SendData(true).ConfigureAwait(false);
}
- private async void OnSessionManagerSessionStarted(object sender, SessionEventArgs e)
+ private async void OnSessionManagerSessionStarted(object? sender, SessionEventArgs e)
{
await SendData(true).ConfigureAwait(false);
}
diff --git a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs
index 0a9958b9e..8b3c6b2e6 100644
--- a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs
+++ b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs
@@ -758,7 +758,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
case MediaProtocol.Http:
{
using var response = await _httpClientFactory.CreateClient(NamedClient.Default)
- .GetAsync(path, cancellationToken)
+ .GetAsync(new Uri(path), cancellationToken)
.ConfigureAwait(false);
return await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
}
diff --git a/MediaBrowser.Model/Net/MimeTypes.cs b/MediaBrowser.Model/Net/MimeTypes.cs
index afe7351d3..55c0e6c9a 100644
--- a/MediaBrowser.Model/Net/MimeTypes.cs
+++ b/MediaBrowser.Model/Net/MimeTypes.cs
@@ -210,9 +210,9 @@ namespace MediaBrowser.Model.Net
return enableStreamDefault ? "application/octet-stream" : null;
}
- public static string? ToExtension(string mimeType)
+ public static string? ToExtension(string? mimeType)
{
- if (mimeType.Length == 0)
+ if (string.IsNullOrEmpty(mimeType))
{
throw new ArgumentException("String can't be empty.", nameof(mimeType));
}
@@ -220,7 +220,7 @@ namespace MediaBrowser.Model.Net
// handle text/html; charset=UTF-8
mimeType = mimeType.Split(';')[0];
- if (_extensionLookup.TryGetValue(mimeType, out string result))
+ if (_extensionLookup.TryGetValue(mimeType, out string? result))
{
return result;
}