Commit 5bffe055 authored by Arthur Edelstein's avatar Arthur Edelstein Committed by Georg Koppen
Browse files

Bug 16690: Don't mishandle multiline commands

Also, when logging, don't show a bunch of extra newlines.

See https://trac.torproject.org/16990#comment:28
parent b195514c
Loading
Loading
Loading
Loading
+18 −5
Original line number Diff line number Diff line
@@ -27,11 +27,11 @@ Cu.import("resource://gre/modules/Services.jsm");
// Logging function
let log;
if ((typeof console) !== "undefined") {
  log = x => console.log(typeof(x) === "string" ? x : JSON.stringify(x));
  log = x => console.log(typeof(x) === "string" ? x.trimRight().replace(/\r\n/g, "\n") : JSON.stringify(x));
} else {
  let logger = Cc["@torproject.org/torbutton-logger;1"]
                 .getService(Components.interfaces.nsISupports).wrappedJSObject;
  log = x => logger.eclog(3, x);
  log = x => logger.eclog(3, x.trimRight().replace(/\r\n/g, "\n"));
}

// ### announce this file
@@ -113,7 +113,7 @@ io.asyncSocket = function (host, port, onInputData, onError) {
                 let totalString = pendingWrites.join("");
                   try {
                     outputStream.write(totalString, totalString.length);
                     log("controlPort << " + aString + "\n");
                     log("controlPort << " + totalString);
                   } catch (err) {
                     onError(err);
                   }
@@ -156,13 +156,26 @@ io.onDataFromOnLine = function (onLine) {
// callback that expects individual lines.
io.onLineFromOnMessage = function (onMessage) {
  // A private variable that stores the last unfinished line.
  let pendingLines = [];
  let pendingLines = [],
      // A private variable to monitor whether we are receiving a multiline
      // value, beginning with ###+ and ending with a single ".".
      multilineValueInProgress = false;
  // Return a callback that expects individual lines.
  return function (line) {
    // Add to the list of pending lines.
    pendingLines.push(line);
    // 'Multiline values' are possible. We avoid interrupting one by detecting it
    // and waiting for a terminating "." on its own line.
    // (See control-spec section 3.9 and https://trac.torproject.org/16990#comment:28
    if (line.match(/^\d\d\d\+.+?=$/) && pendingLines.length === 1) {
      multilineValueInProgress = true;
    }
    if (multilineValueInProgress && line.match(/^\.$/)) {
      multilineValueInProgress = false;
    }
    // If line is the last in a message, then pass on the full multiline message.
    if (line.match(/^\d\d\d /) &&
    if (!multilineValueInProgress &&
        line.match(/^\d\d\d /) &&
        (pendingLines.length === 1 ||
         pendingLines[0].substring(0,3) === line.substring(0,3))) {
      // Combine pending lines to form message.