From e1ffb147787ac37d003c60519a7e859a80f89b1f Mon Sep 17 00:00:00 2001 From: gVisor bot Date: Sat, 23 Mar 2024 05:53:58 -0700 Subject: [PATCH] Restore errno around allocation in test matchers Allocation are not guaranteed to preserve errno, even in case of success. Because the test matchers test against errno, preserve errno when allocating new matchers. PiperOrigin-RevId: 618437007 --- test/util/test_util.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/test/util/test_util.h b/test/util/test_util.h index 7421c0e0c..3ad324ebe 100644 --- a/test/util/test_util.h +++ b/test/util/test_util.h @@ -292,6 +292,20 @@ inline uint64_t ms_elapsed(const struct timespec& begin, namespace internal { +// RAII class to restore errno. Used because malloc/new are not guaranteed to +// preserve errno. +class ErrnoRestorer { + public: + ErrnoRestorer() : saved_errno_(errno) {} + ~ErrnoRestorer() { errno = saved_errno_; } + + ErrnoRestorer(const ErrnoRestorer&) = delete; + ErrnoRestorer& operator=(const ErrnoRestorer&) = delete; + + private: + int saved_errno_; +}; + template class ElementOfMatcher { public: @@ -337,6 +351,8 @@ class SyscallSuccessMatcher { template operator ::testing::Matcher() const { + ErrnoRestorer errno_restorer; + // E is one of three things: // - T, or a type losslessly and implicitly convertible to T. // - A monomorphic Matcher. @@ -393,6 +409,7 @@ class AnySuccessValueMatcher { public: template operator ::testing::Matcher() const { + ErrnoRestorer errno_restorer; return ::testing::MakeMatcher(new Impl()); } @@ -473,6 +490,7 @@ class SpecificErrnoMatcher : public ::testing::MatcherInterface { }; inline ::testing::Matcher SpecificErrno(int const expected) { + ErrnoRestorer errno_restorer; return ::testing::MakeMatcher(new SpecificErrnoMatcher(expected)); }