Details
- Reviewers
philnik pfusik - Group Reviewers
Restricted Project - Commits
- rGd6a92611ebb5: [libc++] Improve the tests for std::basic_stringbuf's constructors and…
Diff Detail
- Repository
- rG LLVM Github Monorepo
Unit Tests
Event Timeline
This fixes use-after-moves spotted by @Mordante in https://reviews.llvm.org/D151896#inline-1482124
The pointers are now set to null, same as in the default constructor of stringbuf.
I am quite certain that basic_stringbuf has to be in a valid but unspecified state, meaning that you can't just check that the pointer are null. You have to find a way to exploit the issue without directly testing the values. For example, would the moved-to buffer get touched when writing to the moved-from stringbuf (or some other operation)?
libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.assign/move.pass.cpp | ||
---|---|---|
64–68 | Thanks for improving the coverage here BTW. |
@philnik Are the tests for libc++ or the C++ standard? The former does specify the state.
Before this change, the pointers were pointing to the string *after* the move, i.e. an empty string. I don't understand what would you like to test here?
Thanks for working on this!
tests in the directory test/std are for the C++ standard. You can use LIBCPP_ASSERT for libc++ specific asserts.
tests in the directory test/libcxx are always libc++ specific tests.
Interesting. IIUC the buffer has to be empty after a move. We can test for that, but it looks to me like that's already the case with the old code. Since you claim that this is a bug fix, this has to be observable in some way by the user without checking for unspecified behavior. Otherwise this is basically an NFC without any reasoning for why the new code is better. It actually looks to me like the old code is correct.
@Mordante You pointed this as a problem in https://reviews.llvm.org/D151896#inline-1482124 Could you please explain? Now I'm confused myself.
BTW. Was stringbuf copy-assignable in C++03 ? See https://en.cppreference.com/w/cpp/io/basic_stringbuf/operator%3D
Commandeering to finish for the GH PR transition.
After consideration, I think our current tests are lacking a bit but there is no risk of use-after-move. Indeed, when we set __p = const_cast<char_type*>(__rhs.__str_.data());, __p is:
- nullptr if the string was not using SSO, because it was moved-out-from above in __str_ = _VSTD::move(__rhs.__str_);
- a pointer to the start of the SSO inside __rhs.__str_ if the string was using SSO
Either way, we are not reusing the storage incorrectly. I will commandeer and fix the tests, but I think our current implementation is fine.
Thanks for improving the coverage here BTW.