summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Sinclair <dsinclair@chromium.org>2018-05-25 16:08:29 +0000
committerChromium commit bot <commit-bot@chromium.org>2018-05-25 16:08:29 +0000
commita2bb072a69b29695242a81e4b75c19c14c39acfb (patch)
treed9eac05e30bd44d2daee9126fe37cb4e321f22c8
parentda060ba107fba8ef679393b5622b6de2f4790379 (diff)
downloadpdfium-a2bb072a69b29695242a81e4b75c19c14c39acfb.tar.xz
[xfa] Clamp selStart, selEnd values in CJX_EventPseudoModel
This CL adds bounds checking for the selStart and selEnd settings of the event object. The selEnd is not allowed to be less then selStart. They are also not allowed to be negative. This also clamps them to the length of the prevText string. Bug: 1066 Change-Id: Ifc9113c669c83a4a97655554affbbce30c2bfc64 Reviewed-on: https://pdfium-review.googlesource.com/32933 Commit-Queue: Ryan Harrison <rharrison@chromium.org> Reviewed-by: Ryan Harrison <rharrison@chromium.org>
-rw-r--r--fxjs/cfxjse_formcalc_context_embeddertest.cpp54
-rw-r--r--fxjs/xfa/cjx_eventpseudomodel.cpp17
2 files changed, 71 insertions, 0 deletions
diff --git a/fxjs/cfxjse_formcalc_context_embeddertest.cpp b/fxjs/cfxjse_formcalc_context_embeddertest.cpp
index 8d1bb36b3d..ba39182364 100644
--- a/fxjs/cfxjse_formcalc_context_embeddertest.cpp
+++ b/fxjs/cfxjse_formcalc_context_embeddertest.cpp
@@ -1500,3 +1500,57 @@ TEST_F(CFXJSE_FormCalcContextEmbedderTest, SetXFAEventFullTextFails) {
EXPECT_TRUE(Execute(test));
EXPECT_EQ(L"Original Full Text", context->GetEventParam()->m_wsFullText);
}
+
+TEST_F(CFXJSE_FormCalcContextEmbedderTest, EventChangeSelection) {
+ ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
+
+ CXFA_EventParam params;
+ params.m_wsPrevText = L"1234";
+ params.m_iSelStart = 1;
+ params.m_iSelEnd = 3;
+
+ CFXJSE_Engine* context = GetScriptContext();
+ context->SetEventParam(params);
+
+ // Moving end to start works fine.
+ EXPECT_TRUE(Execute("xfa.event.selEnd = \"1\""));
+ EXPECT_EQ(1, context->GetEventParam()->m_iSelStart);
+ EXPECT_EQ(1, context->GetEventParam()->m_iSelEnd);
+
+ // Moving end before end, forces start to move in response.
+ EXPECT_TRUE(Execute("xfa.event.selEnd = \"0\""));
+ EXPECT_EQ(0, context->GetEventParam()->m_iSelStart);
+ EXPECT_EQ(0, context->GetEventParam()->m_iSelEnd);
+
+ // Negatives not allowed
+ EXPECT_TRUE(Execute("xfa.event.selEnd = \"-1\""));
+ EXPECT_EQ(0, context->GetEventParam()->m_iSelStart);
+ EXPECT_EQ(0, context->GetEventParam()->m_iSelEnd);
+
+ // Negatives not allowed
+ EXPECT_TRUE(Execute("xfa.event.selStart = \"-1\""));
+ EXPECT_EQ(0, context->GetEventParam()->m_iSelStart);
+ EXPECT_EQ(0, context->GetEventParam()->m_iSelEnd);
+
+ context->GetEventParam()->m_iSelEnd = 1;
+
+ // Moving start to end works fine.
+ EXPECT_TRUE(Execute("xfa.event.selStart = \"1\""));
+ EXPECT_EQ(1, context->GetEventParam()->m_iSelStart);
+ EXPECT_EQ(1, context->GetEventParam()->m_iSelEnd);
+
+ // Moving start after end moves end.
+ EXPECT_TRUE(Execute("xfa.event.selStart = \"2\""));
+ EXPECT_EQ(2, context->GetEventParam()->m_iSelStart);
+ EXPECT_EQ(2, context->GetEventParam()->m_iSelEnd);
+
+ // Setting End past end of string clamps to string length;
+ EXPECT_TRUE(Execute("xfa.event.selEnd = \"20\""));
+ EXPECT_EQ(2, context->GetEventParam()->m_iSelStart);
+ EXPECT_EQ(4, context->GetEventParam()->m_iSelEnd);
+
+ // Setting Start past end of string clamps to string length;
+ EXPECT_TRUE(Execute("xfa.event.selStart = \"20\""));
+ EXPECT_EQ(4, context->GetEventParam()->m_iSelStart);
+ EXPECT_EQ(4, context->GetEventParam()->m_iSelEnd);
+}
diff --git a/fxjs/xfa/cjx_eventpseudomodel.cpp b/fxjs/xfa/cjx_eventpseudomodel.cpp
index a6a876d81b..0dea7153b7 100644
--- a/fxjs/xfa/cjx_eventpseudomodel.cpp
+++ b/fxjs/xfa/cjx_eventpseudomodel.cpp
@@ -6,6 +6,7 @@
#include "fxjs/xfa/cjx_eventpseudomodel.h"
+#include <algorithm>
#include <vector>
#include "fxjs/cfxjse_engine.h"
@@ -243,9 +244,25 @@ void CJX_EventPseudoModel::Property(CFXJSE_Value* pValue,
break;
case XFA_Event::SelectionEnd:
InterProperty(pValue, &pEventParam->m_iSelEnd, bSetting);
+
+ pEventParam->m_iSelEnd = std::max(0, pEventParam->m_iSelEnd);
+ pEventParam->m_iSelEnd =
+ std::min(static_cast<size_t>(pEventParam->m_iSelEnd),
+ pEventParam->m_wsPrevText.GetLength());
+ pEventParam->m_iSelStart =
+ std::min(pEventParam->m_iSelStart, pEventParam->m_iSelEnd);
+
break;
case XFA_Event::SelectionStart:
InterProperty(pValue, &pEventParam->m_iSelStart, bSetting);
+
+ pEventParam->m_iSelStart = std::max(0, pEventParam->m_iSelStart);
+ pEventParam->m_iSelStart =
+ std::min(static_cast<size_t>(pEventParam->m_iSelStart),
+ pEventParam->m_wsPrevText.GetLength());
+ pEventParam->m_iSelEnd =
+ std::max(pEventParam->m_iSelStart, pEventParam->m_iSelEnd);
+
break;
case XFA_Event::Shift:
BooleanProperty(pValue, &pEventParam->m_bShift, bSetting);