[PATCH] Ensure std::getline always 0-terminates string.
Volodymyr Sapsai via cfe-commits
cfe-commits at lists.llvm.org
Mon Nov 20 11:02:13 PST 2017
On Nov 19, 2017, at 08:07, Reimar Döffinger <Reimar.Doeffinger at gmx.de> wrote:
>
> On Wed, Nov 15, 2017 at 11:35:56AM -0800, Volodymyr Sapsai wrote:
>> On Nov 12, 2017, at 12:37, Reimar Döffinger <Reimar.Doeffinger at gmx.de> wrote:
>> libc++ can be built with exceptions enabled or disabled (see LIBCXX_ENABLE_EXCEPTIONS <http://libcxx.llvm.org/docs/BuildingLibcxx.html#cmdoption-arg-libcxx-enable-exceptions>) and we need to support both configurations. The problem with your _LIBCPP_NO_EXCEPTIONS approach is that it won't work when exceptions are disabled. Various exception-related tests are usually guarded with TEST_HAS_NO_EXCEPTIONS macro defined in “test_macros.h”. You can check other tests for examples of TEST_HAS_NO_EXCEPTIONS usage, I had in mind something like
>>
>> #ifndef TEST_HAS_NO_EXCEPTIONS
>> {
>> testbuf<char> sb(" ");
>> std::istream is(&sb);
>> char s[5] = "test";
>> is.exceptions(std::istream::eofbit | std::istream::badbit);
>> try
>> {
>> is.getline(s, 5);
>> assert(false);
>
> That doesn't make sense to me, the whole point is to test the
> code-path in getline that swallows the exception.
> So if you meant for that assert to be there, you're
> not trying to test what I am trying to test.
> Note that the intent is not to ensure 0-termination
> when getline actually exits via an exception, I doubt
> that would be safe to do really (except maybe at the start
> of the loop before the code that might trigger an exception,
> but that would cost performance) and anyway code
> handling exceptions can be expected to not make assumptions
> that the result is in a "safe" state.
> The problem is when the code just swallows the exception
> (when exceptions are disabled, presumably for interoperability
> with code compiled with exceptions enabled? There is no documentation
> why getline catches exceptions when they are disabled),
> then I think the only reasonable choice is to 0-terminate,
> even if it is risky.
> Looking at the other tests it seems that generally functionality
> simply isn't tested at all when exceptions are disabled
> (e.g. stoul.pass.cpp), which seems unfortunate.
> That level of testing is easy to achieve here as well,
> just leave out the test file I added.
> If you want it though, I updated it to not fail (though
> not actually test anything either) if exceptions are
> disabled, and added a comment on what a huge hack it is
> (as the code-path for disabled exceptions is tested if and
> only if exceptions are actually enabled).
> <0001-Ensure-std-istream-getline-always-0-terminates-strin.patch>
I got confused here. When you mention "code path for disabled exceptions”, what exactly code do you have in mind? Is that
> - if (__n > 0)
> - *__s = char_type();
> if (__gc_ == 0)
> __err |= ios_base::failbit;
> this->setstate(__err);
> }
> + if (__n > 0)
> + *__s = char_type();
or
> catch (...)
> {
> + if (__n > 0)
> + *__s = char_type();
> this->__set_badbit_and_consider_rethrow();
> }
or maybe something else?
More information about the cfe-commits
mailing list