}
/**
- * 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);
}
}
<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