aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas L. Delmelle <adelmelle@apache.org>2006-09-02 00:52:38 +0000
committerAndreas L. Delmelle <adelmelle@apache.org>2006-09-02 00:52:38 +0000
commit6b5450d36a58e39798005a2dd6b4192af68bf59c (patch)
tree7ff3b72484629bbc3c581f3fdc1add171504ff28
parent3873a2c6c28a487c3ed7c9b7051f84f4d15653ad (diff)
downloadxmlgraphics-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.java77
-rw-r--r--status.xml6
-rw-r--r--test/layoutengine/disabled-testcases.xml6
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