Bug 1395507 - Re-escape annotations holding JSON strings with newlines; r?mconley draft
authorGabriele Svelto <gsvelto@mozilla.com>
Mon, 25 Sep 2017 10:56:31 +0200
changeset 674519 8955fc3efafd1f2c786fab93c71fd29f5fd894e5
parent 673165 44643fce30b43a8981535c335aaccb45006e456b
child 734362 9b1b7b943f5913cfdf0c6746d676937e7ddc755d
push id82869
push usergsvelto@mozilla.com
push dateTue, 03 Oct 2017 22:09:36 +0000
reviewersmconley
bugs1395507
milestone58.0a1
Bug 1395507 - Re-escape annotations holding JSON strings with newlines; r?mconley MozReview-Commit-ID: Kx4U0wovi1u
toolkit/components/crashes/CrashService.js
toolkit/components/crashes/tests/xpcshell/crash.extra
toolkit/components/crashes/tests/xpcshell/test_crash_service.js
--- a/toolkit/components/crashes/CrashService.js
+++ b/toolkit/components/crashes/CrashService.js
@@ -111,18 +111,27 @@ function computeMinidumpHash(minidumpPat
  * @return {Promise} A promise that resolves to an object holding the crash
  *         annotations.
  */
 function processExtraFile(extraPath) {
   return (async function() {
     try {
       let decoder = new TextDecoder();
       let extraData = await OS.File.read(extraPath);
+      let keyValuePairs = parseKeyValuePairs(decoder.decode(extraData));
 
-      return parseKeyValuePairs(decoder.decode(extraData));
+      // When reading from an .extra file literal '\\n' sequences are
+      // automatically unescaped to two backslashes plus a newline, so we need
+      // to re-escape them into '\\n' again so that the fields holding JSON
+      // strings are valid.
+      [ "TelemetryEnvironment", "StackTraces" ].forEach(field => {
+        keyValuePairs[field] = keyValuePairs[field].replace(/\n/g, "n");
+      });
+
+      return keyValuePairs;
     } catch (e) {
       Cu.reportError(e);
       return {};
     }
   })();
 }
 
 /**
--- a/toolkit/components/crashes/tests/xpcshell/crash.extra
+++ b/toolkit/components/crashes/tests/xpcshell/crash.extra
@@ -1,11 +1,11 @@
 E10SCohort=unsupportedChannel
 ContentSandboxLevel=2
-TelemetryEnvironment={}
+TelemetryEnvironment={"EscapedField":"EscapedData\\n\\nfoo"}
 EMCheckCompatibility=true
 ProductName=Firefox
 ContentSandboxCapabilities=119
 TelemetryClientId=
 Vendor=Mozilla
 InstallTime=1000000000
 Theme=classic/1.0
 ReleaseChannel=default
--- a/toolkit/components/crashes/tests/xpcshell/test_crash_service.js
+++ b/toolkit/components/crashes/tests/xpcshell/test_crash_service.js
@@ -85,16 +85,24 @@ add_task(async function test_addCrash() 
               "The thread list is populated.");
 
     let frames = stackTraces.threads[0].frames;
     Assert.ok(frames && (frames.length > 0), "The stack trace is present.\n");
   } catch (e) {
     Assert.ok(false, "StackTraces does not contain valid JSON.");
   }
 
+  try {
+    let telemetryEnvironment = JSON.parse(crash.metadata.TelemetryEnvironment);
+    Assert.equal(telemetryEnvironment.EscapedField, "EscapedData\n\nfoo");
+  } catch (e) {
+    Assert.ok(false,
+              "TelemetryEnvironment contents were not properly re-escaped\n");
+  }
+
   await teardown();
 });
 
 add_task(async function test_addCrash_quitting() {
   const firstCrashId = "0e578a74-a887-48cb-b270-d4775d01e715";
   const secondCrashId = "208379e5-1979-430d-a066-f6e57a8130ce";
 
   await setup(firstCrashId);