[libcxx-commits] [PATCH] D57761: [libc++] Avoid UB in the no-exceptions mode in a few places
Louis Dionne via Phabricator via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Feb 5 09:30:45 PST 2019
ldionne marked 12 inline comments as done.
ldionne added a comment.
Here's the justification for changes in this patch.
================
Comment at: libcxx/include/unordered_map:1606
if (__i == end())
- throw out_of_range("unordered_map::at: key not found");
-#endif // _LIBCPP_NO_EXCEPTIONS
+ __throw_out_of_range("unordered_map::at: key not found");
return __i->second;
----------------
Justification: If we don't `abort()`, we dereference `__i` below, which is a past-the-end iterator.
================
Comment at: libcxx/include/unordered_map:1616
if (__i == end())
- throw out_of_range("unordered_map::at: key not found");
-#endif // _LIBCPP_NO_EXCEPTIONS
+ __throw_out_of_range("unordered_map::at: key not found");
return __i->second;
----------------
Ditto.
================
Comment at: libcxx/src/hash.cpp:179
// Check for overflow
__check_for_overflow(n);
// Start searching list of potential primes: L * k0 + indices[in]
----------------
I guess nothing good happens if we keep going after `n` has overflown, but TBH I haven't done a deep analysis of this one.
================
Comment at: libcxx/src/ios.cpp:271
if (((state | (__rdbuf_ ? goodbit : badbit)) & __exceptions_) != 0)
- throw failure("ios_base::clear");
-#endif // _LIBCPP_NO_EXCEPTIONS
+ __throw_failure("ios_base::clear");
}
----------------
Actually, looking at this again, it seems like we probably don't want to abort here, since the stream will report the error with the error flags. So I should not change this one -- @mclow.lists does that seem right to you?
================
Comment at: libcxx/src/ios.cpp:312
if (!new_callbacks)
- throw bad_alloc();
-#endif // _LIBCPP_NO_EXCEPTIONS
+ __throw_bad_alloc();
----------------
Justification: If we don't `abort()` when `new_callbacks` is null, we assign `new_callbacks` to `__fn_` on line 343 and we then access `__fn[__event_size]` on line 350, which is UB.
================
Comment at: libcxx/src/ios.cpp:317
if (!new_ints)
- throw bad_alloc();
-#endif // _LIBCPP_NO_EXCEPTIONS
+ __throw_bad_alloc();
}
----------------
Ditto.
================
Comment at: libcxx/src/ios.cpp:324
if (!new_longs)
- throw bad_alloc();
-#endif // _LIBCPP_NO_EXCEPTIONS
+ __throw_bad_alloc();
}
----------------
Ditto.
================
Comment at: libcxx/src/ios.cpp:331
if (!new_pointers)
- throw bad_alloc();
-#endif // _LIBCPP_NO_EXCEPTIONS
+ __throw_bad_alloc();
}
----------------
Ditto.
================
Comment at: libcxx/src/ios.cpp:350
{
__fn_[__event_size_] = rhs.__fn_[__event_size_];
__index_[__event_size_] = rhs.__index_[__event_size_];
----------------
UB here if `new_callbacks` is null and we don't `abort()`.
================
Comment at: libcxx/src/locale.cpp:472
if (!has_facet(id))
- throw bad_cast();
-#endif // _LIBCPP_NO_EXCEPTIONS
+ __throw_bad_cast();
return facets_[static_cast<size_t>(id)];
----------------
Justification: If we don't `abort()`, we will access `facets_` at an out-of-bounds index `id`. The check `has_facet(id)` roughly checks whether `id` is in bound for `facets_`.
================
Comment at: libcxx/src/locale.cpp:539
: __locale_(name ? new __imp(name)
- : throw runtime_error("locale constructed with null"))
-#else // _LIBCPP_NO_EXCEPTIONS
- : __locale_(new __imp(name))
-#endif
+ : (__throw_runtime_error("locale constructed with null"), (__imp*)0))
{
----------------
Justification: If we don't `abort()`, we create the `std::string` member `name_` inside `__imp` from the `name` parameter (which is null). It's UB to construct a `std::string` from a null `char const*`.
================
Comment at: libcxx/src/locale.cpp:552
: __locale_(name ? new __imp(*other.__locale_, name, c)
- : throw runtime_error("locale constructed with null"))
-#else // _LIBCPP_NO_EXCEPTIONS
- : __locale_(new __imp(*other.__locale_, name, c))
-#endif
+ : (__throw_runtime_error("locale constructed with null"), (__imp*)0))
{
----------------
Ditto.
Repository:
rCXX libc++
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D57761/new/
https://reviews.llvm.org/D57761
More information about the libcxx-commits
mailing list