From 130c7d1c5bb4bd983e4b8fd75ea8aecea5a2c0d8 Mon Sep 17 00:00:00 2001 From: JUN FANG Date: Wed, 13 May 2015 14:34:28 -0700 Subject: Fix a global buffer overflow issue in CXFA_ItemLayoutProcessor::CalculatePositionedContainerPos BUG=471991 R=tsepez@chromium.org Review URL: https://codereview.chromium.org/1138993002 --- BUILD.gn | 1 + pdfium.gyp | 1 + xfa/src/fxfa/src/common/xfa_utils.h | 32 ++++++++++--------- xfa/src/fxfa/src/parser/xfa_layout_itemlayout.cpp | 16 ++++++---- xfa/src/fxfa/src/parser/xfa_objectacc_imp.cpp | 9 ++---- xfa/src/fxfa/src/parser/xfa_utils_imp.cpp | 8 +++++ xfa/src/fxfa/src/parser/xfa_utils_imp_unittest.cpp | 36 ++++++++++++++++++++++ 7 files changed, 75 insertions(+), 28 deletions(-) create mode 100644 xfa/src/fxfa/src/parser/xfa_utils_imp_unittest.cpp diff --git a/BUILD.gn b/BUILD.gn index 9e05bab390..b9be538e0b 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -1560,6 +1560,7 @@ test("pdfium_unittests") { "testing/fx_string_testhelpers.cpp", "testing/fx_string_testhelpers.h", "xfa/src/fxbarcode/pdf417/BC_PDF417HighLevelEncoder_unittest.cpp", + "xfa/src/fxfa/src/parser/xfa_utils_imp_unittest.cpp", ] deps = [ "//testing/gtest", diff --git a/pdfium.gyp b/pdfium.gyp index 8a1890948d..7d712c647c 100644 --- a/pdfium.gyp +++ b/pdfium.gyp @@ -928,6 +928,7 @@ 'testing/fx_string_testhelpers.h', 'testing/fx_string_testhelpers.cpp', 'xfa/src/fxbarcode/pdf417/BC_PDF417HighLevelEncoder_unittest.cpp', + 'xfa/src/fxfa/src/parser/xfa_utils_imp_unittest.cpp', ], }, { diff --git a/xfa/src/fxfa/src/common/xfa_utils.h b/xfa/src/fxfa/src/common/xfa_utils.h index c6f0c4773b..b666397e83 100644 --- a/xfa/src/fxfa/src/common/xfa_utils.h +++ b/xfa/src/fxfa/src/common/xfa_utils.h @@ -216,22 +216,24 @@ public: class CXFA_Node; class CXFA_WidgetData; #include "fxfa_localevalue.h" -CXFA_Node* XFA_CreateUIChild(CXFA_Node* pNode, XFA_ELEMENT& eWidgetType); -CXFA_LocaleValue XFA_GetLocaleValue(CXFA_WidgetData* pWidgetData); -CFX_WideString XFA_NumericLimit(const CFX_WideString &wsValue, FX_INT32 iLead, FX_INT32 iTread); -FX_DOUBLE XFA_WideStringToDouble(const CFX_WideString &wsStringVal); -FX_DOUBLE XFA_ByteStringToDouble(FX_BSTR szStringVal); +CXFA_Node* XFA_CreateUIChild(CXFA_Node* pNode, XFA_ELEMENT& eWidgetType); +CXFA_LocaleValue XFA_GetLocaleValue(CXFA_WidgetData* pWidgetData); +CFX_WideString XFA_NumericLimit(const CFX_WideString &wsValue, FX_INT32 iLead, FX_INT32 iTread); +FX_DOUBLE XFA_WideStringToDouble(const CFX_WideString &wsStringVal); +FX_DOUBLE XFA_ByteStringToDouble(FX_BSTR szStringVal); +FX_INT32 XFA_MapRotation(FX_INT32 nRotation); #ifndef XFA_PARSE_HAS_LINEIDENTIFIER #define XFA_PARSE_HAS_LINEIDENTIFIER #endif -FX_BOOL XFA_RecognizeRichText(IFDE_XMLElement* pRichTextXMLNode); -void XFA_GetPlainTextFromRichText(IFDE_XMLNode *pXMLNode, CFX_WideString &wsPlainText); -FX_BOOL XFA_FieldIsMultiListBox(CXFA_Node* pFieldNode); -IFX_Stream* XFA_CreateWideTextRead(const CFX_WideString &wsBuffer); -FX_BOOL XFA_IsLayoutElement(XFA_ELEMENT eElement, FX_BOOL bLayoutContainer = FALSE); -FX_BOOL XFA_IsTakingupSpace(XFA_ATTRIBUTEENUM ePresence); -FX_BOOL XFA_IsFlowingLayout(XFA_ATTRIBUTEENUM eLayout); -FX_BOOL XFA_IsHorizontalFlow(XFA_ATTRIBUTEENUM eLayout); -void XFA_DataExporter_DealWithDataGroupNode(CXFA_Node *pDataNode); -void XFA_DataExporter_RegenerateFormFile(CXFA_Node* pNode, IFX_Stream* pStream, FX_LPCSTR pChecksum = NULL, FX_BOOL bSaveXML = FALSE); +FX_BOOL XFA_RecognizeRichText(IFDE_XMLElement* pRichTextXMLNode); +void XFA_GetPlainTextFromRichText(IFDE_XMLNode *pXMLNode, CFX_WideString &wsPlainText); +FX_BOOL XFA_FieldIsMultiListBox(CXFA_Node* pFieldNode); +IFX_Stream* XFA_CreateWideTextRead(const CFX_WideString &wsBuffer); +FX_BOOL XFA_IsLayoutElement(XFA_ELEMENT eElement, FX_BOOL bLayoutContainer = FALSE); +FX_BOOL XFA_IsTakingupSpace(XFA_ATTRIBUTEENUM ePresence); +FX_BOOL XFA_IsFlowingLayout(XFA_ATTRIBUTEENUM eLayout); +FX_BOOL XFA_IsHorizontalFlow(XFA_ATTRIBUTEENUM eLayout); +void XFA_DataExporter_DealWithDataGroupNode(CXFA_Node *pDataNode); +void XFA_DataExporter_RegenerateFormFile(CXFA_Node* pNode, IFX_Stream* pStream, + FX_LPCSTR pChecksum = NULL, FX_BOOL bSaveXML = FALSE); #endif diff --git a/xfa/src/fxfa/src/parser/xfa_layout_itemlayout.cpp b/xfa/src/fxfa/src/parser/xfa_layout_itemlayout.cpp index e6a2070088..228086734b 100644 --- a/xfa/src/fxfa/src/parser/xfa_layout_itemlayout.cpp +++ b/xfa/src/fxfa/src/parser/xfa_layout_itemlayout.cpp @@ -712,10 +712,6 @@ static inline void XFA_ItemLayoutProcessor_CalculateContainerComponentSizeFromCo } void CXFA_ItemLayoutProcessor::CalculatePositionedContainerPos(CXFA_Node* pNode, FX_FLOAT fWidth, FX_FLOAT fHeight, FX_FLOAT& fAbsoluteX, FX_FLOAT& fAbsoluteY) { - FX_FLOAT fAnchorX = pNode->GetMeasure(XFA_ATTRIBUTE_X).ToUnit(XFA_UNIT_Pt); - FX_FLOAT fAnchorY = pNode->GetMeasure(XFA_ATTRIBUTE_Y).ToUnit(XFA_UNIT_Pt); - FX_INT32 nRotate = FXSYS_round(pNode->GetMeasure(XFA_ATTRIBUTE_Rotate).GetValue()); - nRotate = (nRotate < 0 ? (nRotate % 360) + 360 : nRotate % 360) / 90; XFA_ATTRIBUTEENUM eAnchorType = pNode->GetEnum(XFA_ATTRIBUTE_AnchorType); FX_INT32 nAnchorType = 0; switch(eAnchorType) { @@ -749,7 +745,15 @@ void CXFA_ItemLayoutProcessor::CalculatePositionedContainerPos(CXFA_Node* pNode, default: break; } - static const FX_UINT8 nNextPos[4][9] = {{0, 1, 2, 3, 4, 5, 6, 7, 8}, {6, 3, 0, 7, 4, 1, 8, 5, 2}, {8, 7, 6, 5, 4, 3, 2, 1, 0}, {2, 5, 8, 1, 4, 7, 0, 3, 6}}; + static const FX_UINT8 nNextPos[4][9] = { {0, 1, 2, 3, 4, 5, 6, 7, 8}, + {6, 3, 0, 7, 4, 1, 8, 5, 2}, + {8, 7, 6, 5, 4, 3, 2, 1, 0}, + {2, 5, 8, 1, 4, 7, 0, 3, 6} }; + + FX_FLOAT fAnchorX = pNode->GetMeasure(XFA_ATTRIBUTE_X).ToUnit(XFA_UNIT_Pt); + FX_FLOAT fAnchorY = pNode->GetMeasure(XFA_ATTRIBUTE_Y).ToUnit(XFA_UNIT_Pt); + FX_INT32 nRotate = FXSYS_round(pNode->GetMeasure(XFA_ATTRIBUTE_Rotate).GetValue()); + nRotate = XFA_MapRotation(nRotate) / 90; FX_INT32 nAbsoluteAnchorType = nNextPos[nRotate][nAnchorType]; fAbsoluteX = fAnchorX; fAbsoluteY = fAnchorY; @@ -2297,7 +2301,7 @@ void CXFA_ItemLayoutProcessor::DoLayoutField() FX_FLOAT fWidth = -1; pNotify->StartFieldDrawLayout(m_pFormNode, fWidth, fHeight); FX_INT32 nRotate = FXSYS_round(m_pFormNode->GetMeasure(XFA_ATTRIBUTE_Rotate).GetValue()); - nRotate = (nRotate < 0 ? (nRotate % 360) + 360 : nRotate % 360); + nRotate = XFA_MapRotation(nRotate); if(nRotate == 90 || nRotate == 270) { FX_FLOAT fTmp = fWidth; fWidth = fHeight; diff --git a/xfa/src/fxfa/src/parser/xfa_objectacc_imp.cpp b/xfa/src/fxfa/src/parser/xfa_objectacc_imp.cpp index c3bcd5e20f..c6ece3691b 100644 --- a/xfa/src/fxfa/src/parser/xfa_objectacc_imp.cpp +++ b/xfa/src/fxfa/src/parser/xfa_objectacc_imp.cpp @@ -1792,7 +1792,7 @@ FX_INT32 CXFA_WidgetData::GetRotate() return 0; } FX_INT32 iRotate = FXSYS_round(ms.GetValue()); - iRotate = (iRotate < 0 ? (iRotate % 360) + 360 : iRotate % 360); + iRotate = XFA_MapRotation(iRotate); return iRotate / 90 * 90; } CXFA_Border CXFA_WidgetData::GetBorder(FX_BOOL bModified) @@ -1933,12 +1933,7 @@ FX_BOOL CXFA_WidgetData::SetPresence(FX_INT32 iPresence) } FX_BOOL CXFA_WidgetData::SetRotate(FX_INT32 iRotate) { - while (iRotate < 0) { - iRotate += 360; - } - while (iRotate >= 360) { - iRotate -= 360; - } + iRotate = XFA_MapRotation(iRotate); CXFA_Measurement ms((FX_FLOAT)iRotate, XFA_UNIT_Angle); return m_pNode->SetMeasure(XFA_ATTRIBUTE_Rotate, ms); } diff --git a/xfa/src/fxfa/src/parser/xfa_utils_imp.cpp b/xfa/src/fxfa/src/parser/xfa_utils_imp.cpp index 9c7ca9c274..e4f7545f98 100644 --- a/xfa/src/fxfa/src/parser/xfa_utils_imp.cpp +++ b/xfa/src/fxfa/src/parser/xfa_utils_imp.cpp @@ -375,8 +375,16 @@ FX_DOUBLE XFA_WideStringToDouble(const CFX_WideString &wsStringVal) } return dValue; } + FX_DOUBLE XFA_ByteStringToDouble(FX_BSTR szStringVal) { CFX_WideString wsValue = CFX_WideString::FromUTF8(szStringVal.GetCStr(), szStringVal.GetLength()); return XFA_WideStringToDouble(wsValue); } + +FX_INT32 XFA_MapRotation(FX_INT32 nRotation) { + nRotation = nRotation % 360; + nRotation = nRotation < 0 ? nRotation + 360 : nRotation; + return nRotation; +} + diff --git a/xfa/src/fxfa/src/parser/xfa_utils_imp_unittest.cpp b/xfa/src/fxfa/src/parser/xfa_utils_imp_unittest.cpp new file mode 100644 index 0000000000..a9698721b2 --- /dev/null +++ b/xfa/src/fxfa/src/parser/xfa_utils_imp_unittest.cpp @@ -0,0 +1,36 @@ +// Copyright 2014 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 "../../../foxitlib.h" +#include "../common/xfa_utils.h" + +TEST(XfaUtilsImp, XFA_MapRotation) { + struct TestCase { + int input; + int expected_output; + } TestCases[] = { + {-1000000, 80}, + {-361, 359}, + {-360, 0}, + {-359, 1}, + {-91, 269}, + {-90, 270}, + {-89, 271}, + {-1, 359}, + {0, 0}, + {1, 1}, + {89, 89}, + {90, 90}, + {91, 91}, + {359, 359}, + {360, 0}, + {361, 1}, + {100000, 280} + }; + + for (size_t i = 0; i < FX_ArraySize(TestCases); ++i) { + EXPECT_EQ(TestCases[i].expected_output, XFA_MapRotation(TestCases[i].input)); + } +} -- cgit v1.2.3