public inbox for gcc-bugs@sourceware.org help / color / mirror / Atom feed
From: "jg at jguk dot org" <gcc-bugzilla@gcc.gnu.org> To: gcc-bugs@gcc.gnu.org Subject: [Bug libstdc++/108886] New: Add basic_string throw logic_error when assigned a nullptr Date: Wed, 22 Feb 2023 14:31:43 +0000 [thread overview] Message-ID: <bug-108886-4@http.gcc.gnu.org/bugzilla/> (raw) https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108886 Bug ID: 108886 Summary: Add basic_string throw logic_error when assigned a nullptr Product: gcc Version: 12.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: jg at jguk dot org Target Milestone: --- Checked this on godbolt trunk today. https://godbolt.org/z/6xxEc85c9 basic_string.h will throw a logic_error at runtime if a nullptr gets through to the basic_string() constructor. But assignment doesn't throw a logic_error, it gives SEGV. Could I suggest two improvements please: 1) Add throw logic_error to basic_string.h:815 if pointer is nullptr. _GLIBCXX20_CONSTEXPR basic_string& operator=(const _CharT* __s) { return this->assign(__s); } 2) Add throw logic_error to basic_string:1647 _GLIBCXX20_CONSTEXPR basic_string& assign(const _CharT* __s) { __glibcxx_requires_string(__s); return _M_replace(size_type(0), this->size(), __s, traits_type::length(__s)); } This is what basic_string.h has for normal construction std::__throw_logic_error(__N("basic_string: " "construction from null is not valid")); The basic_string assignment = uses char_traits to check the length using __builtin_strlen and then SEGV. I believe it is the actual __builtin_strlen that does the nullptr dereference. GDB output Core was generated by `./str2'. Program terminated with signal SIGSEGV, Segmentation fault. #0 __strlen_sse2 () at ../sysdeps/x86_64/multiarch/strlen-sse2.S:142 142 ../sysdeps/x86_64/multiarch/strlen-sse2.S: No such file or directory. (gdb) bt #0 __strlen_sse2 () at ../sysdeps/x86_64/multiarch/strlen-sse2.S:142 #1 0x000055ca94a8327e in std::char_traits<char>::length (__s=0x0) at /usr/include/c++/12/bits/char_traits.h:395 #2 std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::assign (__s=0x0, this=0x7fff26f1e370) at /usr/include/c++/12/bits/basic_string.h:1647 #3 std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::operator= (__s=0x0, this=0x7fff26f1e370) at /usr/include/c++/12/bits/basic_string.h:815 #4 make_string (str=str@entry=0x0, out_string="") at str2.cpp:8 #5 0x000055ca94a832d9 in main () at str2.cpp:15 Therefore I propose 1) Add throw logic_error to basic_string.h:815 if pointer is nullptr. _GLIBCXX20_CONSTEXPR basic_string& operator=(const _CharT* __s) { return this->assign(__s); } 2) Add throw logic_error to basic_string:1647 _GLIBCXX20_CONSTEXPR basic_string& assign(const _CharT* __s) { __glibcxx_requires_string(__s); return _M_replace(size_type(0), this->size(), __s, traits_type::length(__s)); } 3) I don't think char_traits allows exceptions, so I can't suggest a logic_error Is there anything else that could be added here? Maybe just a _GLIBCXX_DEBUG_PEDASSERT ? strlen() doesn't have a way to even set errno and return -1 This is what char_traits.h has /usr/include/c++/12/bits/char_traits.h:395:25: runtime error: null pointer passed as argument 1, which is declared to never be null AddressSanitizer:DEADLYSIGNAL /usr/include/c++/12/bits/char_traits.h static _GLIBCXX17_CONSTEXPR size_t length(const char_type* __s) { #if __cplusplus >= 201703L if (std::__is_constant_evaluated()) return __gnu_cxx::char_traits<char_type>::length(__s); #endif return __builtin_strlen(__s); } Example: #include <string> #include <cstdio> void make_string(const char * const str, std::string & out_string) { out_string = str; } int main() { const char * a = NULL; std::string str; make_string(a, str); printf("%s\n", str.c_str()); }
next reply other threads:[~2023-02-22 14:31 UTC|newest] Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top 2023-02-22 14:31 jg at jguk dot org [this message] 2023-02-22 15:57 ` [Bug libstdc++/108886] " redi at gcc dot gnu.org 2023-02-26 23:02 ` jg at jguk dot org 2023-02-27 9:23 ` redi at gcc dot gnu.org 2023-03-12 23:03 ` jg at jguk dot org 2023-03-13 10:20 ` redi at gcc dot gnu.org 2023-03-13 10:26 ` redi at gcc dot gnu.org
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=bug-108886-4@http.gcc.gnu.org/bugzilla/ \ --to=gcc-bugzilla@gcc.gnu.org \ --cc=gcc-bugs@gcc.gnu.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).