summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.co.uk>2015-04-16 14:22:05 +0200
committerMiklos Vajna <vmiklos@collabora.co.uk>2015-04-16 15:32:26 +0200
commit2a3e8b470edf2fe76188f9ccf6b0f32dfc817ea4 (patch)
tree77821561f8bfedcbe21585f124fe8c81cdbde552
parente7df7c098ed3a6dc1ecf5b20857835d16d1f9283 (diff)
RTF import: fix handling of \objdata
There were two problems here: 1) The input stream is read multiple times, so plain naive XInputStream is not enough, XSeekable is needed, as it is the case for the stream provided by the OOXML tokenizer. 2) Seeking to the correct start position is not enough, code using the stream will assume that seeking to the beginning of the stream allows reading the correct data again, so provide a dedicated stream instead. With this, handling of math equations created by Word <= 2007 and embedded to RTF files can be edited finally. Change-Id: Ic225e1e1060f8bdd5651a21e68970620c9ac6b68
-rw-r--r--sw/qa/extras/rtfimport/data/mathtype.rtf142
-rw-r--r--sw/qa/extras/rtfimport/rtfimport.cxx6
-rw-r--r--writerfilter/source/rtftok/rtfdocumentimpl.cxx108
-rw-r--r--writerfilter/source/rtftok/rtfdocumentimpl.hxx2
4 files changed, 211 insertions, 47 deletions
diff --git a/sw/qa/extras/rtfimport/data/mathtype.rtf b/sw/qa/extras/rtfimport/data/mathtype.rtf
new file mode 100644
index 000000000000..411e8bd4d277
--- /dev/null
+++ b/sw/qa/extras/rtfimport/data/mathtype.rtf
@@ -0,0 +1,142 @@
+{\rtf1
+\pard\plain \ltrpar\ql \li0\ri0\nowidctlpar\wrapdefault\hyphpar0\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af40\afs24\alang1081 \ltrch\fcs0
+\fs24\lang1033\langfe2052\kerning1\loch\af39\hich\af39\dbch\af1\cgrid\langnp1033\langfenp2052
+{\rtlch\fcs1 \af40 \ltrch\fcs0 \insrsid2305639 \hich\af39\dbch\af1\loch\f39 Before}
+{\pard\plain \ltrpar
+\ql \li0\ri0\nowidctlpar\wrapdefault\hyphpar0\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af40\afs24\alang1081 \ltrch\fcs0 \fs24\lang1033\langfe2052\kerning1\loch\af39\hich\af39\dbch\af1\cgrid\langnp1033\langfenp2052
+{\object\objemb
+\objw617\objh566
+{\*\objclass Equation.3}
+{\*\objdata 01050000020000000b0000004571756174696f6e2e33000000000000000000000c0000
+d0cf11e0a1b11ae1000000000000000000000000000000003e000300feff0900060000000000000000000000010000000100000000000000001000000200000001000000feffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffdffffff04000000fefffffffefffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffff0100000002ce020000000000c0000000000000460000000000000000000000000000
+00000000000003000000000200000000000001004f006c00650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000200ffffffff02000000ffffffff00000000000000000000000000000000000000000000000000000000
+0000000000000000000000001400000000000000010043006f006d0070004f0062006a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012000200ffffffff03000000ffffffff0000000000000000000000000000000000000000000000000000
+000000000000000000000100000066000000000000004500710075006100740069006f006e0020004e0061007400690076006500000000000000000000000000000000000000000000000000000000000000000000002000020004000000ffffffffffffffff000000000000000000000000000000000000000000000000
+000000000000000000000000030000004300000000000000feffffff02000000feffffff04000000fefffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff010000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100feff030a0000ffffffff02ce020000000000c0000000000000461700
+00004d6963726f736f6674204571756174696f6e20332e30000c0000004453204571756174696f6e000b0000004571756174696f6e2e3300f439b27100000000000000000000000000000000000000000000000000000000000000000000000000001c0000000200c6c1270000000000000090f61400b4eb140000000000
+03010103000a010a010283610002833d00030e00000a0102836200000a01028363000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030001000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000000003004f0062006a0049006e0066006f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012000200ffffffffffffffffffffffff000000000000
+000000000000000000000000000000000000000000000000000000000000050000000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000105000000000000}
+{\result
+{\rtlch\fcs1 \af40 \ltrch\fcs0 \insrsid2305639
+{\*\shppict
+{\pict
+{\*\picprop\shplid1025
+{\sp
+{\sn shapeType}
+{\sv 75}
+}
+{\sp
+{\sn fFlipH}
+{\sv 0}
+}
+{\sp
+{\sn fFlipV}
+{\sv 0}
+}
+{\sp
+{\sn dxTextLeft}
+{\sv 0}
+}
+{\sp
+{\sn dyTextTop}
+{\sv 0}
+}
+{\sp
+{\sn dxTextRight}
+{\sv 0}
+}
+{\sp
+{\sn dyTextBottom}
+{\sv 0}
+}
+{\sp
+{\sn pictureActive}
+{\sv 0}
+}
+{\sp
+{\sn fillBackColor}
+{\sv 0}
+}
+{\sp
+{\sn fFilled}
+{\sv 1}
+}
+{\sp
+{\sn fLine}
+{\sv 0}
+}
+{\sp
+{\sn fLayoutInCell}
+{\sv 1}
+}
+}
+\picscalex100\picscaley100\piccropl0\piccropr0\piccropt0\piccropb0
+\picw1088\pich998\picwgoal617\pichgoal566\emfblip\bliptag671316949
+{\*\blipuid 28037bd500000000c160369662020020}
+010000006c0000000000000000000000280000002500000000000000000000003f040000e503000020454d4600000100180a00003d0000000400000000000000
+000000000000000029000000260000000a00000009000000000000000000000000000000802a0000fc260000460000002c00000020000000454d462b01400100
+1c000000100000000210c0db01000000660000006900000046000000580000004c000000454d462b224000000c000000000000001e4009000c00000000000000
+244000010c00000000000000304001000c00000000000000214000000c00000000000000044000000c00000000000000110000000c000000080000000b000000
+1000000060000000600000000900000010000000ec090000ec0900000c0000001000000000000000000000000a00000010000000000000000000000014000000
+0c0000000d000000120000000c0000000100000021000000080000001e0000001800000000000000000000003f040000e5030000210000000800000052000000
+4c010000010000005afeffff0000000000000000000000009001000001000000000000104c0069006200650072006100740069006f006e002000530065007200
+69006600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000160000000c00000018000000180000000c00000000000000250000000c0000000100000054000000540000006a000000610200003d010000
+220400000100000000000000000000006a00000061020000010000004c00000002000000000000000000000000000000000000005000000061000000d4000000
+220000000c000000ffffffff140000000c0000000d0000002100000008000000250000000c0000000a000080280000000c00000001000000520000004c010000
+010000005afeffff0000000000000000000000009001000000000000000000004f00700065006e00530079006d0062006f006c00000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000160000000c00000018000000180000000c00000000000000250000000c0000000100000054000000540000005801000061020000af02000071040000
+0100000000000000000000005801000061020000010000004c0000000200000000000000000000000000000000000000500000003d0000005801000022000000
+0c000000ffffffff140000000c0000000d0000002100000008000000250000000c0000000a000080280000000c00000001000000520000004c01000001000000
+5afeffff0000000000000000000000009001000001000000000000104c0069006200650072006100740069006f006e0020005300650072006900660000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+160000000c00000018000000180000000c00000000000000250000000c000000010000005400000054000000ca020000720100009d0300003303000001000000
+0000000000000000ca02000072010000010000004c00000002000000000000000000000000000000000000005000000062000000d4000000220000000c000000
+ffffffff140000000c0000000d0000002100000008000000270000001800000002000000000000000000000000000000250000000c0000000200000026000000
+1c00000003000000050000000000000000000000ffffff00250000000c000000030000002b00000018000000b0020000dc010000ba030000f001000022000000
+0c000000ffffffff140000000c0000000d0000002100000008000000250000000c0000000a000080280000000c00000001000000520000004c01000001000000
+5afeffff0000000000000000000000009001000001000000000000104c0069006200650072006100740069006f006e0020005300650072006900660000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+160000000c00000018000000180000000c00000000000000250000000c000000010000005400000054000000e5020000840300009d0300004505000001000000
+0000000000000000e502000084030000010000004c00000002000000000000000000000000000000000000005000000063000000b9000000220000000c000000
+ffffffff140000000c0000000d000000220000000c000000ffffffff140000000c0000000d000000460000001c00000010000000454d462b024000000c000000000000000e00000014000000000000001000000014000000}
+}
+}
+}
+}
+}
+\sectd \ltrsect\linex0\endnhere\sectdefaultcl\sftnbj
+{\rtlch\fcs1 \af40 \ltrch\fcs0
+\insrsid2305639 \hich\af39\dbch\af1\loch\f39 after.
+\par }
+}
diff --git a/sw/qa/extras/rtfimport/rtfimport.cxx b/sw/qa/extras/rtfimport/rtfimport.cxx
index 5262147cb6c1..c579403b7e78 100644
--- a/sw/qa/extras/rtfimport/rtfimport.cxx
+++ b/sw/qa/extras/rtfimport/rtfimport.cxx
@@ -2232,6 +2232,12 @@ DECLARE_RTFIMPORT_TEST(testFdo75614, "tdf75614.rtf")
CPPUNIT_ASSERT_EQUAL(OUString("after."), getRun(getParagraph(1), 3)->getString());
}
+DECLARE_RTFIMPORT_TEST(mathtype, "mathtype.rtf")
+{
+ OUString aFormula = getFormula(getRun(getParagraph(1), 1));
+ CPPUNIT_ASSERT(!aFormula.isEmpty());
+}
+
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
index c74399c79090..d00662375dfc 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
@@ -5349,53 +5349,9 @@ RTFError RTFDocumentImpl::popState()
if (&m_aStates.top().aDestinationText != m_aStates.top().pDestinationText)
break; // not for nested group
- m_pObjectData.reset(new SvMemoryStream());
- int b = 0, count = 2;
-
- // Feed the destination text to a stream.
- OString aStr = OUStringToOString(m_aStates.top().pDestinationText->makeStringAndClear(), RTL_TEXTENCODING_ASCII_US);
- const char* str = aStr.getStr();
- for (int i = 0; i < aStr.getLength(); ++i)
- {
- char ch = str[i];
- if (ch != 0x0d && ch != 0x0a)
- {
- b = b << 4;
- sal_Int8 parsed = m_pTokenizer->asHex(ch);
- if (parsed == -1)
- return RTFError::HEX_INVALID;
- b += parsed;
- count--;
- if (!count)
- {
- m_pObjectData->WriteChar((char)b);
- count = 2;
- b = 0;
- }
- }
- }
-
- if (m_pObjectData->Tell())
- {
- m_pObjectData->Seek(0);
-
- // Skip ObjectHeader
- sal_uInt32 nData;
- m_pObjectData->ReadUInt32(nData); // OLEVersion
- m_pObjectData->ReadUInt32(nData); // FormatID
- m_pObjectData->ReadUInt32(nData); // ClassName
- m_pObjectData->SeekRel(nData);
- m_pObjectData->ReadUInt32(nData); // TopicName
- m_pObjectData->SeekRel(nData);
- m_pObjectData->ReadUInt32(nData); // ItemName
- m_pObjectData->SeekRel(nData);
- m_pObjectData->ReadUInt32(nData); // NativeDataSize
- }
-
- uno::Reference<io::XInputStream> xInputStream(new utl::OInputStreamWrapper(m_pObjectData.get()));
- auto pStreamValue = std::make_shared<RTFValue>(xInputStream);
-
- m_aOLEAttributes.set(NS_ooxml::LN_inputstream, pStreamValue);
+ RTFError eError = handleEmbeddedObject();
+ if (eError != RTFError::OK)
+ return eError;
}
break;
case Destination::OBJCLASS:
@@ -6058,6 +6014,64 @@ RTFError RTFDocumentImpl::popState()
return RTFError::OK;
}
+RTFError RTFDocumentImpl::handleEmbeddedObject()
+{
+ SvMemoryStream aStream;
+ int b = 0, count = 2;
+
+ // Feed the destination text to a stream.
+ OString aStr = OUStringToOString(m_aStates.top().pDestinationText->makeStringAndClear(), RTL_TEXTENCODING_ASCII_US);
+ const char* str = aStr.getStr();
+ for (int i = 0; i < aStr.getLength(); ++i)
+ {
+ char ch = str[i];
+ if (ch != 0x0d && ch != 0x0a)
+ {
+ b = b << 4;
+ sal_Int8 parsed = m_pTokenizer->asHex(ch);
+ if (parsed == -1)
+ return RTFError::HEX_INVALID;
+ b += parsed;
+ count--;
+ if (!count)
+ {
+ aStream.WriteChar(b);
+ count = 2;
+ b = 0;
+ }
+ }
+ }
+
+ // Skip ObjectHeader, see [MS-OLEDS] 2.2.4.
+ if (aStream.Tell())
+ {
+ aStream.Seek(0);
+ sal_uInt32 nData;
+ aStream.ReadUInt32(nData); // OLEVersion
+ aStream.ReadUInt32(nData); // FormatID
+ aStream.ReadUInt32(nData); // ClassName
+ aStream.SeekRel(nData);
+ aStream.ReadUInt32(nData); // TopicName
+ aStream.SeekRel(nData);
+ aStream.ReadUInt32(nData); // ItemName
+ aStream.SeekRel(nData);
+ aStream.ReadUInt32(nData); // NativeDataSize
+
+ if (nData)
+ {
+ m_pObjectData.reset(new SvMemoryStream());
+ m_pObjectData->WriteStream(aStream);
+ m_pObjectData->Seek(0);
+ }
+ }
+
+ uno::Reference<io::XInputStream> xInputStream(new utl::OSeekableInputStreamWrapper(m_pObjectData.get()));
+ auto pStreamValue = std::make_shared<RTFValue>(xInputStream);
+ m_aOLEAttributes.set(NS_ooxml::LN_inputstream, pStreamValue);
+
+ return RTFError::OK;
+}
+
bool RTFDocumentImpl::isInBackground()
{
return m_aStates.top().bInBackground;
diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.hxx b/writerfilter/source/rtftok/rtfdocumentimpl.hxx
index 7112c5833eb6..0af39d3ae98a 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.hxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.hxx
@@ -439,6 +439,8 @@ private:
void resetTableRowProperties();
void backupTableRowProperties();
void restoreTableRowProperties();
+ /// Turns the destination text into an input stream of the current OLE attributes.
+ RTFError handleEmbeddedObject();
css::uno::Reference<css::uno::XComponentContext> const& m_xContext;
css::uno::Reference<css::io::XInputStream> const& m_xInputStream;