Loading changes/bug33781 0 → 100644 +7 −0 Original line number Diff line number Diff line o Minor bugfixes (compatibility): - Strip '\r' characters when reading text files on Unix platforms. This should resolve an issue where a relay operator migrates a relay from Windows to Unix, but does not change the line ending of Tor's various state files to match the platform, the CRLF line endings from Windows ends up leaking into other files such as the extra-info document. Fixes bug 33781; bugfix on 0.0.9pre5. src/lib/fs/files.c +5 −3 Original line number Diff line number Diff line Loading @@ -607,6 +607,9 @@ read_file_to_str_until_eof(int fd, size_t max_bytes_to_read, size_t *sz_out) * If <b>flags</b> & RFTS_BIN, open the file in binary mode. * If <b>flags</b> & RFTS_IGNORE_MISSING, don't warn if the file * doesn't exist. * * Unless the RFTS_BIN flag is set in <b>flags</b>, this function will strip * any CR characters in the return value on all platforms. */ /* * This function <em>may</em> return an erroneous result if the file Loading Loading @@ -685,7 +688,6 @@ read_file_to_str, (const char *filename, int flags, struct stat *stat_out)) } string[r] = '\0'; /* NUL-terminate the result. */ #if defined(_WIN32) || defined(__CYGWIN__) if (!bin && strchr(string, '\r')) { log_debug(LD_FS, "We didn't convert CRLF to LF as well as we hoped " "when reading %s. Coping.", Loading @@ -695,8 +697,7 @@ read_file_to_str, (const char *filename, int flags, struct stat *stat_out)) } if (!bin) { statbuf.st_size = (size_t) r; } else #endif /* defined(_WIN32) || defined(__CYGWIN__) */ } else { if (r != statbuf.st_size) { /* Unless we're using text mode on win32, we'd better have an exact * match for size. */ Loading @@ -708,6 +709,7 @@ read_file_to_str, (const char *filename, int flags, struct stat *stat_out)) errno = save_errno; return NULL; } } close(fd); if (stat_out) { memcpy(stat_out, &statbuf, sizeof(struct stat)); Loading src/test/test_util.c +49 −0 Original line number Diff line number Diff line Loading @@ -173,6 +173,54 @@ test_util_read_file_eof_zero_bytes(void *arg) test_util_read_until_eof_impl("tor_test_fifo_empty", 0, 10000); } static void test_util_read_file_endlines(void *arg) { (void)arg; char *fname = NULL; char *read_content = NULL; int r = -1; /* Write a file that contains both \n and \r\n as line ending. */ const char *file_content = "foo bar\n" "foo bar baz\r\n" "foo bar\r\n"; const char *expected_file_content = "foo bar\n" "foo bar baz\n" "foo bar\n"; fname = tor_strdup(get_fname("file_with_crlf_ending")); r = write_bytes_to_file(fname, file_content, strlen(file_content), 1); tt_int_op(r, OP_EQ, 0); /* Read the file in text mode: we strip \r's from the files on both Windows * and UNIX. */ read_content = read_file_to_str(fname, 0, NULL); tt_ptr_op(read_content, OP_NE, NULL); tt_int_op(strlen(read_content), OP_EQ, strlen(expected_file_content)); tt_str_op(read_content, OP_EQ, expected_file_content); tor_free(read_content); /* Read the file in binary mode: we should preserve the \r here. */ read_content = read_file_to_str(fname, RFTS_BIN, NULL); tt_ptr_op(read_content, OP_NE, NULL); tt_int_op(strlen(read_content), OP_EQ, strlen(file_content)); tt_str_op(read_content, OP_EQ, file_content); tor_free(read_content); done: unlink(fname); tor_free(fname); tor_free(read_content); } /* Test the basic expected behaviour for write_chunks_to_file. * NOTE: This will need to be updated if we ever change the tempfile location * or extension */ Loading Loading @@ -6508,6 +6556,7 @@ struct testcase_t util_tests[] = { UTIL_TEST(read_file_eof_two_loops, 0), UTIL_TEST(read_file_eof_two_loops_b, 0), UTIL_TEST(read_file_eof_zero_bytes, 0), UTIL_TEST(read_file_endlines, 0), UTIL_TEST(write_chunks_to_file, 0), UTIL_TEST(mathlog, 0), UTIL_TEST(fraction, 0), Loading Loading
changes/bug33781 0 → 100644 +7 −0 Original line number Diff line number Diff line o Minor bugfixes (compatibility): - Strip '\r' characters when reading text files on Unix platforms. This should resolve an issue where a relay operator migrates a relay from Windows to Unix, but does not change the line ending of Tor's various state files to match the platform, the CRLF line endings from Windows ends up leaking into other files such as the extra-info document. Fixes bug 33781; bugfix on 0.0.9pre5.
src/lib/fs/files.c +5 −3 Original line number Diff line number Diff line Loading @@ -607,6 +607,9 @@ read_file_to_str_until_eof(int fd, size_t max_bytes_to_read, size_t *sz_out) * If <b>flags</b> & RFTS_BIN, open the file in binary mode. * If <b>flags</b> & RFTS_IGNORE_MISSING, don't warn if the file * doesn't exist. * * Unless the RFTS_BIN flag is set in <b>flags</b>, this function will strip * any CR characters in the return value on all platforms. */ /* * This function <em>may</em> return an erroneous result if the file Loading Loading @@ -685,7 +688,6 @@ read_file_to_str, (const char *filename, int flags, struct stat *stat_out)) } string[r] = '\0'; /* NUL-terminate the result. */ #if defined(_WIN32) || defined(__CYGWIN__) if (!bin && strchr(string, '\r')) { log_debug(LD_FS, "We didn't convert CRLF to LF as well as we hoped " "when reading %s. Coping.", Loading @@ -695,8 +697,7 @@ read_file_to_str, (const char *filename, int flags, struct stat *stat_out)) } if (!bin) { statbuf.st_size = (size_t) r; } else #endif /* defined(_WIN32) || defined(__CYGWIN__) */ } else { if (r != statbuf.st_size) { /* Unless we're using text mode on win32, we'd better have an exact * match for size. */ Loading @@ -708,6 +709,7 @@ read_file_to_str, (const char *filename, int flags, struct stat *stat_out)) errno = save_errno; return NULL; } } close(fd); if (stat_out) { memcpy(stat_out, &statbuf, sizeof(struct stat)); Loading
src/test/test_util.c +49 −0 Original line number Diff line number Diff line Loading @@ -173,6 +173,54 @@ test_util_read_file_eof_zero_bytes(void *arg) test_util_read_until_eof_impl("tor_test_fifo_empty", 0, 10000); } static void test_util_read_file_endlines(void *arg) { (void)arg; char *fname = NULL; char *read_content = NULL; int r = -1; /* Write a file that contains both \n and \r\n as line ending. */ const char *file_content = "foo bar\n" "foo bar baz\r\n" "foo bar\r\n"; const char *expected_file_content = "foo bar\n" "foo bar baz\n" "foo bar\n"; fname = tor_strdup(get_fname("file_with_crlf_ending")); r = write_bytes_to_file(fname, file_content, strlen(file_content), 1); tt_int_op(r, OP_EQ, 0); /* Read the file in text mode: we strip \r's from the files on both Windows * and UNIX. */ read_content = read_file_to_str(fname, 0, NULL); tt_ptr_op(read_content, OP_NE, NULL); tt_int_op(strlen(read_content), OP_EQ, strlen(expected_file_content)); tt_str_op(read_content, OP_EQ, expected_file_content); tor_free(read_content); /* Read the file in binary mode: we should preserve the \r here. */ read_content = read_file_to_str(fname, RFTS_BIN, NULL); tt_ptr_op(read_content, OP_NE, NULL); tt_int_op(strlen(read_content), OP_EQ, strlen(file_content)); tt_str_op(read_content, OP_EQ, file_content); tor_free(read_content); done: unlink(fname); tor_free(fname); tor_free(read_content); } /* Test the basic expected behaviour for write_chunks_to_file. * NOTE: This will need to be updated if we ever change the tempfile location * or extension */ Loading Loading @@ -6508,6 +6556,7 @@ struct testcase_t util_tests[] = { UTIL_TEST(read_file_eof_two_loops, 0), UTIL_TEST(read_file_eof_two_loops_b, 0), UTIL_TEST(read_file_eof_zero_bytes, 0), UTIL_TEST(read_file_endlines, 0), UTIL_TEST(write_chunks_to_file, 0), UTIL_TEST(mathlog, 0), UTIL_TEST(fraction, 0), Loading