WordML import: fix huge recursion depth in replace-spaces
Bug document: fdo67478-1.doc The replace-spaces template consumed one pair of spaces per recursion level. WordML documents with very long space runs (e.g. 61000 consecutive spaces) exceeded libxslt's 3000 depth limit, causing an import error. Consume the entire consecutive space run in a single call by using translate() to find the first non-space character, counting all leading spaces at once, and emitting a single <text:s text:c="N"/> element. Recursion depth is now bounded by the number of separate space runs, not the total number of spaces. Change-Id: Ifb11a61a2e89274684e1d6d38920c8792598fa43 Reviewed-on: https://gerrit.collaboraoffice.com/c/core/+/62 Reviewed-by: Michael Stahl <michael.stahl@collabora.com> Tested-by: Jenkins CPCI <releng@collaboraoffice.com> (cherry picked from commit 7ba970bce9e1200e5712afe76ec3a85056be9263) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/204666 Tested-by: Jenkins Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
This commit is contained in:
committed by
Xisco Fauli
parent
65cc02da04
commit
cb2bc2ba0e
@@ -1001,21 +1001,37 @@
|
||||
</xsl:template>
|
||||
<xsl:template name="replace-spaces">
|
||||
<xsl:param name="curr-string"/>
|
||||
<xsl:if test="contains($curr-string,' ')">
|
||||
<xsl:value-of select="substring-before($curr-string,' ')"/>
|
||||
<text:s text:c="2"/>
|
||||
<xsl:variable name="next-string" select="substring-after($curr-string,' ')"/>
|
||||
<xsl:choose>
|
||||
<xsl:when test="contains($next-string, ' ')">
|
||||
<xsl:call-template name="replace-spaces">
|
||||
<xsl:with-param name="curr-string" select="$next-string"/>
|
||||
</xsl:call-template>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:value-of select="$next-string"/>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:if>
|
||||
<xsl:choose>
|
||||
<xsl:when test="not(contains($curr-string, ' '))">
|
||||
<xsl:value-of select="$curr-string"/>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:value-of select="substring-before($curr-string, ' ')"/>
|
||||
<xsl:variable name="rest" select="substring-after($curr-string, ' ')"/>
|
||||
<xsl:variable name="rest-no-spaces" select="translate($rest, ' ', '')"/>
|
||||
<xsl:variable name="first-nonspace-char" select="substring($rest-no-spaces, 1, 1)"/>
|
||||
<xsl:choose>
|
||||
<xsl:when test="$first-nonspace-char = ''">
|
||||
<text:s>
|
||||
<xsl:attribute name="text:c">
|
||||
<xsl:value-of select="2 + string-length($rest)"/>
|
||||
</xsl:attribute>
|
||||
</text:s>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:variable name="leading" select="substring-before($rest, $first-nonspace-char)"/>
|
||||
<text:s>
|
||||
<xsl:attribute name="text:c">
|
||||
<xsl:value-of select="2 + string-length($leading)"/>
|
||||
</xsl:attribute>
|
||||
</text:s>
|
||||
<xsl:call-template name="replace-spaces">
|
||||
<xsl:with-param name="curr-string" select="substring($rest, string-length($leading) + 1)"/>
|
||||
</xsl:call-template>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:template>
|
||||
<xsl:template match="w:tab">
|
||||
<xsl:element name="text:tab"/>
|
||||
|
||||
Reference in New Issue
Block a user