Skip to content

Commit a7eb0f0

Browse files
committed
Implement memory limits aware handler.
DEVSIX-2856 Autoported commit. Original commit hash: [696df73] Manual files: kernel/src/main/java/com/itextpdf/kernel/pdf/MemoryLimitsAwareOutputStream.java
1 parent 8897768 commit a7eb0f0

22 files changed

+1194
-30
lines changed
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
/*
2+
This file is part of the iText (R) project.
3+
Copyright (c) 1998-2019 iText Group NV
4+
Authors: iText Software.
5+
6+
This program is free software; you can redistribute it and/or modify
7+
it under the terms of the GNU Affero General Public License version 3
8+
as published by the Free Software Foundation with the addition of the
9+
following permission added to Section 15 as permitted in Section 7(a):
10+
FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
11+
ITEXT GROUP. ITEXT GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
12+
OF THIRD PARTY RIGHTS
13+
14+
This program is distributed in the hope that it will be useful, but
15+
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16+
or FITNESS FOR A PARTICULAR PURPOSE.
17+
See the GNU Affero General Public License for more details.
18+
You should have received a copy of the GNU Affero General Public License
19+
along with this program; if not, see http://www.gnu.org/licenses or write to
20+
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21+
Boston, MA, 02110-1301 USA, or download the license from the following URL:
22+
http://itextpdf.com/terms-of-use/
23+
24+
The interactive user interfaces in modified source and object code versions
25+
of this program must display Appropriate Legal Notices, as required under
26+
Section 5 of the GNU Affero General Public License.
27+
28+
In accordance with Section 7(b) of the GNU Affero General Public License,
29+
a covered work must retain the producer line in every PDF that is created
30+
or manipulated using iText.
31+
32+
You can be released from the requirements of the license by purchasing
33+
a commercial license. Buying such a license is mandatory as soon as you
34+
develop commercial activities involving the iText software without
35+
disclosing the source code of your own applications.
36+
These activities include: offering paid services to customers as an ASP,
37+
serving PDFs on the fly in a web application, shipping iText with a closed
38+
source product.
39+
40+
For more information, please contact iText Software Corp. at this
41+
42+
*/
43+
using System;
44+
using iText.Kernel;
45+
46+
namespace iText.Kernel.Pdf {
47+
public class MemoryLimitsAwareHandlerTest {
48+
[NUnit.Framework.Test]
49+
public virtual void DefaultMemoryHandler() {
50+
MemoryLimitsAwareHandler handler = new MemoryLimitsAwareHandler();
51+
NUnit.Framework.Assert.AreEqual(int.MaxValue / 100, handler.GetMaxSizeOfSingleDecompressedPdfStream());
52+
NUnit.Framework.Assert.AreEqual(int.MaxValue / 20, handler.GetMaxSizeOfDecompressedPdfStreamsSum());
53+
}
54+
55+
[NUnit.Framework.Test]
56+
public virtual void CustomMemoryHandler() {
57+
MemoryLimitsAwareHandler handler = new MemoryLimitsAwareHandler(1000000);
58+
NUnit.Framework.Assert.AreEqual(100000000, handler.GetMaxSizeOfSingleDecompressedPdfStream());
59+
NUnit.Framework.Assert.AreEqual(500000000, handler.GetMaxSizeOfDecompressedPdfStreamsSum());
60+
}
61+
62+
[NUnit.Framework.Test]
63+
public virtual void DefaultSingleMemoryHandler() {
64+
MemoryLimitsAwareHandler handler = new MemoryLimitsAwareHandler();
65+
TestSingleStream(handler);
66+
}
67+
68+
[NUnit.Framework.Test]
69+
public virtual void DefaultMultipleMemoryHandler() {
70+
MemoryLimitsAwareHandler handler = new MemoryLimitsAwareHandler();
71+
TestMultipleStreams(handler);
72+
}
73+
74+
[NUnit.Framework.Test]
75+
public virtual void ConsiderBytesTest() {
76+
MemoryLimitsAwareHandler handler = new MemoryLimitsAwareHandler();
77+
long state1 = handler.GetAllMemoryUsedForDecompression();
78+
handler.ConsiderBytesOccupiedByDecompressedPdfStream(100);
79+
long state2 = handler.GetAllMemoryUsedForDecompression();
80+
NUnit.Framework.Assert.AreEqual(state1, state2);
81+
handler.BeginDecompressedPdfStreamProcessing();
82+
handler.ConsiderBytesOccupiedByDecompressedPdfStream(100);
83+
long state3 = handler.GetAllMemoryUsedForDecompression();
84+
NUnit.Framework.Assert.AreEqual(state1, state3);
85+
handler.ConsiderBytesOccupiedByDecompressedPdfStream(80);
86+
long state4 = handler.GetAllMemoryUsedForDecompression();
87+
NUnit.Framework.Assert.AreEqual(state1, state4);
88+
handler.EndDecompressedPdfStreamProcessing();
89+
long state5 = handler.GetAllMemoryUsedForDecompression();
90+
NUnit.Framework.Assert.AreEqual(state1 + 100, state5);
91+
}
92+
93+
private static void TestSingleStream(MemoryLimitsAwareHandler handler) {
94+
String expectedExceptionMessage = PdfException.DuringDecompressionSingleStreamOccupiedMoreMemoryThanAllowed;
95+
int expectedFailureIndex = 10;
96+
String occuredExceptionMessage = null;
97+
int limit = handler.GetMaxSizeOfSingleDecompressedPdfStream();
98+
long step = limit / 10;
99+
int i = 0;
100+
try {
101+
handler.BeginDecompressedPdfStreamProcessing();
102+
for (i = 0; i < 11; i++) {
103+
handler.ConsiderBytesOccupiedByDecompressedPdfStream(step * (1 + i));
104+
}
105+
handler.EndDecompressedPdfStreamProcessing();
106+
}
107+
catch (MemoryLimitsAwareException e) {
108+
occuredExceptionMessage = e.Message;
109+
}
110+
NUnit.Framework.Assert.AreEqual(expectedFailureIndex, i);
111+
NUnit.Framework.Assert.AreEqual(expectedExceptionMessage, occuredExceptionMessage);
112+
}
113+
114+
private static void TestMultipleStreams(MemoryLimitsAwareHandler handler) {
115+
String expectedExceptionMessage = PdfException.DuringDecompressionMultipleStreamsInSumOccupiedMoreMemoryThanAllowed;
116+
int expectedFailureIndex = 10;
117+
String occuredExceptionMessage = null;
118+
int i = 0;
119+
try {
120+
long limit = handler.GetMaxSizeOfDecompressedPdfStreamsSum();
121+
long step = limit / 10;
122+
for (i = 0; i < 11; i++) {
123+
handler.BeginDecompressedPdfStreamProcessing();
124+
handler.ConsiderBytesOccupiedByDecompressedPdfStream(step);
125+
handler.EndDecompressedPdfStreamProcessing();
126+
}
127+
}
128+
catch (MemoryLimitsAwareException e) {
129+
occuredExceptionMessage = e.Message;
130+
}
131+
NUnit.Framework.Assert.AreEqual(expectedFailureIndex, i);
132+
NUnit.Framework.Assert.AreEqual(expectedExceptionMessage, occuredExceptionMessage);
133+
}
134+
}
135+
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/*
2+
This file is part of the iText (R) project.
3+
Copyright (c) 1998-2019 iText Group NV
4+
Authors: iText Software.
5+
6+
This program is free software; you can redistribute it and/or modify
7+
it under the terms of the GNU Affero General Public License version 3
8+
as published by the Free Software Foundation with the addition of the
9+
following permission added to Section 15 as permitted in Section 7(a):
10+
FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
11+
ITEXT GROUP. ITEXT GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
12+
OF THIRD PARTY RIGHTS
13+
14+
This program is distributed in the hope that it will be useful, but
15+
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16+
or FITNESS FOR A PARTICULAR PURPOSE.
17+
See the GNU Affero General Public License for more details.
18+
You should have received a copy of the GNU Affero General Public License
19+
along with this program; if not, see http://www.gnu.org/licenses or write to
20+
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21+
Boston, MA, 02110-1301 USA, or download the license from the following URL:
22+
http://itextpdf.com/terms-of-use/
23+
24+
The interactive user interfaces in modified source and object code versions
25+
of this program must display Appropriate Legal Notices, as required under
26+
Section 5 of the GNU Affero General Public License.
27+
28+
In accordance with Section 7(b) of the GNU Affero General Public License,
29+
a covered work must retain the producer line in every PDF that is created
30+
or manipulated using iText.
31+
32+
You can be released from the requirements of the license by purchasing
33+
a commercial license. Buying such a license is mandatory as soon as you
34+
develop commercial activities involving the iText software without
35+
disclosing the source code of your own applications.
36+
These activities include: offering paid services to customers as an ASP,
37+
serving PDFs on the fly in a web application, shipping iText with a closed
38+
source product.
39+
40+
For more information, please contact iText Software Corp. at this
41+
42+
*/
43+
using System;
44+
45+
namespace iText.Kernel.Pdf {
46+
public class MemoryLimitsAwareOutputStreamTest {
47+
[NUnit.Framework.Test]
48+
public virtual void TestMaxSize() {
49+
NUnit.Framework.Assert.That(() => {
50+
byte[] bigArray = new byte[70];
51+
byte[] smallArray = new byte[31];
52+
MemoryLimitsAwareOutputStream stream = new MemoryLimitsAwareOutputStream();
53+
stream.SetMaxStreamSize(100);
54+
NUnit.Framework.Assert.AreEqual(100, stream.GetMaxStreamSize());
55+
stream.Write(bigArray, 0, bigArray.Length);
56+
NUnit.Framework.Assert.AreEqual(bigArray.Length, stream.Length);
57+
stream.Write(smallArray, 0, smallArray.Length);
58+
}
59+
, NUnit.Framework.Throws.InstanceOf<MemoryLimitsAwareException>())
60+
;
61+
}
62+
63+
[NUnit.Framework.Test]
64+
public virtual void TestNegativeSize() {
65+
NUnit.Framework.Assert.That(() => {
66+
byte[] zeroArray = new byte[0];
67+
MemoryLimitsAwareOutputStream stream = new MemoryLimitsAwareOutputStream();
68+
stream.SetMaxStreamSize(-100);
69+
NUnit.Framework.Assert.AreEqual(-100, stream.GetMaxStreamSize());
70+
stream.Write(zeroArray, 0, zeroArray.Length);
71+
}
72+
, NUnit.Framework.Throws.InstanceOf<MemoryLimitsAwareException>())
73+
;
74+
}
75+
76+
[NUnit.Framework.Test]
77+
public virtual void TestIncorrectLength() {
78+
NUnit.Framework.Assert.That(() => {
79+
MemoryLimitsAwareOutputStream stream = new MemoryLimitsAwareOutputStream();
80+
stream.Write(new byte[1], 0, -1);
81+
}
82+
, NUnit.Framework.Throws.InstanceOf<IndexOutOfRangeException>())
83+
;
84+
}
85+
}
86+
}

0 commit comments

Comments
 (0)