Author: stsp
Date: Sun Jan  3 22:50:50 2010
New Revision: 895501

URL: http://svn.apache.org/viewvc?rev=895501&view=rev
Log:
Make svn patch correctly handle patch files with arbitrary line endings.

* subversion/include/private/svn_diff_private.h
  (svn_patch_t): Remove eol_str field.
  (svn_diff__parse_next_patch): Remove EOL_STR parameter.

* subversion/libsvn_client/patch.c
  (match_hunk): Read lines from hunks using svn_stream_readline_detect_eol().
  (copy_hunk_text): Likewise, and remove the EOL_STR parameter.
  (reject_hunk, apply_one_hunk): Update calls to copy_hunk_text().
  (apply_textdiffs): Update calls to svn_diff__parse_next_patch().

* subversion/libsvn_diff/parse-diff.c
  (parse_next_hunk): Use svn_stream_readline_detect_eol() to read lines from
   the patch file.
  (svn_diff__parse_next_patch): Likewise, and remove EOL_STR parameter. 

* subversion/tests/libsvn_diff/parse-diff-test.c
  (test_parse_unidiff): Update calls to svn_diff__parse_next_patch().

Modified:
    subversion/trunk/subversion/include/private/svn_diff_private.h
    subversion/trunk/subversion/libsvn_client/patch.c
    subversion/trunk/subversion/libsvn_diff/parse-diff.c
    subversion/trunk/subversion/tests/libsvn_diff/parse-diff-test.c

Modified: subversion/trunk/subversion/include/private/svn_diff_private.h
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/include/private/svn_diff_private.h?rev=895501&r1=895500&r2=895501&view=diff
==============================================================================
--- subversion/trunk/subversion/include/private/svn_diff_private.h (original)
+++ subversion/trunk/subversion/include/private/svn_diff_private.h Sun Jan  3 
22:50:50 2010
@@ -97,23 +97,18 @@
   const char *old_filename;
   const char *new_filename;
 
-  /* EOL string used in patch file. */
-  const char *eol_str;
-
   /* An array containing an svn_hunk_t object for each hunk parsed
    * from the patch. */
   apr_array_header_t *hunks;
 } svn_patch_t;
 
-/* Return the next *PATCH in PATCH_FILE. The patch file is assumed to
- * have consistent EOL-markers as specified in EOL_STR.
+/* Return the next *PATCH in PATCH_FILE.
  * If no patch can be found, set *PATCH to NULL.
  * Allocate results in RESULT_POOL.
  * Use SCRATCH_POOL for all other allocations. */
 svn_error_t *
 svn_diff__parse_next_patch(svn_patch_t **patch,
                            apr_file_t *patch_file,
-                           const char *eol_str,
                            apr_pool_t *result_pool,
                            apr_pool_t *scratch_pool);
 

Modified: subversion/trunk/subversion/libsvn_client/patch.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/patch.c?rev=895501&r1=895500&r2=895501&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/patch.c (original)
+++ subversion/trunk/subversion/libsvn_client/patch.c Sun Jan  3 22:50:50 2010
@@ -445,8 +445,8 @@
     {
       svn_pool_clear(iterpool);
 
-      SVN_ERR(svn_stream_readline(hunk->original_text, &hunk_line,
-                                  target->patch->eol_str, &hunk_eof, 
iterpool));
+      SVN_ERR(svn_stream_readline_detect_eol(hunk->original_text, &hunk_line,
+                                             NULL, &hunk_eof, iterpool));
       SVN_ERR(svn_stream_readline(target->stream, &target_line, 
target->eol_str,
                                   &target->eof, iterpool));
       if (! hunk_eof && hunk_line->len > 0)
@@ -697,12 +697,10 @@
 /* Copy HUNK_TEXT into TARGET, line by line, such that the line filter
  * and transformation callbacks set on HUNK_TEXT by the diff parsing
  * code in libsvn_diff will trigger. ABSPATH is the absolute path to the
- * file underlying TARGET. Use EOL_STR as EOL indicator when
- * reading from HUNK_TEXT and when writing to TARGET. */
+ * file underlying TARGET. */
 static svn_error_t *
 copy_hunk_text(svn_stream_t *hunk_text, svn_stream_t *target,
-               const char *abspath, const char *eol_str,
-               apr_pool_t *scratch_pool)
+               const char *abspath, apr_pool_t *scratch_pool)
 {
   svn_boolean_t eof;
   apr_pool_t *iterpool;
@@ -711,18 +709,20 @@
   do
     {
       svn_stringbuf_t *line;
+      const char *eol_str;
 
       svn_pool_clear(iterpool);
 
-      SVN_ERR(svn_stream_readline(hunk_text, &line, eol_str, &eof, iterpool));
+      SVN_ERR(svn_stream_readline_detect_eol(hunk_text, &line, &eol_str,
+                                             &eof, iterpool));
       if (! eof)
         {
           if (line->len >= 1)
             SVN_ERR(try_stream_write(target, abspath, line->data, line->len,
                                      iterpool));
-          /* Add newline. */
-          SVN_ERR(try_stream_write(target, abspath, eol_str, strlen(eol_str),
-                                   iterpool));
+          if (eol_str)
+            SVN_ERR(try_stream_write(target, abspath, eol_str, strlen(eol_str),
+                                     iterpool));
         }
     }
   while (! eof);
@@ -746,8 +746,7 @@
   SVN_ERR(svn_stream_write(target->reject, hunk_header, &len));
 
   SVN_ERR(copy_hunk_text(hunk->diff_text, target->reject,
-                         target->reject_path,
-                         target->patch->eol_str, pool));
+                         target->reject_path, pool));
 
   target->had_rejects = TRUE;
   return SVN_NO_ERROR;
@@ -796,7 +795,7 @@
 
   /* Copy the patched hunk text into the patched stream. */
   SVN_ERR(copy_hunk_text(hunk->modified_text, target->patched,
-                         target->patched_path, target->patch->eol_str, pool));
+                         target->patched_path, pool));
 
   return SVN_NO_ERROR;
 }
@@ -1058,8 +1057,8 @@
       if (ctx->cancel_func)
         SVN_ERR(ctx->cancel_func(ctx->cancel_baton));
 
-      SVN_ERR(svn_diff__parse_next_patch(&patch, patch_file, patch_eol_str,
-                                         iterpool, iterpool));
+      SVN_ERR(svn_diff__parse_next_patch(&patch, patch_file, iterpool,
+                                         iterpool));
       if (patch)
         {
           SVN_ERR(apply_one_patch(patch, wc_path, dry_run, ctx, strip_count,

Modified: subversion/trunk/subversion/libsvn_diff/parse-diff.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_diff/parse-diff.c?rev=895501&r1=895500&r2=895501&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_diff/parse-diff.c (original)
+++ subversion/trunk/subversion/libsvn_diff/parse-diff.c Sun Jan  3 22:50:50 
2010
@@ -249,8 +249,8 @@
 
       /* Remember the current line's offset, and read the line. */
       last_line = pos;
-      SVN_ERR(svn_stream_readline(stream, &line, patch->eol_str, &eof,
-                                  iterpool));
+      SVN_ERR(svn_stream_readline_detect_eol(stream, &line, NULL, &eof,
+                                             iterpool));
 
       /* Lines starting with a backslash are comments, such as
        * "\ No newline at end of file". */
@@ -385,7 +385,6 @@
 svn_error_t *
 svn_diff__parse_next_patch(svn_patch_t **patch,
                            apr_file_t *patch_file,
-                           const char *eol_str,
                            apr_pool_t *result_pool,
                            apr_pool_t *scratch_pool)
 {
@@ -411,7 +410,6 @@
   /* Record what we already know about the patch. */
   *patch = apr_pcalloc(result_pool, sizeof(**patch));
   (*patch)->patch_file = patch_file;
-  (*patch)->eol_str = eol_str;
   (*patch)->path = fname;
 
   /* Get a stream to read lines from the patch file.
@@ -429,7 +427,8 @@
       svn_pool_clear(iterpool);
 
       /* Read a line from the stream. */
-      SVN_ERR(svn_stream_readline(stream, &line, eol_str, &eof, iterpool));
+      SVN_ERR(svn_stream_readline_detect_eol(stream, &line, NULL, &eof,
+                                             iterpool));
 
       /* See if we have a diff header. */
       if (line->len > strlen(indicator) && starts_with(line->data, indicator))

Modified: subversion/trunk/subversion/tests/libsvn_diff/parse-diff-test.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_diff/parse-diff-test.c?rev=895501&r1=895500&r2=895501&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_diff/parse-diff-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_diff/parse-diff-test.c Sun Jan  3 
22:50:50 2010
@@ -89,7 +89,7 @@
 
   /* We have two patches with one hunk each.
    * Parse the first patch. */
-  SVN_ERR(svn_diff__parse_next_patch(&patch, patch_file, NL, pool, pool));
+  SVN_ERR(svn_diff__parse_next_patch(&patch, patch_file, pool, pool));
   SVN_ERR_ASSERT(patch);
   SVN_ERR_ASSERT(! strcmp(patch->old_filename, "A/C/gamma"));
   SVN_ERR_ASSERT(! strcmp(patch->new_filename, "A/C/gamma"));
@@ -118,7 +118,7 @@
   SVN_ERR_ASSERT(buf->len == 0);
 
   /* Parse the second patch. */
-  SVN_ERR(svn_diff__parse_next_patch(&patch, patch_file, NL, pool, pool));
+  SVN_ERR(svn_diff__parse_next_patch(&patch, patch_file, pool, pool));
   SVN_ERR_ASSERT(patch);
   SVN_ERR_ASSERT(! strcmp(patch->old_filename, "A/D/gamma.orig"));
   SVN_ERR_ASSERT(! strcmp(patch->new_filename, "A/D/gamma"));


Reply via email to