sw/qa/extras/ooxmlexport/data/toxmarkhyperlink.fodt |   52 ++++++++++++++++++++
 sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx       |    5 +
 sw/source/filter/ww8/docxattributeoutput.cxx        |   32 ++++++++++--
 3 files changed, 83 insertions(+), 6 deletions(-)

New commits:
commit 103efac8110be7e6f42fffcecc74abdcae4df7f9
Author: Michael Stahl <mst...@redhat.com>
Date:   Thu Mar 2 23:11:29 2017 +0100

    tdf#101178 sw: DOCX export: fix crash
    
    These conditions in DocxAttributeOutput::EndRun() are apparently not
    mutually exclusive, so don't increment m_nFieldsInHyperlink twice.
    
    Whether the m_nFieldsInHyperlink makes any sense considering there are
    *2* hyperlinks then, i can't tell.
    
    Change-Id: I5030f3303bd83633fcb044573860bc8ecaacae32

diff --git a/sw/qa/extras/ooxmlexport/data/toxmarkhyperlink.fodt 
b/sw/qa/extras/ooxmlexport/data/toxmarkhyperlink.fodt
index cbc8b59..b1323f6 100644
--- a/sw/qa/extras/ooxmlexport/data/toxmarkhyperlink.fodt
+++ b/sw/qa/extras/ooxmlexport/data/toxmarkhyperlink.fodt
@@ -42,6 +42,7 @@
     <text:p text:style-name="P1"><text:a xlink:type="simple" 
xlink:href="http://example.com/"; text:style-name="Internet_20_link" 
text:visited-style-name="Visited_20_Internet_20_Link"><text:alphabetical-index-mark
 text:string-value="foo" text:key1="bar"/><text:alphabetical-index-mark 
text:string-value="foo" text:key1="baz"/><text:alphabetical-index-mark 
text:string-value="foo" text:key1="quux"/>foo</text:a></text:p>
     <text:p text:style-name="P1"><text:a xlink:type="simple" 
xlink:href="http://example.com/"; text:style-name="Internet_20_link" 
text:visited-style-name="Visited_20_Internet_20_Link">foo<text:alphabetical-index-mark
 text:string-value="foo" text:key1="bar"/><text:alphabetical-index-mark 
text:string-value="foo" text:key1="baz"/><text:alphabetical-index-mark 
text:string-value="foo" text:key1="quux"/></text:a></text:p>
     <text:p text:style-name="P1"><text:a xlink:type="simple" 
xlink:href="http://example.com/"; text:style-name="Internet_20_link" 
text:visited-style-name="Visited_20_Internet_20_Link">foo</text:a><text:alphabetical-index-mark
 text:string-value="foo" text:key1="bar"/><text:a xlink:type="simple" 
xlink:href="http://example.com/"; text:style-name="Internet_20_link" 
text:visited-style-name="Visited_20_Internet_20_Link">bar</text:a></text:p>
+    <text:p text:style-name="P1"><text:a xlink:type="simple" 
xlink:href="http://example.com/"; text:style-name="Internet_20_link" 
text:visited-style-name="Visited_20_Internet_20_Link">foo</text:a><text:a 
xlink:type="simple" xlink:href="http://example.com/"; 
text:style-name="Internet_20_link" 
text:visited-style-name="Visited_20_Internet_20_Link"><text:bibliography-mark 
text:identifier="fuh" text:bibliography-type="www" text:author="FB" 
text:title="foobar" 
text:url="http://example.com/";>[fuh]</text:bibliography-mark></text:a></text:p>
 
       <!--
 <text:a xlink:type="simple" xlink:href="http://example.com/"; 
text:style-name="Internet_20_link" 
text:visited-style-name="Visited_20_Internet_20_Link">foo</text:a>
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx 
b/sw/source/filter/ww8/docxattributeoutput.cxx
index 0212233..6f7acdb 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -1141,12 +1141,9 @@ void DocxAttributeOutput::EndRun()
                 continue;
             }
 
-            if (m_startedHyperlink)
-                ++m_nFieldsInHyperlink;
-
-            if ( m_pHyperlinkAttrList.is() )
+            if (m_startedHyperlink || m_pHyperlinkAttrList.is())
             {
-                m_nFieldsInHyperlink++;
+                ++m_nFieldsInHyperlink;
             }
         }
         ++pIt;
commit 06f9ad262742ea939bf23e82530b7166ca4ce456
Author: Michael Stahl <mst...@redhat.com>
Date:   Thu Mar 2 22:55:27 2017 +0100

    sw: Fix STL assert on DOCX export of ooo29679-42.odt
    
    The problem was that the StartField_Impl() was called again and again on
    the same field (actually 0-length ToXmark with dummy char), or in other
    words, EndField_Impl() wasn't called and it wasn't removed from
    m_Fields.
    
    So tweak the south-pointing chariot DocxAttributeOutput::EndRun() again
    in the hope it will go another km or two before it starts pointing east.
    
    This doesn't actually produce the elements in the ideal order in some
    cases, but given that this code has clearly passed the complexity event
    horizon that is too much to ask for.
    
    Change-Id: I9b031ce8fae91d3e5af3cb1148390807574fb748

diff --git a/sw/qa/extras/ooxmlexport/data/toxmarkhyperlink.fodt 
b/sw/qa/extras/ooxmlexport/data/toxmarkhyperlink.fodt
new file mode 100644
index 0000000..cbc8b59
--- /dev/null
+++ b/sw/qa/extras/ooxmlexport/data/toxmarkhyperlink.fodt
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<office:document 
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" 
xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" 
xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" 
xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" 
xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" 
xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" 
xmlns:xlink="http://www.w3.org/1999/xlink"; 
xmlns:dc="http://purl.org/dc/elements/1.1/"; 
xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" 
xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" 
xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" 
xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" 
xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" 
xmlns:math="http://www.w3.org/1998/Math/MathML"; 
xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" 
xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" 
xmlns:config="urn:oas
 is:names:tc:opendocument:xmlns:config:1.0" 
xmlns:ooo="http://openoffice.org/2004/office"; 
xmlns:ooow="http://openoffice.org/2004/writer"; 
xmlns:oooc="http://openoffice.org/2004/calc"; 
xmlns:dom="http://www.w3.org/2001/xml-events"; 
xmlns:xforms="http://www.w3.org/2002/xforms"; 
xmlns:xsd="http://www.w3.org/2001/XMLSchema"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xmlns:rpt="http://openoffice.org/2005/report"; 
xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" 
xmlns:xhtml="http://www.w3.org/1999/xhtml"; 
xmlns:grddl="http://www.w3.org/2003/g/data-view#"; 
xmlns:officeooo="http://openoffice.org/2009/office"; 
xmlns:tableooo="http://openoffice.org/2009/table"; 
xmlns:drawooo="http://openoffice.org/2010/draw"; 
xmlns:calcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0"
 
xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0"
 xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0" 
xmlns:formx="urn:openoffice:names:
 experimental:ooxml-odf-interop:xmlns:form:1.0" 
xmlns:css3t="http://www.w3.org/TR/css3-text/"; office:version="1.2" 
office:mimetype="application/vnd.oasis.opendocument.text">
+
+ <office:font-face-decls>
+  <style:font-face style:name="Lohit Devanagari1" svg:font-family="&apos;Lohit 
Devanagari&apos;"/>
+  <style:font-face style:name="Liberation Serif" 
svg:font-family="&apos;Liberation Serif&apos;" 
style:font-family-generic="roman" style:font-pitch="variable"/>
+  <style:font-face style:name="Liberation Sans" 
svg:font-family="&apos;Liberation Sans&apos;" style:font-family-generic="swiss" 
style:font-pitch="variable"/>
+  <style:font-face style:name="Lohit Devanagari" svg:font-family="&apos;Lohit 
Devanagari&apos;" style:font-family-generic="system" 
style:font-pitch="variable"/>
+  <style:font-face style:name="Source Han Sans CN Normal" 
svg:font-family="&apos;Source Han Sans CN Normal&apos;" 
style:font-family-generic="system" style:font-pitch="variable"/>
+ </office:font-face-decls>
+ <office:styles>
+  <style:default-style style:family="paragraph">
+   <style:paragraph-properties fo:hyphenation-ladder-count="no-limit" 
style:text-autospace="ideograph-alpha" style:punctuation-wrap="hanging" 
style:line-break="strict" style:tab-stop-distance="1.251cm" 
style:writing-mode="page"/>
+   <style:text-properties style:use-window-font-color="true" 
style:font-name="Liberation Serif" fo:font-size="12pt" fo:language="de" 
fo:country="DE" style:letter-kerning="true" style:font-name-asian="Source Han 
Sans CN Normal" style:font-size-asian="10.5pt" style:language-asian="zh" 
style:country-asian="CN" style:font-name-complex="Lohit Devanagari" 
style:font-size-complex="12pt" style:language-complex="hi" 
style:country-complex="IN" fo:hyphenate="false" 
fo:hyphenation-remain-char-count="2" fo:hyphenation-push-char-count="2"/>
+  </style:default-style>
+
+  <style:style style:name="Standard" style:family="paragraph" 
style:class="text"/>
+  <style:style style:name="Internet_20_link" style:display-name="Internet 
link" style:family="text">
+   <style:text-properties fo:color="#000080" fo:language="zxx" 
fo:country="none" style:text-underline-style="solid" 
style:text-underline-width="auto" style:text-underline-color="font-color" 
style:language-asian="zxx" style:country-asian="none" 
style:language-complex="zxx" style:country-complex="none"/>
+  </style:style>
+
+ </office:styles>
+ <office:automatic-styles>
+  <style:style style:name="P1" style:family="paragraph" 
style:parent-style-name="Standard">
+   <style:text-properties officeooo:rsid="001000a5" 
officeooo:paragraph-rsid="001000a5"/>
+  </style:style>
+  <style:style style:name="Ru1" style:family="ruby">
+   <style:ruby-properties style:ruby-align="left" style:ruby-position="above"/>
+  </style:style>
+ </office:automatic-styles>
+ <office:body>
+  <office:text>
+    <text:p text:style-name="P1"><text:alphabetical-index-mark 
text:string-value="foo" text:key1="bar"/></text:p>
+    <text:p text:style-name="P1"><text:alphabetical-index-mark 
text:string-value="foo" text:key1="bar"/><text:alphabetical-index-mark 
text:string-value="foo" text:key1="baz"/><text:alphabetical-index-mark 
text:string-value="foo" text:key1="quux"/></text:p>
+    <text:p text:style-name="P1"><text:alphabetical-index-mark 
text:string-value="foo" text:key1="bar"/><text:a xlink:type="simple" 
xlink:href="http://example.com/"; text:style-name="Internet_20_link" 
text:visited-style-name="Visited_20_Internet_20_Link">foo</text:a></text:p>
+    <text:p text:style-name="P1"><text:a xlink:type="simple" 
xlink:href="http://example.com/"; text:style-name="Internet_20_link" 
text:visited-style-name="Visited_20_Internet_20_Link">foo</text:a><text:alphabetical-index-mark
 text:string-value="foo" text:key1="bar"/></text:p>
+    <text:p text:style-name="P1"><text:a xlink:type="simple" 
xlink:href="http://example.com/"; text:style-name="Internet_20_link" 
text:visited-style-name="Visited_20_Internet_20_Link"><text:alphabetical-index-mark
 text:string-value="foo" text:key1="bar"/>foo</text:a></text:p>
+    <text:p text:style-name="P1"><text:a xlink:type="simple" 
xlink:href="http://example.com/"; text:style-name="Internet_20_link" 
text:visited-style-name="Visited_20_Internet_20_Link">foo<text:alphabetical-index-mark
 text:string-value="foo" text:key1="bar"/></text:a></text:p>
+    <text:p text:style-name="P1"><text:alphabetical-index-mark 
text:string-value="foo" text:key1="bar"/><text:alphabetical-index-mark 
text:string-value="foo" text:key1="baz"/><text:alphabetical-index-mark 
text:string-value="foo" text:key1="quux"/><text:a xlink:type="simple" 
xlink:href="http://example.com/"; text:style-name="Internet_20_link" 
text:visited-style-name="Visited_20_Internet_20_Link">foo</text:a></text:p>
+    <text:p text:style-name="P1"><text:a xlink:type="simple" 
xlink:href="http://example.com/"; text:style-name="Internet_20_link" 
text:visited-style-name="Visited_20_Internet_20_Link">foo</text:a><text:alphabetical-index-mark
 text:string-value="foo" text:key1="bar"/><text:alphabetical-index-mark 
text:string-value="foo" text:key1="baz"/><text:alphabetical-index-mark 
text:string-value="foo" text:key1="quux"/></text:p>
+    <text:p text:style-name="P1"><text:a xlink:type="simple" 
xlink:href="http://example.com/"; text:style-name="Internet_20_link" 
text:visited-style-name="Visited_20_Internet_20_Link"><text:alphabetical-index-mark
 text:string-value="foo" text:key1="bar"/><text:alphabetical-index-mark 
text:string-value="foo" text:key1="baz"/><text:alphabetical-index-mark 
text:string-value="foo" text:key1="quux"/>foo</text:a></text:p>
+    <text:p text:style-name="P1"><text:a xlink:type="simple" 
xlink:href="http://example.com/"; text:style-name="Internet_20_link" 
text:visited-style-name="Visited_20_Internet_20_Link">foo<text:alphabetical-index-mark
 text:string-value="foo" text:key1="bar"/><text:alphabetical-index-mark 
text:string-value="foo" text:key1="baz"/><text:alphabetical-index-mark 
text:string-value="foo" text:key1="quux"/></text:a></text:p>
+    <text:p text:style-name="P1"><text:a xlink:type="simple" 
xlink:href="http://example.com/"; text:style-name="Internet_20_link" 
text:visited-style-name="Visited_20_Internet_20_Link">foo</text:a><text:alphabetical-index-mark
 text:string-value="foo" text:key1="bar"/><text:a xlink:type="simple" 
xlink:href="http://example.com/"; text:style-name="Internet_20_link" 
text:visited-style-name="Visited_20_Internet_20_Link">bar</text:a></text:p>
+
+      <!--
+<text:a xlink:type="simple" xlink:href="http://example.com/"; 
text:style-name="Internet_20_link" 
text:visited-style-name="Visited_20_Internet_20_Link">foo</text:a>
+   -->
+  </office:text>
+ </office:body>
+</office:document>
diff --git a/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx
index 779e823..ec8b136 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx
@@ -671,6 +671,11 @@ DECLARE_OOXMLEXPORT_TEST(testFixedDateFields, 
"fixed-date-field.docx")
     }
 }
 
+DECLARE_OOXMLEXPORT_TEST(testToxmarkHyperlink, "toxmarkhyperlink.fodt")
+{
+    // test that export doesn't assert with overlapping fields / hyperlink attr
+}
+
 DECLARE_OOXMLEXPORT_TEST(testOO34469, "ooo34469-1.odt")
 {
     if (xmlDocPtr pXmlDoc = parseExport())
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx 
b/sw/source/filter/ww8/docxattributeoutput.cxx
index 1a52d89..0212233 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -1214,8 +1214,31 @@ void DocxAttributeOutput::EndRun()
     }
 
     // Start the hyperlink after the fields separators or we would generate 
invalid file
+    bool newStartedHyperlink(false);
     if ( m_pHyperlinkAttrList.is() )
     {
+        // if we are ending a hyperlink and there's another one starting here,
+        // don't do this, so that the fields are closed further down when
+        // the end hyperlink is handled, which is more likely to put the end in
+        // the right place, as far as i can tell (not very far in this muck)
+        if (!m_closeHyperlinkInThisRun)
+        {
+            // end ToX fields that want to end _before_ starting the hyperlink
+            for (auto it = m_Fields.rbegin(); it != m_Fields.rend(); )
+            {
+                if (it->bClose && !it->pField)
+                {
+                    EndField_Impl(*it);
+                    it = 
decltype(m_Fields)::reverse_iterator(m_Fields.erase(it.base() - 1));
+                }
+                else
+                {
+                    ++it;
+                }
+            }
+        }
+        newStartedHyperlink = true;
+
         XFastAttributeListRef xAttrList ( m_pHyperlinkAttrList.get() );
         m_pHyperlinkAttrList.clear();
 
@@ -1350,7 +1373,7 @@ void DocxAttributeOutput::EndRun()
         m_closeHyperlinkInThisRun = false;
     }
 
-    if (!m_startedHyperlink)
+    if (!newStartedHyperlink)
     {
         while ( m_Fields.begin() != m_Fields.end() )
         {
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to