summaryrefslogtreecommitdiff
path: root/core/fxcrt
diff options
context:
space:
mode:
authorTom Sepez <tsepez@chromium.org>2018-06-19 16:23:52 +0000
committerChromium commit bot <commit-bot@chromium.org>2018-06-19 16:23:52 +0000
commited1c58049f0c164969946b6ad0ff06d952ab1949 (patch)
tree17e62a9ee118f0b5f3485a8929a1a6f15bf9b3db /core/fxcrt
parentc765d2ac867611935cff6b5c5a2ff8575fe85162 (diff)
downloadpdfium-ed1c58049f0c164969946b6ad0ff06d952ab1949.tar.xz
Speculative fix for segv destroying CPDF_PageObjectHolder::m_GraphicsMap
We speculate that the bug that makes the comparison operator irreflexive might be the cause of the segv on windows production code, should a NaN sneak into the GraphicsData struct. In any event, should this happen, the tree won't be correct with some nodes erroneously replaced. Add a test which fails prior to the patch, but alas does not elicit the segv. Also move operator<() methods to .cpp file corresponding to .h file in which they are delcared. Bug: 852273 Change-Id: Ib7929881e7ffbed8b09f6e2c9fb7898cbde58946 Reviewed-on: https://pdfium-review.googlesource.com/35171 Reviewed-by: dsinclair <dsinclair@chromium.org> Commit-Queue: Tom Sepez <tsepez@chromium.org>
Diffstat (limited to 'core/fxcrt')
-rw-r--r--core/fxcrt/fx_extension.h17
-rw-r--r--core/fxcrt/fx_extension_unittest.cpp30
2 files changed, 47 insertions, 0 deletions
diff --git a/core/fxcrt/fx_extension.h b/core/fxcrt/fx_extension.h
index cef943fc99..dcdd64e1fc 100644
--- a/core/fxcrt/fx_extension.h
+++ b/core/fxcrt/fx_extension.h
@@ -8,6 +8,7 @@
#define CORE_FXCRT_FX_EXTENSION_H_
#include <cctype>
+#include <cmath>
#include <cwctype>
#include <memory>
@@ -92,4 +93,20 @@ void FXSYS_IntToFourHexChars(uint16_t c, char* buf);
size_t FXSYS_ToUTF16BE(uint32_t unicode, char* buf);
+// Strict order over floating types where NaNs may be present.
+template <typename T>
+bool FXSYS_SafeEQ(const T& lhs, const T& rhs) {
+ return (std::isnan(lhs) && std::isnan(rhs)) ||
+ (!std::isnan(lhs) && !std::isnan(rhs) && lhs == rhs);
+}
+
+template <typename T>
+bool FXSYS_SafeLT(const T& lhs, const T& rhs) {
+ if (std::isnan(lhs) && std::isnan(rhs))
+ return false;
+ if (std::isnan(lhs) || std::isnan(rhs))
+ return std::isnan(lhs) < std::isnan(rhs);
+ return lhs < rhs;
+}
+
#endif // CORE_FXCRT_FX_EXTENSION_H_
diff --git a/core/fxcrt/fx_extension_unittest.cpp b/core/fxcrt/fx_extension_unittest.cpp
index 39f26b534b..d84071b83a 100644
--- a/core/fxcrt/fx_extension_unittest.cpp
+++ b/core/fxcrt/fx_extension_unittest.cpp
@@ -3,6 +3,9 @@
// found in the LICENSE file.
#include "core/fxcrt/fx_extension.h"
+
+#include <limits>
+
#include "testing/gtest/include/gtest/gtest.h"
TEST(fxcrt, FXSYS_HexCharToInt) {
@@ -134,3 +137,30 @@ TEST(fxcrt, FXSYS_wcstof) {
FXSYS_wcstof(L"99999999999999999", 17, &used_len));
EXPECT_EQ(17, used_len);
}
+
+TEST(fxcrt, FXSYS_SafeOps) {
+ const float fMin = std::numeric_limits<float>::min();
+ const float fMax = std::numeric_limits<float>::max();
+ const float fInf = std::numeric_limits<float>::infinity();
+ const float fNan = std::numeric_limits<float>::quiet_NaN();
+ const float ascending[] = {fMin, 1.0f, 2.0f, fMax, fInf, fNan};
+
+ for (size_t i = 0; i < FX_ArraySize(ascending); ++i) {
+ for (size_t j = 0; j < FX_ArraySize(ascending); ++j) {
+ if (i == j) {
+ EXPECT_TRUE(FXSYS_SafeEQ(ascending[i], ascending[j]))
+ << " at " << i << " " << j;
+ } else {
+ EXPECT_FALSE(FXSYS_SafeEQ(ascending[i], ascending[j]))
+ << " at " << i << " " << j;
+ }
+ if (i < j) {
+ EXPECT_TRUE(FXSYS_SafeLT(ascending[i], ascending[j]))
+ << " at " << i << " " << j;
+ } else {
+ EXPECT_FALSE(FXSYS_SafeLT(ascending[i], ascending[j]))
+ << " at " << i << " " << j;
+ }
+ }
+ }
+}