#11150 closed Bugs (fixed)
string_ref::to_string is necessarily UB for a default-constructed string_ref, despite stating no preconditions
Reported by: | Tomalak Geret'kal | Owned by: | No-Maintainer |
---|---|---|---|
Milestone: | To Be Determined | Component: | utility |
Version: | Boost 1.57.0 | Severity: | Problem |
Keywords: | Cc: |
Description
Consider:
boost::string_ref foo; auto bar = foo.to_string();
As currently specified (to_string
is not documented but in the code it seems to share the semantics of explicit string conversion, which is defined by the reference material, N3442), this invokes std::string::string(nullptr, 0)
, which has UB because one of the preconditions of that std::string
constructor is that the pointer not be nullptr
or NULL
... and default-constructing boost::string_ref
indeed sets the relevant pointer to NULL
.
This has been fixed in newer versions of the proposal, e.g. by N3762 (seemingly accidentally):
Returns:
basic_string<charT, traits, Allocator>(str.begin(), str.end(), a)
Boost.StringRef should be updated to make the same change, otherwise invoking .to_string()
on a default-constructed boost::to_string
has undefined behaviour, despite there being no preconditions specified on .to_string()
.
Alternatively it could be documented that .to_string()
's precondition is that the string_ref
actually refers to a string.
(Thanks to Mgetz and Luc Danton on Stack Overflow for help identifying this bug.)
(I tried to link to references but Trac thought I was a spammer and the Captcha did not show up.)
Change History (4)
comment:1 by , 8 years ago
comment:2 by , 8 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
Committed 13610caa36edcae896f59246a2933ef4772690f4 to fix this.
comment:3 by , 8 years ago
I disagree. There is such a thing as an array of [at least] 0 elements of charT
:
char* ptr = new char[0]; delete[] ptr;
and a NULL pointer cannot ever point to such an array. It doesn't point to anything.
comment:4 by , 8 years ago
Thanks for fixing, anyway. :)
(Please note that, as you can see, I'm having real difficulty with Trac at the moment. Submissions take a good minute and one appeared to fail but then apparently succeeded. And led to two "comment 3"s?!)
Interestingly enough, this section of the standard
[string.cons]
has changed over time.Specifically the bit about this constructor:
C++03 and C++11 have the following requirement: "Requires: s shall not be a null pointer and n < npos"
C++14 says instead: "Requires: s points to an array of at least n elements of charT."
{ NULL, 0 }
is allowable in the second case, but not in the first.