From e85f971fe9ba628e46bcb0709d5da4368c15d0b0 Mon Sep 17 00:00:00 2001 From: dsinclair Date: Wed, 3 Aug 2016 10:08:13 -0700 Subject: 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 --- xfa/fxfa/fm2js/xfa_simpleexpression.cpp | 5 ++- xfa/fxfa/fm2js/xfa_simpleexpression_unittest.cpp | 42 ++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 xfa/fxfa/fm2js/xfa_simpleexpression_unittest.cpp (limited to 'xfa') 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 + +#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 exp( + new CXFA_FMIdentifierExpressionn(0, CFX_WideStringC(L"sign"))); + + std::unique_ptr> args( + new CFX_ArrayTemplate()); + 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()); +} -- cgit v1.2.3