summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Stahl <mstahl@redhat.com>2014-06-02 23:57:13 +0200
committerMichael Stahl <mstahl@redhat.com>2014-06-03 20:55:12 +0200
commit8cd856d9705fbcd61ad902859769fc98bf6d7a69 (patch)
treeda11c0250dec8851b4a99edbf185b3463b97c82d
parent6c18998d53ad9b1d33173a2004e7086abb98e33f (diff)
fdo#79384: RTF import: fix literal Shift-JIS text
This is a variable-length encoding, and the second byte may be a RTF syntax character like \, {, }. Change-Id: I813ccafda18388af3bf05eb7ce9a0253c627b1c4 (cherry picked from commit 061190a62fcdbfb3a0b266d5afffbd257a3e692e)
-rw-r--r--sw/qa/extras/rtfimport/data/fdo79384.rtf9
-rw-r--r--sw/qa/extras/rtfimport/rtfimport.cxx8
-rw-r--r--writerfilter/source/rtftok/rtfdocumentimpl.cxx34
-rw-r--r--writerfilter/source/rtftok/rtfdocumentimpl.hxx2
4 files changed, 48 insertions, 5 deletions
diff --git a/sw/qa/extras/rtfimport/data/fdo79384.rtf b/sw/qa/extras/rtfimport/data/fdo79384.rtf
new file mode 100644
index 000000000000..2a900852861d
--- /dev/null
+++ b/sw/qa/extras/rtfimport/data/fdo79384.rtf
@@ -0,0 +1,9 @@
+{\rtf1\ansi
+{\fonttbl{\f5\fnil\fprq0\fcharset128 OpenSymbol{\*\falt Arial Unicode MS};}}
+
+\pard\plain
+
+\dbch\f5 „M„p„‚„{„u„‚„ „ƒ„„y„ƒ„{„p
+„}„\
+
+\par }
diff --git a/sw/qa/extras/rtfimport/rtfimport.cxx b/sw/qa/extras/rtfimport/rtfimport.cxx
index e96f03723f72..49e9687385bb 100644
--- a/sw/qa/extras/rtfimport/rtfimport.cxx
+++ b/sw/qa/extras/rtfimport/rtfimport.cxx
@@ -290,6 +290,14 @@ DECLARE_RTFIMPORT_TEST(testN751020, "n751020.rtf")
CPPUNIT_ASSERT_EQUAL(sal_Int32(convertTwipToMm100(200)), getProperty<sal_Int32>(xParaEnum->nextElement(), "ParaBottomMargin"));
}
+DECLARE_RTFIMPORT_TEST(testFdo79384, "fdo79384.rtf")
+{
+ uno::Reference<text::XTextRange> xTextRange = getRun(getParagraph(1), 1);
+
+ CPPUNIT_ASSERT_EQUAL(OUString("ΠœΠ°Ρ€ΠΊΠ΅Ρ€Ρ‹ спискамЫ", 31, RTL_TEXTENCODING_UTF8),
+ xTextRange->getString());
+}
+
DECLARE_RTFIMPORT_TEST(testFdo47326, "fdo47326.rtf")
{
// This was 15 only, as \super buffered text, then the contents of it got lost.
diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
index 686901483b6a..cf989c79f2d2 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
@@ -980,9 +980,33 @@ int RTFDocumentImpl::resolveChars(char ch)
m_aStates.top().nCharsToSkip--;
}
}
+
// read a single char if we're in hex mode
if (m_aStates.top().nInternalState == INTERNAL_HEX)
break;
+
+ if (RTFParserState::DBCH == m_aStates.top().eRunType &&
+ RTL_TEXTENCODING_MS_932 == m_aStates.top().nCurrentEncoding)
+ {
+ unsigned char uch = ch;
+ if ((uch >= 0x80 && uch <= 0x9F) || uch >= 0xE0)
+ {
+ // read second byte of 2-byte Shift-JIS - may be \ { }
+ Strm().ReadChar(ch);
+ if (m_aStates.top().nCharsToSkip == 0)
+ {
+ assert(bUnicodeChecked);
+ aBuf.append(ch);
+ }
+ else
+ {
+ assert(bSkipped);
+ // anybody who uses \ucN with Shift-JIS is insane
+ m_aStates.top().nCharsToSkip--;
+ }
+ }
+ }
+
Strm().ReadChar(ch);
}
if (m_aStates.top().nInternalState != INTERNAL_HEX && !Strm().IsEof())
@@ -2980,12 +3004,13 @@ int RTFDocumentImpl::dispatchFlag(RTFKeyword nKeyword)
break;
case RTF_LOCH:
// Noop, dmapper detects this automatically.
+ m_aStates.top().eRunType = RTFParserState::LOCH;
break;
case RTF_HICH:
- m_aStates.top().bIsCjk = true;
+ m_aStates.top().eRunType = RTFParserState::HICH;
break;
case RTF_DBCH:
- m_aStates.top().bIsCjk = false;
+ m_aStates.top().eRunType = RTFParserState::DBCH;
break;
case RTF_TITLEPG:
{
@@ -3471,7 +3496,8 @@ int RTFDocumentImpl::dispatchValue(RTFKeyword nKeyword, int nParam)
if (nKeyword == RTF_F)
nSprm = NS_ooxml::LN_CT_Fonts_ascii;
else
- nSprm = (m_aStates.top().bIsCjk ? NS_ooxml::LN_CT_Fonts_eastAsia : NS_ooxml::LN_CT_Fonts_cs);
+ nSprm = (m_aStates.top().eRunType == RTFParserState::HICH
+ ? NS_ooxml::LN_CT_Fonts_eastAsia : NS_ooxml::LN_CT_Fonts_cs);
if (m_aStates.top().nDestinationState == DESTINATION_FONTTABLE || m_aStates.top().nDestinationState == DESTINATION_FONTENTRY)
{
m_aFontIndexes.push_back(nParam);
@@ -5714,7 +5740,7 @@ RTFParserState::RTFParserState(RTFDocumentImpl* pDocumentImpl)
aShape(),
aDrawingObject(),
aFrame(this),
- bIsCjk(false),
+ eRunType(LOCH),
nYear(0),
nMonth(0),
nDay(0),
diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.hxx b/writerfilter/source/rtftok/rtfdocumentimpl.hxx
index 3c7d2f318008..d069baa2ca1d 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.hxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.hxx
@@ -256,7 +256,7 @@ public:
RTFFrame aFrame;
/// CJK or CTL?
- bool bIsCjk;
+ enum { LOCH, HICH, DBCH } eRunType;
// Info group.
int nYear;