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 <vmik...@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
_______________________________________________ LibreOffice mailing list LibreOffice@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice