From a272ddcc7869ec2e700ab6d397fc1854760f7e64 Mon Sep 17 00:00:00 2001 From: epriestley Date: Sun, 4 May 2014 10:48:49 -0700 Subject: [PATCH] Fix two parsing issues for diffs with damaged whitespace Summary: Fixes T4941. If a diff has had trailing whitespace stripped, we will fail to handle empty lines correctly (previously, these lines had a leading space when the original tool emitted them). (This probably stopped working around the time we began retaining newlines.) Test Plan: The diff in T4941 now parses and renders correctly. Reviewers: asherkin, btrahan Reviewed By: btrahan Subscribers: epriestley Maniphest Tasks: T4941 Differential Revision: https://secure.phabricator.com/D8968 --- .../parser/DifferentialHunkParser.php | 35 ++++++++++++++++--- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/src/applications/differential/parser/DifferentialHunkParser.php b/src/applications/differential/parser/DifferentialHunkParser.php index ef4b696a0e..4964e109c3 100644 --- a/src/applications/differential/parser/DifferentialHunkParser.php +++ b/src/applications/differential/parser/DifferentialHunkParser.php @@ -423,16 +423,41 @@ final class DifferentialHunkParser { $lines = phutil_split_lines($lines); $line_type_map = array(); + $line_text = array(); foreach ($lines as $line_index => $line) { if (isset($line[0])) { $char = $line[0]; - if ($char == ' ') { - $line_type_map[$line_index] = null; - } else { - $line_type_map[$line_index] = $char; + switch ($char) { + case " ": + $line_type_map[$line_index] = null; + $line_text[$line_index] = substr($line, 1); + break; + case "\r": + case "\n": + // NOTE: Normally, the first character is a space, plus, minus or + // backslash, but it may be a newline if it used to be a space and + // trailing whitespace has been stripped via email transmission or + // some similar mechanism. In these cases, we essentially pretend + // the missing space is still there. + $line_type_map[$line_index] = null; + $line_text[$line_index] = $line; + break; + case "+": + case "-": + case "\\": + $line_type_map[$line_index] = $char; + $line_text[$line_index] = substr($line, 1); + break; + default: + throw new Exception( + pht( + 'Unexpected leading character "%s" at line index %s!', + $char, + $line_index)); } } else { $line_type_map[$line_index] = null; + $line_text[$line_index] = ''; } } @@ -444,7 +469,7 @@ final class DifferentialHunkParser { $type = $line_type_map[$cursor]; $data = array( 'type' => $type, - 'text' => (string)substr($lines[$cursor], 1), + 'text' => $line_text[$cursor], 'line' => $new_line, ); if ($type == '\\') {