diff options
| -rw-r--r-- | Emby.Dlna/PlayTo/Device.cs | 4 | ||||
| -rw-r--r-- | Emby.Dlna/Server/DescriptionXmlBuilder.cs | 182 | ||||
| -rw-r--r-- | Emby.Dlna/Service/ServiceXmlBuilder.cs | 34 |
3 files changed, 102 insertions, 118 deletions
diff --git a/Emby.Dlna/PlayTo/Device.cs b/Emby.Dlna/PlayTo/Device.cs index c5080b90f..72834c69d 100644 --- a/Emby.Dlna/PlayTo/Device.cs +++ b/Emby.Dlna/PlayTo/Device.cs @@ -4,12 +4,12 @@ using System; using System.Collections.Generic; using System.Globalization; using System.Linq; +using System.Security; using System.Threading; using System.Threading.Tasks; using System.Xml; using System.Xml.Linq; using Emby.Dlna.Common; -using Emby.Dlna.Server; using Emby.Dlna.Ssdp; using MediaBrowser.Common.Net; using MediaBrowser.Controller.Configuration; @@ -334,7 +334,7 @@ namespace Emby.Dlna.PlayTo return string.Empty; } - return DescriptionXmlBuilder.Escape(value); + return SecurityElement.Escape(value); } private Task SetPlay(TransportCommands avCommands, CancellationToken cancellationToken) diff --git a/Emby.Dlna/Server/DescriptionXmlBuilder.cs b/Emby.Dlna/Server/DescriptionXmlBuilder.cs index 7143c3109..bca9e81cd 100644 --- a/Emby.Dlna/Server/DescriptionXmlBuilder.cs +++ b/Emby.Dlna/Server/DescriptionXmlBuilder.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Globalization; using System.Linq; +using System.Security; using System.Text; using Emby.Dlna.Common; using MediaBrowser.Model.Dlna; @@ -64,10 +65,10 @@ namespace Emby.Dlna.Server foreach (var att in attributes) { - builder.AppendFormat(" {0}=\"{1}\"", att.Name, att.Value); + builder.AppendFormat(CultureInfo.InvariantCulture, " {0}=\"{1}\"", att.Name, att.Value); } - builder.Append(">"); + builder.Append('>'); builder.Append("<specVersion>"); builder.Append("<major>1</major>"); @@ -76,7 +77,9 @@ namespace Emby.Dlna.Server if (!EnableAbsoluteUrls) { - builder.Append("<URLBase>" + Escape(_serverAddress) + "</URLBase>"); + builder.Append("<URLBase>") + .Append(SecurityElement.Escape(_serverAddress)) + .Append("</URLBase>"); } AppendDeviceInfo(builder); @@ -93,91 +96,14 @@ namespace Emby.Dlna.Server AppendIconList(builder); - builder.Append("<presentationURL>" + Escape(_serverAddress) + "/web/index.html</presentationURL>"); + builder.Append("<presentationURL>") + .Append(SecurityElement.Escape(_serverAddress)) + .Append("/web/index.html</presentationURL>"); AppendServiceList(builder); builder.Append("</device>"); } - private static readonly char[] s_escapeChars = new char[] - { - '<', - '>', - '"', - '\'', - '&' - }; - - private static readonly string[] s_escapeStringPairs = new[] - { - "<", - "<", - ">", - ">", - "\"", - """, - "'", - "'", - "&", - "&" - }; - - private static string GetEscapeSequence(char c) - { - int num = s_escapeStringPairs.Length; - for (int i = 0; i < num; i += 2) - { - string text = s_escapeStringPairs[i]; - string result = s_escapeStringPairs[i + 1]; - if (text[0] == c) - { - return result; - } - } - - return c.ToString(CultureInfo.InvariantCulture); - } - - /// <summary>Replaces invalid XML characters in a string with their valid XML equivalent.</summary> - /// <returns>The input string with invalid characters replaced.</returns> - /// <param name="str">The string within which to escape invalid characters. </param> - public static string Escape(string str) - { - if (str == null) - { - return null; - } - - StringBuilder stringBuilder = null; - int length = str.Length; - int num = 0; - while (true) - { - int num2 = str.IndexOfAny(s_escapeChars, num); - if (num2 == -1) - { - break; - } - - if (stringBuilder == null) - { - stringBuilder = new StringBuilder(); - } - - stringBuilder.Append(str, num, num2 - num); - stringBuilder.Append(GetEscapeSequence(str[num2])); - num = num2 + 1; - } - - if (stringBuilder == null) - { - return str; - } - - stringBuilder.Append(str, num, length - num); - return stringBuilder.ToString(); - } - private void AppendDeviceProperties(StringBuilder builder) { builder.Append("<dlna:X_DLNACAP/>"); @@ -187,32 +113,54 @@ namespace Emby.Dlna.Server builder.Append("<deviceType>urn:schemas-upnp-org:device:MediaServer:1</deviceType>"); - builder.Append("<friendlyName>" + Escape(GetFriendlyName()) + "</friendlyName>"); - builder.Append("<manufacturer>" + Escape(_profile.Manufacturer ?? string.Empty) + "</manufacturer>"); - builder.Append("<manufacturerURL>" + Escape(_profile.ManufacturerUrl ?? string.Empty) + "</manufacturerURL>"); - - builder.Append("<modelDescription>" + Escape(_profile.ModelDescription ?? string.Empty) + "</modelDescription>"); - builder.Append("<modelName>" + Escape(_profile.ModelName ?? string.Empty) + "</modelName>"); - - builder.Append("<modelNumber>" + Escape(_profile.ModelNumber ?? string.Empty) + "</modelNumber>"); - builder.Append("<modelURL>" + Escape(_profile.ModelUrl ?? string.Empty) + "</modelURL>"); + builder.Append("<friendlyName>") + .Append(SecurityElement.Escape(GetFriendlyName())) + .Append("</friendlyName>"); + builder.Append("<manufacturer>") + .Append(SecurityElement.Escape(_profile.Manufacturer ?? string.Empty)) + .Append("</manufacturer>"); + builder.Append("<manufacturerURL>") + .Append(SecurityElement.Escape(_profile.ManufacturerUrl ?? string.Empty)) + .Append("</manufacturerURL>"); + + builder.Append("<modelDescription>") + .Append(SecurityElement.Escape(_profile.ModelDescription ?? string.Empty)) + .Append("</modelDescription>"); + builder.Append("<modelName>") + .Append(SecurityElement.Escape(_profile.ModelName ?? string.Empty)) + .Append("</modelName>"); + + builder.Append("<modelNumber>") + .Append(SecurityElement.Escape(_profile.ModelNumber ?? string.Empty)) + .Append("</modelNumber>"); + builder.Append("<modelURL>") + .Append(SecurityElement.Escape(_profile.ModelUrl ?? string.Empty)) + .Append("</modelURL>"); if (string.IsNullOrEmpty(_profile.SerialNumber)) { - builder.Append("<serialNumber>" + Escape(_serverId) + "</serialNumber>"); + builder.Append("<serialNumber>") + .Append(SecurityElement.Escape(_serverId)) + .Append("</serialNumber>"); } else { - builder.Append("<serialNumber>" + Escape(_profile.SerialNumber) + "</serialNumber>"); + builder.Append("<serialNumber>") + .Append(SecurityElement.Escape(_profile.SerialNumber)) + .Append("</serialNumber>"); } builder.Append("<UPC/>"); - builder.Append("<UDN>uuid:" + Escape(_serverUdn) + "</UDN>"); + builder.Append("<UDN>uuid:") + .Append(SecurityElement.Escape(_serverUdn)) + .Append("</UDN>"); if (!string.IsNullOrEmpty(_profile.SonyAggregationFlags)) { - builder.Append("<av:aggregationFlags xmlns:av=\"urn:schemas-sony-com:av\">" + Escape(_profile.SonyAggregationFlags) + "</av:aggregationFlags>"); + builder.Append("<av:aggregationFlags xmlns:av=\"urn:schemas-sony-com:av\">") + .Append(SecurityElement.Escape(_profile.SonyAggregationFlags)) + .Append("</av:aggregationFlags>"); } } @@ -250,11 +198,21 @@ namespace Emby.Dlna.Server { builder.Append("<icon>"); - builder.Append("<mimetype>" + Escape(icon.MimeType ?? string.Empty) + "</mimetype>"); - builder.Append("<width>" + Escape(icon.Width.ToString(_usCulture)) + "</width>"); - builder.Append("<height>" + Escape(icon.Height.ToString(_usCulture)) + "</height>"); - builder.Append("<depth>" + Escape(icon.Depth ?? string.Empty) + "</depth>"); - builder.Append("<url>" + BuildUrl(icon.Url) + "</url>"); + builder.Append("<mimetype>") + .Append(SecurityElement.Escape(icon.MimeType ?? string.Empty)) + .Append("</mimetype>"); + builder.Append("<width>") + .Append(SecurityElement.Escape(icon.Width.ToString(_usCulture))) + .Append("</width>"); + builder.Append("<height>") + .Append(SecurityElement.Escape(icon.Height.ToString(_usCulture))) + .Append("</height>"); + builder.Append("<depth>") + .Append(SecurityElement.Escape(icon.Depth ?? string.Empty)) + .Append("</depth>"); + builder.Append("<url>") + .Append(BuildUrl(icon.Url)) + .Append("</url>"); builder.Append("</icon>"); } @@ -270,11 +228,21 @@ namespace Emby.Dlna.Server { builder.Append("<service>"); - builder.Append("<serviceType>" + Escape(service.ServiceType ?? string.Empty) + "</serviceType>"); - builder.Append("<serviceId>" + Escape(service.ServiceId ?? string.Empty) + "</serviceId>"); - builder.Append("<SCPDURL>" + BuildUrl(service.ScpdUrl) + "</SCPDURL>"); - builder.Append("<controlURL>" + BuildUrl(service.ControlUrl) + "</controlURL>"); - builder.Append("<eventSubURL>" + BuildUrl(service.EventSubUrl) + "</eventSubURL>"); + builder.Append("<serviceType>") + .Append(SecurityElement.Escape(service.ServiceType ?? string.Empty)) + .Append("</serviceType>"); + builder.Append("<serviceId>") + .Append(SecurityElement.Escape(service.ServiceId ?? string.Empty)) + .Append("</serviceId>"); + builder.Append("<SCPDURL>") + .Append(BuildUrl(service.ScpdUrl)) + .Append("</SCPDURL>"); + builder.Append("<controlURL>") + .Append(BuildUrl(service.ControlUrl)) + .Append("</controlURL>"); + builder.Append("<eventSubURL>") + .Append(BuildUrl(service.EventSubUrl)) + .Append("</eventSubURL>"); builder.Append("</service>"); } @@ -298,7 +266,7 @@ namespace Emby.Dlna.Server url = _serverAddress.TrimEnd('/') + url; } - return Escape(url); + return SecurityElement.Escape(url); } private IEnumerable<DeviceIcon> GetIcons() diff --git a/Emby.Dlna/Service/ServiceXmlBuilder.cs b/Emby.Dlna/Service/ServiceXmlBuilder.cs index af557aa14..6c7d6f846 100644 --- a/Emby.Dlna/Service/ServiceXmlBuilder.cs +++ b/Emby.Dlna/Service/ServiceXmlBuilder.cs @@ -1,9 +1,9 @@ #pragma warning disable CS1591 using System.Collections.Generic; +using System.Security; using System.Text; using Emby.Dlna.Common; -using Emby.Dlna.Server; namespace Emby.Dlna.Service { @@ -37,7 +37,9 @@ namespace Emby.Dlna.Service { builder.Append("<action>"); - builder.Append("<name>" + DescriptionXmlBuilder.Escape(item.Name ?? string.Empty) + "</name>"); + builder.Append("<name>") + .Append(SecurityElement.Escape(item.Name ?? string.Empty)) + .Append("</name>"); builder.Append("<argumentList>"); @@ -45,9 +47,15 @@ namespace Emby.Dlna.Service { builder.Append("<argument>"); - builder.Append("<name>" + DescriptionXmlBuilder.Escape(argument.Name ?? string.Empty) + "</name>"); - builder.Append("<direction>" + DescriptionXmlBuilder.Escape(argument.Direction ?? string.Empty) + "</direction>"); - builder.Append("<relatedStateVariable>" + DescriptionXmlBuilder.Escape(argument.RelatedStateVariable ?? string.Empty) + "</relatedStateVariable>"); + builder.Append("<name>") + .Append(SecurityElement.Escape(argument.Name ?? string.Empty)) + .Append("</name>"); + builder.Append("<direction>") + .Append(SecurityElement.Escape(argument.Direction ?? string.Empty)) + .Append("</direction>"); + builder.Append("<relatedStateVariable>") + .Append(SecurityElement.Escape(argument.RelatedStateVariable ?? string.Empty)) + .Append("</relatedStateVariable>"); builder.Append("</argument>"); } @@ -68,17 +76,25 @@ namespace Emby.Dlna.Service { var sendEvents = item.SendsEvents ? "yes" : "no"; - builder.Append("<stateVariable sendEvents=\"" + sendEvents + "\">"); + builder.Append("<stateVariable sendEvents=\"") + .Append(sendEvents) + .Append("\">"); - builder.Append("<name>" + DescriptionXmlBuilder.Escape(item.Name ?? string.Empty) + "</name>"); - builder.Append("<dataType>" + DescriptionXmlBuilder.Escape(item.DataType ?? string.Empty) + "</dataType>"); + builder.Append("<name>") + .Append(SecurityElement.Escape(item.Name ?? string.Empty)) + .Append("</name>"); + builder.Append("<dataType>") + .Append(SecurityElement.Escape(item.DataType ?? string.Empty)) + .Append("</dataType>"); if (item.AllowedValues.Length > 0) { builder.Append("<allowedValueList>"); foreach (var allowedValue in item.AllowedValues) { - builder.Append("<allowedValue>" + DescriptionXmlBuilder.Escape(allowedValue) + "</allowedValue>"); + builder.Append("<allowedValue>") + .Append(SecurityElement.Escape(allowedValue)) + .Append("</allowedValue>"); } builder.Append("</allowedValueList>"); |
