C++ ZLib GZipStream Decompression NULL terminated -


there lot of questions out there revolving around zlib , gzipstreams none i've found answer question. i'm using c# gzipstream send compressed data client. reads compressed data in entirely tries decompress it. however, each time inflate() called in loop gets null terminated string. when sending binary pretty huge problem.

before show code, wanted if write received compressed bytes .gz file , use gzfile/gzopen/gzread/gzclose works perfectly. means data coming in properly. want read in compressed data, decompress in memory, , have contents in variable.

i think issue inflate() writing char* null terminated. don't know how string. anticipate being major oversight , simple fix. help!

here's decompression code:

bool decompressstring(const std::string& message, std::string& dmsg) {     int buffersize = 512;     int messagesize = message.size() + 1;     //decompress string     z_stream zs;     memset(&zs, 0, sizeof(zs));      zs.zalloc = z_null;     zs.zfree = z_null;     zs.opaque = z_null;     zs.next_in = (bytef*)message.data();     zs.avail_in = messagesize;      int ret = z_ok;     unsigned char* outbuffer = new unsigned char[buffersize];      if (inflateinit2(&zs, 16+max_wbits) == z_ok)     {         {             zs.next_out = outbuffer;             zs.avail_out = buffersize;              ret = inflate(&zs, z_no_flush);              if (ret < 0) return false;             std::stringstream tmpstring;             tmpstring << outbuffer;             if (dmsg.size() < zs.total_out) {                 dmsg.append(tmpstring.str().substr(0, zs.total_out - dmsg.size()));             }         } while (ret == z_ok);     }      inflateend(&zs);     delete[] outbuffer;     //"\n<eof>" appended sender signify end of file. removes     if (dmsg.find("\n<eof>") != -1)         dmsg = dmsg.substr(0, dmsg.find("\n<eof>"));      return true; } 

working code solution:

bool decompressstring(const std::string& message, std::string& dmsg) {     int buffersize = 512;     int messagesize = message.size() + 1;     //decompress string     z_stream zs;     memset(&zs, 0, sizeof(zs));      zs.zalloc = z_null;     zs.zfree = z_null;     zs.opaque = z_null;     zs.next_in = (bytef*)message.data();     zs.avail_in = messagesize;      int ret = z_ok;     unsigned char* outbuffer = new unsigned char[buffersize];      if (inflateinit2(&zs, 16+max_wbits) == z_ok)     {         // decompressed bytes blockwise using repeated calls inflate         {             zs.next_out = outbuffer;             zs.avail_out = buffersize;              ret = inflate(&zs, z_no_flush);              if (ret < 0) return false;             //here's difference             if (dmsg.size() < zs.total_out)                 dmsg.append(reinterpret_cast<char*>(outbuffer), buffersize);             //end         } while (ret == z_ok);     }      inflateend(&zs);     delete[] outbuffer;      if (dmsg.find("\n<eof>") != -1)         dmsg = dmsg.substr(0, dmsg.find("\n<eof>"));      return true; } 

string not problem in itself, can handle binary data. line assumes zero-terminated c-string:

tmpstring << outbuffer; 

replace with

tmpstring.append(outbuffer, buffersize); 

Comments

Popular posts from this blog

php - Wordpress website dashboard page or post editor content is not showing but front end data is showing properly -

How to get the ip address of VM and use it to configure SSH connection dynamically in Ansible -

javascript - Get parameter of GET request -