summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--BUILD.gn1
-rw-r--r--core/fxcrt/pdfium_span_unittest.cpp30
-rw-r--r--core/fxcrt/unowned_ptr.h15
-rw-r--r--third_party/base/span.h13
4 files changed, 56 insertions, 3 deletions
diff --git a/BUILD.gn b/BUILD.gn
index 6dc1de38ee..36ee859264 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -2905,6 +2905,7 @@ test("pdfium_unittests") {
"core/fxcrt/fx_system_unittest.cpp",
"core/fxcrt/maybe_owned_unittest.cpp",
"core/fxcrt/observable_unittest.cpp",
+ "core/fxcrt/pdfium_span_unittest.cpp",
"core/fxcrt/retain_ptr_unittest.cpp",
"core/fxcrt/shared_copy_on_write_unittest.cpp",
"core/fxcrt/string_pool_template_unittest.cpp",
diff --git a/core/fxcrt/pdfium_span_unittest.cpp b/core/fxcrt/pdfium_span_unittest.cpp
new file mode 100644
index 0000000000..177bc4097e
--- /dev/null
+++ b/core/fxcrt/pdfium_span_unittest.cpp
@@ -0,0 +1,30 @@
+// Copyright 2018 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/base/span.h"
+#include "third_party/base/stl_util.h"
+
+// Tests PDFium-modifications to base::span. The name of this file is
+// chosen to avoid collisions with base's span_unittest.cc
+
+TEST(PdfiumSpan, EmptySpan) {
+ int stuff[] = {1, 2, 3};
+ pdfium::span<int> stuff_span(stuff);
+ pdfium::span<int> empty_first_span = stuff_span.first(0);
+ pdfium::span<int> empty_last_span = stuff_span.last(0);
+ pdfium::span<int> empty_sub_span1 = stuff_span.subspan(0, 0);
+ pdfium::span<int> empty_sub_span2 = stuff_span.subspan(3, 0);
+ EXPECT_TRUE(empty_first_span.empty());
+ EXPECT_TRUE(empty_last_span.empty());
+ EXPECT_TRUE(empty_sub_span1.empty());
+ EXPECT_TRUE(empty_sub_span2.empty());
+}
+
+TEST(PdfiumSpan, EmptySpanDeath) {
+ int stuff[] = {1, 2, 3};
+ pdfium::span<int> stuff_span(stuff);
+ pdfium::span<int> empty_span = stuff_span.last(0);
+ EXPECT_DEATH(empty_span[0] += 1, ".*");
+}
diff --git a/core/fxcrt/unowned_ptr.h b/core/fxcrt/unowned_ptr.h
index 0e3bf9e09b..0a44f9db52 100644
--- a/core/fxcrt/unowned_ptr.h
+++ b/core/fxcrt/unowned_ptr.h
@@ -35,6 +35,13 @@
// other heap object. Use pdfium::span<> for the cases where indexing
// into an unowned array is desired, which performs the same checks.
+namespace pdfium {
+
+template <typename T>
+class span;
+
+} // namespace pdfium
+
namespace fxcrt {
template <class T>
@@ -95,6 +102,8 @@ class UnownedPtr {
T* operator->() const { return m_pObj; }
private:
+ friend class pdfium::span<T>;
+
inline void ProbeForLowSeverityLifetimeIssue() {
#if defined(MEMORY_TOOL_REPLACES_ALLOCATOR)
if (m_pObj)
@@ -102,6 +111,12 @@ class UnownedPtr {
#endif
}
+ inline void ReleaseBadPointer() {
+#if defined(MEMORY_TOOL_REPLACES_ALLOCATOR)
+ m_pObj = nullptr;
+#endif
+ }
+
T* m_pObj = nullptr;
};
diff --git a/third_party/base/span.h b/third_party/base/span.h
index 034c6a35e7..0fb627ba8c 100644
--- a/third_party/base/span.h
+++ b/third_party/base/span.h
@@ -195,6 +195,7 @@ class span {
// [span.cons], span constructors, copy, assignment, and destructor
constexpr span() noexcept : data_(nullptr), size_(0) {}
constexpr span(T* data, size_t size) noexcept : data_(data), size_(size) {}
+
// TODO(dcheng): Implement construction from a |begin| and |end| pointer.
template <size_t N>
constexpr span(T (&array)[N]) noexcept : span(array, N) {}
@@ -215,12 +216,18 @@ class span {
template <typename U, typename = internal::EnableIfLegalSpanConversion<U, T>>
constexpr span(const span<U>& other) : span(other.data(), other.size()) {}
span& operator=(const span& other) noexcept = default;
- ~span() noexcept = default;
+ ~span() noexcept {
+ if (!size_) {
+ // Empty spans might point to byte N+1 of a N-byte object, legal for
+ // C pointers but not UnownedPtrs.
+ data_.ReleaseBadPointer();
+ }
+ }
// [span.sub], span subviews
const span first(size_t count) const {
CHECK(count <= size_);
- return span(data_, count);
+ return span(data_.Get(), count);
}
const span last(size_t count) const {
@@ -240,7 +247,7 @@ class span {
constexpr bool empty() const noexcept { return size_ == 0; }
// [span.elem], span element access
- const T& operator[](size_t index) const noexcept {
+ T& operator[](size_t index) const noexcept {
CHECK(index < size_);
return data_.Get()[index];
}