Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 490fad67 authored by Tao Bao's avatar Tao Bao
Browse files

applypatch: Don't call inflate() when it expects zero-length output.

We may have expanded_len == 0 when calling inflate(). After switching to
using std::vector, it passes a nullptr buffer to inflate() and leads to
Z_STREAM_ERROR.

Bug: 29312140
Change-Id: Iab7c6c07a9e8488e844e7cdda76d02bd60d2ea98
parent b0ddae55
Loading
Loading
Loading
Loading
+66 −57
Original line number Diff line number Diff line
@@ -151,6 +151,10 @@ int ApplyImagePatch(const unsigned char* old_data, ssize_t old_size,
            size_t bonus_size = (i == 1 && bonus_data != NULL) ? bonus_data->size : 0;

            std::vector<unsigned char> expanded_source(expanded_len);

            // inflate() doesn't like strm.next_out being a nullptr even with
            // avail_out being zero (Z_STREAM_ERROR).
            if (expanded_len != 0) {
                z_stream strm;
                strm.zalloc = Z_NULL;
                strm.zfree = Z_NULL;
@@ -186,6 +190,7 @@ int ApplyImagePatch(const unsigned char* old_data, ssize_t old_size,
                    memcpy(expanded_source.data() + (expanded_len - bonus_size),
                           bonus_data->data, bonus_size);
                }
            }

            // Next, apply the bsdiff patch (in memory) to the uncompressed
            // data.
@@ -203,15 +208,18 @@ int ApplyImagePatch(const unsigned char* old_data, ssize_t old_size,
            if (expanded_source.size() < 32768U) {
                expanded_source.resize(32768U);
            }

            {
                std::vector<unsigned char>& temp_data = expanded_source;

                // now the deflate stream
                z_stream strm;
                strm.zalloc = Z_NULL;
                strm.zfree = Z_NULL;
                strm.opaque = Z_NULL;
                strm.avail_in = uncompressed_target_data.size();
                strm.next_in = uncompressed_target_data.data();
            ret = deflateInit2(&strm, level, method, windowBits, memLevel, strategy);
                int ret = deflateInit2(&strm, level, method, windowBits, memLevel, strategy);
                if (ret != Z_OK) {
                    printf("failed to init uncompressed data deflation: %d\n", ret);
                    return -1;
@@ -230,6 +238,7 @@ int ApplyImagePatch(const unsigned char* old_data, ssize_t old_size,
                    if (ctx) SHA1_Update(ctx, temp_data.data(), have);
                } while (ret != Z_STREAM_END);
                deflateEnd(&strm);
            }
        } else {
            printf("patch chunk %d is unknown type %d\n", i, type);
            return -1;