From 67222ffc4c83d918ce8395aa61769eeb77df4c4d Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Tue, 6 Aug 2019 07:13:35 -0700 Subject: Export of internal Abseil changes -- 5315e7b98905922e779798f3168d98343438c134 by Derek Mauro : Fix absl::string_view::copy to throw std::out_of_range when pos > size(). Fixes https://github.com/abseil/abseil-cpp/issues/362 PiperOrigin-RevId: 261907364 GitOrigin-RevId: 5315e7b98905922e779798f3168d98343438c134 Change-Id: Ia8ab971c54f287411f6ea4b99f9c666c989c33fd --- absl/strings/string_view.cc | 12 ------------ absl/strings/string_view.h | 13 ++++++++++++- absl/strings/string_view_test.cc | 5 +++++ 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/absl/strings/string_view.cc b/absl/strings/string_view.cc index cb79d5df..dc034a83 100644 --- a/absl/strings/string_view.cc +++ b/absl/strings/string_view.cc @@ -77,18 +77,6 @@ std::ostream& operator<<(std::ostream& o, string_view piece) { return o; } -string_view::size_type string_view::copy(char* buf, size_type n, - size_type pos) const { - size_type ulen = length_; - assert(pos <= ulen); - size_type rlen = std::min(ulen - pos, n); - if (rlen > 0) { - const char* start = ptr_ + pos; - std::copy(start, start + rlen, buf); - } - return rlen; -} - string_view::size_type string_view::find(string_view s, size_type pos) const noexcept { if (empty() || pos > length_) { diff --git a/absl/strings/string_view.h b/absl/strings/string_view.h index 65b1772d..25a4d1ed 100644 --- a/absl/strings/string_view.h +++ b/absl/strings/string_view.h @@ -50,6 +50,7 @@ using std::string_view; #include "absl/base/internal/throw_delegate.h" #include "absl/base/macros.h" +#include "absl/base/optimization.h" #include "absl/base/port.h" namespace absl { @@ -334,7 +335,17 @@ class string_view { // // Copies the contents of the `string_view` at offset `pos` and length `n` // into `buf`. - size_type copy(char* buf, size_type n, size_type pos = 0) const; + size_type copy(char* buf, size_type n, size_type pos = 0) const { + if (ABSL_PREDICT_FALSE(pos > length_)) { + base_internal::ThrowStdOutOfRange("absl::string_view::copy"); + } + size_type rlen = (std::min)(length_ - pos, n); + if (rlen > 0) { + const char* start = ptr_ + pos; + std::copy(start, start + rlen, buf); + } + return rlen; + } // string_view::substr() // diff --git a/absl/strings/string_view_test.cc b/absl/strings/string_view_test.cc index 2380e1a3..22d43536 100644 --- a/absl/strings/string_view_test.cc +++ b/absl/strings/string_view_test.cc @@ -369,6 +369,11 @@ TEST(StringViewTest, STL1) { EXPECT_EQ(buf[1], c[1]); EXPECT_EQ(buf[2], c[2]); EXPECT_EQ(buf[3], a[3]); +#ifdef ABSL_HAVE_EXCEPTIONS + EXPECT_THROW(a.copy(buf, 1, 27), std::out_of_range); +#else + EXPECT_DEATH(a.copy(buf, 1, 27), "absl::string_view::copy"); +#endif } // Separated from STL1() because some compilers produce an overly -- cgit v1.2.3