summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.co.uk>2013-11-28 13:35:27 +0100
committerMarkus Mohrhard <markus.mohrhard@googlemail.com>2014-01-27 03:10:16 +0000
commite7debed56f5f037208e49233034ad8a578d1dfbc (patch)
treecde251e8f3c7276deae9cd7b29923bc3c5c7d58e
parentc6020d169c857d4250f966150f2d48d0735e2c75 (diff)
fdo#66011 abi#2128 RTF import: fix memory leak
Commit 9389cf78e304a5a99bcf1745b9388e14ac36281a (cp#1000018 RTF import: empty para at the end of footnote text got lost, 2013-11-15) assumed that \par at the end of all substreams means an empty paragraph, but it turns out this is only true for footnotes/endnotes, but not for e.g. headers. Additionally, that commit actually causes a memory leak, which is detected by an assert in the SwIndexReg dtor, so crash-testing caught this. (cherry picked from commit f7ef84640258e4ee6ddc4cc5cbf58a2d89860afa) Change-Id: Idfa040bf3026a9515a120cd7afaf7d314553a131 Reviewed-on: https://gerrit.libreoffice.org/7663 Reviewed-by: Markus Mohrhard <markus.mohrhard@googlemail.com> Tested-by: Markus Mohrhard <markus.mohrhard@googlemail.com>
-rw-r--r--sw/qa/core/data/rtf/pass/abi2128.rtf17
-rw-r--r--writerfilter/source/rtftok/rtfdocumentimpl.cxx11
-rw-r--r--writerfilter/source/rtftok/rtfdocumentimpl.hxx3
3 files changed, 30 insertions, 1 deletions
diff --git a/sw/qa/core/data/rtf/pass/abi2128.rtf b/sw/qa/core/data/rtf/pass/abi2128.rtf
new file mode 100644
index 000000000000..270c675c7bad
--- /dev/null
+++ b/sw/qa/core/data/rtf/pass/abi2128.rtf
@@ -0,0 +1,17 @@
+{\rtf1\ansi\ansicpg1252\deff0
+{\fonttbl
+{\f0\froman\fcharset0\fprq2\fttruetype Times New Roman;}}
+{\colortbl
+\red0\green0\blue0;
+\red255\green255\blue255;}
+{\stylesheet
+{\s2\sl240\slmult1\sbasedon1 Normal Clean;}
+{\s1\sl240\slmult1\f0\fs24 Normal;}}
+\kerning0\cf0\viewkind1\paperw12240\paperh15840\margl1440\margr1440\widowctl
+\sectd\sbknone\colsx360\headery0\footery0
+\pard\qj\sl240\slmult1{\f0\fs24\lang1033{\*\listtag0}the big green dog bit the little afgan. the big green dog bit the little afgan. the big green dog bit the little afgan. the big green dog bit the little afgan. the big green dog bit the little afgan. the big green dog bit the little afgan. the big green dog bit the little afgan. the big green dog bit the little afgan. the big green dog bit the little afgan. the big green dog bit the little afgan. the big green dog bit the little afgan.}
+{\header
+\par\pard\sl240\slmult1
+\par\pard\sl240\slmult1
+\par\pard\sl240\slmult1
+\par\pard\s2\sl240\slmult1{\f0\fs24\lang1033{\*\listtag0}Hi this is the header}}} \ No newline at end of file
diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
index 72f2c8cc55d0..7f3e25353665 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
@@ -252,6 +252,7 @@ RTFDocumentImpl::RTFDocumentImpl(uno::Reference<uno::XComponentContext> const& x
m_aSuperBuffer(),
m_bHasFootnote(false),
m_pSuperstream(0),
+ m_nStreamType(0),
m_nHeaderFooterPositions(),
m_nGroupStartPos(0),
m_aBookmarks(),
@@ -313,6 +314,11 @@ void RTFDocumentImpl::setSuperstream(RTFDocumentImpl *pSuperstream)
m_pSuperstream = pSuperstream;
}
+void RTFDocumentImpl::setStreamType(Id nId)
+{
+ m_nStreamType = nId;
+}
+
void RTFDocumentImpl::setAuthor(OUString& rAuthor)
{
m_aAuthor = rAuthor;
@@ -349,6 +355,7 @@ void RTFDocumentImpl::resolveSubstream(sal_uInt32 nPos, Id nId, OUString& rIgnor
// Seek to header position, parse, then seek back.
RTFDocumentImpl::Pointer_t pImpl(new RTFDocumentImpl(m_xContext, m_xInputStream, m_xDstDoc, m_xFrame, m_xStatusIndicator));
pImpl->setSuperstream(this);
+ pImpl->setStreamType(nId);
pImpl->setIgnoreFirst(rIgnoreFirst);
if (!m_aAuthor.isEmpty())
{
@@ -4523,7 +4530,9 @@ int RTFDocumentImpl::popState()
// This is the end of the doc, see if we need to close the last section.
if (m_pTokenizer->getGroup() == 1 && !m_bFirstRun)
{
- if (m_bNeedCr && !isSubstream())
+ // \par means an empty paragraph at the end of footnotes/endnotes, but
+ // not in case of other substreams, like headers.
+ if (m_bNeedCr && !(m_nStreamType == NS_rtf::LN_footnote || m_nStreamType == NS_rtf::LN_endnote))
dispatchSymbol(RTF_PAR);
sectBreak(true);
}
diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.hxx b/writerfilter/source/rtftok/rtfdocumentimpl.hxx
index a0b1076f3a03..eada5faf0092 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.hxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.hxx
@@ -313,6 +313,7 @@ namespace writerfilter {
Stream& Mapper();
void setSubstream(bool bIsSubtream);
void setSuperstream(RTFDocumentImpl *pSuperstream);
+ void setStreamType(Id nId);
void setAuthor(OUString& rAuthor);
void setAuthorInitials(OUString& rAuthorInitials);
void setIgnoreFirst(OUString& rIgnoreFirst);
@@ -413,6 +414,8 @@ namespace writerfilter {
bool m_bHasFootnote;
/// Superstream of this substream.
RTFDocumentImpl *m_pSuperstream;
+ /// Type of the stream: header, footer, footnote, etc.
+ Id m_nStreamType;
std::queue< std::pair<Id, sal_uInt32> > m_nHeaderFooterPositions;
sal_uInt32 m_nGroupStartPos;
/// Ignore the first occurrence of this text.