Commit 160e95dc by Jonathan Wakely Committed by Jonathan Wakely

libstdc++: Fix undefined behaviour in random dist serialization (PR93205)

The deserialization functions for random number distributions fail to
check the stream state before using the extracted values. In some cases
this leads to using indeterminate values to resize a vector, and then
filling that vector with indeterminate values.

No values that affect control flow should be used without checking that a
good value was read from the stream.

Additionally, where reasonable to do so, defer modifying any state in
the distribution until all values have been successfully read, to avoid
modifying some of the distribution's parameters and leaving others
unchanged.

	PR libstdc++/93205
	* include/bits/random.h (operator>>): Check stream operation succeeds.
	* include/bits/random.tcc (operator<<): Remove redundant __ostream_type
	typedefs.
	(operator>>): Remove redundant __istream_type typedefs. Check stream
	operations succeed.
	(__extract_params): New function to fill a vector from a stream.
	* testsuite/26_numerics/random/pr60037-neg.cc: Adjust dg-error line.

From-SVN: r280061
parent 0a09a948
2020-01-09 Jonathan Wakely <jwakely@redhat.com> 2020-01-09 Jonathan Wakely <jwakely@redhat.com>
PR libstdc++/93205
* include/bits/random.h (operator>>): Check stream operation succeeds.
* include/bits/random.tcc (operator<<): Remove redundant __ostream_type
typedefs.
(operator>>): Remove redundant __istream_type typedefs. Check stream
operations succeed.
(__extract_params): New function to fill a vector from a stream.
* testsuite/26_numerics/random/pr60037-neg.cc: Adjust dg-error line.
PR libstdc++/93208 PR libstdc++/93208
* config/abi/pre/gnu.ver: Add new exports. * config/abi/pre/gnu.ver: Add new exports.
* include/std/memory_resource (memory_resource::~memory_resource()): * include/std/memory_resource (memory_resource::~memory_resource()):
......
...@@ -3720,13 +3720,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -3720,13 +3720,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @returns The input stream with @p __x extracted or in an error state. * @returns The input stream with @p __x extracted or in an error state.
*/ */
template<typename _CharT, typename _Traits> template<typename _CharT, typename _Traits>
std::basic_istream<_CharT, _Traits>& inline std::basic_istream<_CharT, _Traits>&
operator>>(std::basic_istream<_CharT, _Traits>& __is, operator>>(std::basic_istream<_CharT, _Traits>& __is,
std::bernoulli_distribution& __x) std::bernoulli_distribution& __x)
{ {
double __p; double __p;
__is >> __p; if (__is >> __p)
__x.param(bernoulli_distribution::param_type(__p)); __x.param(bernoulli_distribution::param_type(__p));
return __is; return __is;
} }
......
...@@ -12,4 +12,4 @@ auto x = std::generate_canonical<std::size_t, ...@@ -12,4 +12,4 @@ auto x = std::generate_canonical<std::size_t,
// { dg-error "static assertion failed: template argument must be a floating point type" "" { target *-*-* } 171 } // { dg-error "static assertion failed: template argument must be a floating point type" "" { target *-*-* } 171 }
// { dg-error "static assertion failed: template argument must be a floating point type" "" { target *-*-* } 3320 } // { dg-error "static assertion failed: template argument must be a floating point type" "" { target *-*-* } 3281 }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment