C语言使用ZLIB的uncompress函数解压缩返回BUF_ERROR(-5)问题求助
问题修复方案
核心错误点
- 错误1:
uncompress第四个参数(压缩数据的长度)赋值错误
你当前用compressBound(ucompSize_out)作为第四个参数是完全错误的,这个参数应该传入base45解码后得到的压缩数据实际长度,也就是base45_decode输出的size_out值,compressBound是压缩时用来预估输出缓冲区大小的接口,解压场景完全不适用。 - 错误2:
uncompress第二个参数(解压输出缓冲区长度)初始值错误
你当前把ucompSize_out设为strlen(out)+1完全错误,首先out是base45解码后的二进制zlib数据,内部可能包含\0字节,strlen会提前截断得到错误的长度,其次这个参数初始值应该传入你定义的输出缓冲区u_out的总大小,也就是sizeof(u_out)。 - 错误3:解压成功后直接用
%s打印u_out的行为错误
如果解压后的数据不是纯ASCII字符串,或者末尾没有\0结束符,printf("%s")会出现内存越界访问,只有确认解压结果是字符串的场景下,需要手动在末尾补\0再打印。
修正后代码
unsigned char out[20000], u_out[20000]; size_t size_out; unsigned char* in = ""; // 原始输入数据 int err; uLongf ucompSize_out; // 和uncompress要求的参数类型匹配,避免自定义类型长度不匹配 uLong compSize_out; size_out = sizeof(out); // base45解码 err = base45_decode(out, &size_out, in, strlen(in)); printf("\nbase45 decode result length: %zu", size_out); printf("\nbase45 decode err code: %d", err); // 先判断base45解码是否成功,失败直接终止后续逻辑 if (err != 0 /* 替换为你用的base45库解码成功的返回值 */) { printf("\nbase45 decode failed"); return -1; } // zlib解压缩参数修正 ucompSize_out = sizeof(u_out); // 初始值设为输出缓冲区的总大小 compSize_out = size_out; // 压缩数据的长度是base45解码得到的实际长度 err = uncompress((Byte *)u_out, &ucompSize_out, (const Byte *)out, compSize_out); // 按结果分支处理 if (err == Z_OK) { // 确认是字符串场景再补结束符打印 if (ucompSize_out < sizeof(u_out)) { u_out[ucompSize_out] = '\0'; printf("\nzlib uncompress result: \"%s\" ", (char*)u_out); } printf("\nuncompress success, output length: %lu", ucompSize_out); } else { printf("\nuncompress failed, err code: %d", err); }
额外排查点
如果修正后还是报BUF_ERROR,可以先检查u_out的缓冲区大小是否足够,若解压后的数据超过20000字节,需要调大缓冲区或者用动态分配内存的方式获取足够的输出空间。
内容的提问来源于stack exchange,提问作者ilaria
相关产品推荐
相关产品推荐

