Kaynağa Gözat

Merge pull request #5596 from BaronGreenback/DLNA_Hardening

Implemented DLNA exception handling

(cherry picked from commit 55102973d6ab8d527a08cbfd110356f1541ed2a6)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
Bond-009 4 yıl önce
ebeveyn
işleme
dbfaafc08a

+ 33 - 8
Emby.Dlna/PlayTo/Device.cs

@@ -219,7 +219,7 @@ namespace Emby.Dlna.PlayTo
         {
             var rendererCommands = await GetRenderingProtocolAsync(cancellationToken).ConfigureAwait(false);
 
-            var command = rendererCommands.ServiceActions.FirstOrDefault(c => c.Name == "SetMute");
+            var command = rendererCommands?.ServiceActions.FirstOrDefault(c => c.Name == "SetMute");
             if (command == null)
             {
                 return false;
@@ -253,7 +253,7 @@ namespace Emby.Dlna.PlayTo
         {
             var rendererCommands = await GetRenderingProtocolAsync(cancellationToken).ConfigureAwait(false);
 
-            var command = rendererCommands.ServiceActions.FirstOrDefault(c => c.Name == "SetVolume");
+            var command = rendererCommands?.ServiceActions.FirstOrDefault(c => c.Name == "SetVolume");
             if (command == null)
             {
                 return;
@@ -278,7 +278,7 @@ namespace Emby.Dlna.PlayTo
         {
             var avCommands = await GetAVProtocolAsync(cancellationToken).ConfigureAwait(false);
 
-            var command = avCommands.ServiceActions.FirstOrDefault(c => c.Name == "Seek");
+            var command = avCommands?.ServiceActions.FirstOrDefault(c => c.Name == "Seek");
             if (command == null)
             {
                 return;
@@ -305,7 +305,7 @@ namespace Emby.Dlna.PlayTo
 
             _logger.LogDebug("{0} - SetAvTransport Uri: {1} DlnaHeaders: {2}", Properties.Name, url, header);
 
-            var command = avCommands.ServiceActions.FirstOrDefault(c => c.Name == "SetAVTransportURI");
+            var command = avCommands?.ServiceActions.FirstOrDefault(c => c.Name == "SetAVTransportURI");
             if (command == null)
             {
                 return;
@@ -378,6 +378,10 @@ namespace Emby.Dlna.PlayTo
         public async Task SetPlay(CancellationToken cancellationToken)
         {
             var avCommands = await GetAVProtocolAsync(cancellationToken).ConfigureAwait(false);
+            if (avCommands == null)
+            {
+                return;
+            }
 
             await SetPlay(avCommands, cancellationToken).ConfigureAwait(false);
 
@@ -388,7 +392,7 @@ namespace Emby.Dlna.PlayTo
         {
             var avCommands = await GetAVProtocolAsync(cancellationToken).ConfigureAwait(false);
 
-            var command = avCommands.ServiceActions.FirstOrDefault(c => c.Name == "Stop");
+            var command = avCommands?.ServiceActions.FirstOrDefault(c => c.Name == "Stop");
             if (command == null)
             {
                 return;
@@ -406,7 +410,7 @@ namespace Emby.Dlna.PlayTo
         {
             var avCommands = await GetAVProtocolAsync(cancellationToken).ConfigureAwait(false);
 
-            var command = avCommands.ServiceActions.FirstOrDefault(c => c.Name == "Pause");
+            var command = avCommands?.ServiceActions.FirstOrDefault(c => c.Name == "Pause");
             if (command == null)
             {
                 return;
@@ -528,7 +532,7 @@ namespace Emby.Dlna.PlayTo
 
             var rendererCommands = await GetRenderingProtocolAsync(cancellationToken).ConfigureAwait(false);
 
-            var command = rendererCommands.ServiceActions.FirstOrDefault(c => c.Name == "GetVolume");
+            var command = rendererCommands?.ServiceActions.FirstOrDefault(c => c.Name == "GetVolume");
             if (command == null)
             {
                 return;
@@ -578,7 +582,7 @@ namespace Emby.Dlna.PlayTo
 
             var rendererCommands = await GetRenderingProtocolAsync(cancellationToken).ConfigureAwait(false);
 
-            var command = rendererCommands.ServiceActions.FirstOrDefault(c => c.Name == "GetMute");
+            var command = rendererCommands?.ServiceActions.FirstOrDefault(c => c.Name == "GetMute");
             if (command == null)
             {
                 return;
@@ -665,6 +669,10 @@ namespace Emby.Dlna.PlayTo
             }
 
             var rendererCommands = await GetRenderingProtocolAsync(cancellationToken).ConfigureAwait(false);
+            if (rendererCommands == null)
+            {
+                return null;
+            }
 
             var result = await new SsdpHttpClient(_httpClientFactory).SendCommandAsync(
                 Properties.BaseUrl,
@@ -733,6 +741,11 @@ namespace Emby.Dlna.PlayTo
 
             var rendererCommands = await GetRenderingProtocolAsync(cancellationToken).ConfigureAwait(false);
 
+            if (rendererCommands == null)
+            {
+                return (false, null);
+            }
+
             var result = await new SsdpHttpClient(_httpClientFactory).SendCommandAsync(
                 Properties.BaseUrl,
                 service,
@@ -914,6 +927,10 @@ namespace Emby.Dlna.PlayTo
             var httpClient = new SsdpHttpClient(_httpClientFactory);
 
             var document = await httpClient.GetDataAsync(url, cancellationToken).ConfigureAwait(false);
+            if (document == null)
+            {
+                return null;
+            }
 
             AvCommands = TransportCommands.Create(document);
             return AvCommands;
@@ -942,6 +959,10 @@ namespace Emby.Dlna.PlayTo
             var httpClient = new SsdpHttpClient(_httpClientFactory);
             _logger.LogDebug("Dlna Device.GetRenderingProtocolAsync");
             var document = await httpClient.GetDataAsync(url, cancellationToken).ConfigureAwait(false);
+            if (document == null)
+            {
+                return null;
+            }
 
             RendererCommands = TransportCommands.Create(document);
             return RendererCommands;
@@ -973,6 +994,10 @@ namespace Emby.Dlna.PlayTo
             var ssdpHttpClient = new SsdpHttpClient(httpClientFactory);
 
             var document = await ssdpHttpClient.GetDataAsync(url.ToString(), cancellationToken).ConfigureAwait(false);
+            if (document == null)
+            {
+                return null;
+            }
 
             var friendlyNames = new List<string>();
 

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

@@ -178,6 +178,11 @@ namespace Emby.Dlna.PlayTo
             if (controller == null)
             {
                 var device = await Device.CreateuPnpDeviceAsync(uri, _httpClientFactory, _logger, cancellationToken).ConfigureAwait(false);
+                if (device == null)
+                {
+                    _logger.LogError("Ignoring device as xml response is invalid.");
+                    return;
+                }
 
                 string deviceName = device.Properties.Name;
 

+ 11 - 4
Emby.Dlna/PlayTo/SsdpHttpClient.cs

@@ -94,10 +94,17 @@ namespace Emby.Dlna.PlayTo
             options.Headers.TryAddWithoutValidation("FriendlyName.DLNA.ORG", FriendlyName);
             using var response = await _httpClientFactory.CreateClient(NamedClient.Default).SendAsync(options, HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
             await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
-            return await XDocument.LoadAsync(
-                stream,
-                LoadOptions.PreserveWhitespace,
-                cancellationToken).ConfigureAwait(false);
+            try
+            {
+                return await XDocument.LoadAsync(
+                    stream,
+                    LoadOptions.PreserveWhitespace,
+                    cancellationToken).ConfigureAwait(false);
+            }
+            catch
+            {
+                return null;
+            }
         }
 
         private async Task<HttpResponseMessage> PostSoapDataAsync(

+ 2 - 2
tests/Jellyfin.Networking.Tests/NetworkTesting/NetworkParseTests.cs

@@ -85,7 +85,7 @@ namespace Jellyfin.Networking.Tests
         /// <summary>
         /// Checks IP address formats.
         /// </summary>
-        /// <param name="address"></param>
+        /// <param name="address">IP Address.</param>
         [Theory]
         [InlineData("127.0.0.1")]
         [InlineData("127.0.0.1:123")]
@@ -109,7 +109,7 @@ namespace Jellyfin.Networking.Tests
         /// <summary>
         /// Checks IP address formats.
         /// </summary>
-        /// <param name="address"></param>
+        /// <param name="address">IP Address.</param>
         [Theory]
         [InlineData("127.0.0.1")]
         [InlineData("fd23:184f:2029:0:3139:7386:67d7:d517")]