Hi,

I'm trying to fix a problem when applying certain git patches.
While analyzing the code, I found a part that I don't quite understand:

in libsvn_diff\parse-diff.c, line 1287 there's this little bit of code:
/* Run the state machine. */
for (i = 0; i < (sizeof(transitions) / sizeof(transitions[0])); i++)
{
  if (line->len > strlen(transitions[i].expected_input)  // <--- why?
      && starts_with(line->data, transitions[i].expected_input)
      && state == transitions[i].required_state)
    {
      SVN_ERR(transitions[i].fn(&state, line->data, *patch,
                                result_pool, iterpool));
      valid_header_line = TRUE;
      break;
    }
}

The first condition of the if statement checks whether the patch line is longer than the string it needs comparing to.
But 'starts_with' doesn't need that check first:
#define starts_with(str, start)  \
  (strncmp((str), (start), strlen(start)) == 0)

if the patch line would be smaller than the comparison string, then
'starts_with' would return false anyway.

So if I understand this correctly, that piece of code could (and should! Explanation below) be changed to this:

/* Run the state machine. */
for (i = 0; i < (sizeof(transitions) / sizeof(transitions[0])); i++)
{
  if (starts_with(line->data, transitions[i].expected_input)
      && state == transitions[i].required_state)
    {
      SVN_ERR(transitions[i].fn(&state, line->data, *patch,
                                result_pool, iterpool));
      valid_header_line = TRUE;
      break;
    }
}


The check
line->len > strlen(transitions[i].expected_input)
actually prevents the transitions:
  {"--- /dev/null", state_git_tree_seen,    git_minus},
  {"+++ /dev/null", state_git_minus_seen,   git_plus},
from ever being used: the patch lines in these situations match the "expected input" string exactly, so the patch line is actually equal, not longer than the expected input.


This is just one problem I could pinpoint for now. I'm dealing with git patches that look like this:

 src/tools/ConsoleRunner/hi.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/tools/ConsoleRunner/hi.txt b/src/tools/ConsoleRunner/hi.txt
new file mode 100644
index 0000000..c82a38f
--- /dev/null
+++ b/src/tools/ConsoleRunner/hi.txt
@@ -0,0 +1 @@
+hihihihihihi
\ No newline at end of file


So there's an additional line after "new file mode xxxx" which makes applying such patches fail.
Working on that...

Stefan

--
       ___
  oo  // \\      "De Chelonian Mobile"
 (_,\/ \_/ \     TortoiseSVN
   \ \_/_\_/>    The coolest Interface to (Sub)Version Control
   /_/   \_\     http://tortoisesvn.net

Reply via email to