You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by rh...@apache.org on 2013/06/12 13:18:18 UTC

svn commit: r1492145 - in /subversion/trunk/subversion: libsvn_subr/io.c tests/libsvn_subr/io-test.c

Author: rhuijben
Date: Wed Jun 12 11:18:18 2013
New Revision: 1492145

URL: http://svn.apache.org/r1492145
Log:
Make sure svn_io_read_length_line() can't get in an endless loop when neither
an EOL nor EOF is found before the buffer is filled. Add regression test.

* subversion/libsvn_subr/io.c
  (svn_io_read_length_line): If there is nothing to get, break.

* subversion/tests/libsvn_subr/io-test.c
  (read_length_line_shouldnt_loop): New function.
  (test_funcs): Add read_length_line_shouldnt_loop.

Found by: Markus Schaber <m.schaber{_AT_}codesys.com>

Modified:
    subversion/trunk/subversion/libsvn_subr/io.c
    subversion/trunk/subversion/tests/libsvn_subr/io-test.c

Modified: subversion/trunk/subversion/libsvn_subr/io.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_subr/io.c?rev=1492145&r1=1492144&r2=1492145&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_subr/io.c (original)
+++ subversion/trunk/subversion/libsvn_subr/io.c Wed Jun 12 11:18:18 2013
@@ -3614,6 +3614,9 @@ svn_io_read_length_line(apr_file_t *file
       apr_size_t bytes_read = 0;
       char *eol;
 
+      if (to_read == 0)
+        break;
+
       /* read data block (or just a part of it) */
       SVN_ERR(svn_io_file_read_full2(file, buf, to_read,
                                      &bytes_read, &eof, pool));

Modified: subversion/trunk/subversion/tests/libsvn_subr/io-test.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_subr/io-test.c?rev=1492145&r1=1492144&r2=1492145&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_subr/io-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_subr/io-test.c Wed Jun 12 11:18:18 2013
@@ -481,6 +481,31 @@ test_three_file_content_comparison(apr_p
   return err;
 }
 
+static svn_error_t *
+read_length_line_shouldnt_loop(apr_pool_t *pool)
+{
+  const char *tmp_dir;
+  const char *tmp_file;
+  char buffer[4];
+  apr_size_t buffer_limit = sizeof(buffer);
+  apr_file_t *f;
+
+  SVN_ERR(svn_dirent_get_absolute(&tmp_dir, "read_length_tmp", pool));
+  SVN_ERR(svn_io_remove_dir2(tmp_dir, TRUE, NULL, NULL, pool));
+  SVN_ERR(svn_io_make_dir_recursively(tmp_dir, pool));
+  svn_test_add_dir_cleanup(tmp_dir);
+
+  SVN_ERR(svn_io_write_unique(&tmp_file, tmp_dir, "1234\r\n", 6,
+                              svn_io_file_del_on_pool_cleanup, pool));
+
+  SVN_ERR(svn_io_file_open(&f, tmp_file, APR_READ, APR_OS_DEFAULT, pool));
+
+  SVN_TEST_ASSERT_ERROR(svn_io_read_length_line(f, buffer, &buffer_limit,
+                                                pool), SVN_ERR_MALFORMED_FILE);
+  SVN_TEST_ASSERT(buffer_limit == 4);
+
+  return SVN_NO_ERROR;
+}
 
 
 /* The test table.  */
@@ -496,5 +521,7 @@ struct svn_test_descriptor_t test_funcs[
                    "three file size comparison"),
     SVN_TEST_PASS2(test_three_file_content_comparison,
                    "three file content comparison"),
+    SVN_TEST_PASS2(read_length_line_shouldnt_loop,
+                   "svn_io_read_length_line() shouldn't loop"),
     SVN_TEST_NULL
   };