int result = inflateInit (&stream); // this returns -2 if (result) { return result; }
int wrap_inflate ( unsigned char* output, int size_output , const unsigned char* input, int size_input , int* written_output ) { z_stream stream; stream.zalloc = NULL; stream.zfree = NULL; stream.next_in = const_cast<Bytef*> (input); stream.avail_in = size_input; stream.next_out = output; stream.avail_out = size_output; int result = inflateInit (&stream); // this returns -2 if (result) { return result; } int inflateResult = inflate (&stream, 4); if (inflateResult == 1) { *written_output = stream.total_out; return inflateEnd (&stream); } else { inflateEnd (&stream); if (inflateResult != 2 && (inflateResult != -5 || stream.avail_in)) { return inflateResult; } return -3; } }
#define Z_STREAM_ERROR (-2)
inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_VERSION_ERROR if the zlib library version is incompatible with the version assumed by the caller, or Z_STREAM_ERROR if the parameters are invalid, such as a null pointer to the structure. msg is set to null if there is no error message. inflateInit does not perform any decompression apart from possibly reading the zlib header if present: actual decompression will be done by inflate(). (So next_in and avail_in may be modified, but next_out and avail_out are unused and unchanged.) The current implementation of inflateInit() does not process any header information -- that is deferred until inflate() is called.
std::vector<unsigned char> output_data (entry->inflated_data_size); zlib::inflate (input_data, &output_data);
output_data is supposed to be empty, but the exact size given in the BsnI. Input should not be &(*output)[0] though, but &input[0]. Oo
int wrap_inflate ( unsigned char* output, int size_output , const unsigned char* input, int size_input , int* written_output )
const int res (wrap_inflate (&(*output)[0], output->size(), &input[0], input.size(), &inflated));
Version of zlib?
int wrap_inflate ( unsigned char* output, int size_output , const unsigned char* input, int size_input , int* written_output ) { z_stream stream; stream.zalloc = NULL; stream.zfree = NULL; stream.next_in = const_cast<Bytef*> (input); stream.avail_in = size_input; stream.next_out = output; stream.avail_out = size_output; int result = inflateInit (&stream); if (result) { return result; } int inflateResult = inflate (&stream, 4); std::cout << std::endl << "Inflate result from inflate(&stream, 4) = " << inflateResult << std::endl; if (inflateResult == 1) { *written_output = stream.total_out; return inflateEnd (&stream); } else { inflateEnd (&stream); std::cout << "if inflateResult != 2 && (inflateResult != 5 || stream.availin) return result, else return -3" << std::endl; std::cout << "stream.avail_in: " << stream.avail_in; if (inflateResult != 2 && (inflateResult != -5 || stream.avail_in)) { return inflateResult; } return -3; // this is being returned } }
Why is avail_in 0? It should be about half of avail_out, as given in the BsnI entry.
Being half was only an estimation. Any non-zero number will do.Given that total_in/out are not the same as avail_in/out: This really is the state before calling anything in zlib?
int wrap_inflate ( unsigned char* output, int size_output , const unsigned char* input, int size_input , int* written_output ) { z_stream stream; stream.zalloc = NULL; stream.zfree = NULL; stream.next_in = const_cast<Bytef*> (input); stream.avail_in = size_input; stream.next_out = output; stream.avail_out = size_output;
In your screenshot, zalloc and zfree are non NULL. It is technically impossible that this is the state at that line.