Zlib decompression method warning using ios 64bit Architecture

210 views Asked by At

I am just updating one of my applications and I have an error with my decompression method.

This is the warning I am experiencing

Implicit conversion loses integer precision: 'unsigned long' to 'unit' (aka 'unsigned int')

this is the line of code its happening on

stream.avail_in = len - stream.total_in;

And this is what the whole method looks like

#pragma mark - ZLib Compression Methods
//  Returns the decompressed version if the zlib compressed input data or nil if there was an error
- (NSData*) dataByDecompressingData:(NSData*)data {

     NSLog(@"%lu", (unsigned long)data.length);

    Byte* bytes = (Byte*)[data bytes];
    NSInteger len = [data length];
    NSMutableData *decompressedData = [[NSMutableData alloc] initWithCapacity:COMPRESSION_BLOCK];
    Byte* decompressedBytes = (Byte*) malloc(COMPRESSION_BLOCK);

    z_stream stream;
    int err;
    stream.zalloc = (alloc_func)0;
    stream.zfree = (free_func)0;
    stream.opaque = (voidpf)0;

    stream.next_in = bytes;
    err = inflateInit(&stream);
    CHECK_ERR(err, @"inflateInit");

    while (true) {
        stream.avail_in = len - stream.total_in;
        stream.next_out = decompressedBytes;
        stream.avail_out = COMPRESSION_BLOCK;
        err = inflate(&stream, Z_NO_FLUSH);
        [decompressedData appendBytes:decompressedBytes length:(stream.total_out-[decompressedData length])];
        if(err == Z_STREAM_END)
            break;
        CHECK_ERR(err, @"inflate");
    }

    err = inflateEnd(&stream);
    CHECK_ERR(err, @"inflateEnd");

    free(decompressedBytes);
    return decompressedData;
}
1

There are 1 answers

0
Mark Adler On

First off, you should not use stream.total_in. It may or may not be a large enough type for your application. It is always unsigned long. Use your own total input counter sized for your application and ignore stream.total_in.

Second, I'm guessing that your CHECK_ERR() aborts somehow. You should not abort in the event of a Z_BUF_ERROR. In that case, you can continue by simply providing more input and/or more output space.

Third, the problem here is that you need to pick a stream.avail_in that is assured to fit in unsigned. You should be comparing the amount of remaining input to the largest value of unsigned, e.g. UINT_MAX or (unsigned)0 - 1. If the remaining data is larger, use the max value and deduct that from the remaining input. If smaller or equal, use all of it and set the remaining input to zero.