diff options
author | Andreas L. Delmelle <adelmelle@apache.org> | 2006-09-02 00:52:38 +0000 |
---|---|---|
committer | Andreas L. Delmelle <adelmelle@apache.org> | 2006-09-02 00:52:38 +0000 |
commit | 6b5450d36a58e39798005a2dd6b4192af68bf59c (patch) | |
tree | 7ff3b72484629bbc3c581f3fdc1add171504ff28 | |
parent | 3873a2c6c28a487c3ed7c9b7051f84f4d15653ad (diff) | |
download | xmlgraphics-fop-6b5450d36a58e39798005a2dd6b4192af68bf59c.tar.gz xmlgraphics-fop-6b5450d36a58e39798005a2dd6b4192af68bf59c.zip |
Bugzilla #39414:
Uninterrupted text blocks larger than 32K characters would cause overflows during layout,
so make sure the FOText char arrays are never larger, by splitting them up into multiple
instances.
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@439511 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r-- | src/java/org/apache/fop/fo/FObjMixed.java | 77 | ||||
-rw-r--r-- | status.xml | 6 | ||||
-rw-r--r-- | test/layoutengine/disabled-testcases.xml | 6 |
3 files changed, 55 insertions, 34 deletions
diff --git a/src/java/org/apache/fop/fo/FObjMixed.java b/src/java/org/apache/fop/fo/FObjMixed.java index 67e95c5e8..87f31216b 100644 --- a/src/java/org/apache/fop/fo/FObjMixed.java +++ b/src/java/org/apache/fop/fo/FObjMixed.java @@ -85,40 +85,63 @@ public abstract class FObjMixed extends FObj { } /** - * Adds accumulated text as one FOText instance. - * Makes sure that nested calls to itself do nothing. + * Adds accumulated text as one FOText instance, unless + * the one instance's char array contains more than + * Short.MAX_VALUE characters. In the latter case the + * instance is split up into more manageable chunks. + * * @throws FOPException if there is a problem during processing */ protected void flushText() throws FOPException { - if (ft != null) { + if (ft != null) { FOText lft = ft; + /* make sure nested calls to itself have no effect */ ft = null; - if (getNameId() == FO_BLOCK) { - lft.createBlockPointers((org.apache.fop.fo.flow.Block) this); - this.lastFOTextProcessed = lft; - } else if (getNameId() != FO_MARKER - && getNameId() != FO_TITLE - && getNameId() != FO_BOOKMARK_TITLE) { - FONode fo = parent; - int foNameId = fo.getNameId(); - while (foNameId != FO_BLOCK - && foNameId != FO_MARKER - && foNameId != FO_TITLE - && foNameId != FO_BOOKMARK_TITLE - && foNameId != FO_PAGE_SEQUENCE) { - fo = fo.getParent(); - foNameId = fo.getNameId(); - } - if (foNameId == FO_BLOCK) { - lft.createBlockPointers((org.apache.fop.fo.flow.Block) fo); - ((FObjMixed) fo).lastFOTextProcessed = lft; - } else if (foNameId == FO_PAGE_SEQUENCE) { - log.error("Could not create block pointers." - + " FOText w/o Block ancestor."); + FOText tmpText; + int indexStart = 0; + int indexEnd = (lft.ca.length > Short.MAX_VALUE + ? Short.MAX_VALUE : lft.ca.length) - 1; + int charCount = 0; + short tmpSize; + while (charCount < lft.ca.length) { + tmpSize = (short) (indexEnd - indexStart + 1); + charCount += tmpSize; + tmpText = (FOText) lft.clone(this, false); + tmpText.ca = new char[tmpSize]; + tmpText.startIndex = 0; + tmpText.endIndex = tmpSize; + System.arraycopy(lft.ca, indexStart, + tmpText.ca, 0, indexEnd - indexStart + 1); + if (getNameId() == FO_BLOCK) { + tmpText.createBlockPointers((org.apache.fop.fo.flow.Block) this); + this.lastFOTextProcessed = tmpText; + } else if (getNameId() != FO_MARKER + && getNameId() != FO_TITLE + && getNameId() != FO_BOOKMARK_TITLE) { + FONode fo = parent; + int foNameId = fo.getNameId(); + while (foNameId != FO_BLOCK + && foNameId != FO_MARKER + && foNameId != FO_TITLE + && foNameId != FO_BOOKMARK_TITLE + && foNameId != FO_PAGE_SEQUENCE) { + fo = fo.getParent(); + foNameId = fo.getNameId(); + } + if (foNameId == FO_BLOCK) { + tmpText.createBlockPointers((org.apache.fop.fo.flow.Block) fo); + ((FObjMixed) fo).lastFOTextProcessed = tmpText; + } else if (foNameId == FO_PAGE_SEQUENCE) { + log.error("Could not create block pointers." + + " FOText w/o Block ancestor."); + } } + tmpText.endOfNode(); + addChildNode(tmpText); + indexStart = indexEnd + 1; + indexEnd = (((lft.ca.length - charCount) < Short.MAX_VALUE) + ? lft.ca.length : charCount + Short.MAX_VALUE) - 1; } - lft.endOfNode(); - addChildNode(lft); } } diff --git a/status.xml b/status.xml index 9b4fa0b5c..cdf6f68c3 100644 --- a/status.xml +++ b/status.xml @@ -28,12 +28,16 @@ <changes> <release version="FOP Trunk"> + <action context="Code" dev="AD" type="fix" fixes-bug="39414"> + Split up FOText instances larger than 32K characters to avoid + integer overflow during layout. + </action> <action context="Code" dev="JM" type="fix"> Bugfix: Corrected painting of shading patterns and position of links for SVG images inside FO documents. </action> <action context="Code" dev="AD" type="update"> - Minor fix: correctly set negative values to zero. + Minor fix: correctly set negative values for ipd/bpd to zero. </action> <action context="Code" dev="AD" type="update" fixes-bug="35656"> Rework of default column-creation / column-width setting from diff --git a/test/layoutengine/disabled-testcases.xml b/test/layoutengine/disabled-testcases.xml index 945ded11d..a17668934 100644 --- a/test/layoutengine/disabled-testcases.xml +++ b/test/layoutengine/disabled-testcases.xml @@ -323,10 +323,4 @@ block-level element because its layout manager is written to handle only inline content.</description> </testcase> - <testcase> - <name>Bugzilla #39414: block containing long text</name> - <file>block_bug39414.xml</file> - <description>Long text cause an IndexOutOfBounds exception</description> - <reference>http://issues.apache.org/bugzilla/show_bug.cgi?id=39414</reference> - </testcase> </disabled-testcases>
\ No newline at end of file |