Browse Source

Merge branch 'master' into comparisons

BaronGreenback 4 years ago
parent
commit
97c2c523a8
100 changed files with 291 additions and 230 deletions
  1. 0 2
      .github/workflows/automation.yml
  2. 2 0
      Emby.Dlna/Configuration/DlnaOptions.cs
  3. 0 1
      Emby.Dlna/ConfigurationExtension.cs
  4. 2 0
      Emby.Dlna/ContentDirectory/ContentDirectoryService.cs
  5. 2 0
      Emby.Dlna/ContentDirectory/ControlHandler.cs
  6. 2 0
      Emby.Dlna/ControlRequest.cs
  7. 2 0
      Emby.Dlna/ControlResponse.cs
  8. 2 0
      Emby.Dlna/Didl/DidlBuilder.cs
  9. 1 1
      Emby.Dlna/Didl/StringWriterWithEncoding.cs
  10. 0 1
      Emby.Dlna/DlnaConfigurationFactory.cs
  11. 2 0
      Emby.Dlna/DlnaManager.cs
  12. 1 0
      Emby.Dlna/Emby.Dlna.csproj
  13. 2 0
      Emby.Dlna/EventSubscriptionResponse.cs
  14. 2 0
      Emby.Dlna/Eventing/DlnaEventManager.cs
  15. 2 0
      Emby.Dlna/Eventing/EventSubscription.cs
  16. 2 0
      Emby.Dlna/Main/DlnaEntryPoint.cs
  17. 2 0
      Emby.Dlna/PlayTo/Device.cs
  18. 2 0
      Emby.Dlna/PlayTo/DeviceInfo.cs
  19. 2 0
      Emby.Dlna/PlayTo/MediaChangedEventArgs.cs
  20. 2 0
      Emby.Dlna/PlayTo/PlayToController.cs
  21. 2 0
      Emby.Dlna/PlayTo/PlayToManager.cs
  22. 2 0
      Emby.Dlna/PlayTo/PlaybackProgressEventArgs.cs
  23. 2 0
      Emby.Dlna/PlayTo/PlaybackStartEventArgs.cs
  24. 2 0
      Emby.Dlna/PlayTo/PlaybackStoppedEventArgs.cs
  25. 2 0
      Emby.Dlna/PlayTo/PlaylistItem.cs
  26. 2 0
      Emby.Dlna/PlayTo/PlaylistItemFactory.cs
  27. 2 0
      Emby.Dlna/PlayTo/SsdpHttpClient.cs
  28. 7 7
      Emby.Dlna/PlayTo/TransportCommands.cs
  29. 2 0
      Emby.Dlna/PlayTo/uBaseObject.cs
  30. 2 1
      Emby.Dlna/Server/DescriptionXmlBuilder.cs
  31. 2 2
      Emby.Dlna/Service/BaseControlHandler.cs
  32. 2 0
      Emby.Dlna/Ssdp/DeviceDiscovery.cs
  33. 3 3
      Emby.Dlna/Ssdp/SsdpExtensions.cs
  34. 5 0
      Emby.Server.Implementations/Library/ResolverHelper.cs
  35. 3 4
      Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs
  36. 7 7
      Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs
  37. 12 22
      Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs
  38. 4 6
      Emby.Server.Implementations/Localization/LocalizationManager.cs
  39. 3 2
      Jellyfin.Api/Auth/BaseAuthorizationHandler.cs
  40. 6 0
      Jellyfin.Api/Controllers/ConfigurationController.cs
  41. 1 1
      Jellyfin.Api/Controllers/LibraryController.cs
  42. 1 4
      Jellyfin.Api/Helpers/HlsHelpers.cs
  43. 2 0
      MediaBrowser.Common/Configuration/ConfigurationStore.cs
  44. 1 0
      MediaBrowser.Common/Configuration/ConfigurationUpdateEventArgs.cs
  45. 2 0
      MediaBrowser.Common/Configuration/IApplicationPaths.cs
  46. 0 1
      MediaBrowser.Common/Cryptography/PasswordHash.cs
  47. 2 2
      MediaBrowser.Common/Events/EventHelper.cs
  48. 0 2
      MediaBrowser.Common/Extensions/BaseExtensions.cs
  49. 0 2
      MediaBrowser.Common/Extensions/CopyToExtensions.cs
  50. 1 1
      MediaBrowser.Common/Extensions/HttpContextExtensions.cs
  51. 0 2
      MediaBrowser.Common/Extensions/MethodNotAllowedException.cs
  52. 0 2
      MediaBrowser.Common/Extensions/ProcessExtensions.cs
  53. 0 1
      MediaBrowser.Common/Extensions/RateLimitExceededException.cs
  54. 0 2
      MediaBrowser.Common/Extensions/ResourceNotFoundException.cs
  55. 0 2
      MediaBrowser.Common/Extensions/ShuffleExtensions.cs
  56. 1 1
      MediaBrowser.Common/Extensions/SplitStringExtensions.cs
  57. 17 5
      MediaBrowser.Common/Extensions/StreamExtensions.cs
  58. 2 0
      MediaBrowser.Common/IApplicationHost.cs
  59. 3 54
      MediaBrowser.Common/Json/Converters/JsonCommaDelimitedArrayConverter.cs
  60. 2 2
      MediaBrowser.Common/Json/Converters/JsonCommaDelimitedArrayConverterFactory.cs
  61. 81 0
      MediaBrowser.Common/Json/Converters/JsonDelimitedArrayConverter.cs
  62. 3 3
      MediaBrowser.Common/Json/Converters/JsonNullableStructConverterFactory.cs
  63. 12 6
      MediaBrowser.Common/Json/Converters/JsonOmdbNotAvailableStringConverter.cs
  64. 3 54
      MediaBrowser.Common/Json/Converters/JsonPipeDelimitedArrayConverter.cs
  65. 2 2
      MediaBrowser.Common/Json/Converters/JsonPipeDelimitedArrayConverterFactory.cs
  66. 4 4
      MediaBrowser.Common/Json/Converters/JsonStringConverter.cs
  67. 1 1
      MediaBrowser.Common/Json/Converters/JsonVersionConverter.cs
  68. 1 0
      MediaBrowser.Common/MediaBrowser.Common.csproj
  69. 0 1
      MediaBrowser.Common/Net/INetworkManager.cs
  70. 0 1
      MediaBrowser.Common/Net/IPHost.cs
  71. 0 1
      MediaBrowser.Common/Net/IPNetAddress.cs
  72. 0 1
      MediaBrowser.Common/Net/IPObject.cs
  73. 2 0
      MediaBrowser.Common/Plugins/BasePlugin.cs
  74. 2 0
      MediaBrowser.Common/Plugins/BasePluginOfT.cs
  75. 2 0
      MediaBrowser.Common/Plugins/IPlugin.cs
  76. 0 2
      MediaBrowser.Common/Plugins/IPluginManager.cs
  77. 0 1
      MediaBrowser.Common/Plugins/LocalPlugin.cs
  78. 0 2
      MediaBrowser.Common/Plugins/PluginManifest.cs
  79. 2 2
      MediaBrowser.Common/Progress/ActionableProgress.cs
  80. 1 1
      MediaBrowser.Common/Progress/SimpleProgress.cs
  81. 1 3
      MediaBrowser.Common/Providers/ProviderIdParsers.cs
  82. 0 2
      MediaBrowser.Common/Updates/IInstallationManager.cs
  83. 2 0
      MediaBrowser.Common/Updates/InstallationEventArgs.cs
  84. 1 0
      MediaBrowser.Common/Updates/InstallationFailedEventArgs.cs
  85. 2 0
      MediaBrowser.Controller/Authentication/AuthenticationResult.cs
  86. 2 0
      MediaBrowser.Controller/Authentication/IAuthenticationProvider.cs
  87. 2 0
      MediaBrowser.Controller/Authentication/IPasswordResetProvider.cs
  88. 2 0
      MediaBrowser.Controller/BaseItemManager/BaseItemManager.cs
  89. 2 0
      MediaBrowser.Controller/BaseItemManager/IBaseItemManager.cs
  90. 2 0
      MediaBrowser.Controller/Channels/Channel.cs
  91. 2 0
      MediaBrowser.Controller/Channels/ChannelItemInfo.cs
  92. 2 0
      MediaBrowser.Controller/Channels/ChannelItemResult.cs
  93. 2 0
      MediaBrowser.Controller/Channels/ChannelSearchInfo.cs
  94. 2 0
      MediaBrowser.Controller/Channels/IChannel.cs
  95. 2 0
      MediaBrowser.Controller/Channels/IChannelManager.cs
  96. 2 0
      MediaBrowser.Controller/Channels/IHasCacheKey.cs
  97. 2 0
      MediaBrowser.Controller/Channels/ISearchableChannel.cs
  98. 2 0
      MediaBrowser.Controller/Channels/InternalChannelFeatures.cs
  99. 2 0
      MediaBrowser.Controller/Channels/InternalChannelItemQuery.cs
  100. 2 0
      MediaBrowser.Controller/Collections/CollectionCreationOptions.cs

+ 0 - 2
.github/workflows/automation.yml

@@ -2,8 +2,6 @@ name: Automation
 
 on:
   pull_request:
-  issues:
-  issue_comment:
 
 jobs:
   main:

+ 2 - 0
Emby.Dlna/Configuration/DlnaOptions.cs

@@ -1,3 +1,5 @@
+#nullable disable
+
 #pragma warning disable CS1591
 
 namespace Emby.Dlna.Configuration

+ 0 - 1
Emby.Dlna/ConfigurationExtension.cs

@@ -1,4 +1,3 @@
-#nullable enable
 #pragma warning disable CS1591
 
 using Emby.Dlna.Configuration;

+ 2 - 0
Emby.Dlna/ContentDirectory/ContentDirectoryService.cs

@@ -1,3 +1,5 @@
+#nullable disable
+
 #pragma warning disable CS1591
 
 using System;

+ 2 - 0
Emby.Dlna/ContentDirectory/ControlHandler.cs

@@ -1,3 +1,5 @@
+#nullable disable
+
 using System;
 using System.Collections.Generic;
 using System.Globalization;

+ 2 - 0
Emby.Dlna/ControlRequest.cs

@@ -1,3 +1,5 @@
+#nullable disable
+
 #pragma warning disable CS1591
 
 using System.IO;

+ 2 - 0
Emby.Dlna/ControlResponse.cs

@@ -1,3 +1,5 @@
+#nullable disable
+
 #pragma warning disable CS1591
 
 using System.Collections.Generic;

+ 2 - 0
Emby.Dlna/Didl/DidlBuilder.cs

@@ -1,3 +1,5 @@
+#nullable disable
+
 #pragma warning disable CS1591
 
 using System;

+ 1 - 1
Emby.Dlna/Didl/StringWriterWithEncoding.cs

@@ -9,7 +9,7 @@ namespace Emby.Dlna.Didl
 {
     public class StringWriterWithEncoding : StringWriter
     {
-        private readonly Encoding _encoding;
+        private readonly Encoding? _encoding;
 
         public StringWriterWithEncoding()
         {

+ 0 - 1
Emby.Dlna/DlnaConfigurationFactory.cs

@@ -1,4 +1,3 @@
-#nullable enable
 #pragma warning disable CS1591
 
 using System.Collections.Generic;

+ 2 - 0
Emby.Dlna/DlnaManager.cs

@@ -1,3 +1,5 @@
+#nullable disable
+
 #pragma warning disable CS1591
 
 using System;

+ 1 - 0
Emby.Dlna/Emby.Dlna.csproj

@@ -21,6 +21,7 @@
     <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
     <GenerateDocumentationFile>true</GenerateDocumentationFile>
     <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
+    <Nullable>enable</Nullable>
   </PropertyGroup>
 
   <!-- Code Analyzers-->

+ 2 - 0
Emby.Dlna/EventSubscriptionResponse.cs

@@ -1,3 +1,5 @@
+#nullable disable
+
 #pragma warning disable CS1591
 
 using System.Collections.Generic;

+ 2 - 0
Emby.Dlna/Eventing/DlnaEventManager.cs

@@ -1,3 +1,5 @@
+#nullable disable
+
 #pragma warning disable CS1591
 
 using System;

+ 2 - 0
Emby.Dlna/Eventing/EventSubscription.cs

@@ -1,3 +1,5 @@
+#nullable disable
+
 #pragma warning disable CS1591
 
 using System;

+ 2 - 0
Emby.Dlna/Main/DlnaEntryPoint.cs

@@ -1,3 +1,5 @@
+#nullable disable
+
 #pragma warning disable CS1591
 
 using System;

+ 2 - 0
Emby.Dlna/PlayTo/Device.cs

@@ -1,3 +1,5 @@
+#nullable disable
+
 #pragma warning disable CS1591
 
 using System;

+ 2 - 0
Emby.Dlna/PlayTo/DeviceInfo.cs

@@ -1,3 +1,5 @@
+#nullable disable
+
 #pragma warning disable CS1591
 
 using System.Collections.Generic;

+ 2 - 0
Emby.Dlna/PlayTo/MediaChangedEventArgs.cs

@@ -1,3 +1,5 @@
+#nullable disable
+
 #pragma warning disable CS1591
 
 using System;

+ 2 - 0
Emby.Dlna/PlayTo/PlayToController.cs

@@ -1,3 +1,5 @@
+#nullable disable
+
 #pragma warning disable CS1591
 
 using System;

+ 2 - 0
Emby.Dlna/PlayTo/PlayToManager.cs

@@ -1,3 +1,5 @@
+#nullable disable
+
 #pragma warning disable CS1591
 
 using System;

+ 2 - 0
Emby.Dlna/PlayTo/PlaybackProgressEventArgs.cs

@@ -1,3 +1,5 @@
+#nullable disable
+
 #pragma warning disable CS1591
 
 using System;

+ 2 - 0
Emby.Dlna/PlayTo/PlaybackStartEventArgs.cs

@@ -1,3 +1,5 @@
+#nullable disable
+
 #pragma warning disable CS1591
 
 using System;

+ 2 - 0
Emby.Dlna/PlayTo/PlaybackStoppedEventArgs.cs

@@ -1,3 +1,5 @@
+#nullable disable
+
 #pragma warning disable CS1591
 
 using System;

+ 2 - 0
Emby.Dlna/PlayTo/PlaylistItem.cs

@@ -1,3 +1,5 @@
+#nullable disable
+
 #pragma warning disable CS1591
 
 using MediaBrowser.Model.Dlna;

+ 2 - 0
Emby.Dlna/PlayTo/PlaylistItemFactory.cs

@@ -1,3 +1,5 @@
+#nullable disable
+
 #pragma warning disable CS1591
 
 using System.IO;

+ 2 - 0
Emby.Dlna/PlayTo/SsdpHttpClient.cs

@@ -1,3 +1,5 @@
+#nullable disable
+
 #pragma warning disable CS1591
 
 using System;

+ 7 - 7
Emby.Dlna/PlayTo/TransportCommands.cs

@@ -46,7 +46,7 @@ namespace Emby.Dlna.PlayTo
         {
             var serviceAction = new ServiceAction
             {
-                Name = container.GetValue(UPnpNamespaces.Svc + "name"),
+                Name = container.GetValue(UPnpNamespaces.Svc + "name") ?? string.Empty,
             };
 
             var argumentList = serviceAction.ArgumentList;
@@ -68,9 +68,9 @@ namespace Emby.Dlna.PlayTo
 
             return new Argument
             {
-                Name = container.GetValue(UPnpNamespaces.Svc + "name"),
-                Direction = container.GetValue(UPnpNamespaces.Svc + "direction"),
-                RelatedStateVariable = container.GetValue(UPnpNamespaces.Svc + "relatedStateVariable")
+                Name = container.GetValue(UPnpNamespaces.Svc + "name") ?? string.Empty,
+                Direction = container.GetValue(UPnpNamespaces.Svc + "direction") ?? string.Empty,
+                RelatedStateVariable = container.GetValue(UPnpNamespaces.Svc + "relatedStateVariable") ?? string.Empty
             };
         }
 
@@ -89,8 +89,8 @@ namespace Emby.Dlna.PlayTo
 
             return new StateVariable
             {
-                Name = container.GetValue(UPnpNamespaces.Svc + "name"),
-                DataType = container.GetValue(UPnpNamespaces.Svc + "dataType"),
+                Name = container.GetValue(UPnpNamespaces.Svc + "name") ?? string.Empty,
+                DataType = container.GetValue(UPnpNamespaces.Svc + "dataType") ?? string.Empty,
                 AllowedValues = allowedValues
             };
         }
@@ -166,7 +166,7 @@ namespace Emby.Dlna.PlayTo
             return string.Format(CultureInfo.InvariantCulture, CommandBase, action.Name, xmlNamesapce, stateString);
         }
 
-        private string BuildArgumentXml(Argument argument, string value, string commandParameter = "")
+        private string BuildArgumentXml(Argument argument, string? value, string commandParameter = "")
         {
             var state = StateVariables.FirstOrDefault(a => string.Equals(a.Name, argument.RelatedStateVariable, StringComparison.OrdinalIgnoreCase));
 

+ 2 - 0
Emby.Dlna/PlayTo/uBaseObject.cs

@@ -1,3 +1,5 @@
+#nullable disable
+
 #pragma warning disable CS1591
 
 using System;

+ 2 - 1
Emby.Dlna/Server/DescriptionXmlBuilder.cs

@@ -250,7 +250,8 @@ namespace Emby.Dlna.Server
 
             url = _serverAddress.TrimEnd('/') + "/dlna/" + _serverUdn + "/" + url.TrimStart('/');
 
-            return SecurityElement.Escape(url);
+            // TODO: @bond remove null-coalescing operator when https://github.com/dotnet/runtime/pull/52442 is merged/released
+            return SecurityElement.Escape(url) ?? string.Empty;
         }
 
         private IEnumerable<DeviceIcon> GetIcons()

+ 2 - 2
Emby.Dlna/Service/BaseControlHandler.cs

@@ -47,7 +47,7 @@ namespace Emby.Dlna.Service
 
         private async Task<ControlResponse> ProcessControlRequestInternalAsync(ControlRequest request)
         {
-            ControlRequestInfo requestInfo;
+            ControlRequestInfo? requestInfo = null;
 
             using (var streamReader = new StreamReader(request.InputXml, Encoding.UTF8))
             {
@@ -151,7 +151,7 @@ namespace Emby.Dlna.Service
 
         private async Task<ControlRequestInfo> ParseBodyTagAsync(XmlReader reader)
         {
-            string namespaceURI = null, localName = null;
+            string? namespaceURI = null, localName = null;
 
             await reader.MoveToContentAsync().ConfigureAwait(false);
             await reader.ReadAsync().ConfigureAwait(false);

+ 2 - 0
Emby.Dlna/Ssdp/DeviceDiscovery.cs

@@ -1,3 +1,5 @@
+#nullable disable
+
 #pragma warning disable CS1591
 
 using System;

+ 3 - 3
Emby.Dlna/Ssdp/SsdpExtensions.cs

@@ -7,21 +7,21 @@ namespace Emby.Dlna.Ssdp
 {
     public static class SsdpExtensions
     {
-        public static string GetValue(this XElement container, XName name)
+        public static string? GetValue(this XElement container, XName name)
         {
             var node = container.Element(name);
 
             return node?.Value;
         }
 
-        public static string GetAttributeValue(this XElement container, XName name)
+        public static string? GetAttributeValue(this XElement container, XName name)
         {
             var node = container.Attribute(name);
 
             return node?.Value;
         }
 
-        public static string GetDescendantValue(this XElement container, XName name)
+        public static string? GetDescendantValue(this XElement container, XName name)
             => container.Descendants(name).FirstOrDefault()?.Value;
     }
 }

+ 5 - 0
Emby.Server.Implementations/Library/ResolverHelper.cs

@@ -44,6 +44,11 @@ namespace Emby.Server.Implementations.Library
 
             // Make sure DateCreated and DateModified have values
             var fileInfo = directoryService.GetFile(item.Path);
+            if (fileInfo == null)
+            {
+                throw new FileNotFoundException("Can't find item path.", item.Path);
+            }
+
             SetDateCreated(item, fileInfo);
 
             EnsureName(item, fileInfo);

+ 3 - 4
Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs

@@ -10,6 +10,7 @@ using System.Text.Json;
 using System.Threading;
 using System.Threading.Tasks;
 using MediaBrowser.Common.Configuration;
+using MediaBrowser.Common.Extensions;
 using MediaBrowser.Common.Json;
 using MediaBrowser.Controller;
 using MediaBrowser.Controller.Configuration;
@@ -307,13 +308,11 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
             {
                 using (var reader = new StreamReader(source))
                 {
-                    while (!reader.EndOfStream)
+                    await foreach (var line in reader.ReadAllLinesAsync().ConfigureAwait(false))
                     {
-                        var line = await reader.ReadLineAsync().ConfigureAwait(false);
-
                         var bytes = Encoding.UTF8.GetBytes(Environment.NewLine + line);
 
-                        await target.WriteAsync(bytes, 0, bytes.Length).ConfigureAwait(false);
+                        await target.WriteAsync(bytes.AsMemory()).ConfigureAwait(false);
                         await target.FlushAsync().ConfigureAwait(false);
                     }
                 }

+ 7 - 7
Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs

@@ -182,16 +182,16 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
             await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
             using var sr = new StreamReader(stream, System.Text.Encoding.UTF8);
             var tuners = new List<LiveTvTunerInfo>();
-            while (!sr.EndOfStream)
+            await foreach (var line in sr.ReadAllLinesAsync().ConfigureAwait(false))
             {
-                string line = StripXML(sr.ReadLine());
-                if (line.Contains("Channel", StringComparison.Ordinal))
+                string stripedLine = StripXML(line);
+                if (stripedLine.Contains("Channel", StringComparison.Ordinal))
                 {
                     LiveTvTunerStatus status;
-                    var index = line.IndexOf("Channel", StringComparison.OrdinalIgnoreCase);
-                    var name = line.Substring(0, index - 1);
-                    var currentChannel = line.Substring(index + 7);
-                    if (currentChannel != "none")
+                    var index = stripedLine.IndexOf("Channel", StringComparison.OrdinalIgnoreCase);
+                    var name = stripedLine.Substring(0, index - 1);
+                    var currentChannel = stripedLine.Substring(index + 7);
+                    if (string.Equals(currentChannel, "none", StringComparison.Ordinal))
                     {
                         status = LiveTvTunerStatus.LiveTv;
                     }

+ 12 - 22
Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs

@@ -35,16 +35,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
             // Read the file and display it line by line.
             using (var reader = new StreamReader(await GetListingsStream(info, cancellationToken).ConfigureAwait(false)))
             {
-                return GetChannels(reader, channelIdPrefix, info.Id);
-            }
-        }
-
-        public List<ChannelInfo> ParseString(string text, string channelIdPrefix, string tunerHostId)
-        {
-            // Read the file and display it line by line.
-            using (var reader = new StringReader(text))
-            {
-                return GetChannels(reader, channelIdPrefix, tunerHostId);
+                return await GetChannelsAsync(reader, channelIdPrefix, info.Id).ConfigureAwait(false);
             }
         }
 
@@ -70,43 +61,42 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
 
         private const string ExtInfPrefix = "#EXTINF:";
 
-        private List<ChannelInfo> GetChannels(TextReader reader, string channelIdPrefix, string tunerHostId)
+        private async Task<List<ChannelInfo>> GetChannelsAsync(TextReader reader, string channelIdPrefix, string tunerHostId)
         {
             var channels = new List<ChannelInfo>();
-            string line;
             string extInf = string.Empty;
 
-            while ((line = reader.ReadLine()) != null)
+            await foreach (var line in reader.ReadAllLinesAsync().ConfigureAwait(false))
             {
-                line = line.Trim();
-                if (string.IsNullOrWhiteSpace(line))
+                var trimmedLine = line.Trim();
+                if (string.IsNullOrWhiteSpace(trimmedLine))
                 {
                     continue;
                 }
 
-                if (line.StartsWith("#EXTM3U", StringComparison.OrdinalIgnoreCase))
+                if (trimmedLine.StartsWith("#EXTM3U", StringComparison.OrdinalIgnoreCase))
                 {
                     continue;
                 }
 
-                if (line.StartsWith(ExtInfPrefix, StringComparison.OrdinalIgnoreCase))
+                if (trimmedLine.StartsWith(ExtInfPrefix, StringComparison.OrdinalIgnoreCase))
                 {
-                    extInf = line.Substring(ExtInfPrefix.Length).Trim();
+                    extInf = trimmedLine.Substring(ExtInfPrefix.Length).Trim();
                     _logger.LogInformation("Found m3u channel: {0}", extInf);
                 }
-                else if (!string.IsNullOrWhiteSpace(extInf) && !line.StartsWith('#'))
+                else if (!string.IsNullOrWhiteSpace(extInf) && !trimmedLine.StartsWith('#'))
                 {
-                    var channel = GetChannelnfo(extInf, tunerHostId, line);
+                    var channel = GetChannelnfo(extInf, tunerHostId, trimmedLine);
                     if (string.IsNullOrWhiteSpace(channel.Id))
                     {
-                        channel.Id = channelIdPrefix + line.GetMD5().ToString("N", CultureInfo.InvariantCulture);
+                        channel.Id = channelIdPrefix + trimmedLine.GetMD5().ToString("N", CultureInfo.InvariantCulture);
                     }
                     else
                     {
                         channel.Id = channelIdPrefix + channel.Id.GetMD5().ToString("N", CultureInfo.InvariantCulture);
                     }
 
-                    channel.Path = line;
+                    channel.Path = trimmedLine;
                     channels.Add(channel);
                     extInf = string.Empty;
                 }

+ 4 - 6
Emby.Server.Implementations/Localization/LocalizationManager.cs

@@ -7,6 +7,7 @@ using System.Linq;
 using System.Reflection;
 using System.Text.Json;
 using System.Threading.Tasks;
+using MediaBrowser.Common.Extensions;
 using MediaBrowser.Common.Json;
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Model.Entities;
@@ -72,8 +73,7 @@ namespace Emby.Server.Implementations.Localization
                 using (var str = _assembly.GetManifestResourceStream(resource))
                 using (var reader = new StreamReader(str))
                 {
-                    string line;
-                    while ((line = await reader.ReadLineAsync().ConfigureAwait(false)) != null)
+                    await foreach (var line in reader.ReadAllLinesAsync().ConfigureAwait(false))
                     {
                         if (string.IsNullOrWhiteSpace(line))
                         {
@@ -118,10 +118,8 @@ namespace Emby.Server.Implementations.Localization
             using (var stream = _assembly.GetManifestResourceStream(ResourcePath))
             using (var reader = new StreamReader(stream))
             {
-                while (!reader.EndOfStream)
+                await foreach (var line in reader.ReadAllLinesAsync().ConfigureAwait(false))
                 {
-                    var line = await reader.ReadLineAsync().ConfigureAwait(false);
-
                     if (string.IsNullOrWhiteSpace(line))
                     {
                         continue;
@@ -179,7 +177,7 @@ namespace Emby.Server.Implementations.Localization
         /// <inheritdoc />
         public IEnumerable<CountryInfo> GetCountries()
         {
-            StreamReader reader = new StreamReader(_assembly.GetManifestResourceStream("Emby.Server.Implementations.Localization.countries.json"));
+            using StreamReader reader = new StreamReader(_assembly.GetManifestResourceStream("Emby.Server.Implementations.Localization.countries.json"));
 
             return JsonSerializer.Deserialize<IEnumerable<CountryInfo>>(reader.ReadToEnd(), _jsonOptions);
         }

+ 3 - 2
Jellyfin.Api/Auth/BaseAuthorizationHandler.cs

@@ -77,8 +77,9 @@ namespace Jellyfin.Api.Auth
                 return false;
             }
 
-            var ip = _httpContextAccessor.HttpContext.GetNormalizedRemoteIp();
-            var isInLocalNetwork = _networkManager.IsInLocalNetwork(ip);
+            var isInLocalNetwork = _httpContextAccessor.HttpContext != null
+                && _networkManager.IsInLocalNetwork(_httpContextAccessor.HttpContext.GetNormalizedRemoteIp());
+
             // User cannot access remotely and user is remote
             if (!user.HasPermission(PermissionKind.EnableRemoteAccess) && !isInLocalNetwork)
             {

+ 6 - 0
Jellyfin.Api/Controllers/ConfigurationController.cs

@@ -1,3 +1,4 @@
+using System;
 using System.ComponentModel.DataAnnotations;
 using System.Net.Mime;
 using System.Text.Json;
@@ -94,6 +95,11 @@ namespace Jellyfin.Api.Controllers
         {
             var configurationType = _configurationManager.GetConfigurationType(key);
             var configuration = await JsonSerializer.DeserializeAsync(Request.Body, configurationType, _serializerOptions).ConfigureAwait(false);
+            if (configuration == null)
+            {
+                throw new ArgumentException("Body doesn't contain a valid configuration");
+            }
+
             _configurationManager.SaveConfiguration(key, configuration);
             return NoContent();
         }

+ 1 - 1
Jellyfin.Api/Controllers/LibraryController.cs

@@ -600,7 +600,7 @@ namespace Jellyfin.Api.Controllers
         {
             foreach (var item in dto.Updates)
             {
-                _libraryMonitor.ReportFileSystemChanged(item.Path);
+                _libraryMonitor.ReportFileSystemChanged(item.Path ?? throw new ArgumentException("Item path can't be null."));
             }
 
             return NoContent();

+ 1 - 4
Jellyfin.Api/Helpers/HlsHelpers.cs

@@ -118,10 +118,7 @@ namespace Jellyfin.Api.Helpers
         /// <returns>The playlist text as a string.</returns>
         public static string GetLivePlaylistText(string path, StreamState state)
         {
-            using var stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
-            using var reader = new StreamReader(stream);
-
-            var text = reader.ReadToEnd();
+            var text = File.ReadAllText(path);
 
             var segmentFormat = EncodingHelper.GetSegmentFileExtension(state.Request.SegmentContainer).TrimStart('.');
             if (string.Equals(segmentFormat, "mp4", StringComparison.OrdinalIgnoreCase))

+ 2 - 0
MediaBrowser.Common/Configuration/ConfigurationStore.cs

@@ -1,3 +1,5 @@
+#nullable disable
+
 using System;
 
 namespace MediaBrowser.Common.Configuration

+ 1 - 0
MediaBrowser.Common/Configuration/ConfigurationUpdateEventArgs.cs

@@ -1,3 +1,4 @@
+#nullable disable
 #pragma warning disable CS1591
 
 using System;

+ 2 - 0
MediaBrowser.Common/Configuration/IApplicationPaths.cs

@@ -1,3 +1,5 @@
+#nullable disable
+
 namespace MediaBrowser.Common.Configuration
 {
     /// <summary>

+ 0 - 1
MediaBrowser.Common/Cryptography/PasswordHash.cs

@@ -1,5 +1,4 @@
 #pragma warning disable CS1591
-#nullable enable
 
 using System;
 using System.Collections.Generic;

+ 2 - 2
MediaBrowser.Common/Events/EventHelper.cs

@@ -17,7 +17,7 @@ namespace MediaBrowser.Common.Events
         /// <param name="sender">The sender.</param>
         /// <param name="args">The <see cref="EventArgs" /> instance containing the event data.</param>
         /// <param name="logger">The logger.</param>
-        public static void QueueEventIfNotNull(EventHandler handler, object sender, EventArgs args, ILogger logger)
+        public static void QueueEventIfNotNull(EventHandler? handler, object sender, EventArgs args, ILogger logger)
         {
             if (handler != null)
             {
@@ -43,7 +43,7 @@ namespace MediaBrowser.Common.Events
         /// <param name="sender">The sender.</param>
         /// <param name="args">The args.</param>
         /// <param name="logger">The logger.</param>
-        public static void QueueEventIfNotNull<T>(EventHandler<T> handler, object sender, T args, ILogger logger)
+        public static void QueueEventIfNotNull<T>(EventHandler<T>? handler, object sender, T args, ILogger logger)
         {
             if (handler != null)
             {

+ 0 - 2
MediaBrowser.Common/Extensions/BaseExtensions.cs

@@ -1,5 +1,3 @@
-#nullable enable
-
 using System;
 using System.Security.Cryptography;
 using System.Text;

+ 0 - 2
MediaBrowser.Common/Extensions/CopyToExtensions.cs

@@ -1,5 +1,3 @@
-#nullable enable
-
 using System.Collections.Generic;
 
 namespace MediaBrowser.Common.Extensions

+ 1 - 1
MediaBrowser.Common/Extensions/HttpContextExtensions.cs

@@ -17,7 +17,7 @@ namespace MediaBrowser.Common.Extensions
         {
             return (context.Connection.LocalIpAddress == null
                     && context.Connection.RemoteIpAddress == null)
-                   || context.Connection.LocalIpAddress.Equals(context.Connection.RemoteIpAddress);
+                   || Equals(context.Connection.LocalIpAddress, context.Connection.RemoteIpAddress);
         }
 
         /// <summary>

+ 0 - 2
MediaBrowser.Common/Extensions/MethodNotAllowedException.cs

@@ -1,5 +1,3 @@
-#nullable enable
-
 using System;
 
 namespace MediaBrowser.Common.Extensions

+ 0 - 2
MediaBrowser.Common/Extensions/ProcessExtensions.cs

@@ -1,5 +1,3 @@
-#nullable enable
-
 using System;
 using System.Diagnostics;
 using System.Threading;

+ 0 - 1
MediaBrowser.Common/Extensions/RateLimitExceededException.cs

@@ -1,4 +1,3 @@
-#nullable enable
 #pragma warning disable CS1591
 
 using System;

+ 0 - 2
MediaBrowser.Common/Extensions/ResourceNotFoundException.cs

@@ -1,5 +1,3 @@
-#nullable enable
-
 using System;
 
 namespace MediaBrowser.Common.Extensions

+ 0 - 2
MediaBrowser.Common/Extensions/ShuffleExtensions.cs

@@ -1,5 +1,3 @@
-#nullable enable
-
 using System;
 using System.Collections.Generic;
 

+ 1 - 1
MediaBrowser.Common/Extensions/SplitStringExtensions.cs

@@ -21,7 +21,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.
  */
-#nullable enable
+
 #pragma warning disable CS1591
 #pragma warning disable CA1034
 using System;

+ 17 - 5
MediaBrowser.Common/Extensions/StreamExtensions.cs

@@ -1,5 +1,3 @@
-#nullable enable
-
 using System.Collections.Generic;
 using System.IO;
 using System.Linq;
@@ -35,11 +33,11 @@ namespace MediaBrowser.Common.Extensions
         }
 
         /// <summary>
-        /// Reads all lines in the <see cref="StreamReader" />.
+        /// Reads all lines in the <see cref="TextReader" />.
         /// </summary>
-        /// <param name="reader">The <see cref="StreamReader" /> to read from.</param>
+        /// <param name="reader">The <see cref="TextReader" /> to read from.</param>
         /// <returns>All lines in the stream.</returns>
-        public static IEnumerable<string> ReadAllLines(this StreamReader reader)
+        public static IEnumerable<string> ReadAllLines(this TextReader reader)
         {
             string? line;
             while ((line = reader.ReadLine()) != null)
@@ -47,5 +45,19 @@ namespace MediaBrowser.Common.Extensions
                 yield return line;
             }
         }
+
+        /// <summary>
+        /// Reads all lines in the <see cref="TextReader" />.
+        /// </summary>
+        /// <param name="reader">The <see cref="TextReader" /> to read from.</param>
+        /// <returns>All lines in the stream.</returns>
+        public static async IAsyncEnumerable<string> ReadAllLinesAsync(this TextReader reader)
+        {
+            string? line;
+            while ((line = await reader.ReadLineAsync().ConfigureAwait(false)) != null)
+            {
+                yield return line;
+            }
+        }
     }
 }

+ 2 - 0
MediaBrowser.Common/IApplicationHost.cs

@@ -1,3 +1,5 @@
+#nullable disable
+
 using System;
 using System.Collections.Generic;
 using System.Reflection;

+ 3 - 54
MediaBrowser.Common/Json/Converters/JsonCommaDelimitedArrayConverter.cs

@@ -9,67 +9,16 @@ namespace MediaBrowser.Common.Json.Converters
     /// Convert comma delimited string to array of type.
     /// </summary>
     /// <typeparam name="T">Type to convert to.</typeparam>
-    public class JsonCommaDelimitedArrayConverter<T> : JsonConverter<T[]>
+    public sealed class JsonCommaDelimitedArrayConverter<T> : JsonDelimitedArrayConverter<T>
     {
-        private readonly TypeConverter _typeConverter;
-
         /// <summary>
         /// Initializes a new instance of the <see cref="JsonCommaDelimitedArrayConverter{T}"/> class.
         /// </summary>
-        public JsonCommaDelimitedArrayConverter()
+        public JsonCommaDelimitedArrayConverter() : base()
         {
-            _typeConverter = TypeDescriptor.GetConverter(typeof(T));
         }
 
         /// <inheritdoc />
-        public override T[] Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
-        {
-            if (reader.TokenType == JsonTokenType.String)
-            {
-                var stringEntries = reader.GetString().Split(',', StringSplitOptions.RemoveEmptyEntries);
-                if (stringEntries.Length == 0)
-                {
-                    return Array.Empty<T>();
-                }
-
-                var parsedValues = new object[stringEntries.Length];
-                var convertedCount = 0;
-                for (var i = 0; i < stringEntries.Length; i++)
-                {
-                    try
-                    {
-                        parsedValues[i] = _typeConverter.ConvertFrom(stringEntries[i].Trim());
-                        convertedCount++;
-                    }
-                    catch (FormatException)
-                    {
-                        // TODO log when upgraded to .Net6
-                        // https://github.com/dotnet/runtime/issues/42975
-                        // _logger.LogDebug(e, "Error converting value.");
-                    }
-                }
-
-                var typedValues = new T[convertedCount];
-                var typedValueIndex = 0;
-                for (var i = 0; i < stringEntries.Length; i++)
-                {
-                    if (parsedValues[i] != null)
-                    {
-                        typedValues.SetValue(parsedValues[i], typedValueIndex);
-                        typedValueIndex++;
-                    }
-                }
-
-                return typedValues;
-            }
-
-            return JsonSerializer.Deserialize<T[]>(ref reader, options);
-        }
-
-        /// <inheritdoc />
-        public override void Write(Utf8JsonWriter writer, T[] value, JsonSerializerOptions options)
-        {
-            throw new NotImplementedException();
-        }
+        protected override char Delimiter => ',';
     }
 }

+ 2 - 2
MediaBrowser.Common/Json/Converters/JsonCommaDelimitedArrayConverterFactory.cs

@@ -19,10 +19,10 @@ namespace MediaBrowser.Common.Json.Converters
         }
 
         /// <inheritdoc />
-        public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options)
+        public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options)
         {
             var structType = typeToConvert.GetElementType() ?? typeToConvert.GenericTypeArguments[0];
-            return (JsonConverter)Activator.CreateInstance(typeof(JsonCommaDelimitedArrayConverter<>).MakeGenericType(structType));
+            return (JsonConverter?)Activator.CreateInstance(typeof(JsonCommaDelimitedArrayConverter<>).MakeGenericType(structType));
         }
     }
 }

+ 81 - 0
MediaBrowser.Common/Json/Converters/JsonDelimitedArrayConverter.cs

@@ -0,0 +1,81 @@
+using System;
+using System.ComponentModel;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+namespace MediaBrowser.Common.Json.Converters
+{
+    /// <summary>
+    /// Convert delimited string to array of type.
+    /// </summary>
+    /// <typeparam name="T">Type to convert to.</typeparam>
+    public abstract class JsonDelimitedArrayConverter<T> : JsonConverter<T[]?>
+    {
+        private readonly TypeConverter _typeConverter;
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="JsonDelimitedArrayConverter{T}"/> class.
+        /// </summary>
+        protected JsonDelimitedArrayConverter()
+        {
+            _typeConverter = TypeDescriptor.GetConverter(typeof(T));
+        }
+
+        /// <summary>
+        /// Gets the array delimiter.
+        /// </summary>
+        protected virtual char Delimiter { get; }
+
+        /// <inheritdoc />
+        public override T[]? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+        {
+            if (reader.TokenType == JsonTokenType.String)
+            {
+                // GetString can't return null here because we already handled it above
+                var stringEntries = reader.GetString()?.Split(Delimiter, StringSplitOptions.RemoveEmptyEntries);
+                if (stringEntries == null || stringEntries.Length == 0)
+                {
+                    return Array.Empty<T>();
+                }
+
+                var parsedValues = new object[stringEntries.Length];
+                var convertedCount = 0;
+                for (var i = 0; i < stringEntries.Length; i++)
+                {
+                    try
+                    {
+                        parsedValues[i] = _typeConverter.ConvertFrom(stringEntries[i].Trim());
+                        convertedCount++;
+                    }
+                    catch (FormatException)
+                    {
+                        // TODO log when upgraded to .Net6
+                        // https://github.com/dotnet/runtime/issues/42975
+                        // _logger.LogDebug(e, "Error converting value.");
+                    }
+                }
+
+                var typedValues = new T[convertedCount];
+                var typedValueIndex = 0;
+                for (var i = 0; i < stringEntries.Length; i++)
+                {
+                    if (parsedValues[i] != null)
+                    {
+                        typedValues.SetValue(parsedValues[i], typedValueIndex);
+                        typedValueIndex++;
+                    }
+                }
+
+                return typedValues;
+            }
+
+            return JsonSerializer.Deserialize<T[]>(ref reader, options);
+        }
+
+        /// <inheritdoc />
+        public override void Write(Utf8JsonWriter writer, T[]? value, JsonSerializerOptions options)
+        {
+            throw new NotImplementedException();
+        }
+    }
+}

+ 3 - 3
MediaBrowser.Common/Json/Converters/JsonNullableStructConverterFactory.cs

@@ -18,10 +18,10 @@ namespace MediaBrowser.Common.Json.Converters
         }
 
         /// <inheritdoc />
-        public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options)
+        public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options)
         {
             var structType = typeToConvert.GenericTypeArguments[0];
-            return (JsonConverter)Activator.CreateInstance(typeof(JsonNullableStructConverter<>).MakeGenericType(structType));
+            return (JsonConverter?)Activator.CreateInstance(typeof(JsonNullableStructConverter<>).MakeGenericType(structType));
         }
     }
-}
+}

+ 12 - 6
MediaBrowser.Common/Json/Converters/JsonOmdbNotAvailableStringConverter.cs

@@ -7,15 +7,21 @@ namespace MediaBrowser.Common.Json.Converters
     /// <summary>
     /// Converts a string <c>N/A</c> to <c>string.Empty</c>.
     /// </summary>
-    public class JsonOmdbNotAvailableStringConverter : JsonConverter<string>
+    public class JsonOmdbNotAvailableStringConverter : JsonConverter<string?>
     {
         /// <inheritdoc />
-        public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+        public override string? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
         {
+            if (reader.TokenType == JsonTokenType.Null)
+            {
+                return null;
+            }
+
             if (reader.TokenType == JsonTokenType.String)
             {
-                var str = reader.GetString();
-                if (str != null && str.Equals("N/A", StringComparison.OrdinalIgnoreCase))
+                // GetString can't return null here because we already handled it above
+                var str = reader.GetString()!;
+                if (str.Equals("N/A", StringComparison.OrdinalIgnoreCase))
                 {
                     return null;
                 }
@@ -23,11 +29,11 @@ namespace MediaBrowser.Common.Json.Converters
                 return str;
             }
 
-            return JsonSerializer.Deserialize<string>(ref reader, options);
+            return JsonSerializer.Deserialize<string?>(ref reader, options);
         }
 
         /// <inheritdoc />
-        public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options)
+        public override void Write(Utf8JsonWriter writer, string? value, JsonSerializerOptions options)
         {
             writer.WriteStringValue(value);
         }

+ 3 - 54
MediaBrowser.Common/Json/Converters/JsonPipeDelimitedArrayConverter.cs

@@ -9,67 +9,16 @@ namespace MediaBrowser.Common.Json.Converters
     /// Convert Pipe delimited string to array of type.
     /// </summary>
     /// <typeparam name="T">Type to convert to.</typeparam>
-    public class JsonPipeDelimitedArrayConverter<T> : JsonConverter<T[]>
+    public sealed class JsonPipeDelimitedArrayConverter<T> : JsonDelimitedArrayConverter<T>
     {
-        private readonly TypeConverter _typeConverter;
-
         /// <summary>
         /// Initializes a new instance of the <see cref="JsonPipeDelimitedArrayConverter{T}"/> class.
         /// </summary>
-        public JsonPipeDelimitedArrayConverter()
+        public JsonPipeDelimitedArrayConverter() : base()
         {
-            _typeConverter = TypeDescriptor.GetConverter(typeof(T));
         }
 
         /// <inheritdoc />
-        public override T[] Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
-        {
-            if (reader.TokenType == JsonTokenType.String)
-            {
-                var stringEntries = reader.GetString()?.Split('|', StringSplitOptions.RemoveEmptyEntries);
-                if (stringEntries == null || stringEntries.Length == 0)
-                {
-                    return Array.Empty<T>();
-                }
-
-                var parsedValues = new object[stringEntries.Length];
-                var convertedCount = 0;
-                for (var i = 0; i < stringEntries.Length; i++)
-                {
-                    try
-                    {
-                        parsedValues[i] = _typeConverter.ConvertFrom(stringEntries[i].Trim());
-                        convertedCount++;
-                    }
-                    catch (FormatException)
-                    {
-                        // TODO log when upgraded to .Net6
-                        // https://github.com/dotnet/runtime/issues/42975
-                        // _logger.LogDebug(e, "Error converting value.");
-                    }
-                }
-
-                var typedValues = new T[convertedCount];
-                var typedValueIndex = 0;
-                for (var i = 0; i < stringEntries.Length; i++)
-                {
-                    if (parsedValues[i] != null)
-                    {
-                        typedValues.SetValue(parsedValues[i], typedValueIndex);
-                        typedValueIndex++;
-                    }
-                }
-
-                return typedValues;
-            }
-
-            return JsonSerializer.Deserialize<T[]>(ref reader, options);
-        }
-
-        /// <inheritdoc />
-        public override void Write(Utf8JsonWriter writer, T[] value, JsonSerializerOptions options)
-        {
-            throw new NotImplementedException();
-        }
+        protected override char Delimiter => '|';
     }
 }

+ 2 - 2
MediaBrowser.Common/Json/Converters/JsonPipeDelimitedArrayConverterFactory.cs

@@ -19,10 +19,10 @@ namespace MediaBrowser.Common.Json.Converters
         }
 
         /// <inheritdoc />
-        public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options)
+        public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options)
         {
             var structType = typeToConvert.GetElementType() ?? typeToConvert.GenericTypeArguments[0];
-            return (JsonConverter)Activator.CreateInstance(typeof(JsonPipeDelimitedArrayConverter<>).MakeGenericType(structType));
+            return (JsonConverter?)Activator.CreateInstance(typeof(JsonPipeDelimitedArrayConverter<>).MakeGenericType(structType));
         }
     }
 }

+ 4 - 4
MediaBrowser.Common/Json/Converters/JsonStringConverter.cs

@@ -9,10 +9,10 @@ namespace MediaBrowser.Common.Json.Converters
     /// <summary>
     /// Converter to allow the serializer to read strings.
     /// </summary>
-    public class JsonStringConverter : JsonConverter<string>
+    public class JsonStringConverter : JsonConverter<string?>
     {
         /// <inheritdoc />
-        public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+        public override string? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
         {
             return reader.TokenType switch
             {
@@ -23,7 +23,7 @@ namespace MediaBrowser.Common.Json.Converters
         }
 
         /// <inheritdoc />
-        public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options)
+        public override void Write(Utf8JsonWriter writer, string? value, JsonSerializerOptions options)
         {
             writer.WriteStringValue(value);
         }
@@ -36,4 +36,4 @@ namespace MediaBrowser.Common.Json.Converters
             return Encoding.UTF8.GetString(utf8Bytes);
         }
     }
-}
+}

+ 1 - 1
MediaBrowser.Common/Json/Converters/JsonVersionConverter.cs

@@ -14,7 +14,7 @@ namespace MediaBrowser.Common.Json.Converters
     {
         /// <inheritdoc />
         public override Version Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
-            => new Version(reader.GetString());
+            => new Version(reader.GetString()!); // Will throw ArgumentNullException on null
 
         /// <inheritdoc />
         public override void Write(Utf8JsonWriter writer, Version value, JsonSerializerOptions options)

+ 1 - 0
MediaBrowser.Common/MediaBrowser.Common.csproj

@@ -33,6 +33,7 @@
     <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
     <GenerateDocumentationFile>true</GenerateDocumentationFile>
     <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
+    <Nullable>enable</Nullable>
     <AnalysisMode>AllEnabledByDefault</AnalysisMode>
     <CodeAnalysisRuleSet>../jellyfin.ruleset</CodeAnalysisRuleSet>
     <PublishRepositoryUrl>true</PublishRepositoryUrl>

+ 0 - 1
MediaBrowser.Common/Net/INetworkManager.cs

@@ -1,4 +1,3 @@
-#nullable enable
 using System;
 using System.Collections.Generic;
 using System.Collections.ObjectModel;

+ 0 - 1
MediaBrowser.Common/Net/IPHost.cs

@@ -1,4 +1,3 @@
-#nullable enable
 using System;
 using System.Diagnostics;
 using System.Linq;

+ 0 - 1
MediaBrowser.Common/Net/IPNetAddress.cs

@@ -1,4 +1,3 @@
-#nullable enable
 using System;
 using System.Net;
 using System.Net.Sockets;

+ 0 - 1
MediaBrowser.Common/Net/IPObject.cs

@@ -1,4 +1,3 @@
-#nullable enable
 using System;
 using System.Net;
 using System.Net.Sockets;

+ 2 - 0
MediaBrowser.Common/Plugins/BasePlugin.cs

@@ -1,3 +1,5 @@
+#nullable disable
+
 using System;
 using System.IO;
 using System.Reflection;

+ 2 - 0
MediaBrowser.Common/Plugins/BasePluginOfT.cs

@@ -1,4 +1,6 @@
+#nullable disable
 #pragma warning disable SA1649 // File name should match first type name
+
 using System;
 using System.IO;
 using System.Runtime.InteropServices;

+ 2 - 0
MediaBrowser.Common/Plugins/IPlugin.cs

@@ -1,3 +1,5 @@
+#nullable disable
+
 using System;
 using MediaBrowser.Model.Plugins;
 

+ 0 - 2
MediaBrowser.Common/Plugins/IPluginManager.cs

@@ -1,5 +1,3 @@
-#nullable enable
-
 using System;
 using System.Collections.Generic;
 using System.Reflection;

+ 0 - 1
MediaBrowser.Common/Plugins/LocalPlugin.cs

@@ -1,4 +1,3 @@
-#nullable enable
 using System;
 using System.Collections.Generic;
 using MediaBrowser.Model.Plugins;

+ 0 - 2
MediaBrowser.Common/Plugins/PluginManifest.cs

@@ -1,5 +1,3 @@
-#nullable enable
-
 using System;
 using System.Text.Json.Serialization;
 using MediaBrowser.Model.Plugins;

+ 2 - 2
MediaBrowser.Common/Progress/ActionableProgress.cs

@@ -14,9 +14,9 @@ namespace MediaBrowser.Common.Progress
         /// <summary>
         /// The _actions.
         /// </summary>
-        private Action<T> _action;
+        private Action<T>? _action;
 
-        public event EventHandler<T> ProgressChanged;
+        public event EventHandler<T>? ProgressChanged;
 
         /// <summary>
         /// Registers the action.

+ 1 - 1
MediaBrowser.Common/Progress/SimpleProgress.cs

@@ -7,7 +7,7 @@ namespace MediaBrowser.Common.Progress
 {
     public class SimpleProgress<T> : IProgress<T>
     {
-        public event EventHandler<T> ProgressChanged;
+        public event EventHandler<T>? ProgressChanged;
 
         public void Report(T value)
         {

+ 1 - 3
MediaBrowser.Common/Providers/ProviderIdParsers.cs

@@ -1,6 +1,4 @@
-#nullable enable
-
-using System;
+using System;
 using System.Diagnostics.CodeAnalysis;
 
 namespace MediaBrowser.Common.Providers

+ 0 - 2
MediaBrowser.Common/Updates/IInstallationManager.cs

@@ -1,5 +1,3 @@
-#nullable enable
-
 using System;
 using System.Collections.Generic;
 using System.Threading;

+ 2 - 0
MediaBrowser.Common/Updates/InstallationEventArgs.cs

@@ -1,3 +1,5 @@
+#nullable disable
+
 using System;
 using MediaBrowser.Model.Updates;
 

+ 1 - 0
MediaBrowser.Common/Updates/InstallationFailedEventArgs.cs

@@ -1,3 +1,4 @@
+#nullable disable
 #pragma warning disable CS1591
 
 using System;

+ 2 - 0
MediaBrowser.Controller/Authentication/AuthenticationResult.cs

@@ -1,3 +1,5 @@
+#nullable disable
+
 #pragma warning disable CS1591
 
 using MediaBrowser.Controller.Session;

+ 2 - 0
MediaBrowser.Controller/Authentication/IAuthenticationProvider.cs

@@ -1,3 +1,5 @@
+#nullable disable
+
 #pragma warning disable CS1591
 
 using System.Threading.Tasks;

+ 2 - 0
MediaBrowser.Controller/Authentication/IPasswordResetProvider.cs

@@ -1,3 +1,5 @@
+#nullable disable
+
 #pragma warning disable CS1591
 
 using System;

+ 2 - 0
MediaBrowser.Controller/BaseItemManager/BaseItemManager.cs

@@ -1,3 +1,5 @@
+#nullable disable
+
 using System;
 using System.Linq;
 using System.Threading;

+ 2 - 0
MediaBrowser.Controller/BaseItemManager/IBaseItemManager.cs

@@ -1,3 +1,5 @@
+#nullable disable
+
 using System.Threading;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Model.Configuration;

+ 2 - 0
MediaBrowser.Controller/Channels/Channel.cs

@@ -1,3 +1,5 @@
+#nullable disable
+
 #pragma warning disable CS1591
 
 using System;

+ 2 - 0
MediaBrowser.Controller/Channels/ChannelItemInfo.cs

@@ -1,3 +1,5 @@
+#nullable disable
+
 #pragma warning disable CS1591
 
 using System;

+ 2 - 0
MediaBrowser.Controller/Channels/ChannelItemResult.cs

@@ -1,3 +1,5 @@
+#nullable disable
+
 #pragma warning disable CS1591
 
 using System.Collections.Generic;

+ 2 - 0
MediaBrowser.Controller/Channels/ChannelSearchInfo.cs

@@ -1,3 +1,5 @@
+#nullable disable
+
 #pragma warning disable CS1591
 
 namespace MediaBrowser.Controller.Channels

+ 2 - 0
MediaBrowser.Controller/Channels/IChannel.cs

@@ -1,3 +1,5 @@
+#nullable disable
+
 #pragma warning disable CS1591
 
 using System.Collections.Generic;

+ 2 - 0
MediaBrowser.Controller/Channels/IChannelManager.cs

@@ -1,3 +1,5 @@
+#nullable disable
+
 #pragma warning disable CS1591
 
 using System;

+ 2 - 0
MediaBrowser.Controller/Channels/IHasCacheKey.cs

@@ -1,3 +1,5 @@
+#nullable disable
+
 #pragma warning disable CS1591
 
 namespace MediaBrowser.Controller.Channels

+ 2 - 0
MediaBrowser.Controller/Channels/ISearchableChannel.cs

@@ -1,3 +1,5 @@
+#nullable disable
+
 #pragma warning disable CS1591
 
 using System.Collections.Generic;

+ 2 - 0
MediaBrowser.Controller/Channels/InternalChannelFeatures.cs

@@ -1,3 +1,5 @@
+#nullable disable
+
 #pragma warning disable CS1591
 
 using System.Collections.Generic;

+ 2 - 0
MediaBrowser.Controller/Channels/InternalChannelItemQuery.cs

@@ -1,3 +1,5 @@
+#nullable disable
+
 #pragma warning disable CS1591
 
 using System;

+ 2 - 0
MediaBrowser.Controller/Collections/CollectionCreationOptions.cs

@@ -1,3 +1,5 @@
+#nullable disable
+
 #pragma warning disable CS1591
 
 using System;

Some files were not shown because too many files changed in this diff