zoukankan      html  css  js  c++  java
  • linux 使用不安全的sprintf函数,存储字符越界导致程序莫名崩溃问题

    linux c++编程

    问题背景

    在处理一个公共模块的代码中,其中有以下代码片段

    1 //代码片段-组合一组字符串并存放到szSignKey数组中
    2 char szSignKey[256] = {0};                                                                                                                                                                                                      sprintf(szSignKey, "userid&%u&version&%s&msg_body&%s&%s", uiUserID, strVersion.c_str(), strMsgBody.c_str(), SIGN_KEY);
    strMsgBody是一组json格式的字符串,里面会根据协议请求传入不同数据的json格式字符串。
    当strMsgBody请求的字符串过大,导致要存入szSignKey数组中的字符串超过255个时,会导致字符数组越界,超出的字符会在数组后面的内存空间中存储。
    但是这个问题不会马上暴露出来,printf szSignKey的时候,还是会输出完整的越界字符串数组。但是在函数执行完return后,析构函数内的局部变量的时候导致程序崩溃。
    使用gdb调试的时候,显示的也是一些其他临时对象析构导致崩溃,无法找到真正的崩溃原因。

    问题原因:
    sprintf函数是不安全的c 字符处理函数,它在写字符串到字符数组时不会考虑字符数组的大小,当要存储的字符超过数组长度时,会把超出的字符写在数组后面的内存空间中,导致字符数组存储越界。
    类型的C函数还有strcpy()等

    解决办法:
    使用安全的字符处理函数strncpy()、 snprintf()等。使用安全的字符处理函数会要求写入字符数粗的最大长度参数,超出的部分不会写入到数组中。
    上面的sprintf代码可以修改成
    1 char szSignKey[256] = {0};                                                                                                     
    snprintf(szSignKey,sizeof(szSignKey),"userid&%u&version&%s&msg_body&%s&%s", uiUserID,strVersion.c_str(),strMsgBody.c_str(), SIGN_KEY);

      超出的字符会被截断掉,不会导致字符数组越界问题。



  • 相关阅读:
    贰、js的基础(二)类型转换
    贰、js的基础(一)
    ajax的异步请求小结
    壹、js的概述
    sass的用法小结(四)进阶篇
    sass的用法小结(三)
    sass的用法小结(二)
    sass的用法小结(一)
    H5页面在线制作工具搜集
    H5教程:移动页面性能优化
  • 原文地址:https://www.cnblogs.com/lisuyun/p/7641316.html
Copyright © 2011-2022 走看看