]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Fix error checking in writing files 2672/head
authorRose <gfunni234@gmail.com>
Wed, 11 Jun 2025 19:21:46 +0000 (15:21 -0400)
committerRose <gfunni234@gmail.com>
Fri, 20 Jun 2025 17:55:57 +0000 (13:55 -0400)
For write, 0 may not mean an error at all. We need to instead check for the length not being the same.

With fwrite, because 0 could mean an error, but not always. We must check that we wrote the entire file!

Note that unlike write, fwrite's description according to POSIX does not mention returning a negative type at all. Nor does it say you can retry unlike write.

Finally, with write, we need to check less than 0, not 0, as 0 is a valid return and does not mean an error.

libarchive/archive_check_magic.c
libarchive/archive_write_open_fd.c
libarchive/archive_write_open_file.c
libarchive/archive_write_open_filename.c

index d12f0c496e279ba298a69e5cfc995bd2783eed52..6b8e0c5595f469bf204b62bbfcc16b9aea53c638 100644 (file)
@@ -30,6 +30,7 @@
 #endif
 
 #include <stdio.h>
+#include <errno.h>
 #ifdef HAVE_STDLIB_H
 #include <stdlib.h>
 #endif
@@ -54,8 +55,14 @@ errmsg(const char *m)
 
        while (s > 0) {
                written = write(2, m, s);
-               if (written <= 0)
+               if (written == 0)
                        return;
+               if (written < 0)
+               {
+                       if (errno == EINTR)
+                               continue;
+                       return;
+               }
                m += written;
                s -= written;
        }
index 8a3f68d0699dc060c9801eb7ceec64cfbb1fbe2a..ba034ed92f8a1c634138f8c4b4c118a59c38e11d 100644 (file)
@@ -122,7 +122,7 @@ file_write(struct archive *a, void *client_data, const void *buff, size_t length
        mine = (struct write_fd_data *)client_data;
        for (;;) {
                bytesWritten = write(mine->fd, buff, length);
-               if (bytesWritten <= 0) {
+               if (bytesWritten < 0) {
                        if (errno == EINTR)
                                continue;
                        archive_set_error(a, errno, "Write error");
index 4c6ebfb2269dfe9cd98c2504b91c442909b751a6..0b310f3da83b41cf1f04ed41c8484bda2dd03a9c 100644 (file)
@@ -85,16 +85,12 @@ file_write(struct archive *a, void *client_data, const void *buff, size_t length
        size_t  bytesWritten;
 
        mine = client_data;
-       for (;;) {
-               bytesWritten = fwrite(buff, 1, length, mine->f);
-               if (bytesWritten <= 0) {
-                       if (errno == EINTR)
-                               continue;
-                       archive_set_error(a, errno, "Write error");
-                       return (-1);
-               }
-               return (bytesWritten);
+       bytesWritten = fwrite(buff, 1, length, mine->f);
+       if (bytesWritten != length) {
+               archive_set_error(a, errno, "Write error");
+               return (-1);
        }
+       return (bytesWritten);
 }
 
 static int
index 633f7fe1794d31eca1ff9ca508c2998ac55fae62..7d0f9bde1dbb2a59729cbdea7ffab90ec88e6414 100644 (file)
@@ -228,7 +228,7 @@ file_write(struct archive *a, void *client_data, const void *buff,
        mine = (struct write_file_data *)client_data;
        for (;;) {
                bytesWritten = write(mine->fd, buff, length);
-               if (bytesWritten <= 0) {
+               if (bytesWritten < 0) {
                        if (errno == EINTR)
                                continue;
                        archive_set_error(a, errno, "Write error");