apply BusyBox 1.21.0 hotfixes
[busybox-power] / debian / patches / hotfixes / busybox-1.21.0-xz.patch
1 --- busybox-1.21.0/archival/libarchive/decompress_unxz.c
2 +++ busybox-1.21.0-xz/archival/libarchive/decompress_unxz.c
3 @@ -40,6 +40,7 @@ static uint32_t xz_crc32(const uint8_t *
4  IF_DESKTOP(long long) int FAST_FUNC
5  unpack_xz_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd)
6  {
7 +       enum xz_ret xz_result;
8         struct xz_buf iobuf;
9         struct xz_dec *state;
10         unsigned char *membuf;
11 @@ -63,9 +64,8 @@ unpack_xz_stream(transformer_aux_data_t
12         /* Limit memory usage to about 64 MiB. */
13         state = xz_dec_init(XZ_DYNALLOC, 64*1024*1024);
14  
15 +       xz_result = X_OK;
16         while (1) {
17 -               enum xz_ret r;
18 -
19                 if (iobuf.in_pos == iobuf.in_size) {
20                         int rd = safe_read(src_fd, membuf, BUFSIZ);
21                         if (rd < 0) {
22 @@ -73,28 +73,57 @@ unpack_xz_stream(transformer_aux_data_t
23                                 total = -1;
24                                 break;
25                         }
26 +                       if (rd == 0 && xz_result == XZ_STREAM_END)
27 +                               break;
28                         iobuf.in_size = rd;
29                         iobuf.in_pos = 0;
30                 }
31 +               if (xz_result == XZ_STREAM_END) {
32 +                       /*
33 +                        * Try to start decoding next concatenated stream.
34 +                        * Stream padding must always be a multiple of four
35 +                        * bytes to preserve four-byte alignment. To keep the
36 +                        * code slightly smaller, we aren't as strict here as
37 +                        * the .xz spec requires. We just skip all zero-bytes
38 +                        * without checking the alignment and thus can accept
39 +                        * files that aren't valid, e.g. the XZ utils test
40 +                        * files bad-0pad-empty.xz and bad-0catpad-empty.xz.
41 +                        */
42 +                       do {
43 +                               if (membuf[iobuf.in_pos] != 0) {
44 +                                       xz_dec_reset(state);
45 +                                       goto do_run;
46 +                               }
47 +                               iobuf.in_pos++;
48 +                       } while (iobuf.in_pos < iobuf.in_size);
49 +               }
50 + do_run:
51  //             bb_error_msg(">in pos:%d size:%d out pos:%d size:%d",
52  //                             iobuf.in_pos, iobuf.in_size, iobuf.out_pos, iobuf.out_size);
53 -               r = xz_dec_run(state, &iobuf);
54 +               xz_result = xz_dec_run(state, &iobuf);
55  //             bb_error_msg("<in pos:%d size:%d out pos:%d size:%d r:%d",
56 -//                             iobuf.in_pos, iobuf.in_size, iobuf.out_pos, iobuf.out_size, r);
57 +//                             iobuf.in_pos, iobuf.in_size, iobuf.out_pos, iobuf.out_size, xz_result);
58                 if (iobuf.out_pos) {
59                         xwrite(dst_fd, iobuf.out, iobuf.out_pos);
60                         IF_DESKTOP(total += iobuf.out_pos;)
61                         iobuf.out_pos = 0;
62                 }
63 -               if (r == XZ_STREAM_END) {
64 -                       break;
65 +               if (xz_result == XZ_STREAM_END) {
66 +                       /*
67 +                        * Can just "break;" here, if not for concatenated
68 +                        * .xz streams.
69 +                        * Checking for padding may require buffer
70 +                        * replenishment. Can't do it here.
71 +                        */
72 +                       continue;
73                 }
74 -               if (r != XZ_OK && r != XZ_UNSUPPORTED_CHECK) {
75 +               if (xz_result != XZ_OK && xz_result != XZ_UNSUPPORTED_CHECK) {
76                         bb_error_msg("corrupted data");
77                         total = -1;
78                         break;
79                 }
80         }
81 +
82         xz_dec_end(state);
83         free(membuf);
84