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

ztmd8pv5  于 3个月前  发布在  Git
关注(0)|答案(1)|浏览(74)

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

pack = pack.substr(20, pack.length() - 40); // skip 8 byte http header, 12 byte pack header, 20 byte pack trailer
    int type;
    int pos = 0;
    std::string lengthstr;
    int length = 0;
    type = (pack[pos] & 112) >> 4; // 112 is 11100000 so this gets the first 3 bits
    length = length | (pack[pos] & 0x0F); // take the last 4 bits
    if (pack[pos] & 0x80) { // if the type bit starts with 0 then the last 4 bits are simply the length
        pos++;
        while (pack[pos] & 0x80) { // while leftmost bit is 1
            length = length << 7;
            length = length | (pack[pos] & 0x7F); // flip first bit to 0 si it's ignored, then we append the other 7 bits to the integer
            pos++;
        }
        length = length << 7;
        length = length | pack[pos]; // set the leftmost bit to 1 so it's ignored, and do the same thing
    }
    pos++;
    FILE* customStdout = fdopen(1, "w");

    FILE* source = fmemopen((void*)pack.substr(pos, length).c_str(), length, "r");
    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调用

int ret;
    unsigned have;
    z_stream strm;
    unsigned char in[16384];
    unsigned char out[16384];

    /* allocate inflate state */
    strm.zalloc = Z_NULL;
    strm.zfree = Z_NULL;
    strm.opaque = Z_NULL;
    strm.avail_in = 0;
    strm.next_in = Z_NULL;
    ret = inflateInit(&strm);
    strm.avail_in = pack.length() - pos;
    for (int i = 0; i < 16384; i++) {
        in[i] = pack[pos + i];
    }
    strm.next_in = in;
    strm.avail_out = 16384;
    strm.next_out = out;
    inflate(&strm, Z_NO_FLUSH);

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

相关问题