Commit 448b85c4 authored by Matt Hyman's avatar Matt Hyman
Browse files

Added logic to detect a SystemPerformanceInformation JSON formatting error and fix it.

parent f59deecc
Loading
Loading
Loading
Loading
+48 −2
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@
using System;
using System.IO;
using System.Runtime.Serialization.Json;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace Microsoft.Tools.WindowsDevicePortal
@@ -16,6 +17,49 @@ namespace Microsoft.Tools.WindowsDevicePortal
    /// </content>
    public partial class DevicePortal
    {
        /// <summary>
        /// The prefix for the <see cref="SystemPerformanceInformation" /> JSON formatting error.
        /// </summary>
        private static readonly string SysPerfInfoErrorPrefix = "{\"Reason\" : \"";

        /// <summary>
        /// The postfix for the <see cref="SystemPerformanceInformation" /> JSON formatting error.
        /// </summary>
        private static readonly string SysPerfInfoErrorPostfix = "\"}";

        /// <summary>
        /// Checks the JSON for any known formatting errors and fixes them.
        /// </summary>
        /// <typeparam name="T">Return type for the JSON message</typeparam>
        /// <param name="jsonStream">The stream that contains the JSON message to be checked.</param>
        private static void JsonFormatCheck<T>(Stream jsonStream)
        {
            if (typeof(T) == typeof(SystemPerformanceInformation))
            {
                StreamReader read = new StreamReader(jsonStream);
                string rawJsonString = read.ReadToEnd();

                // Recover from an error in which SystemPerformanceInformation is returned with an incorrect prefix, postfix and the message converted into JSON a second time.
                if (rawJsonString.StartsWith(SysPerfInfoErrorPrefix, StringComparison.InvariantCultureIgnoreCase) && rawJsonString.EndsWith(SysPerfInfoErrorPostfix, StringComparison.InvariantCultureIgnoreCase))
                {
                    // Remove the incorrect prefix and postfix from the JSON message.
                    rawJsonString = rawJsonString.Substring(SysPerfInfoErrorPrefix.Length, rawJsonString.Length - SysPerfInfoErrorPrefix.Length - SysPerfInfoErrorPostfix.Length);

                    // Undo the second JSON conversion.
                    rawJsonString = Regex.Replace(rawJsonString, "\\\\\"", "\"", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
                    rawJsonString = Regex.Replace(rawJsonString, "\\\\\\\\", "\\", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);

                    // Overwrite the stream with the fixed JSON.
                    jsonStream.SetLength(0);
                    var sw = new StreamWriter(jsonStream);
                    sw.Write(rawJsonString);
                    sw.Flush();
                }

                jsonStream.Seek(0, SeekOrigin.Begin);
            }
        }

        /// <summary>
        /// Calls the specified API with the provided payload.
        /// </summary>
@@ -40,6 +84,8 @@ namespace Microsoft.Tools.WindowsDevicePortal
            {
                if (dataStream != null)
                {
                    JsonFormatCheck<T>(dataStream);
 
                    object response = serializer.ReadObject(dataStream);
                    data = (T)response;
                }