dpkg-deb: work around bogus error message when working with XZ compressed packages
authorDenys Vlasenko <vda.linux@googlemail.com>
Fri, 11 Oct 2019 12:11:44 +0000 (14:11 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Fri, 11 Oct 2019 12:11:44 +0000 (14:11 +0200)
function                                             old     new   delta
unpack_xz_stream                                    2309    2317      +8
bb_full_fd_action                                    464     472      +8

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
archival/libarchive/decompress_unxz.c
archival/libarchive/unxz/xz_stream.h
libbb/copyfd.c

index f0334138457b70372d969aa7d405cff0e52f022e..3dd9bbf4934eb51ed23f2e7dadad784a66dc7f99 100644 (file)
@@ -96,6 +96,24 @@ unpack_xz_stream(transformer_state_t *xstate)
                         */
                        do {
                                if (membuf[iobuf.in_pos] != 0) {
+                                       /* There is more data, but is it XZ data?
+                                        * Example: dpkg-deb -f busybox_1.30.1-4_amd64.deb
+                                        * reads control.tar.xz "control" file
+                                        * inside the ar archive, but tar.xz
+                                        * extraction code reaches end of xz data,
+                                        * reached this code and reads the beginning
+                                        * of data.tar.xz's ar header, which isn't xz data,
+                                        * and prints "corrupted data".
+                                        * The correct solution is to not read
+                                        * past nested archive (to simulate EOF).
+                                        * This is a workaround:
+                                        */
+                                       if (membuf[iobuf.in_pos] != 0xfd) {
+                                               /* It's definitely not a xz signature
+                                                * (which is 0xfd,"7zXZ",0x00).
+                                                */
+                                               goto end;
+                                       }
                                        xz_dec_reset(state);
                                        goto do_run;
                                }
@@ -128,7 +146,7 @@ unpack_xz_stream(transformer_state_t *xstate)
                        break;
                }
        }
-
+ end:
        xz_dec_end(state);
        free(membuf);
 
index 66cb5a7055ec83298de08e625902e1e229c9ce42..45056e42cbc7aacc89787976ed8564e75a51a6c8 100644 (file)
@@ -25,7 +25,7 @@
 
 #define STREAM_HEADER_SIZE 12
 
-#define HEADER_MAGIC "\3757zXZ"
+#define HEADER_MAGIC "\375""7zXZ"
 #define HEADER_MAGIC_SIZE 6
 
 #define FOOTER_MAGIC "YZ"
index ae5c26999073e63a4aca7ec42db257738e8cf2fa..d41fd10f02c742823f891bfba31eb288ff900d3a 100644 (file)
@@ -18,7 +18,7 @@
  * was seen to cause largish delays when user tries to ^C a file copy.
  * Let's use a saner size.
  * Note: needs to be >= max(CONFIG_FEATURE_COPYBUF_KB),
- * or else "copy to eof" code will use neddlesly short reads.
+ * or else "copy to eof" code will use needlesly short reads.
  */
 #define SENDFILE_BIGBUF (16*1024*1024)
 
@@ -60,10 +60,13 @@ static off_t bb_full_fd_action(int src_fd, int dst_fd, off_t size)
                ssize_t rd;
 
                if (sendfile_sz) {
-                       rd = sendfile(dst_fd, src_fd, NULL,
-                               size > sendfile_sz ? sendfile_sz : size);
-                       if (rd >= 0)
-                               goto read_ok;
+                       /* dst_fd == -1 is a fake, else... */
+                       if (dst_fd >= 0) {
+                               rd = sendfile(dst_fd, src_fd, NULL,
+                                       size > sendfile_sz ? sendfile_sz : size);
+                               if (rd >= 0)
+                                       goto read_ok;
+                       }
                        sendfile_sz = 0; /* do not try sendfile anymore */
                }
 #if CONFIG_FEATURE_COPYBUF_KB > 4