-
Notifications
You must be signed in to change notification settings - Fork 146
Closed
Description
There's a bug in environment::key_char_traits::move() on Windows:
| return std::move_backward(s2, s2 + n, s1); |
The final parameter should point one-past-the-end of the range to be moved to -- https://en.cppreference.com/w/cpp/algorithm/move_backward
The correct code is:
return std::move_backward(s2, s2 + n, s1 + n);Analysis
I saw segfaults when adding elements to a std::unordered_map<env::key, env::value> from an env::key_view/env::value_view
While investigating, I noticed that, occasionally, a newly constructed key would be empty, despite all the parameters looking plausible. I eventually narrowed it down to the use of move_backward when moving the string contents -- the final parameter should point to the end of the range to be moved to.
A minimal demonstration of the underlying problem:
#include <boost/process/v2/environment.hpp>
#include <array>
#include <cassert>
int main() {
std::array<boost::process::v2::environment::key::string_type, 2> arr;
arr[0] = L"def";
arr[1].assign(arr[0].data(), arr[0].size());
assert(arr[1] == L"def");
}In this demonstration:
- The source string at
arr[0]has an address before the destination stringarr[1] - The small string optimization is in effect, so the addresses of the buffers are in the same order as the strings themselves
- Therefore, in
char_traits::move(),s1(dest) is afters2(src) - So the
move_backward()branch is taken move_backward()moves the chars before the start of the destination string, due to the 3rd parameter- Either you get a segfault (due to writing before the start of the string memory), or the assert fails (due to the contents being written before the target string buffer)
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels