C++安全编码规范

声明与初始化(DCL)

  • DCL50-CPP 不要定义C风格的可变参函数
  • DCL51-CPP 不要声明或定义保留标识符
  • DCL52-CPP 不要用const或volatile限定一个引用类型
  • DCL53-CPP 不要写在语法上引起歧义的声明
  • DCL54-CPP 在同一个作用域同时重载alloc和dealloc的函数
  • DCL55-CPP 当传递一个类对象需要跨边界的时候要避免信息泄露
  • DCL56-CPP 静态对象的初始化期间避免循环初始化
  • DCL57-CPP 不要让异常逃离析构函数和dealloc函数的范围
  • DCL58-CPP. 不要修改标准名字空间
  • DCL59-CPP 不要在头文件中定义一个未命名的名字空间
  • DCL60-CPP 遵循只有一个定义的原则

表达式(EXP)

  • EXP50-CPP 不要依赖求值顺序所造成的副作用
  • EXP51-CPP 不要通过不正确的类型的指针来删除一个数组
  • EXP53-CPP 不要读取未初始化的内存
  • EXP54-CPP 不要访问处于其生命周期之外的对象
  • EXP55-CPP 不要通过cv-unqualified的类型来访问一个cv-qualified类型的对象
  • EXP56-CPP. 不要调用从语言链接上不匹配的函数
  • EXP57-CPP. 不要删除或转换指向不完整类的指针
  • EXP59-CPP. offsetof函数使用在合法的类型和成员上
  • EXP60-CPP. 不要跨执行边界传递非标准布局类型的对象
  • EXP61-CPP. 一个lambda对象在生命周期必须在它所引用捕获的对象生命周期内
  • EXP62-CPP. 不要访问不属于对象的value representation的bit位域
  • EXP63-CPP. 不要依赖moved-from对象的值

整数型 (INT)

  • INT50-CPP. 不要转换超出枚举值的范围

容器类(CTR)

  • CTR50-CPP. 保证容器的索引和迭代器在合法的范围内
  • CTR51-CPP. 使用合法的引用,指针,迭代器来引用容器的元素
  • CTR52-CPP. 保证库函数不溢出
  • CTR53-CPP. 使用合法的迭代器范围
  • CTR54-CPP. 没有指向相同容器的迭代器之间不要做减法
  • CTR55-CPP. 如果会导致溢出就不要在一个迭代器上做加法操作
  • CTR56-CPP. 不要用指针在多态对象上进行算数运算
  • CTR57-CPP. 提供合法的顺序谓词(predicate)
  • CTR58-CPP. 谓词函数对象应该不能被修改

字符串类(STR)

  • STR50-CPP. 保证字符串类有足够的存储空间预留给字符数据和null结束符
  • STR51-CPP. 构造std::string对象时,不要传入null指针
  • STR52-CPP. 使用合法的引用,指针和迭代器来指向std::basic_string的元素
  • STR53-CPP. 访问字符串元素时检查下标范围

内存管理(MEM)

  • MEM50-CPP. 不要访问已经释放的内存
  • MEM51-CPP. 恰当的释放已经动态分配的资源
  • MEM52-CPP. 检测和处理内存分配错误
  • MEM53-CPP. 当手动管理对象生命周期的时候一定要显式构造和析构对象
  • MEM54-CPP. 使用placement new的时候需要注意指针在内存空间上的对齐
  • MEM55-CPP. 自定义动态内存管理函数时需要遵守其替换规范
  • MEM56-CPP. 不要把一个已拥有所属权的指针的值保存进一个无关的智能指针
  • MEM57-CPP. 避免使用默认的operator new来生成超出对齐大小的类型

文件IO(FIO)

  • FIO50-CPP. 在使用文件流输入输出的时候不要不使用中介定位调用
  • FIO51-CPP. 当不需要操作文件的时候一定要关闭文件

异常和错误处理 (ERR)

  • ERR50-CPP. 不要突然的终止程序
  • ERR51-CPP. 处理所有的异常
  • ERR52-CPP. 不要使用setjmp()或longjmp()函数
  • ERR53-CPP. 在构造函数和析构函数中不要在function-try-block handler中引用基类或者类的数据成员
  • ERR54-CPP. catch handler的参数类型应该采用从most derived到least derived的优先级顺序考虑,从低到高
  • ERR55-CPP. 遵循异常规范
  • ERR56-CPP. 保证异常安全
  • ERR57-CPP. 当处理异常的时候不要泄漏资源
  • ERR58-CPP. 在main函数开始执行之前处理所有的异常
  • ERR59-CPP. 不要跨执行边界抛异常
  • ERR60-CPP. 异常对象不要以拷贝构造的形式抛出
  • ERR61-CPP. catch异常的时候以左值引用的方式捕获异常对象
  • ERR62-CPP. 当把字符串转换成一个数值时,注意检测异常

面向对象编程(OOP)

  • OOP50-CPP. 不要在构造函数或析构函数中调用虚函数
  • OOP51-CPP. 不要切分继承类的对象
  • OOP52-CPP. 不要删除没有虚析构函数的多态对象
  • OOP53-CPP. 用成员变量的声明顺序在构造函数的成员初始化列表中初始化成员变量
  • OOP54-CPP. 小心得处理自拷贝赋值
  • OOP55-CPP. 不要使用pointer-to-member操作符访问不存在的成员
  • OOP56-CPP. 遵守handler的替换规范
  • OOP57-CPP. 优先选择特定的成员函数来代替C标准库提供的重载操作符的函
  • OOP58-CPP. 对象的拷贝操作必须不能修改源对象(source object)

并发编程 (CON)

  • CON50-CPP. 当mutex被上锁的时候不要销毁mutex
  • CON51-CPP. 确保持有锁的线程在遇到异常的时候及时释放锁
  • CON52-CPP. 在多线程访问bit-fields的时候防止数据竞争
  • CON53-CPP. 通过预先定义的顺序来加锁以避免出现死锁
  • CON54-CPP. 包装在循环中能伪唤醒的函数
  • CON55-CPP. 在使用condition variable的时候保持线程安全和线程活动(存
  • CON56-CPP. 在一个已获得锁的调用线程中不要“推测性”地对一个不支持递归的mutex再次上锁

其他功能杂项 (MSC)

  • MSC50-CPP. 不要使用std::rand()生成伪随机数
  • MSC51-CPP. 确保随机数生成器被恰当的种子初始化
  • MSC52-CPP. 如果函数是有返回值的,那么在所有函数退出路径中必须返回一个值
  • MSC53-CPP. 如果函数被声明为[[noreturn]],那么就一定不能返回
  • MSC54-CPP. 信号处理函数必须是一个平坦老式的函数

发表评论

电子邮件地址不会被公开。 必填项已用*标注