Hi,
See
http://cgit.freedesktop.org/libreoffice/core/commit/?id=5187174
Regression from 3.4; testcase in sw/qa/extras/rtftok/data/fdo39053.rtf;
backported patch attached.
Thanks,
Miklos
From 0e53b7a1eda752017a620c7b6f07bcba342e1490 Mon Sep 17 00:00:00 2001
From: Miklos Vajna <vmiklos@suse.cz>
Date: Sun, 15 Apr 2012 14:10:49 +0200
Subject: [PATCH] fdo#39053 writerfilter: implement RTF_BIN
Conflicts:
writerfilter/source/rtftok/rtfdocumentimpl.cxx
writerfilter/source/rtftok/rtftokenizer.cxx
---
writerfilter/source/rtftok/rtfdocumentimpl.cxx | 64 +++++++++++++++++-------
writerfilter/source/rtftok/rtfdocumentimpl.hxx | 4 ++
writerfilter/source/rtftok/rtftokenizer.cxx | 4 +-
3 files changed, 52 insertions(+), 20 deletions(-)
diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx
b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
index 023b6c6..621288d 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
@@ -609,34 +609,42 @@ void RTFDocumentImpl::resolve(Stream & rMapper)
int RTFDocumentImpl::resolvePict(bool bInline)
{
SvMemoryStream aStream;
- int b = 0, count = 2;
+ SvStream *pStream = 0;
- // Feed the destination text to a stream.
- OString aStr = OUStringToOString(m_aStates.top().aDestinationText.makeStringAndClear(),
RTL_TEXTENCODING_ASCII_US);
- const char *str = aStr.getStr();
- for (int i = 0; i < aStr.getLength(); ++i)
+ if (!m_pBinaryData.get())
{
- char ch = str[i];
- if (ch != 0x0d && ch != 0x0a)
+ pStream = &aStream;
+ int b = 0, count = 2;
+
+ // Feed the destination text to a stream.
+ OString aStr = OUStringToOString(m_aStates.top().aDestinationText.makeStringAndClear(),
RTL_TEXTENCODING_ASCII_US);
+ const char *str = aStr.getStr();
+ for (int i = 0; i < aStr.getLength(); ++i)
{
- b = b << 4;
- sal_Int8 parsed = m_pTokenizer->asHex(ch);
- if (parsed == -1)
- return ERROR_HEX_INVALID;
- b += parsed;
- count--;
- if (!count)
+ char ch = str[i];
+ if (ch != 0x0d && ch != 0x0a)
{
- aStream << (char)b;
- count = 2;
- b = 0;
+ b = b << 4;
+ sal_Int8 parsed = m_pTokenizer->asHex(ch);
+ if (parsed == -1)
+ return ERROR_HEX_INVALID;
+ b += parsed;
+ count--;
+ if (!count)
+ {
+ aStream << (char)b;
+ count = 2;
+ b = 0;
+ }
}
}
}
+ else
+ pStream = m_pBinaryData.get();
// Store, and get its URL.
- aStream.Seek(0);
- uno::Reference<io::XInputStream> xInputStream(new utl::OInputStreamWrapper(&aStream));
+ pStream->Seek(0);
+ uno::Reference<io::XInputStream> xInputStream(new utl::OInputStreamWrapper(pStream));
WMF_EXTERNALHEADER aExtHeader;
aExtHeader.mapMode = m_aStates.top().aPicture.eWMetafile;
aExtHeader.xExt = m_aStates.top().aPicture.nWidth;
@@ -775,6 +783,19 @@ int RTFDocumentImpl::resolvePict(bool bInline)
int RTFDocumentImpl::resolveChars(char ch)
{
+ if (m_aStates.top().nInternalState == INTERNAL_BIN)
+ {
+ m_pBinaryData.reset(new SvMemoryStream());
+ *m_pBinaryData << ch;
+ for (int i = 0; i < m_aStates.top().nBinaryToRead - 1; ++i)
+ {
+ Strm() >> ch;
+ *m_pBinaryData << ch;
+ }
+ m_aStates.top().nInternalState = INTERNAL_NORMAL;
+ return 0;
+ }
+
if (m_aStates.top().nInternalState != INTERNAL_HEX)
checkUnicode(false, true);
@@ -2784,6 +2805,10 @@ int RTFDocumentImpl::dispatchValue(RTFKeyword nKeyword, int nParam)
lcl_putNestedSprm(m_aStates.top().aTableSprms, NS_ooxml::LN_CT_Lvl_rPr,
NS_sprm::LN_CRgFtc0, pValue);
}
break;
+ case RTF_BIN:
+ m_aStates.top().nInternalState = INTERNAL_BIN;
+ m_aStates.top().nBinaryToRead = nParam;
+ break;
default:
#if OSL_DEBUG_LEVEL > 1
OSL_TRACE("%s: TODO handle value '%s'", OSL_THIS_FUNC, lcl_RtfToString(nKeyword));
@@ -3601,6 +3626,7 @@ RTFParserState::RTFParserState(RTFDocumentImpl *pDocumentImpl)
nCurrentEncoding(0),
nUc(1),
nCharsToSkip(0),
+ nBinaryToRead(0),
nListLevelNum(0),
aListLevelEntries(),
aLevelNumbers(),
diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.hxx
b/writerfilter/source/rtftok/rtfdocumentimpl.hxx
index 0126882..1d0a37d 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.hxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.hxx
@@ -281,6 +281,8 @@ namespace writerfilter {
int nUc;
/// Characters to skip, set to nUc by \u.
int nCharsToSkip;
+ /// Characters to read, once in binary mode.
+ int nBinaryToRead;
/// Next list level index to use when parsing list table.
int nListLevelNum;
@@ -467,6 +469,8 @@ namespace writerfilter {
bool m_bObject;
/// Contents of the objdata group.
boost::shared_ptr<SvStream> m_pObjectData;
+ /// If the data for a picture is a binary one, it's stored here.
+ boost::shared_ptr<SvStream> m_pBinaryData;
RTFReferenceTable::Entries_t m_aFontTableEntries;
int m_nCurrentFontIndex;
diff --git a/writerfilter/source/rtftok/rtftokenizer.cxx
b/writerfilter/source/rtftok/rtftokenizer.cxx
index 8a0f155..8fa5992 100644
--- a/writerfilter/source/rtftok/rtftokenizer.cxx
+++ b/writerfilter/source/rtftok/rtftokenizer.cxx
@@ -95,7 +95,9 @@ int RTFTokenizer::resolveParse()
return ERROR_GROUP_UNDER;
if (!m_rImport.isEmpty() && m_rImport.getState().nInternalState == INTERNAL_BIN)
{
- OSL_TRACE("%s: TODO, binary internal state", OSL_THIS_FUNC);
+ ret = m_rImport.resolveChars(ch);
+ if (ret)
+ return ret;
}
else
{
--
1.7.7
Context
- [REVIEW:3-5] fdo#39053 writerfilter: implement RTF_BIN · Miklos Vajna
Privacy Policy |
Impressum (Legal Info) |
Copyright information: Unless otherwise specified, all text and images
on this website are licensed under the
Creative Commons Attribution-Share Alike 3.0 License.
This does not include the source code of LibreOffice, which is
licensed under the Mozilla Public License (
MPLv2).
"LibreOffice" and "The Document Foundation" are
registered trademarks of their corresponding registered owners or are
in actual use as trademarks in one or more countries. Their respective
logos and icons are also subject to international copyright laws. Use
thereof is explained in our
trademark policy.