diff --git a/CMake/AbseilDll.cmake b/CMake/AbseilDll.cmake index e52d456..358a131 100644 --- a/CMake/AbseilDll.cmake +++ b/CMake/AbseilDll.cmake
@@ -46,8 +46,6 @@ "base/internal/sysinfo.h" "base/internal/thread_identity.cc" "base/internal/thread_identity.h" - "base/internal/throw_delegate.cc" - "base/internal/throw_delegate.h" "base/internal/tracing.cc" "base/internal/tracing.h" "base/internal/tsan_mutex_interface.h"
diff --git a/absl/base/BUILD.bazel b/absl/base/BUILD.bazel index 72f9e24..f95e187 100644 --- a/absl/base/BUILD.bazel +++ b/absl/base/BUILD.bazel
@@ -378,11 +378,9 @@ cc_library( name = "throw_delegate", srcs = [ - "internal/throw_delegate.cc", "throw_delegate.cc", ], hdrs = [ - "internal/throw_delegate.h", "throw_delegate.h", ], copts = ABSL_DEFAULT_COPTS,
diff --git a/absl/base/CMakeLists.txt b/absl/base/CMakeLists.txt index f39a9ae..91a8a58 100644 --- a/absl/base/CMakeLists.txt +++ b/absl/base/CMakeLists.txt
@@ -294,10 +294,8 @@ NAME throw_delegate HDRS - "internal/throw_delegate.h" "throw_delegate.h" SRCS - "internal/throw_delegate.cc" "throw_delegate.cc" COPTS ${ABSL_DEFAULT_COPTS}
diff --git a/absl/base/internal/throw_delegate.cc b/absl/base/internal/throw_delegate.cc deleted file mode 100644 index 337e870..0000000 --- a/absl/base/internal/throw_delegate.cc +++ /dev/null
@@ -1,203 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "absl/base/internal/throw_delegate.h" - -#include <cstdlib> -#include <functional> -#include <new> -#include <stdexcept> - -#include "absl/base/config.h" -#include "absl/base/internal/raw_logging.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace base_internal { - -// NOTE: The exception types, like `std::logic_error`, do not exist on all -// platforms. (For example, the Android NDK does not have them.) -// Therefore, their use must be guarded by `#ifdef` or equivalent. - -void ThrowStdLogicError(const std::string& what_arg) { -#ifdef ABSL_HAVE_EXCEPTIONS - throw std::logic_error(what_arg); -#else - ABSL_RAW_LOG(FATAL, "%s", what_arg.c_str()); - std::abort(); -#endif -} -void ThrowStdLogicError(const char* what_arg) { -#ifdef ABSL_HAVE_EXCEPTIONS - throw std::logic_error(what_arg); -#else - ABSL_RAW_LOG(FATAL, "%s", what_arg); - std::abort(); -#endif -} -void ThrowStdInvalidArgument(const std::string& what_arg) { -#ifdef ABSL_HAVE_EXCEPTIONS - throw std::invalid_argument(what_arg); -#else - ABSL_RAW_LOG(FATAL, "%s", what_arg.c_str()); - std::abort(); -#endif -} -void ThrowStdInvalidArgument(const char* what_arg) { -#ifdef ABSL_HAVE_EXCEPTIONS - throw std::invalid_argument(what_arg); -#else - ABSL_RAW_LOG(FATAL, "%s", what_arg); - std::abort(); -#endif -} - -void ThrowStdDomainError(const std::string& what_arg) { -#ifdef ABSL_HAVE_EXCEPTIONS - throw std::domain_error(what_arg); -#else - ABSL_RAW_LOG(FATAL, "%s", what_arg.c_str()); - std::abort(); -#endif -} -void ThrowStdDomainError(const char* what_arg) { -#ifdef ABSL_HAVE_EXCEPTIONS - throw std::domain_error(what_arg); -#else - ABSL_RAW_LOG(FATAL, "%s", what_arg); - std::abort(); -#endif -} - -void ThrowStdLengthError(const std::string& what_arg) { -#ifdef ABSL_HAVE_EXCEPTIONS - throw std::length_error(what_arg); -#else - ABSL_RAW_LOG(FATAL, "%s", what_arg.c_str()); - std::abort(); -#endif -} -void ThrowStdLengthError(const char* what_arg) { -#ifdef ABSL_HAVE_EXCEPTIONS - throw std::length_error(what_arg); -#else - ABSL_RAW_LOG(FATAL, "%s", what_arg); - std::abort(); -#endif -} - -void ThrowStdOutOfRange(const std::string& what_arg) { -#ifdef ABSL_HAVE_EXCEPTIONS - throw std::out_of_range(what_arg); -#else - ABSL_RAW_LOG(FATAL, "%s", what_arg.c_str()); - std::abort(); -#endif -} -void ThrowStdOutOfRange(const char* what_arg) { -#ifdef ABSL_HAVE_EXCEPTIONS - throw std::out_of_range(what_arg); -#else - ABSL_RAW_LOG(FATAL, "%s", what_arg); - std::abort(); -#endif -} - -void ThrowStdRuntimeError(const std::string& what_arg) { -#ifdef ABSL_HAVE_EXCEPTIONS - throw std::runtime_error(what_arg); -#else - ABSL_RAW_LOG(FATAL, "%s", what_arg.c_str()); - std::abort(); -#endif -} -void ThrowStdRuntimeError(const char* what_arg) { -#ifdef ABSL_HAVE_EXCEPTIONS - throw std::runtime_error(what_arg); -#else - ABSL_RAW_LOG(FATAL, "%s", what_arg); - std::abort(); -#endif -} - -void ThrowStdRangeError(const std::string& what_arg) { -#ifdef ABSL_HAVE_EXCEPTIONS - throw std::range_error(what_arg); -#else - ABSL_RAW_LOG(FATAL, "%s", what_arg.c_str()); - std::abort(); -#endif -} -void ThrowStdRangeError(const char* what_arg) { -#ifdef ABSL_HAVE_EXCEPTIONS - throw std::range_error(what_arg); -#else - ABSL_RAW_LOG(FATAL, "%s", what_arg); - std::abort(); -#endif -} - -void ThrowStdOverflowError(const std::string& what_arg) { -#ifdef ABSL_HAVE_EXCEPTIONS - throw std::overflow_error(what_arg); -#else - ABSL_RAW_LOG(FATAL, "%s", what_arg.c_str()); - std::abort(); -#endif -} -void ThrowStdOverflowError(const char* what_arg) { -#ifdef ABSL_HAVE_EXCEPTIONS - throw std::overflow_error(what_arg); -#else - ABSL_RAW_LOG(FATAL, "%s", what_arg); - std::abort(); -#endif -} - -void ThrowStdUnderflowError(const std::string& what_arg) { -#ifdef ABSL_HAVE_EXCEPTIONS - throw std::underflow_error(what_arg); -#else - ABSL_RAW_LOG(FATAL, "%s", what_arg.c_str()); - std::abort(); -#endif -} -void ThrowStdUnderflowError(const char* what_arg) { -#ifdef ABSL_HAVE_EXCEPTIONS - throw std::underflow_error(what_arg); -#else - ABSL_RAW_LOG(FATAL, "%s", what_arg); - std::abort(); -#endif -} - -void ThrowStdBadFunctionCall() { -#ifdef ABSL_HAVE_EXCEPTIONS - throw std::bad_function_call(); -#else - std::abort(); -#endif -} - -void ThrowStdBadAlloc() { -#ifdef ABSL_HAVE_EXCEPTIONS - throw std::bad_alloc(); -#else - std::abort(); -#endif -} - -} // namespace base_internal -ABSL_NAMESPACE_END -} // namespace absl
diff --git a/absl/base/internal/throw_delegate.h b/absl/base/internal/throw_delegate.h deleted file mode 100644 index 075f527..0000000 --- a/absl/base/internal/throw_delegate.h +++ /dev/null
@@ -1,75 +0,0 @@ -// -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -#ifndef ABSL_BASE_INTERNAL_THROW_DELEGATE_H_ -#define ABSL_BASE_INTERNAL_THROW_DELEGATE_H_ - -#include <string> - -#include "absl/base/config.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace base_internal { - -// Helper functions that allow throwing exceptions consistently from anywhere. -// The main use case is for header-based libraries (eg templates), as they will -// be built by many different targets with their own compiler options. -// In particular, this will allow a safe way to throw exceptions even if the -// caller is compiled with -fno-exceptions. This is intended for implementing -// things like map<>::at(), which the standard documents as throwing an -// exception on error. -// -// Using other techniques like #if tricks could lead to ODR violations. -// -// You shouldn't use it unless you're writing code that you know will be built -// both with and without exceptions and you need to conform to an interface -// that uses exceptions. - -[[noreturn]] void ThrowStdLogicError(const std::string& what_arg); -[[noreturn]] void ThrowStdLogicError(const char* what_arg); -[[noreturn]] void ThrowStdInvalidArgument(const std::string& what_arg); -[[noreturn]] void ThrowStdInvalidArgument(const char* what_arg); -[[noreturn]] void ThrowStdDomainError(const std::string& what_arg); -[[noreturn]] void ThrowStdDomainError(const char* what_arg); -[[noreturn]] void ThrowStdLengthError(const std::string& what_arg); -[[noreturn]] void ThrowStdLengthError(const char* what_arg); -[[noreturn]] void ThrowStdOutOfRange(const std::string& what_arg); -[[noreturn]] void ThrowStdOutOfRange(const char* what_arg); -[[noreturn]] void ThrowStdRuntimeError(const std::string& what_arg); -[[noreturn]] void ThrowStdRuntimeError(const char* what_arg); -[[noreturn]] void ThrowStdRangeError(const std::string& what_arg); -[[noreturn]] void ThrowStdRangeError(const char* what_arg); -[[noreturn]] void ThrowStdOverflowError(const std::string& what_arg); -[[noreturn]] void ThrowStdOverflowError(const char* what_arg); -[[noreturn]] void ThrowStdUnderflowError(const std::string& what_arg); -[[noreturn]] void ThrowStdUnderflowError(const char* what_arg); - -[[noreturn]] void ThrowStdBadFunctionCall(); -[[noreturn]] void ThrowStdBadAlloc(); - -// ThrowStdBadArrayNewLength() cannot be consistently supported because -// std::bad_array_new_length is missing in libstdc++ until 4.9.0. -// https://gcc.gnu.org/onlinedocs/gcc-4.8.3/libstdc++/api/a01379_source.html -// https://gcc.gnu.org/onlinedocs/gcc-4.9.0/libstdc++/api/a01327_source.html -// libcxx (as of 3.2) and msvc (as of 2015) both have it. -// [[noreturn]] void ThrowStdBadArrayNewLength(); - -} // namespace base_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_BASE_INTERNAL_THROW_DELEGATE_H_
diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h index a123ebd..8e27bbb 100644 --- a/absl/container/internal/raw_hash_set.h +++ b/absl/container/internal/raw_hash_set.h
@@ -441,24 +441,16 @@ // It is big enough to ensure non-determinism of iteration order. // We store the seed inside a uint64_t together with size and other metadata. // Using 16 bits allows us to save one `and` instruction in H1 (we use - // sign-extended move instead of mov+and). + // zero-extended move instead of mov+and). When absl::Hash is inlined, it can + // also have lower latency knowing that the high bits of the seed are zero. static constexpr size_t kBitCount = 16; - static constexpr size_t kSignBit = uint64_t{1} << (kBitCount - 1); // Returns the seed for the table. - size_t seed() const { - // We use a sign-extended load to ensure high bits are non-zero. - int16_t seed_signed = absl::bit_cast<int16_t>(seed_); - auto seed_sign_extended = - static_cast<std::make_signed_t<size_t>>(seed_signed); - return absl::bit_cast<size_t>(seed_sign_extended); - } + size_t seed() const { return seed_; } private: friend class HashtableSize; - explicit PerTableSeed(uint16_t seed) : seed_(seed) { - ABSL_SWISSTABLE_ASSERT((seed & kSignBit) != 0 || seed == 0); - } + explicit PerTableSeed(uint16_t seed) : seed_(seed) {} // The most significant bit of the seed is always 1 when there is a non-zero // seed. This way, when sign-extended the seed has non-zero high bits. @@ -496,10 +488,10 @@ // We need to use a constant seed when the table is sampled so that sampled // hashes use the same seed and can e.g. identify stuck bits accurately. - void set_sampled_seed() { set_seed(PerTableSeed::kSignBit); } + void set_sampled_seed() { set_seed((std::numeric_limits<uint16_t>::max)()); } bool is_sampled_seed() const { - return (data_ & kSeedMask) == PerTableSeed::kSignBit; + return (data_ & kSeedMask) == (std::numeric_limits<uint16_t>::max)(); } // Returns true if the table has infoz. @@ -516,9 +508,7 @@ static uint16_t NextSeed(); private: - void set_seed(uint16_t seed) { - data_ = (data_ & ~kSeedMask) | (seed | PerTableSeed::kSignBit); - } + void set_seed(uint16_t seed) { data_ = (data_ & ~kSeedMask) | seed; } static constexpr size_t kSizeShift = 64 - kSizeBitCount; static constexpr uint64_t kSizeOneNoMetadata = uint64_t{1} << kSizeShift; static constexpr uint64_t kMetadataMask = kSizeOneNoMetadata - 1;
diff --git a/absl/container/internal/raw_hash_set_test.cc b/absl/container/internal/raw_hash_set_test.cc index 0b5ad8f..7136691 100644 --- a/absl/container/internal/raw_hash_set_test.cc +++ b/absl/container/internal/raw_hash_set_test.cc
@@ -4168,16 +4168,6 @@ EXPECT_EQ(t.capacity(), kTargetCapacity); } -// Test that after calling generate_new_seed(), the high bits of the returned -// seed are non-zero. -TEST(PerTableSeed, HighBitsAreNonZero) { - HashtableSize hs(no_seed_empty_tag_t{}); - for (int i = 0; i < 100; ++i) { - hs.generate_new_seed(); - ASSERT_GT(hs.seed().seed() >> 16, 0); - } -} - } // namespace } // namespace container_internal ABSL_NAMESPACE_END
diff --git a/absl/hash/internal/hash.h b/absl/hash/internal/hash.h index ea04f47..4fe474e 100644 --- a/absl/hash/internal/hash.h +++ b/absl/hash/internal/hash.h
@@ -1060,10 +1060,46 @@ return mem0 | mem1; } +#ifdef ABSL_HASH_INTERNAL_HAS_CRC32 + +ABSL_ATTRIBUTE_ALWAYS_INLINE inline uint64_t CombineRawImpl(uint64_t state, + uint64_t value) { + // We use a union to access the high and low 32 bits of the state. + union { + uint64_t u64; + struct { +#ifdef ABSL_IS_LITTLE_ENDIAN + uint32_t low, high; +#else // big endian + uint32_t high, low; +#endif + } u32s; + } s; + s.u64 = state; + // The general idea here is to do two CRC32 operations in parallel using the + // low and high 32 bits of state as CRC states. Note that: (1) when absl::Hash + // is inlined into swisstable lookups, we know that the seed's high bits are + // zero so s.u32s.high is available immediately. (2) We chose to rotate value + // right by 45 for the low CRC because that minimizes the probe benchmark + // geomean across the 64 possible rotations. (3) The union makes it easy for + // the compiler to understand that the high and low CRC states are independent + // from each other so that when CombineRawImpl is repeated (e.g. for + // std::pair<size_t, size_t>), the CRC chains can run in parallel. We + // originally tried using bswaps rather than shifting by 32 bits (to get from + // high to low bits) because bswap is one byte smaller in code size, but the + // compiler couldn't understand that the CRC chains were independent. + s.u32s.high = + static_cast<uint32_t>(ABSL_HASH_INTERNAL_CRC32_U64(s.u32s.high, value)); + s.u32s.low = static_cast<uint32_t>( + ABSL_HASH_INTERNAL_CRC32_U64(s.u32s.low, absl::rotr(value, 45))); + return s.u64; +} +#else // ABSL_HASH_INTERNAL_HAS_CRC32 ABSL_ATTRIBUTE_ALWAYS_INLINE inline uint64_t CombineRawImpl(uint64_t state, uint64_t value) { return Mix(state ^ value, kMul); } +#endif // ABSL_HASH_INTERNAL_HAS_CRC32 // Slow dispatch path for calls to CombineContiguousImpl with a size argument // larger than inlined size. Has the same effect as calling
diff --git a/absl/strings/escaping.cc b/absl/strings/escaping.cc index 228e527..9f887b8 100644 --- a/absl/strings/escaping.cc +++ b/absl/strings/escaping.cc
@@ -179,14 +179,17 @@ absl::ascii_isxdigit(static_cast<unsigned char>(src[p + 1]))) { // Arbitrarily many hex digits ch = (ch << 4) + hex_digit_to_int(src[++p]); - } - if (ch > 0xFF) { - if (error != nullptr) { - *error = "Value of \\" + - std::string(src.substr(hex_start, p + 1 - hex_start)) + - " exceeds 0xff"; + // If ch was 0xFF at the start of this loop, the most can it can be + // here is (0xFF << 4) + 0xF, which is 4095, thus ch cannot overflow + // 32-bits here. The check below is sufficient. + if (ch > 0xFF) { + if (error != nullptr) { + *error = "Value of \\" + + std::string(src.substr(hex_start, p + 1 - hex_start)) + + " exceeds 0xff"; + } + return false; } - return false; } if ((ch == 0) && leave_nulls_escaped) { // Copy the escape sequence for the null character
diff --git a/absl/strings/escaping_test.cc b/absl/strings/escaping_test.cc index 08618aa..cb9e37f 100644 --- a/absl/strings/escaping_test.cc +++ b/absl/strings/escaping_test.cc
@@ -170,22 +170,23 @@ EXPECT_EQ(out, val.unescaped); } constexpr absl::string_view bad[] = { - "\\u1", // too short - "\\U1", // too short - "\\Uffffff", // exceeds 0x10ffff (largest Unicode) - "\\U00110000", // exceeds 0x10ffff (largest Unicode) - "\\uD835", // surrogate character (D800-DFFF) - "\\U0000DD04", // surrogate character (D800-DFFF) - "\\777", // exceeds 0xff - "\\xABCD", // exceeds 0xff - "endswith\\", // ends with "\" - "endswith\\x", // ends with "\x" - "endswith\\X", // ends with "\X" - "\\x.2345678", // non-hex follows "\x" - "\\X.2345678", // non-hex follows "\X" - "\\u.2345678", // non-hex follows "\U" - "\\U.2345678", // non-hex follows "\U" - "\\.unknown", // unknown escape sequence + "\\u1", // too short + "\\U1", // too short + "\\Uffffff", // exceeds 0x10ffff (largest Unicode) + "\\U00110000", // exceeds 0x10ffff (largest Unicode) + "\\uD835", // surrogate character (D800-DFFF) + "\\U0000DD04", // surrogate character (D800-DFFF) + "\\777", // exceeds 0xff + "\\xABCD", // exceeds 0xff + "\\x100000041", // overflows uint32_t + "endswith\\", // ends with "\" + "endswith\\x", // ends with "\x" + "endswith\\X", // ends with "\X" + "\\x.2345678", // non-hex follows "\x" + "\\X.2345678", // non-hex follows "\X" + "\\u.2345678", // non-hex follows "\U" + "\\U.2345678", // non-hex follows "\U" + "\\.unknown", // unknown escape sequence }; for (const auto e : bad) { std::string error;
diff --git a/absl/time/format_test.cc b/absl/time/format_test.cc index a9a1eb8..0e145a8 100644 --- a/absl/time/format_test.cc +++ b/absl/time/format_test.cc
@@ -245,6 +245,11 @@ EXPECT_THAT(err, HasSubstr("Illegal trailing data")); EXPECT_FALSE(absl::ParseTime("%Ez", "-00:-0", &t, &err)) << err; EXPECT_THAT(err, HasSubstr("Illegal trailing data")); + + // Check that we do not accept strings with embedded NULs. + EXPECT_FALSE( + absl::ParseTime("%Y", std::string("2026\0payload", 12), &t, &err)); + EXPECT_THAT(err, HasSubstr("Illegal trailing data")); } TEST(ParseTime, ExtendedSeconds) {
diff --git a/absl/time/internal/cctz/src/time_zone_format.cc b/absl/time/internal/cctz/src/time_zone_format.cc index 5b80c80..c31a3a0 100644 --- a/absl/time/internal/cctz/src/time_zone_format.cc +++ b/absl/time/internal/cctz/src/time_zone_format.cc
@@ -978,7 +978,7 @@ while (std::isspace(*data)) ++data; // parse() must consume the entire input string. - if (*data != '\0') { + if (data != input.data() + input.size()) { if (err != nullptr) *err = "Illegal trailing data in input string"; return false; }
diff --git a/absl/time/internal/cctz/src/time_zone_format_test.cc b/absl/time/internal/cctz/src/time_zone_format_test.cc index a270f4d..19dc973 100644 --- a/absl/time/internal/cctz/src/time_zone_format_test.cc +++ b/absl/time/internal/cctz/src/time_zone_format_test.cc
@@ -967,6 +967,9 @@ EXPECT_FALSE(parse("%Ez", "+-0:00", tz, &tp)); EXPECT_FALSE(parse("%z", "-00-0", tz, &tp)); EXPECT_FALSE(parse("%Ez", "-00:-0", tz, &tp)); + + // Check that we do not accept strings with embedded NULs. + EXPECT_FALSE(parse("%Y", std::string("2026\0payload", 12), tz, &tp)); } TEST(Parse, PosixConversions) {