STR51-CPP. 不用试图以空指针创建 str::string
原文链接:
STR51-CPP. Do not attempt to create a std::string from a null pointer
std::basic_string
类型使用 traits
设计模式来处理各种字符串类型的实现细节, 形成一系列具有通用底层实现的类 string 类. 确切地说, std::basic_string
通过配对使用 std::char_traits
来创建 std::string
, std::wstring
, std::u16string
, 和 std::u32string
类. std::char_traits
类被显式特例化来对 std::basic_string
类型提供基于策略的实现细节 (policy-based implementation details) . std::char_traits::length()
函数是这类实现细节之一 – 常用于判定以空字符终止的字符串的字符数目. 根据 C++ Standard, [char.traits.require], Table 62 [ISO/IEC 14882-2014], 将 null 指针传入该函数是 未定义行为, undefined behavior , 因为这将导致解引用空指针.
下述 std::basic_string
成员函数都会调用 std::char_traits::length()
:
basic_string::basic_string(const charT *, const Allocator &)
basic_string &basic_string::append(const charT *)
basic_string &basic_string::assign(const charT *)
basic_string &basic_string::insert(size_type, const charT *)
basic_string &basic_string::replace(size_type, size_type, const charT *)
basic_string &basic_string::replace(const_iterator, const_iterator, const charT *)
size_type basic_string::find(const charT *, size_type)
size_type basic_string::rfind(const charT *, size_type)
size_type basic_string::find_first_of(const charT *, size_type)
size_type basic_string::find_last_of(const charT *, size_type)
size_type basic_string::find_first_not_of(const charT *, size_type)
size_type basic_string::find_last_not_of(const charT *, size_type)
int basic_string::compare(const charT *)
int basic_string::compare(size_type, size_type, const charT *)
basic_string &basic_string::operator=(const charT *)
basic_string &basic_string::operator+=(const charT *)
下述 std::basic_string
非成员函数会调用 std::char_traits::length()
:
basic_string operator+(const charT *, const basic_string&)
basic_string operator+(const charT *, basic_string &&)
basic_string operator+(const basic_string &, const charT *)
basic_string operator+(basic_string &&, const charT *)
bool operator==(const charT *, const basic_string &)
bool operator==(const basic_string &, const charT *)
bool operator!=(const charT *, const basic_string &)
bool operator!=(const basic_string &, const charT *)
bool operator<(const charT *, const basic_string &)
bool operator<(const basic_string &, const charT *)
bool operator>(const charT *, const basic_string &)
bool operator>(const basic_string &, const charT *)
bool operator<=(const charT *, const basic_string &)
bool operator<=(const basic_string &, const charT *)
bool operator>=(const charT *, const basic_string &)
bool operator>=(const basic_string &, const charT *)
空指针作为 const charT *
的参数时, 不要调用任一上述的函数. 这条规则是 EXP34-C. Do not dereference null pointers 的一个具体例子.
实现细节
某些厂商的标准库, 像 libstdc++, 当在上述函数调用中使用空指针时, 会抛出 std::logic_error
, 尽管不在调用 std::char_traits::length()
时. 然而, std::logic_error
并不是 C++ Standard 所必需具备的, 某些厂商 (例如, libc++ 和 Microsoft Visual Studio STL) 并没有实现该行为. 考虑移植性, 你不应该依赖这个行为.
不合规代码示例
在这个不合规代码示例中, 创建了一个 std::string
对象来保存 std::getenv()
调用返回的结果. 然而, 因为 std::getenv()
在失败时返回空指针, 所以当环境变量不存在 (或者发生其他错误) 时, 这段代码会导致 未定义行为, undefined behavior .
1 |
|
合规方案
在这个合规方案中, 在构造 std::string
对象之前, 检查了 std::getenv()
调用返回的结果是否为空.
1 |
|
风险预估
解引用空指针是 未定义行为, undefined behavior, 典型地是 程序异常终止, abnormal program termination. 在某些情景中, 解引用空指针会导致任意代码执行 [Jack 2007, van Sprundel 2006]. 标示的严重性是对于某些更严重的情况而言的; 在那些无法 利用, exploit 解引用空指针来执行任意代码的平台上, 实际的严重性较低.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
STR51-CPP | High | Likely | Medium | P18 | L1 |
Automated Detection
Tool | Version | Checker | Description |
---|---|---|---|
Astrée | 20.10 | **assert_failure ** | |
Helix QAC | 2021.2 | C++4770, C++4771, C++4772, C++4773, C++4774 | |
Klocwork | 2021.1 | NPD.CHECK.CALL.MIGHT NPD.CHECK.CALL.MUST NPD.CHECK.MIGHTNPD.CHECK.MUSTNPD.CONST.CALL NPD.CONST.DEREF NPD.FUNC.CALL.MIGHT NPD.FUNC.CALL.MUST NPD.FUNC.MIGHT **NPD.FUNC.MUSTNPD.GEN.CALL.MIGHT NPD.GEN.CALL.MUST NPD.GEN.MIGHT NPD.GEN.MUSTRNPD.CALL RNPD.DEREF ** | |
Parasoft C/C++test | 2021.1 | CERT_CPP-STR51-a | Avoid null pointer dereferencing |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Related Guidelines
SEI CERT C Coding Standard | EXP34-C. Do not dereference null pointers |
---|---|
Bibliography
[ISO/IEC 9899:2011] | Subclause 7.20.3, “Memory Management Functions” |
---|---|
[ISO/IEC 14882-2014] | Subclause 21.2.1, “Character Trait Requirements” |
[Jack 2007] | |
[van Sprundel 2006] |
本文标题:STR51-CPP. 不用试图以空指针创建 str::string
文章作者:xwnb
发布时间:2021-11-20
最后更新:2023-04-17
原始链接:https://xwnb.github.io/posts/3622452883/
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!并保留本声明。感谢您的阅读和支持!
分享