about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAbseil Team <absl-team@google.com>2019-08-06T14·13-0700
committerCJ Johnson <johnsoncj@google.com>2019-08-06T18·16-0400
commit67222ffc4c83d918ce8395aa61769eeb77df4c4d (patch)
tree6dba7ec72ecc36105c848fc5da5c044a33643e13
parentc5c4db4f5191fe5e76cbf68dcc71fb28702f7d2b (diff)
Export of internal Abseil changes
--
5315e7b98905922e779798f3168d98343438c134 by Derek Mauro <dmauro@google.com>:

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
-rw-r--r--absl/strings/string_view.cc12
-rw-r--r--absl/strings/string_view.h13
-rw-r--r--absl/strings/string_view_test.cc5
3 files changed, 17 insertions, 13 deletions
diff --git a/absl/strings/string_view.cc b/absl/strings/string_view.cc
index cb79d5df7065..dc034a83eea8 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 65b1772de747..25a4d1edeafe 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 2380e1a377a3..22d43536be55 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