Fix a global buffer overflow issue in CXFA_ItemLayoutProcessor::CalculatePositionedCo...
authorJUN FANG <jun_fang@foxitsoftware.com>
Wed, 13 May 2015 21:34:28 +0000 (14:34 -0700)
committerJUN FANG <jun_fang@foxitsoftware.com>
Wed, 13 May 2015 21:34:28 +0000 (14:34 -0700)
BUG=471991
R=tsepez@chromium.org

Review URL: https://codereview.chromium.org/1138993002

BUILD.gn
pdfium.gyp
xfa/src/fxfa/src/common/xfa_utils.h
xfa/src/fxfa/src/parser/xfa_layout_itemlayout.cpp
xfa/src/fxfa/src/parser/xfa_objectacc_imp.cpp
xfa/src/fxfa/src/parser/xfa_utils_imp.cpp
xfa/src/fxfa/src/parser/xfa_utils_imp_unittest.cpp [new file with mode: 0644]

index 9e05bab..b9be538 100644 (file)
--- 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",
index 8a18909..7d712c6 100644 (file)
         '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',
       ],
     },
     {
index c6f0c47..b666397 100644 (file)
@@ -216,22 +216,24 @@ public:
 class CXFA_Node;\r
 class CXFA_WidgetData;\r
 #include "fxfa_localevalue.h"\r
-CXFA_Node*                     XFA_CreateUIChild(CXFA_Node* pNode, XFA_ELEMENT& eWidgetType);\r
-CXFA_LocaleValue       XFA_GetLocaleValue(CXFA_WidgetData* pWidgetData);\r
-CFX_WideString         XFA_NumericLimit(const CFX_WideString &wsValue, FX_INT32 iLead, FX_INT32 iTread);\r
-FX_DOUBLE XFA_WideStringToDouble(const CFX_WideString &wsStringVal);\r
-FX_DOUBLE XFA_ByteStringToDouble(FX_BSTR szStringVal);\r
+CXFA_Node*          XFA_CreateUIChild(CXFA_Node* pNode, XFA_ELEMENT& eWidgetType);\r
+CXFA_LocaleValue    XFA_GetLocaleValue(CXFA_WidgetData* pWidgetData);\r
+CFX_WideString     XFA_NumericLimit(const CFX_WideString &wsValue, FX_INT32 iLead, FX_INT32 iTread);\r
+FX_DOUBLE           XFA_WideStringToDouble(const CFX_WideString &wsStringVal);\r
+FX_DOUBLE           XFA_ByteStringToDouble(FX_BSTR szStringVal);\r
+FX_INT32            XFA_MapRotation(FX_INT32 nRotation); \r
 #ifndef XFA_PARSE_HAS_LINEIDENTIFIER\r
 #define XFA_PARSE_HAS_LINEIDENTIFIER\r
 #endif\r
-FX_BOOL XFA_RecognizeRichText(IFDE_XMLElement* pRichTextXMLNode);\r
-void   XFA_GetPlainTextFromRichText(IFDE_XMLNode *pXMLNode, CFX_WideString &wsPlainText);\r
-FX_BOOL XFA_FieldIsMultiListBox(CXFA_Node* pFieldNode);\r
-IFX_Stream* XFA_CreateWideTextRead(const CFX_WideString &wsBuffer);\r
-FX_BOOL                XFA_IsLayoutElement(XFA_ELEMENT eElement, FX_BOOL bLayoutContainer = FALSE);\r
-FX_BOOL                XFA_IsTakingupSpace(XFA_ATTRIBUTEENUM ePresence);\r
-FX_BOOL                XFA_IsFlowingLayout(XFA_ATTRIBUTEENUM eLayout);\r
-FX_BOOL                XFA_IsHorizontalFlow(XFA_ATTRIBUTEENUM eLayout);\r
-void           XFA_DataExporter_DealWithDataGroupNode(CXFA_Node *pDataNode);\r
-void           XFA_DataExporter_RegenerateFormFile(CXFA_Node* pNode, IFX_Stream* pStream, FX_LPCSTR pChecksum = NULL, FX_BOOL bSaveXML = FALSE);\r
+FX_BOOL             XFA_RecognizeRichText(IFDE_XMLElement* pRichTextXMLNode);\r
+void                XFA_GetPlainTextFromRichText(IFDE_XMLNode *pXMLNode, CFX_WideString &wsPlainText);\r
+FX_BOOL             XFA_FieldIsMultiListBox(CXFA_Node* pFieldNode);\r
+IFX_Stream*         XFA_CreateWideTextRead(const CFX_WideString &wsBuffer);\r
+FX_BOOL             XFA_IsLayoutElement(XFA_ELEMENT eElement, FX_BOOL bLayoutContainer = FALSE);\r
+FX_BOOL             XFA_IsTakingupSpace(XFA_ATTRIBUTEENUM ePresence);\r
+FX_BOOL             XFA_IsFlowingLayout(XFA_ATTRIBUTEENUM eLayout);\r
+FX_BOOL                    XFA_IsHorizontalFlow(XFA_ATTRIBUTEENUM eLayout);\r
+void                XFA_DataExporter_DealWithDataGroupNode(CXFA_Node *pDataNode);\r
+void                XFA_DataExporter_RegenerateFormFile(CXFA_Node* pNode, IFX_Stream* pStream,\r
+                                                        FX_LPCSTR pChecksum = NULL, FX_BOOL bSaveXML = FALSE);\r
 #endif\r
index e6a2070..2280867 100644 (file)
@@ -712,10 +712,6 @@ static inline void XFA_ItemLayoutProcessor_CalculateContainerComponentSizeFromCo
 }\r
 void CXFA_ItemLayoutProcessor::CalculatePositionedContainerPos(CXFA_Node* pNode, FX_FLOAT fWidth, FX_FLOAT fHeight, FX_FLOAT& fAbsoluteX, FX_FLOAT& fAbsoluteY)\r
 {\r
-    FX_FLOAT fAnchorX = pNode->GetMeasure(XFA_ATTRIBUTE_X).ToUnit(XFA_UNIT_Pt);\r
-    FX_FLOAT fAnchorY = pNode->GetMeasure(XFA_ATTRIBUTE_Y).ToUnit(XFA_UNIT_Pt);\r
-    FX_INT32 nRotate = FXSYS_round(pNode->GetMeasure(XFA_ATTRIBUTE_Rotate).GetValue());\r
-    nRotate = (nRotate < 0 ? (nRotate % 360) + 360 : nRotate % 360) / 90;\r
     XFA_ATTRIBUTEENUM eAnchorType = pNode->GetEnum(XFA_ATTRIBUTE_AnchorType);\r
     FX_INT32 nAnchorType = 0;\r
     switch(eAnchorType) {\r
@@ -749,7 +745,15 @@ void CXFA_ItemLayoutProcessor::CalculatePositionedContainerPos(CXFA_Node* pNode,
         default:\r
             break;\r
     }\r
-    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}};\r
+    static const FX_UINT8 nNextPos[4][9] = { {0, 1, 2, 3, 4, 5, 6, 7, 8},\r
+                                             {6, 3, 0, 7, 4, 1, 8, 5, 2}, \r
+                                             {8, 7, 6, 5, 4, 3, 2, 1, 0},\r
+                                             {2, 5, 8, 1, 4, 7, 0, 3, 6} };\r
+\r
+    FX_FLOAT fAnchorX = pNode->GetMeasure(XFA_ATTRIBUTE_X).ToUnit(XFA_UNIT_Pt);\r
+    FX_FLOAT fAnchorY = pNode->GetMeasure(XFA_ATTRIBUTE_Y).ToUnit(XFA_UNIT_Pt);\r
+    FX_INT32 nRotate = FXSYS_round(pNode->GetMeasure(XFA_ATTRIBUTE_Rotate).GetValue());\r
+    nRotate = XFA_MapRotation(nRotate) / 90;\r
     FX_INT32 nAbsoluteAnchorType = nNextPos[nRotate][nAnchorType];\r
     fAbsoluteX = fAnchorX;\r
     fAbsoluteY = fAnchorY;\r
@@ -2297,7 +2301,7 @@ void CXFA_ItemLayoutProcessor::DoLayoutField()
     FX_FLOAT fWidth = -1;\r
     pNotify->StartFieldDrawLayout(m_pFormNode, fWidth, fHeight);\r
     FX_INT32 nRotate = FXSYS_round(m_pFormNode->GetMeasure(XFA_ATTRIBUTE_Rotate).GetValue());\r
-    nRotate = (nRotate < 0 ? (nRotate % 360) + 360 : nRotate % 360);\r
+    nRotate = XFA_MapRotation(nRotate);\r
     if(nRotate == 90 || nRotate == 270) {\r
         FX_FLOAT fTmp = fWidth;\r
         fWidth = fHeight;\r
index c3bcd5e..c6ece36 100644 (file)
@@ -1792,7 +1792,7 @@ FX_INT32 CXFA_WidgetData::GetRotate()
         return 0;\r
     }\r
     FX_INT32 iRotate =  FXSYS_round(ms.GetValue());\r
-    iRotate = (iRotate < 0 ? (iRotate % 360) + 360 : iRotate % 360);\r
+    iRotate = XFA_MapRotation(iRotate);\r
     return iRotate / 90 * 90;\r
 }\r
 CXFA_Border CXFA_WidgetData::GetBorder(FX_BOOL bModified)\r
@@ -1933,12 +1933,7 @@ FX_BOOL CXFA_WidgetData::SetPresence(FX_INT32 iPresence)
 }\r
 FX_BOOL CXFA_WidgetData::SetRotate(FX_INT32 iRotate)\r
 {\r
-    while (iRotate < 0) {\r
-        iRotate += 360;\r
-    }\r
-    while (iRotate >= 360) {\r
-        iRotate -= 360;\r
-    }\r
+    iRotate = XFA_MapRotation(iRotate);\r
     CXFA_Measurement ms((FX_FLOAT)iRotate, XFA_UNIT_Angle);\r
     return m_pNode->SetMeasure(XFA_ATTRIBUTE_Rotate, ms);\r
 }\r
index 9c7ca9c..e4f7545 100644 (file)
@@ -375,8 +375,16 @@ FX_DOUBLE XFA_WideStringToDouble(const CFX_WideString &wsStringVal)
     }\r
     return dValue;\r
 }\r
+\r
 FX_DOUBLE XFA_ByteStringToDouble(FX_BSTR szStringVal)\r
 {\r
     CFX_WideString wsValue = CFX_WideString::FromUTF8(szStringVal.GetCStr(), szStringVal.GetLength());\r
     return XFA_WideStringToDouble(wsValue);\r
 }\r
+\r
+FX_INT32 XFA_MapRotation(FX_INT32 nRotation) {\r
+    nRotation = nRotation % 360;\r
+    nRotation = nRotation < 0 ? nRotation + 360 : nRotation;\r
+    return nRotation;\r
+}\r
+\r
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 (file)
index 0000000..a969872
--- /dev/null
@@ -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));
+    }
+}