From: Tim Kientzle Date: Sun, 24 May 2009 23:35:53 +0000 (-0400) Subject: Be more careful about text/binary mode. X-Git-Tag: v2.8.0~637 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b70fcb33e382ef56fe94c0a390688f09be1fca63;p=thirdparty%2Flibarchive.git Be more careful about text/binary mode. Libarchive is already pretty careful about using O_BINARY whenever it opens a file handle internally; this extends that care to file descriptors that are passed in from clients by invoking _setmode() explicitly. The test harness was much less careful about O_BINARY; this adds those flags to all open() calls and modifies fopen() calls to use "wb" and "rb" explicitly. In particular, this should remove the need for clients to use invoke _set_fmode() at all. This is not yet completely tested... SVN-Revision: 1103 --- diff --git a/libarchive/archive_read_open_fd.c b/libarchive/archive_read_open_fd.c index f5be2e5b9..ed58c6c48 100644 --- a/libarchive/archive_read_open_fd.c +++ b/libarchive/archive_read_open_fd.c @@ -96,6 +96,10 @@ archive_read_open_fd(struct archive *a, int fd, size_t block_size) } else mine->can_skip = 0; +#if defined(_WIN32_) + _setmode(mine->fd, _O_BINARY); +#endif + return (archive_read_open2(a, mine, NULL, file_read, file_skip, file_close)); } diff --git a/libarchive/archive_read_open_file.c b/libarchive/archive_read_open_file.c index 1e87166da..5e78bfe4d 100644 --- a/libarchive/archive_read_open_file.c +++ b/libarchive/archive_read_open_file.c @@ -94,6 +94,10 @@ archive_read_open_FILE(struct archive *a, FILE *f) } else mine->can_skip = 0; +#if defined(_WIN32_) + _setmode(_fileno(mine->f), _O_BINARY); +#endif + return (archive_read_open2(a, mine, NULL, file_read, file_skip, file_close)); } diff --git a/libarchive/archive_read_open_filename.c b/libarchive/archive_read_open_filename.c index efd9e862b..2651323eb 100644 --- a/libarchive/archive_read_open_filename.c +++ b/libarchive/archive_read_open_filename.c @@ -96,6 +96,9 @@ archive_read_open_filename(struct archive *a, const char *filename, */ filename = ""; /* Normalize NULL to "" */ fd = 0; +#if defined(_WIN32_) + _setmode(0, _O_BINARY); +#endif } else { fd = open(filename, O_RDONLY | O_BINARY); if (fd < 0) { diff --git a/libarchive/test/main.c b/libarchive/test/main.c index c4a972178..0f217eaf1 100644 --- a/libarchive/test/main.c +++ b/libarchive/test/main.c @@ -538,7 +538,7 @@ test_assert_empty_file(const char *f1fmt, ...) fprintf(stderr, "%s:%d: File not empty: %s\n", test_filename, test_line, f1); fprintf(stderr, " File size: %d\n", (int)st.st_size); fprintf(stderr, " Contents:\n"); - fd = open(f1, O_RDONLY); + fd = open(f1, O_RDONLY | O_BINARY); if (fd < 0) { fprintf(stderr, " Unable to open %s\n", f1); } else { @@ -566,8 +566,8 @@ test_assert_equal_file(const char *f1, const char *f2pattern, ...) vsprintf(f2, f2pattern, ap); va_end(ap); - fd1 = open(f1, O_RDONLY); - fd2 = open(f2, O_RDONLY); + fd1 = open(f1, O_RDONLY | O_BINARY); + fd2 = open(f2, O_RDONLY | O_BINARY); for (;;) { n1 = read(fd1, buff1, sizeof(buff1)); n2 = read(fd2, buff2, sizeof(buff2)); @@ -645,7 +645,7 @@ test_assert_file_contents(const void *buff, int s, const char *fpattern, ...) vsprintf(f, fpattern, ap); va_end(ap); - fd = open(f, O_RDONLY); + fd = open(f, O_RDONLY | O_BINARY); contents = malloc(s * 2); n = read(fd, contents, s * 2); if (n == s && memcmp(buff, contents, s) == 0) { @@ -707,7 +707,7 @@ slurpfile(size_t * sizep, const char *fmt, ...) vsprintf(filename, fmt, ap); va_end(ap); - fd = open(filename, O_RDONLY); + fd = open(filename, O_RDONLY | O_BINARY); if (fd < 0) { /* Note: No error; non-existent file is okay here. */ return (NULL); @@ -893,7 +893,7 @@ extract_reference_file(const char *name) } /* Now, decode the rest and write it. */ /* Not a lot of error checking here; the input better be right. */ - out = fopen(name, "w"); + out = fopen(name, "wb"); while (fgets(buff, sizeof(buff), in) != NULL) { char *p = buff; int bytes; @@ -1033,7 +1033,10 @@ int main(int argc, char **argv) /* To stop to run the default invalid parameter handler. */ _set_invalid_parameter_handler(invalid_parameter_handler); /* for open() to a binary mode. */ - _set_fmode(_O_BINARY); + /* This shouldn't be needed, because all tests should + * explicitly use O_BINARY flag to open() and "b" to + * fopen(): */ + /* _set_fmode(_O_BINARY); */ /* Disable annoying assertion message box. */ _CrtSetReportMode(_CRT_ASSERT, 0); #endif diff --git a/libarchive/test/test_acl_freebsd.c b/libarchive/test/test_acl_freebsd.c index b48fae0c2..ea52a336a 100644 --- a/libarchive/test/test_acl_freebsd.c +++ b/libarchive/test/test_acl_freebsd.c @@ -206,7 +206,7 @@ DEFINE_TEST(test_acl_freebsd) acl = acl_from_text("u::rwx,u:1:rw,g::rwx,g:15:rx,o::rwx,m::rwx"); assert((void *)acl != NULL); /* Create a test file and try to set an ACL on it. */ - fd = open("pretest", O_WRONLY | O_CREAT | O_EXCL, 0777); + fd = open("pretest", O_WRONLY | O_CREAT | O_EXCL | O_BINARY, 0777); failure("Could not create test file?!"); if (!assert(fd >= 0)) { acl_free(acl); diff --git a/libarchive/test/test_acl_pax.c b/libarchive/test/test_acl_pax.c index 26329cbaf..1d616a815 100644 --- a/libarchive/test/test_acl_pax.c +++ b/libarchive/test/test_acl_pax.c @@ -453,12 +453,14 @@ DEFINE_TEST(test_acl_pax) #endif /* Write out the data we generated to a file for manual inspection. */ - assert(-1 < (fd = open("testout", O_WRONLY | O_CREAT | O_TRUNC, 0775))); + assert(-1 < (fd = open("testout", + O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0775))); assert(used == (size_t)write(fd, buff, (unsigned int)used)); close(fd); /* Write out the reference data to a file for manual inspection. */ - assert(-1 < (fd = open("reference", O_WRONLY | O_CREAT | O_TRUNC, 0775))); + assert(-1 < (fd = open("reference", + O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0775))); assert(sizeof(reference) == write(fd, reference, sizeof(reference))); close(fd); diff --git a/libarchive/test/test_extattr_freebsd.c b/libarchive/test/test_extattr_freebsd.c index 19881c2ec..b4e0ec150 100644 --- a/libarchive/test/test_extattr_freebsd.c +++ b/libarchive/test/test_extattr_freebsd.c @@ -56,7 +56,7 @@ DEFINE_TEST(test_extattr_freebsd) * doesn't, we'll simply skip the remaining tests. */ /* Create a test file and try to set an ACL on it. */ - fd = open("pretest", O_RDWR | O_CREAT, 0777); + fd = open("pretest", O_RDWR | O_CREAT | O_BINARY, 0777); failure("Could not create test file?!"); if (!assert(fd >= 0)) return; @@ -78,7 +78,7 @@ DEFINE_TEST(test_extattr_freebsd) * permissions, not file permissions), but is known broken on * some versions of FreeBSD. */ - fd = open("pretest2", O_RDWR | O_CREAT, 00000); + fd = open("pretest2", O_RDWR | O_CREAT | O_BINARY, 00000); failure("Could not create test file?!"); if (!assert(fd >= 0)) return; diff --git a/libarchive/test/test_fuzz.c b/libarchive/test/test_fuzz.c index 38f5796d5..6e07173be 100644 --- a/libarchive/test/test_fuzz.c +++ b/libarchive/test/test_fuzz.c @@ -135,7 +135,7 @@ DEFINE_TEST(test_fuzz) * If we crash, that file will be useful. */ fd = open("after.test.failure.send.this.file." "to.libarchive.maintainers.with.system.details", - O_WRONLY | O_CREAT | O_TRUNC, 0744); + O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0744); write(fd, image, (off_t)size); close(fd); diff --git a/libarchive/test/test_open_fd.c b/libarchive/test/test_open_fd.c index 0aec1d5e9..18e461cbf 100644 --- a/libarchive/test/test_open_fd.c +++ b/libarchive/test/test_open_fd.c @@ -33,7 +33,7 @@ DEFINE_TEST(test_open_fd) struct archive *a; int fd; - fd = open("test.tar", O_RDWR | O_CREAT, 0777); + fd = open("test.tar", O_RDWR | O_CREAT | O_BINARY, 0777); assert(fd >= 0); if (fd < 0) return; diff --git a/libarchive/test/test_open_file.c b/libarchive/test/test_open_file.c index e931163de..7e6c5719a 100644 --- a/libarchive/test/test_open_file.c +++ b/libarchive/test/test_open_file.c @@ -32,7 +32,7 @@ DEFINE_TEST(test_open_file) struct archive *a; FILE *f; - f = fopen("test.tar", "w"); + f = fopen("test.tar", "wb"); assert(f != NULL); if (f == NULL) return; @@ -73,7 +73,7 @@ DEFINE_TEST(test_open_file) /* * Now, read the data back. */ - f = fopen("test.tar", "r"); + f = fopen("test.tar", "rb"); assert(f != NULL); if (f == NULL) return; diff --git a/libarchive/test/test_read_data_large.c b/libarchive/test/test_read_data_large.c index 1716c4914..040d74109 100644 --- a/libarchive/test/test_read_data_large.c +++ b/libarchive/test/test_read_data_large.c @@ -96,7 +96,7 @@ DEFINE_TEST(test_read_data_large) assertA(0 == archive_read_support_compression_all(a)); assertA(0 == archive_read_open_memory(a, buff1, sizeof(buff1))); assertA(0 == archive_read_next_header(a, &ae)); - tmpfilefd = open(tmpfilename, O_WRONLY | O_CREAT, 0777); + tmpfilefd = open(tmpfilename, O_WRONLY | O_CREAT | O_BINARY, 0777); assert(tmpfilefd != 0); assertEqualIntA(a, 0, archive_read_data_into_fd(a, tmpfilefd)); assert(0 == archive_read_close(a)); @@ -107,7 +107,7 @@ DEFINE_TEST(test_read_data_large) #endif close(tmpfilefd); - tmpfilefd = open(tmpfilename, O_RDONLY); + tmpfilefd = open(tmpfilename, O_RDONLY | O_BINARY); assert(tmpfilefd != 0); assertEqualIntA(NULL, sizeof(buff3), read(tmpfilefd, buff3, sizeof(buff3))); close(tmpfilefd); diff --git a/libarchive/test/test_read_disk_entry_from_file.c b/libarchive/test/test_read_disk_entry_from_file.c index 8b3b6d79c..9a636466e 100644 --- a/libarchive/test/test_read_disk_entry_from_file.c +++ b/libarchive/test/test_read_disk_entry_from_file.c @@ -57,7 +57,7 @@ DEFINE_TEST(test_read_disk_entry_from_file) assertEqualString(archive_read_disk_gname(a, 0), "FOOGROUP"); /* Create a file on disk. */ - fd = open("foo", O_WRONLY | O_CREAT, 0777); + fd = open("foo", O_WRONLY | O_CREAT | O_BINARY, 0777); assert(fd >= 0); assertEqualInt(4, write(fd, "1234", 4)); close(fd); diff --git a/libarchive/test/test_read_extract.c b/libarchive/test/test_read_extract.c index bbd7e32ae..9017af922 100644 --- a/libarchive/test/test_read_extract.c +++ b/libarchive/test/test_read_extract.c @@ -154,7 +154,7 @@ DEFINE_TEST(test_read_extract) assertEqualInt(st.st_mode, S_IFREG | 0755); failure("The file extracted to disk is the wrong size."); assert(st.st_size == FILE_BUFF_SIZE); - fd = open("file", O_RDONLY); + fd = open("file", O_RDONLY | O_BINARY); failure("The file on disk could not be opened."); assert(fd != 0); bytes_read = read(fd, buff, FILE_BUFF_SIZE); diff --git a/libarchive/test/test_read_format_mtree.c b/libarchive/test/test_read_format_mtree.c index a88d0826c..56589ea21 100644 --- a/libarchive/test/test_read_format_mtree.c +++ b/libarchive/test/test_read_format_mtree.c @@ -74,7 +74,7 @@ DEFINE_TEST(test_read_format_mtree) /* * Read "file", whose data is available on disk. */ - fd = open("file", O_WRONLY | O_CREAT, 0777); + fd = open("file", O_WRONLY | O_CREAT | O_BINARY, 0777); assert(fd >= 0); assertEqualInt(3, write(fd, "hi\n", 3)); close(fd); diff --git a/libarchive/test/test_read_large.c b/libarchive/test/test_read_large.c index 3ad2af35c..43a8f5e60 100644 --- a/libarchive/test/test_read_large.c +++ b/libarchive/test/test_read_large.c @@ -77,7 +77,8 @@ DEFINE_TEST(test_read_large) assertA(0 == archive_read_support_compression_all(a)); assertA(0 == archive_read_open_memory(a, buff, sizeof(buff))); assertA(0 == archive_read_next_header(a, &entry)); - assert(0 < (tmpfilefd = open(tmpfilename, O_WRONLY | O_CREAT | O_BINARY, 0755))); + assert(0 < (tmpfilefd = open(tmpfilename, + O_WRONLY | O_CREAT | O_BINARY, 0755))); assertA(0 == archive_read_data_into_fd(a, tmpfilefd)); close(tmpfilefd); #if ARCHIVE_VERSION_NUMBER < 2000000 @@ -85,7 +86,7 @@ DEFINE_TEST(test_read_large) #else assertA(0 == archive_read_finish(a)); #endif - tmpfilefd = open(tmpfilename, O_RDONLY); + tmpfilefd = open(tmpfilename, O_RDONLY | O_BINARY); read(tmpfilefd, testdatacopy, sizeof(testdatacopy)); close(tmpfilefd); assert(0 == memcmp(testdata, testdatacopy, sizeof(testdata))); diff --git a/libarchive/test/test_write_disk.c b/libarchive/test/test_write_disk.c index 2d8ef2f51..672266222 100644 --- a/libarchive/test/test_write_disk.c +++ b/libarchive/test/test_write_disk.c @@ -152,7 +152,7 @@ static void create_reg_file2(struct archive_entry *ae, const char *msg) assertEqualInt(st.st_size, i); compare = malloc(datasize); - fd = open(archive_entry_pathname(ae), O_RDONLY); + fd = open(archive_entry_pathname(ae), O_RDONLY | O_BINARY); assertEqualInt(datasize, read(fd, compare, datasize)); close(fd); assert(memcmp(compare, data, datasize) == 0); diff --git a/libarchive/test/test_write_disk_failures.c b/libarchive/test/test_write_disk_failures.c index c9dc824e6..6040be0e3 100644 --- a/libarchive/test/test_write_disk_failures.c +++ b/libarchive/test/test_write_disk_failures.c @@ -48,7 +48,7 @@ DEFINE_TEST(test_write_disk_failures) assertEqualInt(0, mkdir("dir", 0555)); /* Can we? */ - fd = open("dir/testfile", O_WRONLY | O_CREAT, 0777); + fd = open("dir/testfile", O_WRONLY | O_CREAT | O_BINARY, 0777); if (fd >= 0) { /* Apparently, we can, so the test below won't work. */ close(fd); diff --git a/libarchive/test/test_write_disk_perms.c b/libarchive/test/test_write_disk_perms.c index e898fc40a..5ed36ff25 100644 --- a/libarchive/test/test_write_disk_perms.c +++ b/libarchive/test/test_write_disk_perms.c @@ -60,7 +60,7 @@ searchgid(void) _searched = 1; /* Create a file on disk in the current default dir. */ - fd = open("test_gid", O_CREAT, 0664); + fd = open("test_gid", O_CREAT | O_BINARY, 0664); failure("Couldn't create a file for gid testing."); assert(fd > 0); diff --git a/libarchive/test/test_write_disk_sparse.c b/libarchive/test/test_write_disk_sparse.c index c9c00d3d1..8e41dadb6 100644 --- a/libarchive/test/test_write_disk_sparse.c +++ b/libarchive/test/test_write_disk_sparse.c @@ -78,7 +78,7 @@ verify_write_data(struct archive *a, int sparse) /* Test the entry on disk. */ assert(0 == stat(archive_entry_pathname(ae), &st)); assertEqualInt(st.st_size, 8 * buff_size); - fd = open(archive_entry_pathname(ae), O_RDONLY); + fd = open(archive_entry_pathname(ae), O_RDONLY | O_BINARY); if (!assert(fd >= 0)) return; @@ -174,7 +174,7 @@ verify_write_data_block(struct archive *a, int sparse) /* Test the entry on disk. */ assert(0 == stat(archive_entry_pathname(ae), &st)); assertEqualInt(st.st_size, 8 * buff_size); - fd = open(archive_entry_pathname(ae), O_RDONLY); + fd = open(archive_entry_pathname(ae), O_RDONLY | O_BINARY); if (!assert(fd >= 0)) return;