]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
Bugzilla #39414:
authorAndreas L. Delmelle <adelmelle@apache.org>
Sat, 2 Sep 2006 00:52:38 +0000 (00:52 +0000)
committerAndreas L. Delmelle <adelmelle@apache.org>
Sat, 2 Sep 2006 00:52:38 +0000 (00:52 +0000)
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

src/java/org/apache/fop/fo/FObjMixed.java
status.xml
test/layoutengine/disabled-testcases.xml

index 67e95c5e8ba4ce267d0b57f38e13ec418350544a..87f31216b8ad1a4e140ab5d88087a55ae285134e 100644 (file)
@@ -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);
         }
     }
 
index 9b4fa0b5ccfccacf760bb304bc6b8eca164b2512..cdf6f68c30c9aa6cb98d2dcbd5e115ccb79839b4 100644 (file)
 
   <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
index 945ded11d4aee857ee2f05912c4954ff6e378294..a17668934e24bfa727136c054a0b1cab79314e47 100644 (file)
     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