summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordsinclair <dsinclair@chromium.org>2016-08-03 10:08:13 -0700
committerCommit bot <commit-bot@chromium.org>2016-08-03 10:08:13 -0700
commite85f971fe9ba628e46bcb0709d5da4368c15d0b0 (patch)
treeef0bd0cecbd4b7be0fcd9031be002ffc10fd7fb7
parent0d8c2d120efe62d79d083f25b43aa814d0f24646 (diff)
downloadpdfium-e85f971fe9ba628e46bcb0709d5da4368c15d0b0.tar.xz
Fix FMCallExpression undefined shift behaviour.
When determining which params should be an object and which are a value it is possible to overflow the int on the shift comparision (if there are more then 32 arguments). This never happens in practise as it's a controlled list of method calls which we pass objects for. Cap the check at 32 for the shifting so it doesn't overflow. We can revisit and extend the value later if we ever have an internal formcalc method that needs an object in a position greater then 32. BUG=chromium:603490 Review-Url: https://codereview.chromium.org/2206253002
-rw-r--r--BUILD.gn1
-rw-r--r--pdfium.gyp1
-rw-r--r--xfa/fxfa/fm2js/xfa_simpleexpression.cpp5
-rw-r--r--xfa/fxfa/fm2js/xfa_simpleexpression_unittest.cpp42
4 files changed, 48 insertions, 1 deletions
diff --git a/BUILD.gn b/BUILD.gn
index 6b5e78d49a..a03102aa7a 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -1578,6 +1578,7 @@ test("pdfium_unittests") {
"xfa/fde/xml/fde_xml_imp_unittest.cpp",
"xfa/fxbarcode/pdf417/BC_PDF417HighLevelEncoder_unittest.cpp",
"xfa/fxfa/app/xfa_textlayout_unittest.cpp",
+ "xfa/fxfa/fm2js/xfa_simpleexpression_unittest.cpp",
"xfa/fxfa/parser/xfa_utils_unittest.cpp",
]
}
diff --git a/pdfium.gyp b/pdfium.gyp
index 61890e81cd..26f46edba9 100644
--- a/pdfium.gyp
+++ b/pdfium.gyp
@@ -949,6 +949,7 @@
'xfa/fde/xml/fde_xml_imp_unittest.cpp',
'xfa/fxbarcode/pdf417/BC_PDF417HighLevelEncoder_unittest.cpp',
'xfa/fxfa/app/xfa_textlayout_unittest.cpp',
+ 'xfa/fxfa/fm2js/xfa_simpleexpression_unittest.cpp',
'xfa/fxfa/parser/xfa_utils_unittest.cpp',
],
}],
diff --git a/xfa/fxfa/fm2js/xfa_simpleexpression.cpp b/xfa/fxfa/fm2js/xfa_simpleexpression.cpp
index 47bb9df235..a7a88ec30a 100644
--- a/xfa/fxfa/fm2js/xfa_simpleexpression.cpp
+++ b/xfa/fxfa/fm2js/xfa_simpleexpression.cpp
@@ -541,7 +541,10 @@ void CXFA_FMCallExpression::ToJavaScript(CFX_WideTextBuf& javascript) {
uint32_t methodPara = IsMethodWithObjParam(funcName.AsStringC());
if (methodPara > 0) {
for (int i = 0; i < m_pArguments->GetSize(); ++i) {
- if ((methodPara & (0x01 << i)) > 0) {
+ // Currently none of our expressions use objects for a parameter over
+ // the 6th. Make sure we don't overflow the shift when doing this
+ // check. If we ever need more the 32 object params we can revisit.
+ if (i < 32 && (methodPara & (0x01 << i)) > 0) {
javascript << gs_lpStrExpFuncName[GETFMJSOBJ];
} else {
javascript << gs_lpStrExpFuncName[GETFMVALUE];
diff --git a/xfa/fxfa/fm2js/xfa_simpleexpression_unittest.cpp b/xfa/fxfa/fm2js/xfa_simpleexpression_unittest.cpp
new file mode 100644
index 0000000000..171922aecd
--- /dev/null
+++ b/xfa/fxfa/fm2js/xfa_simpleexpression_unittest.cpp
@@ -0,0 +1,42 @@
+// Copyright 2016 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 "xfa/fxfa/fm2js/xfa_simpleexpression.h"
+
+#include <memory>
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "xfa/fxfa/fm2js/xfa_lexer.h"
+
+TEST(FMCallExpression, more_than_32_arguments) {
+ // Use sign as it has 3 object parameters at positions 0, 5, and 6.
+ std::unique_ptr<CXFA_FMIdentifierExpressionn> exp(
+ new CXFA_FMIdentifierExpressionn(0, CFX_WideStringC(L"sign")));
+
+ std::unique_ptr<CFX_ArrayTemplate<CXFA_FMSimpleExpression*>> args(
+ new CFX_ArrayTemplate<CXFA_FMSimpleExpression*>());
+ for (size_t i = 0; i < 50; i++)
+ args->Add(new CXFA_FMSimpleExpression(0, TOKnan));
+
+ CXFA_FMCallExpression callExp(0, exp.release(), args.release(), TRUE);
+ CFX_WideTextBuf js;
+ callExp.ToJavaScript(js);
+
+ // Generate the result javascript string.
+ CFX_WideString result = L"sign(";
+ for (size_t i = 0; i < 50; i++) {
+ if (i > 0)
+ result += L", ";
+
+ result += L"foxit_xfa_formcalc_runtime.get_fm_";
+ // Object positions for sign() method.
+ if (i == 0 || i == 5 || i == 6)
+ result += L"jsobj()";
+ else
+ result += L"value()";
+ }
+ result += L")";
+
+ EXPECT_EQ(result.AsStringC(), js.AsStringC());
+}