c++ zlib不正确的头检查解压缩git包

ztmd8pv5  于 2024-01-09  发布在  Git
关注(0)|答案(1)|浏览(234)

我正在尝试解析一个git包,我收到了一个POST到https://github.com/codecrafters-io/git-sample-3/git-upload-pack的数据,并将返回的字符串存储在std::string pack中。

  1. pack = pack.substr(20, pack.length() - 40); // skip 8 byte http header, 12 byte pack header, 20 byte pack trailer
  2. int type;
  3. int pos = 0;
  4. std::string lengthstr;
  5. int length = 0;
  6. type = (pack[pos] & 112) >> 4; // 112 is 11100000 so this gets the first 3 bits
  7. length = length | (pack[pos] & 0x0F); // take the last 4 bits
  8. if (pack[pos] & 0x80) { // if the type bit starts with 0 then the last 4 bits are simply the length
  9. pos++;
  10. while (pack[pos] & 0x80) { // while leftmost bit is 1
  11. length = length << 7;
  12. length = length | (pack[pos] & 0x7F); // flip first bit to 0 si it's ignored, then we append the other 7 bits to the integer
  13. pos++;
  14. }
  15. length = length << 7;
  16. length = length | pack[pos]; // set the leftmost bit to 1 so it's ignored, and do the same thing
  17. }
  18. pos++;
  19. FILE* customStdout = fdopen(1, "w");
  20. FILE* source = fmemopen((void*)pack.substr(pos, length).c_str(), length, "r");
  21. std::cout << inf(source, customStdout) << "\n";

字符串
其中,inf来自zpipe.c。inf调用的结果是Z_DATA_ERROR,并带有消息incorrect header check
我实际上打印出了二进制的位,从pos开始的位是我期望的zlib头(78 9C),所以我不知道为什么我在这里得到了不正确的头。
我还尝试使用inflateInit2(&strm, -MAX_WBITS)并在pos中添加2以完全跳过标头,但它返回相同的错误,并显示消息invalid stored block lengths

6psbrbz9

6psbrbz91#

使用以下代码替换inf调用

  1. int ret;
  2. unsigned have;
  3. z_stream strm;
  4. unsigned char in[16384];
  5. unsigned char out[16384];
  6. /* allocate inflate state */
  7. strm.zalloc = Z_NULL;
  8. strm.zfree = Z_NULL;
  9. strm.opaque = Z_NULL;
  10. strm.avail_in = 0;
  11. strm.next_in = Z_NULL;
  12. ret = inflateInit(&strm);
  13. strm.avail_in = pack.length() - pos;
  14. for (int i = 0; i < 16384; i++) {
  15. in[i] = pack[pos + i];
  16. }
  17. strm.next_in = in;
  18. strm.avail_out = 16384;
  19. strm.next_out = out;
  20. inflate(&strm, Z_NO_FLUSH);

字符串
允许inflate调用成功。我观察到的唯一区别是,我直接将pack中的字符复制到流缓冲区中。我怀疑这个问题与我创建文件的方式有关

展开查看全部

相关问题