strlen误用导致内容重叠
【作者】:权安静
【工号】:42183
【部门】:业务与软件研发部/业务与软件数据业务开发部/业务与软件数据业务维护优化部
【案例提供时间】:2006-02-20
【关键词】:memcpy strlen 消息内容重叠
【来源】:网上事故
【案例类别】:可靠性
【案例根源活动】:编码
【案例分级】:SWE(软件开发人员)
1 现象:问题描述
某版本短消息中心前后的消息内容出现重叠:
移动手机、电信小灵通发给ETS终端出现的问题。移动手机和小灵通都是经过电信的二级网关(Z公司的产品)作中转发到rasys短信中心的。问题是比如移动手机或小灵通发送短信内容"ABCDEF"给ETS终端,ETS终端能正常收到短信"ABCDEF",第二次移动手机再发"XY"到该ETS终端,ETS终端收到的短信内容是"XYCDEF"。跟踪与二级网关接口,送过来的是的确是"XY",但查询短消息历史库却是"XYCDEF"。
2 关键过程:根本原因分析
首先,接到这个网上问题。我们先分析了一下现场提交消息的码流,发现该消息采用的编码方式为DCS=15。这条消息采用的是15bit编码的方式,通过分析代码,检查到在编解码函数
int CCodeTool::ConvertTextToDataEx(LPCSTR pString, int nStrLen, UC nDCS, \
UC* pData,US& nLen, CODE_INTERFACE CodeInterface)
{
…….
if(15 == nDCS)
{
return ConvertTextToUCS2(pString, pData, nLen);
}
…….
}
可见函数中处理15bit编码的时候使用ConvertTextToUCS2(pString,pData,nlen)进行编解码操作的。
该函数实现为:
int CCodeTool::ConvertTextToUCS2(LPCSTR pString, UC* pData,US& nLen)
{
…….
int nCount = strlen(pString);
…….
}
可见在该函数中实现的计算pString的长度信息是通过strlen()函数来实现的。而先前用过的pString缓冲区本身也没有清空操作。就是这里导致计算原缓冲区消息长度的时候长度出现偏差。
为什么对于字符串的内容不能够通过strlen得到呢?因为首先短消息中心在拷贝消息内容的时候,考虑到消息内容不一定都为ASCII码,一般拷贝内容的时候都使用memcpy(),拷贝的长度都取消息长度字段中的内容。这样就会导致在赋值内容的时候,没有赋值结束符标志。然后当目的缓冲区经常被使用且没有清空处理的时候,消息会同原来缓冲区中的内容连接起来,造成消息被拉长。
3 结论:解决方案及效果
通过仔细观察其他相关的编解码函数,发现传送的参数均为4个。都携带了(LPCSTR pString,int nStrlen,UC* pData,US& nLen)。所以我们在对应的编解码函数中增加了原始缓冲区长度参数,直接通过赋值得到。替换通过strlen()计算得到。
4 经验总结:预防措施和规范建议
在处理消息缓冲区互相赋值或者对消息进行编解码操作的时候,尽量把原或者目的缓冲区的消息长度字段携带进去,每一次对消息内容操作的时候,使用结构中携带的长度字段值。不要用系统提供的字符串长度计算函数来获得。在开发新的功能的时候,在消息结构中,需要为每个内容字段提供一个长度信息字段。
5 备注
6 考核点
memcpy strlen
阅读(273) | 评论(0) | 转发(0) |