Fix heap use after free in Document::DoFieldDelay and Document::delay
[pdfium.git] / fpdfsdk / src / fxedit / fxet_ap.cpp
index 9730d37..92e5bfc 100644 (file)
-// Copyright 2014 PDFium Authors. All rights reserved.\r
-// Use of this source code is governed by a BSD-style license that can be\r
-// found in the LICENSE file.\r
\r
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com\r
-\r
-#include "../../include/fxedit/fxet_stub.h"\r
-#include "../../include/fxedit/fx_edit.h"\r
-#include "../../include/fxedit/fxet_edit.h"\r
-\r
-CFX_ByteString GetPDFWordString(IFX_Edit_FontMap * pFontMap, FX_INT32 nFontIndex, FX_WORD Word, FX_WORD SubWord) \r
-{\r
-       ASSERT (pFontMap != NULL);\r
-\r
-       CFX_ByteString sWord;\r
-\r
-       if (CPDF_Font * pPDFFont = pFontMap->GetPDFFont(nFontIndex))\r
-       {\r
-               if (SubWord > 0)\r
-               {\r
-                       Word = SubWord;         \r
-               }\r
-               else\r
-               {\r
-                       FX_DWORD dwCharCode = -1;\r
-\r
-                       if (pPDFFont->IsUnicodeCompatible())\r
-                               dwCharCode = pPDFFont->CharCodeFromUnicode(Word);\r
-                       else\r
-                               dwCharCode = pFontMap->CharCodeFromUnicode(nFontIndex, Word);\r
-\r
-                       if (dwCharCode > 0 )\r
-                       {\r
-                               pPDFFont->AppendChar(sWord, dwCharCode);\r
-                               return sWord;\r
-                       }\r
-               }\r
-\r
-               pPDFFont->AppendChar(sWord, Word);\r
-       }\r
-\r
-       return sWord;\r
-}\r
-\r
-static CFX_ByteString GetWordRenderString(const CFX_ByteString & strWords)\r
-{\r
-       if (strWords.GetLength() > 0)\r
-               return PDF_EncodeString(strWords) + " Tj\n";\r
-\r
-       return "";\r
-}\r
-\r
-static CFX_ByteString GetFontSetString(IFX_Edit_FontMap * pFontMap, FX_INT32 nFontIndex, FX_FLOAT fFontSize)\r
-{\r
-       CFX_ByteTextBuf sRet;\r
-\r
-       if (pFontMap)\r
-       {\r
-               CFX_ByteString sFontAlias = pFontMap->GetPDFFontAlias(nFontIndex);\r
-\r
-               if (sFontAlias.GetLength() > 0 && fFontSize > 0 )\r
-                       sRet << "/" << sFontAlias << " " << fFontSize << " Tf\n";\r
-       }\r
-\r
-       return sRet.GetByteString();\r
-}\r
-\r
-CFX_ByteString IFX_Edit::GetEditAppearanceStream(IFX_Edit* pEdit, const CPDF_Point & ptOffset, \r
-                                                                                                const CPVT_WordRange * pRange /* = NULL*/, FX_BOOL bContinuous/* = TRUE*/, FX_WORD SubWord/* = 0*/)\r
-{\r
-       CFX_ByteTextBuf sEditStream, sWords;\r
-\r
-       CPDF_Point ptOld(0.0f,0.0f),ptNew(0.0f,0.0f);\r
-       FX_INT32 nCurFontIndex = -1;\r
-\r
-       if (IFX_Edit_Iterator* pIterator = pEdit->GetIterator())\r
-       {\r
-               if (pRange)\r
-                       pIterator->SetAt(pRange->BeginPos);\r
-               else\r
-                       pIterator->SetAt(0);\r
-\r
-               CPVT_WordPlace oldplace;\r
-\r
-               while (pIterator->NextWord())\r
-               {\r
-                       CPVT_WordPlace place = pIterator->GetAt();\r
-\r
-                       if (pRange && place.WordCmp(pRange->EndPos) > 0) break;\r
-\r
-                       if (bContinuous)                        \r
-                       {\r
-                               if (place.LineCmp(oldplace) != 0)\r
-                               {\r
-                                       if (sWords.GetSize() > 0)\r
-                                       {\r
-                                               sEditStream << GetWordRenderString(sWords.GetByteString());\r
-                                               sWords.Clear();\r
-                                       }\r
-\r
-                                       CPVT_Word word;\r
-                                       if (pIterator->GetWord(word))\r
-                                       {\r
-                                               ptNew = CPDF_Point(word.ptWord.x + ptOffset.x, word.ptWord.y + ptOffset.y);\r
-                                       }\r
-                                       else\r
-                                       {\r
-                                               CPVT_Line line;\r
-                                               pIterator->GetLine(line);\r
-                                               ptNew = CPDF_Point(line.ptLine.x + ptOffset.x, line.ptLine.y + ptOffset.y);\r
-                                       }\r
-\r
-                                       if (ptNew.x != ptOld.x || ptNew.y != ptOld.y)\r
-                                       {\r
-                                               sEditStream << ptNew.x - ptOld.x << " " << ptNew.y - ptOld.y << " Td\n";\r
-\r
-                                               ptOld = ptNew;\r
-                                       }\r
-                               }\r
-\r
-                               CPVT_Word word;\r
-                               if (pIterator->GetWord(word))\r
-                               {       \r
-                                       if (word.nFontIndex != nCurFontIndex)\r
-                                       {\r
-                                               if (sWords.GetSize() > 0)\r
-                                               {\r
-                                                       sEditStream << GetWordRenderString(sWords.GetByteString());\r
-                                                       sWords.Clear();\r
-                                               }\r
-                                               sEditStream << GetFontSetString(pEdit->GetFontMap(),word.nFontIndex,word.fFontSize);\r
-                                               nCurFontIndex = word.nFontIndex;\r
-                                       }\r
-\r
-                                       sWords << GetPDFWordString(pEdit->GetFontMap(),nCurFontIndex,word.Word,SubWord);\r
-                               }\r
-\r
-                               oldplace = place;\r
-                       }\r
-                       else\r
-                       {\r
-                               CPVT_Word word;\r
-                               if (pIterator->GetWord(word))\r
-                               {\r
-                                       ptNew = CPDF_Point(word.ptWord.x + ptOffset.x, word.ptWord.y + ptOffset.y);\r
-\r
-                                       if (ptNew.x != ptOld.x || ptNew.y != ptOld.y)\r
-                                       {\r
-                                               sEditStream << ptNew.x - ptOld.x << " " << ptNew.y - ptOld.y << " Td\n";\r
-                                               ptOld = ptNew;\r
-                                       }       \r
-\r
-                                       if (word.nFontIndex != nCurFontIndex)\r
-                                       {\r
-                                               sEditStream << GetFontSetString(pEdit->GetFontMap(),word.nFontIndex,word.fFontSize);\r
-                                               nCurFontIndex = word.nFontIndex;\r
-                                       }\r
-\r
-                                       sEditStream << GetWordRenderString(GetPDFWordString(pEdit->GetFontMap(),nCurFontIndex,word.Word,SubWord));\r
-                               }\r
-                       }\r
-               }\r
-\r
-               if (sWords.GetSize() > 0)\r
-               {\r
-                       sEditStream << GetWordRenderString(sWords.GetByteString());\r
-                       sWords.Clear();\r
-               }\r
-       }\r
-\r
-       CFX_ByteTextBuf sAppStream;\r
-       if (sEditStream.GetSize() > 0)\r
-       {\r
-               FX_INT32 nHorzScale = pEdit->GetHorzScale();\r
-               if (nHorzScale != 100)\r
-               {\r
-                       sAppStream << nHorzScale << " Tz\n";\r
-               }\r
-\r
-               FX_FLOAT fCharSpace = pEdit->GetCharSpace();\r
-               if (!FX_EDIT_IsFloatZero(fCharSpace))\r
-               {\r
-                       sAppStream << fCharSpace << " Tc\n";\r
-               }\r
-\r
-               sAppStream << sEditStream;\r
-       }       \r
-\r
-       return sAppStream.GetByteString();\r
-}\r
-\r
-CFX_ByteString IFX_Edit::GetSelectAppearanceStream(IFX_Edit* pEdit, const CPDF_Point & ptOffset, \r
-                                                       const CPVT_WordRange * pRange /*= NULL*/)\r
-{\r
-       CFX_ByteTextBuf sRet;\r
-\r
-       if (pRange && pRange->IsExist())\r
-       {\r
-               if (IFX_Edit_Iterator* pIterator = pEdit->GetIterator())\r
-               {\r
-                       pIterator->SetAt(pRange->BeginPos);\r
-                       \r
-                       while (pIterator->NextWord())\r
-                       {\r
-                               CPVT_WordPlace place = pIterator->GetAt();\r
-\r
-                               if (pRange && place.WordCmp(pRange->EndPos) > 0) break;                         \r
-\r
-                               CPVT_Word word;\r
-                               CPVT_Line line;\r
-                               if (pIterator->GetWord(word) && pIterator->GetLine(line))\r
-                               {                       \r
-                                       //CPDF_Rect rcWordSel = CPDF_Rect(word.ptWord.x,line.ptLine.y + line.fLineDescent,\r
-                                       //              word.ptWord.x+word.fWidth,line.ptLine.y + line.fLineAscent);\r
-\r
-                                       sRet << word.ptWord.x + ptOffset.x << " " << line.ptLine.y + line.fLineDescent\r
-                                               << " " << word.fWidth << " " << line.fLineAscent - line.fLineDescent << " re\nf\n";                             \r
-                               }\r
-                       }\r
-               }\r
-       }\r
-\r
-       return sRet.GetByteString();\r
-}\r
-\r
+// 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.
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../include/fxedit/fxet_stub.h"
+#include "../../include/fxedit/fx_edit.h"
+#include "../../include/fxedit/fxet_edit.h"
+
+CFX_ByteString GetPDFWordString(IFX_Edit_FontMap * pFontMap, FX_INT32 nFontIndex, FX_WORD Word, FX_WORD SubWord) 
+{
+       ASSERT (pFontMap != NULL);
+
+       CFX_ByteString sWord;
+
+       if (CPDF_Font * pPDFFont = pFontMap->GetPDFFont(nFontIndex))
+       {
+               if (SubWord > 0)
+               {
+                       Word = SubWord;         
+               }
+               else
+               {
+                       FX_DWORD dwCharCode = -1;
+
+                       if (pPDFFont->IsUnicodeCompatible())
+                               dwCharCode = pPDFFont->CharCodeFromUnicode(Word);
+                       else
+                               dwCharCode = pFontMap->CharCodeFromUnicode(nFontIndex, Word);
+
+                       if (dwCharCode > 0 )
+                       {
+                               pPDFFont->AppendChar(sWord, dwCharCode);
+                               return sWord;
+                       }
+               }
+
+               pPDFFont->AppendChar(sWord, Word);
+       }
+
+       return sWord;
+}
+
+static CFX_ByteString GetWordRenderString(const CFX_ByteString & strWords)
+{
+       if (strWords.GetLength() > 0)
+               return PDF_EncodeString(strWords) + " Tj\n";
+
+       return "";
+}
+
+static CFX_ByteString GetFontSetString(IFX_Edit_FontMap * pFontMap, FX_INT32 nFontIndex, FX_FLOAT fFontSize)
+{
+       CFX_ByteTextBuf sRet;
+
+       if (pFontMap)
+       {
+               CFX_ByteString sFontAlias = pFontMap->GetPDFFontAlias(nFontIndex);
+
+               if (sFontAlias.GetLength() > 0 && fFontSize > 0 )
+                       sRet << "/" << sFontAlias << " " << fFontSize << " Tf\n";
+       }
+
+       return sRet.GetByteString();
+}
+
+CFX_ByteString IFX_Edit::GetEditAppearanceStream(IFX_Edit* pEdit, const CPDF_Point & ptOffset, 
+                                                                                                const CPVT_WordRange * pRange /* = NULL*/, FX_BOOL bContinuous/* = TRUE*/, FX_WORD SubWord/* = 0*/)
+{
+       CFX_ByteTextBuf sEditStream, sWords;
+
+       CPDF_Point ptOld(0.0f,0.0f),ptNew(0.0f,0.0f);
+       FX_INT32 nCurFontIndex = -1;
+
+       if (IFX_Edit_Iterator* pIterator = pEdit->GetIterator())
+       {
+               if (pRange)
+                       pIterator->SetAt(pRange->BeginPos);
+               else
+                       pIterator->SetAt(0);
+
+               CPVT_WordPlace oldplace;
+
+               while (pIterator->NextWord())
+               {
+                       CPVT_WordPlace place = pIterator->GetAt();
+
+                       if (pRange && place.WordCmp(pRange->EndPos) > 0) break;
+
+                       if (bContinuous)                        
+                       {
+                               if (place.LineCmp(oldplace) != 0)
+                               {
+                                       if (sWords.GetSize() > 0)
+                                       {
+                                               sEditStream << GetWordRenderString(sWords.GetByteString());
+                                               sWords.Clear();
+                                       }
+
+                                       CPVT_Word word;
+                                       if (pIterator->GetWord(word))
+                                       {
+                                               ptNew = CPDF_Point(word.ptWord.x + ptOffset.x, word.ptWord.y + ptOffset.y);
+                                       }
+                                       else
+                                       {
+                                               CPVT_Line line;
+                                               pIterator->GetLine(line);
+                                               ptNew = CPDF_Point(line.ptLine.x + ptOffset.x, line.ptLine.y + ptOffset.y);
+                                       }
+
+                                       if (ptNew.x != ptOld.x || ptNew.y != ptOld.y)
+                                       {
+                                               sEditStream << ptNew.x - ptOld.x << " " << ptNew.y - ptOld.y << " Td\n";
+
+                                               ptOld = ptNew;
+                                       }
+                               }
+
+                               CPVT_Word word;
+                               if (pIterator->GetWord(word))
+                               {       
+                                       if (word.nFontIndex != nCurFontIndex)
+                                       {
+                                               if (sWords.GetSize() > 0)
+                                               {
+                                                       sEditStream << GetWordRenderString(sWords.GetByteString());
+                                                       sWords.Clear();
+                                               }
+                                               sEditStream << GetFontSetString(pEdit->GetFontMap(),word.nFontIndex,word.fFontSize);
+                                               nCurFontIndex = word.nFontIndex;
+                                       }
+
+                                       sWords << GetPDFWordString(pEdit->GetFontMap(),nCurFontIndex,word.Word,SubWord);
+                               }
+
+                               oldplace = place;
+                       }
+                       else
+                       {
+                               CPVT_Word word;
+                               if (pIterator->GetWord(word))
+                               {
+                                       ptNew = CPDF_Point(word.ptWord.x + ptOffset.x, word.ptWord.y + ptOffset.y);
+
+                                       if (ptNew.x != ptOld.x || ptNew.y != ptOld.y)
+                                       {
+                                               sEditStream << ptNew.x - ptOld.x << " " << ptNew.y - ptOld.y << " Td\n";
+                                               ptOld = ptNew;
+                                       }       
+
+                                       if (word.nFontIndex != nCurFontIndex)
+                                       {
+                                               sEditStream << GetFontSetString(pEdit->GetFontMap(),word.nFontIndex,word.fFontSize);
+                                               nCurFontIndex = word.nFontIndex;
+                                       }
+
+                                       sEditStream << GetWordRenderString(GetPDFWordString(pEdit->GetFontMap(),nCurFontIndex,word.Word,SubWord));
+                               }
+                       }
+               }
+
+               if (sWords.GetSize() > 0)
+               {
+                       sEditStream << GetWordRenderString(sWords.GetByteString());
+                       sWords.Clear();
+               }
+       }
+
+       CFX_ByteTextBuf sAppStream;
+       if (sEditStream.GetSize() > 0)
+       {
+               FX_INT32 nHorzScale = pEdit->GetHorzScale();
+               if (nHorzScale != 100)
+               {
+                       sAppStream << nHorzScale << " Tz\n";
+               }
+
+               FX_FLOAT fCharSpace = pEdit->GetCharSpace();
+               if (!FX_EDIT_IsFloatZero(fCharSpace))
+               {
+                       sAppStream << fCharSpace << " Tc\n";
+               }
+
+               sAppStream << sEditStream;
+       }       
+
+       return sAppStream.GetByteString();
+}
+
+CFX_ByteString IFX_Edit::GetSelectAppearanceStream(IFX_Edit* pEdit, const CPDF_Point & ptOffset, 
+                                                       const CPVT_WordRange * pRange /*= NULL*/)
+{
+       CFX_ByteTextBuf sRet;
+
+       if (pRange && pRange->IsExist())
+       {
+               if (IFX_Edit_Iterator* pIterator = pEdit->GetIterator())
+               {
+                       pIterator->SetAt(pRange->BeginPos);
+                       
+                       while (pIterator->NextWord())
+                       {
+                               CPVT_WordPlace place = pIterator->GetAt();
+
+                               if (pRange && place.WordCmp(pRange->EndPos) > 0) break;                         
+
+                               CPVT_Word word;
+                               CPVT_Line line;
+                               if (pIterator->GetWord(word) && pIterator->GetLine(line))
+                               {                       
+                                       //CPDF_Rect rcWordSel = CPDF_Rect(word.ptWord.x,line.ptLine.y + line.fLineDescent,
+                                       //              word.ptWord.x+word.fWidth,line.ptLine.y + line.fLineAscent);
+
+                                       sRet << word.ptWord.x + ptOffset.x << " " << line.ptLine.y + line.fLineDescent
+                                               << " " << word.fWidth << " " << line.fLineAscent - line.fLineDescent << " re\nf\n";                             
+                               }
+                       }
+               }
+       }
+
+       return sRet.GetByteString();
+}
+