文章目录
一、sprintf引起的内存越界
有玩家客户端发过来的数据包解包失败,但不知道原因,所以增加了一个函数把错误的数据包以 16 进制输出到 log 的函数
char *buffer = calloc(sz*2+1, sizeof(char));
先分配一块内存,长度是要 dump 的数据长度两倍加一。然后循环
sprintf(buffer+i*2, "%02x", data[i]);
这就是我们看了几次没留意的 bug 所在:data 是 const char
类型,有符号的。当 data[i] 是一个负数时, %02x 不一定只输出 3 个字节(别忘记字符串结尾的 \0)。buffer 这块内存就被写越界了
-
问题
最后一个字符是负数的时候 就越界了 超过两个字符 把尾部得0覆盖掉了 所以问题就来了, -
解决
改成snprintf或
sprintf(buffer+i*2, "%02x", (unsigned char)data[i]);