diff --git a/barcodes/pom.xml b/barcodes/pom.xml index 30b7a8af74..78706b84b4 100644 --- a/barcodes/pom.xml +++ b/barcodes/pom.xml @@ -4,7 +4,7 @@ com.itextpdf root - 7.1.15 + 7.1.16 barcodes iText 7 - barcodes diff --git a/barcodes/src/test/java/com/itextpdf/barcodes/BarcodeDataMatrixTest.java b/barcodes/src/test/java/com/itextpdf/barcodes/BarcodeDataMatrixTest.java index af955e167b..70857b1b30 100644 --- a/barcodes/src/test/java/com/itextpdf/barcodes/BarcodeDataMatrixTest.java +++ b/barcodes/src/test/java/com/itextpdf/barcodes/BarcodeDataMatrixTest.java @@ -52,13 +52,12 @@ This file is part of the iText (R) project. import com.itextpdf.kernel.utils.CompareTool; import com.itextpdf.test.ExtendedITextTest; import com.itextpdf.test.annotations.type.IntegrationTest; + import java.io.IOException; import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(IntegrationTest.class) public class BarcodeDataMatrixTest extends ExtendedITextTest { @@ -66,9 +65,6 @@ public class BarcodeDataMatrixTest extends ExtendedITextTest { public static final String destinationFolder = "./target/test/com/itextpdf/barcodes/BarcodeDataMatrix/"; public static final String sourceFolder = "./src/test/resources/com/itextpdf/barcodes/"; - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @BeforeClass public static void beforeClass() { createOrClearDestinationFolder(destinationFolder); @@ -191,6 +187,7 @@ public void barcode07Test() { String aCode = "aBCdeFG12"; int result = bc.setCode(aCode); + Assert.assertEquals(result, BarcodeDataMatrix.DM_ERROR_TEXT_TOO_BIG); } @@ -200,6 +197,7 @@ public void barcode08Test() { barcodeDataMatrix.setWidth(18); barcodeDataMatrix.setHeight(18); int result = barcodeDataMatrix.setCode("AbcdFFghijklmnopqrstuWXSQ"); + Assert.assertEquals(BarcodeDataMatrix.DM_ERROR_TEXT_TOO_BIG, result); } @@ -209,6 +207,7 @@ public void barcode09Test() { barcodeDataMatrix.setWidth(17); barcodeDataMatrix.setHeight(17); int result = barcodeDataMatrix.setCode("AbcdFFghijklmnopqrstuWXSQ"); + Assert.assertEquals(BarcodeDataMatrix.DM_ERROR_INVALID_SQUARE, result); } @@ -218,6 +217,7 @@ public void barcode10Test() { barcodeDataMatrix.setWidth(26); barcodeDataMatrix.setHeight(12); int result = barcodeDataMatrix.setCode("AbcdFFghijklmnopqrstuWXSQ"); + Assert.assertEquals(BarcodeDataMatrix.DM_ERROR_TEXT_TOO_BIG, result); } @@ -228,37 +228,38 @@ public void barcode11Test() { barcodeDataMatrix.setHeight(18); byte[] str = "AbcdFFghijklmnop".getBytes(); int result = barcodeDataMatrix.setCode(str, 0, str.length); + Assert.assertEquals(BarcodeDataMatrix.DM_NO_ERROR, result); } @Test public void barcode12Test() { - junitExpectedException.expect(IndexOutOfBoundsException.class); BarcodeDataMatrix barcodeDataMatrix = new BarcodeDataMatrix(); barcodeDataMatrix.setWidth(18); barcodeDataMatrix.setHeight(18); byte[] str = "AbcdFFghijklmnop".getBytes(); - barcodeDataMatrix.setCode(str, -1, str.length); + + Exception e = Assert.assertThrows(IndexOutOfBoundsException.class, () -> barcodeDataMatrix.setCode(str, -1, str.length)); } @Test public void barcode13Test() { - junitExpectedException.expect(IndexOutOfBoundsException.class); BarcodeDataMatrix barcodeDataMatrix = new BarcodeDataMatrix(); barcodeDataMatrix.setWidth(18); barcodeDataMatrix.setHeight(18); byte[] str = "AbcdFFghijklmnop".getBytes(); - barcodeDataMatrix.setCode(str, 0, str.length + 1); + + Assert.assertThrows(IndexOutOfBoundsException.class, () -> barcodeDataMatrix.setCode(str, 0, str.length + 1)); } @Test public void barcode14Test() { - junitExpectedException.expect(IndexOutOfBoundsException.class); BarcodeDataMatrix barcodeDataMatrix = new BarcodeDataMatrix(); barcodeDataMatrix.setWidth(18); barcodeDataMatrix.setHeight(18); byte[] str = "AbcdFFghijklmnop".getBytes(); - barcodeDataMatrix.setCode(str, 0, -1); + + Assert.assertThrows(IndexOutOfBoundsException.class, () -> barcodeDataMatrix.setCode(str, 0, -1)); } @Test @@ -268,6 +269,7 @@ public void barcode15Test() { barcodeDataMatrix.setHeight(18); byte[] str = "AbcdFFghijklmnop".getBytes(); int result = barcodeDataMatrix.setCode(str, str.length, 0); + Assert.assertEquals(BarcodeDataMatrix.DM_NO_ERROR, result); } diff --git a/barcodes/src/test/java/com/itextpdf/barcodes/BarcodeEANUnitTest.java b/barcodes/src/test/java/com/itextpdf/barcodes/BarcodeEANUnitTest.java index 922d4fe685..1dae99b9fa 100644 --- a/barcodes/src/test/java/com/itextpdf/barcodes/BarcodeEANUnitTest.java +++ b/barcodes/src/test/java/com/itextpdf/barcodes/BarcodeEANUnitTest.java @@ -51,19 +51,14 @@ This file is part of the iText (R) project. import java.io.ByteArrayOutputStream; import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(UnitTest.class) public class BarcodeEANUnitTest extends ExtendedITextTest { public static final float EPS = 0.0001f; - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void calculateEANParityTest() throws PdfException { int expectedParity = BarcodeEAN.calculateEANParity("1234567890"); @@ -227,9 +222,6 @@ public void getBarcodeSizeSUPP2Test() throws PdfException { @Test public void getBarcodeSizeIncorrectTypeTest() throws PdfException { - junitExpectedException.expect(PdfException.class); - junitExpectedException.expectMessage("Invalid code type"); - PdfDocument document = new PdfDocument(new PdfWriter(new ByteArrayOutputStream())); Barcode1D barcode = new BarcodeEAN(document); @@ -239,6 +231,7 @@ public void getBarcodeSizeIncorrectTypeTest() throws PdfException { barcode.setCodeType(1234); // We do expect an exception here - barcode.getBarcodeSize(); + Exception e = Assert.assertThrows(PdfException.class, () -> barcode.getBarcodeSize()); + Assert.assertEquals("Invalid code type", e.getMessage()); } } diff --git a/barcodes/src/test/java/com/itextpdf/barcodes/BarcodePDF417Test.java b/barcodes/src/test/java/com/itextpdf/barcodes/BarcodePDF417Test.java index 54fe72e238..4a8d75ae1c 100644 --- a/barcodes/src/test/java/com/itextpdf/barcodes/BarcodePDF417Test.java +++ b/barcodes/src/test/java/com/itextpdf/barcodes/BarcodePDF417Test.java @@ -62,10 +62,8 @@ This file is part of the iText (R) project. import java.io.IOException; import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(IntegrationTest.class) public class BarcodePDF417Test extends ExtendedITextTest { @@ -77,9 +75,6 @@ public static void beforeClass() { createDestinationFolder(destinationFolder); } - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void barcode01Test() throws IOException, PdfException, InterruptedException { String filename = "barcode417_01.pdf"; @@ -440,9 +435,6 @@ public void barcode417OptionsWithBarcodeGenerationTest() { @Test public void barcode417OptionsWithBarcodeGenerationInvalidSizeTest() { - junitExpectedException.expect(PdfException.class); - junitExpectedException.expectMessage("Invalid codeword size."); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); PdfWriter writer = new PdfWriter(baos); PdfDocument document = new PdfDocument(writer); @@ -452,8 +444,11 @@ public void barcode417OptionsWithBarcodeGenerationInvalidSizeTest() { BarcodePDF417 barcode = new BarcodePDF417(); barcode.setOptions(64); - barcode.placeBarcode(canvas, null); + Exception e = Assert.assertThrows(PdfException.class, + () -> barcode.placeBarcode(canvas, null) + ); + Assert.assertEquals("Invalid codeword size.", e.getMessage()); Assert.assertEquals(64, barcode.getOptions()); } diff --git a/font-asian/pom.xml b/font-asian/pom.xml index c2fc5fd7ee..5a43dc0d66 100644 --- a/font-asian/pom.xml +++ b/font-asian/pom.xml @@ -4,7 +4,7 @@ com.itextpdf root - 7.1.15 + 7.1.16 font-asian iText 7 - Asian fonts diff --git a/forms/pom.xml b/forms/pom.xml index fb42fb40af..cc11f50353 100644 --- a/forms/pom.xml +++ b/forms/pom.xml @@ -4,7 +4,7 @@ com.itextpdf root - 7.1.15 + 7.1.16 forms iText 7 - forms diff --git a/forms/src/main/java/com/itextpdf/forms/xfa/XfaForm.java b/forms/src/main/java/com/itextpdf/forms/xfa/XfaForm.java index 36ebb40c0a..c3942b0b07 100644 --- a/forms/src/main/java/com/itextpdf/forms/xfa/XfaForm.java +++ b/forms/src/main/java/com/itextpdf/forms/xfa/XfaForm.java @@ -54,28 +54,24 @@ This file is part of the iText (R) project. import com.itextpdf.kernel.pdf.PdfString; import com.itextpdf.kernel.pdf.PdfVersion; import com.itextpdf.kernel.pdf.VersionConforming; +import com.itextpdf.kernel.utils.XmlProcessorCreator; import com.itextpdf.kernel.xmp.XmlDomWriter; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; - import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; -import java.io.StringReader; import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Map; - +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.ParserConfigurationException; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; -import org.xml.sax.EntityResolver; import org.xml.sax.InputSource; import org.xml.sax.SAXException; @@ -107,13 +103,14 @@ public XfaForm() { /** * Creates an XFA form by the stream containing all xml information + * * @param inputStream the InputStream */ public XfaForm(InputStream inputStream) { try { initXfaForm(inputStream); } catch (Exception e) { - throw new PdfException(e); + throw new PdfException(e.getMessage(), e); } } @@ -140,7 +137,7 @@ public XfaForm(PdfDictionary acroFormDictionary) { try { initXfaForm(xfa); } catch (Exception e) { - throw new PdfException(e); + throw new PdfException(e.getMessage(), e); } } } @@ -157,7 +154,7 @@ public XfaForm(PdfDocument pdfDocument) { try { initXfaForm(xfa); } catch (Exception e) { - throw new PdfException(e); + throw new PdfException(e.getMessage(), e); } } } @@ -497,17 +494,12 @@ public void fillXfaForm(InputSource is) throws IOException { * @throws java.io.IOException if any I/O issue occurs on the {@link InputSource} */ public void fillXfaForm(InputSource is, boolean readOnly) throws IOException { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - DocumentBuilder db; try { - db = dbf.newDocumentBuilder(); - db.setEntityResolver(new SafeEmptyEntityResolver()); + DocumentBuilder db = XmlProcessorCreator.createSafeDocumentBuilder(false, false); Document newdoc = db.parse(is); fillXfaForm(newdoc.getDocumentElement(), readOnly); - } catch (ParserConfigurationException e) { - throw new PdfException(e); } catch (SAXException e) { - throw new PdfException(e); + throw new PdfException(e.getMessage(), e); } } @@ -631,11 +623,8 @@ private void initXfaForm(PdfObject xfa) throws IOException, ParserConfigurationE initXfaForm(new ByteArrayInputStream(bout.toByteArray())); } - private void initXfaForm(InputStream inputStream) throws ParserConfigurationException, IOException, SAXException { - DocumentBuilderFactory fact = DocumentBuilderFactory.newInstance(); - fact.setNamespaceAware(true); - DocumentBuilder db = fact.newDocumentBuilder(); - db.setEntityResolver(new SafeEmptyEntityResolver()); + private void initXfaForm(InputStream inputStream) throws IOException, SAXException { + DocumentBuilder db = XmlProcessorCreator.createSafeDocumentBuilder(true, false); setDomDocument(db.parse(inputStream)); xfaPresent = true; } @@ -696,12 +685,4 @@ private Node findDataNode(Node datasetsNode) { } return null; } - - // Prevents XXE attacks - private static class SafeEmptyEntityResolver implements EntityResolver { - public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException { - return new InputSource(new StringReader("")); - } - } - } diff --git a/forms/src/main/java/com/itextpdf/forms/xfdf/XfdfFileUtils.java b/forms/src/main/java/com/itextpdf/forms/xfdf/XfdfFileUtils.java index 1a7c857a56..7df65453da 100644 --- a/forms/src/main/java/com/itextpdf/forms/xfdf/XfdfFileUtils.java +++ b/forms/src/main/java/com/itextpdf/forms/xfdf/XfdfFileUtils.java @@ -42,24 +42,20 @@ This file is part of the iText (R) project. */ package com.itextpdf.forms.xfdf; -import org.w3c.dom.Document; -import org.xml.sax.EntityResolver; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; +import com.itextpdf.kernel.PdfException; +import com.itextpdf.kernel.utils.XmlProcessorCreator; +import java.io.InputStream; +import java.io.OutputStream; import javax.xml.XMLConstants; import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.StringReader; +import org.w3c.dom.Document; final class XfdfFileUtils { @@ -68,32 +64,40 @@ private XfdfFileUtils() { /** * Creates a new xml-styled document for writing xfdf info. + * * @throws ParserConfigurationException in case of failure to create a new document. */ - static Document createNewXfdfDocument() throws ParserConfigurationException { - DocumentBuilderFactory documentFactory = DocumentBuilderFactory.newInstance(); - DocumentBuilder documentBuilder = documentFactory.newDocumentBuilder(); - documentBuilder.setEntityResolver(new XfdfFileUtils.SafeEmptyEntityResolver()); - return documentBuilder.newDocument(); + static Document createNewXfdfDocument() { + try { + DocumentBuilder db = XmlProcessorCreator.createSafeDocumentBuilder(false, false); + return db.newDocument(); + } catch (Exception e) { + throw new PdfException(e.getMessage(), e); + } } /** * Creates a new xfdf document based on given input stream. + * * @param inputStream containing xfdf info. */ - static Document createXfdfDocumentFromStream(InputStream inputStream) throws ParserConfigurationException, IOException, SAXException { - DocumentBuilderFactory documentFactory = DocumentBuilderFactory.newInstance(); - DocumentBuilder documentBuilder = documentFactory.newDocumentBuilder(); - documentBuilder.setEntityResolver(new XfdfFileUtils.SafeEmptyEntityResolver()); - return documentBuilder.parse(inputStream); + static Document createXfdfDocumentFromStream(InputStream inputStream) { + try { + DocumentBuilder db = XmlProcessorCreator.createSafeDocumentBuilder(false, false); + return db.parse(inputStream); + } catch (Exception e) { + throw new PdfException(e.getMessage(), e); + } } /** - * Saves the info from output stream to xml-styled document. - * @param document to save info to. - * @param outputStream the stream containing xfdf info. + * Saves the info from XML-styled {@link Document} to {@link OutputStream}. + * + * @param document input {@link Document} that contains XFDF info + * @param outputStream the output stream */ - static void saveXfdfDocumentToFile(Document document, OutputStream outputStream) throws TransformerException { + static void saveXfdfDocumentToFile(Document document, OutputStream outputStream) + throws TransformerException { TransformerFactory transformerFactory = TransformerFactory.newInstance(); transformerFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); @@ -103,11 +107,4 @@ static void saveXfdfDocumentToFile(Document document, OutputStream outputStream) StreamResult streamResult = new StreamResult(outputStream); transformer.transform(domSource, streamResult); } - - // Prevents XXE attacks - private static class SafeEmptyEntityResolver implements EntityResolver { - public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException { - return new InputSource(new StringReader("")); - } - } } diff --git a/forms/src/test/java/com/itextpdf/forms/XfdfUnitTest.java b/forms/src/test/java/com/itextpdf/forms/XfdfUnitTest.java index c5e5da7c82..9b1d9efa60 100644 --- a/forms/src/test/java/com/itextpdf/forms/XfdfUnitTest.java +++ b/forms/src/test/java/com/itextpdf/forms/XfdfUnitTest.java @@ -28,25 +28,17 @@ This file is part of the iText (R) project. import com.itextpdf.test.annotations.type.UnitTest; import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(UnitTest.class) public class XfdfUnitTest extends ExtendedITextTest { - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void fitObjectWithEmptyPageTest(){ - junitExpectedException.expect(XfdfException.class); - junitExpectedException.expectMessage(XfdfException.PAGE_IS_MISSING); - - FitObject fitObject = new FitObject(null); - - Assert.fail(); + Exception e = Assert.assertThrows(XfdfException.class, + () -> new FitObject(null) + ); + Assert.assertEquals(XfdfException.PAGE_IS_MISSING, e.getMessage()); } - } diff --git a/forms/src/test/java/com/itextpdf/forms/XfdfWriterTest.java b/forms/src/test/java/com/itextpdf/forms/XfdfWriterTest.java index bae0e48cc0..aa0f6486e9 100644 --- a/forms/src/test/java/com/itextpdf/forms/XfdfWriterTest.java +++ b/forms/src/test/java/com/itextpdf/forms/XfdfWriterTest.java @@ -58,12 +58,9 @@ This file is part of the iText (R) project. import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; import org.xml.sax.SAXException; - import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.TransformerException; import java.io.FileInputStream; @@ -75,10 +72,6 @@ public class XfdfWriterTest extends ExtendedITextTest { public static final String sourceFolder = "./src/test/resources/com/itextpdf/forms/XfdfWriterTest/"; public static final String destinationFolder = "./target/test/com/itextpdf/forms/XfdfWriterTest/"; - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - - @BeforeClass public static void beforeClass() { createDestinationFolder(destinationFolder); @@ -1047,10 +1040,6 @@ public void xfdfDropDown() throws IOException, ParserConfigurationException, SAX @Test public void xfdfEmptyAttributeTest() { - - junitExpectedException.expect(XfdfException.class); - junitExpectedException.expectMessage(XfdfException.ATTRIBUTE_NAME_OR_VALUE_MISSING); - XfdfObject xfdfObject = new XfdfObject(); AnnotsObject annots = new AnnotsObject(); @@ -1064,8 +1053,13 @@ public void xfdfEmptyAttributeTest() { String valuePresent = "value"; String valueAbsent = null; - annot.addAttribute(new AttributeObject(nameAbsent, valuePresent)); - annot.addAttribute(new AttributeObject(namePresent, valueAbsent)); - + Exception e = Assert.assertThrows(XfdfException.class, + () -> annot.addAttribute(new AttributeObject(nameAbsent, valuePresent)) + ); + Assert.assertEquals(XfdfException.ATTRIBUTE_NAME_OR_VALUE_MISSING, e.getMessage()); + Exception e2 = Assert.assertThrows(XfdfException.class, + () -> annot.addAttribute(new AttributeObject(namePresent, valueAbsent)) + ); + Assert.assertEquals(XfdfException.ATTRIBUTE_NAME_OR_VALUE_MISSING, e2.getMessage()); } } diff --git a/forms/src/test/java/com/itextpdf/forms/xfa/SecurityTestXmlParserFactory.java b/forms/src/test/java/com/itextpdf/forms/xfa/SecurityTestXmlParserFactory.java new file mode 100644 index 0000000000..b5fb6c83b9 --- /dev/null +++ b/forms/src/test/java/com/itextpdf/forms/xfa/SecurityTestXmlParserFactory.java @@ -0,0 +1,75 @@ +/* + This file is part of the iText (R) project. + Copyright (c) 1998-2021 iText Group NV + Authors: iText Software. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License version 3 + as published by the Free Software Foundation with the addition of the + following permission added to Section 15 as permitted in Section 7(a): + FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY + ITEXT GROUP. ITEXT GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT + OF THIRD PARTY RIGHTS + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Affero General Public License for more details. + You should have received a copy of the GNU Affero General Public License + along with this program; if not, see http://www.gnu.org/licenses or write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA, 02110-1301 USA, or download the license from the following URL: + http://itextpdf.com/terms-of-use/ + + The interactive user interfaces in modified source and object code versions + of this program must display Appropriate Legal Notices, as required under + Section 5 of the GNU Affero General Public License. + + In accordance with Section 7(b) of the GNU Affero General Public License, + a covered work must retain the producer line in every PDF that is created + or manipulated using iText. + + You can be released from the requirements of the license by purchasing + a commercial license. Buying such a license is mandatory as soon as you + develop commercial activities involving the iText software without + disclosing the source code of your own applications. + These activities include: offering paid services to customers as an ASP, + serving PDFs on the fly in a web application, shipping iText with a closed + source product. + + For more information, please contact iText Software Corp. at this + address: sales@itextpdf.com + */ +package com.itextpdf.forms.xfa; + +import com.itextpdf.kernel.PdfException; +import com.itextpdf.kernel.utils.DefaultSafeXmlParserFactory; +import com.itextpdf.test.ExceptionTestUtil; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import org.xml.sax.EntityResolver; +import org.xml.sax.InputSource; + +public class SecurityTestXmlParserFactory extends DefaultSafeXmlParserFactory { + + @Override + public DocumentBuilder createDocumentBuilderInstance(boolean namespaceAware, boolean ignoringComments) { + DocumentBuilder db; + try { + db = DocumentBuilderFactory.newInstance().newDocumentBuilder(); + } catch (ParserConfigurationException e) { + throw new PdfException(e.getMessage(), e); + } + + db.setEntityResolver(new TestEntityResolver()); + return db; + } + + private static class TestEntityResolver implements EntityResolver { + public InputSource resolveEntity(String publicId, String systemId) { + throw new PdfException(ExceptionTestUtil.getXxeTestMessage()); + } + } +} \ No newline at end of file diff --git a/forms/src/test/java/com/itextpdf/forms/xfa/XfaSecurityTest.java b/forms/src/test/java/com/itextpdf/forms/xfa/XfaSecurityTest.java new file mode 100644 index 0000000000..efc57160a5 --- /dev/null +++ b/forms/src/test/java/com/itextpdf/forms/xfa/XfaSecurityTest.java @@ -0,0 +1,148 @@ +/* + This file is part of the iText (R) project. + Copyright (c) 1998-2021 iText Group NV + Authors: iText Software. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License version 3 + as published by the Free Software Foundation with the addition of the + following permission added to Section 15 as permitted in Section 7(a): + FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY + ITEXT GROUP. ITEXT GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT + OF THIRD PARTY RIGHTS + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Affero General Public License for more details. + You should have received a copy of the GNU Affero General Public License + along with this program; if not, see http://www.gnu.org/licenses or write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA, 02110-1301 USA, or download the license from the following URL: + http://itextpdf.com/terms-of-use/ + + The interactive user interfaces in modified source and object code versions + of this program must display Appropriate Legal Notices, as required under + Section 5 of the GNU Affero General Public License. + + In accordance with Section 7(b) of the GNU Affero General Public License, + a covered work must retain the producer line in every PDF that is created + or manipulated using iText. + + You can be released from the requirements of the license by purchasing + a commercial license. Buying such a license is mandatory as soon as you + develop commercial activities involving the iText software without + disclosing the source code of your own applications. + These activities include: offering paid services to customers as an ASP, + serving PDFs on the fly in a web application, shipping iText with a closed + source product. + + For more information, please contact iText Software Corp. at this + address: sales@itextpdf.com + */ +package com.itextpdf.forms.xfa; + +import com.itextpdf.forms.PdfAcroForm; +import com.itextpdf.kernel.PdfException; +import com.itextpdf.kernel.pdf.PdfDocument; +import com.itextpdf.kernel.pdf.PdfReader; +import com.itextpdf.kernel.pdf.PdfWriter; +import com.itextpdf.kernel.utils.DefaultSafeXmlParserFactory; +import com.itextpdf.kernel.utils.XmlProcessorCreator; +import com.itextpdf.test.ExceptionTestUtil; +import com.itextpdf.test.ExtendedITextTest; +import com.itextpdf.test.annotations.type.IntegrationTest; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +@Category(IntegrationTest.class) +public class XfaSecurityTest extends ExtendedITextTest { + + private static final String SOURCE_FOLDER = "./src/test/resources/com/itextpdf/forms/xfa/XfaSecurityTest/"; + + private static final String DTD_EXCEPTION_MESSAGE = ExceptionTestUtil.getDoctypeIsDisallowedExceptionMessage(); + + private static final String XFA_WITH_DTD_XML = "\n" + + "\n" + + "\n" + + "\n" + + "\n"; + + @Before + public void resetXmlParserFactoryToDefault() { + XmlProcessorCreator.setXmlParserFactory(new DefaultSafeXmlParserFactory()); + } + + @Test + public void xfaExternalFileTest() throws IOException { + xfaSecurityExceptionTest(SOURCE_FOLDER + "xfaExternalFile.pdf"); + } + + @Test + public void xfaExternalConnectionTest() throws IOException { + xfaSecurityExceptionTest(SOURCE_FOLDER + "xfaExternalConnection.pdf"); + } + + @Test + public void xfaInternalEntityTest() throws IOException { + xfaSecurityExceptionTest(SOURCE_FOLDER + "xfaInternalEntity.pdf"); + } + + @Test + public void xfaExternalFileCustomFactoryTest() throws IOException { + String inFileName = SOURCE_FOLDER + "xfaExternalFile.pdf"; + XmlProcessorCreator.setXmlParserFactory(new SecurityTestXmlParserFactory()); + try (PdfDocument pdfDoc = new PdfDocument(new PdfReader(inFileName), + new PdfWriter(new ByteArrayOutputStream()))) { + Exception e = Assert.assertThrows(PdfException.class, + () -> PdfAcroForm.getAcroForm(pdfDoc, true) + ); + Assert.assertEquals(ExceptionTestUtil.getXxeTestMessage(), e.getMessage()); + } + } + + @Test + public void xfaExternalFileXfaFormTest() throws IOException { + String inFileName = SOURCE_FOLDER + "xfaExternalFile.pdf"; + try (PdfDocument pdfDoc = new PdfDocument(new PdfReader(inFileName))) { + Exception e = Assert.assertThrows(PdfException.class, () -> new XfaForm(pdfDoc)); + Assert.assertEquals(DTD_EXCEPTION_MESSAGE, e.getMessage()); + } + } + + @Test + public void xfaWithDtdXfaFormTest() throws IOException { + try (InputStream inputStream = new ByteArrayInputStream(XFA_WITH_DTD_XML.getBytes(StandardCharsets.UTF_8))) { + Exception e = Assert.assertThrows(PdfException.class, () -> new XfaForm(inputStream)); + Assert.assertEquals(DTD_EXCEPTION_MESSAGE, e.getMessage()); + } + } + + @Test + public void fillXfaFormTest() throws IOException { + try (InputStream inputStream = new ByteArrayInputStream(XFA_WITH_DTD_XML.getBytes(StandardCharsets.UTF_8))) { + XfaForm form = new XfaForm(); + Exception e = Assert.assertThrows(PdfException.class, () -> form.fillXfaForm(inputStream, true)); + Assert.assertEquals(DTD_EXCEPTION_MESSAGE, e.getMessage()); + } + } + + private void xfaSecurityExceptionTest(String inputFileName) throws IOException { + try (PdfDocument pdfDoc = new PdfDocument(new PdfReader(inputFileName), + new PdfWriter(new ByteArrayOutputStream()))) { + Exception e = Assert.assertThrows(PdfException.class, + () -> PdfAcroForm.getAcroForm(pdfDoc, true) + ); + Assert.assertEquals(DTD_EXCEPTION_MESSAGE, e.getMessage()); + } + } +} diff --git a/forms/src/test/java/com/itextpdf/forms/xfdf/ExceptionTestXmlParserFactory.java b/forms/src/test/java/com/itextpdf/forms/xfdf/ExceptionTestXmlParserFactory.java new file mode 100644 index 0000000000..47cd505acd --- /dev/null +++ b/forms/src/test/java/com/itextpdf/forms/xfdf/ExceptionTestXmlParserFactory.java @@ -0,0 +1,36 @@ +/* + This file is part of the iText (R) project. + Copyright (c) 1998-2021 iText Group NV + Authors: iText Software. + + This program is offered under a commercial and under the AGPL license. + For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below. + + AGPL licensing: + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + */ +package com.itextpdf.forms.xfdf; + +import com.itextpdf.kernel.PdfException; +import com.itextpdf.kernel.utils.DefaultSafeXmlParserFactory; +import com.itextpdf.test.ExceptionTestUtil; + +import javax.xml.parsers.DocumentBuilder; + +public class ExceptionTestXmlParserFactory extends DefaultSafeXmlParserFactory { + @Override + public DocumentBuilder createDocumentBuilderInstance(boolean namespaceAware, boolean ignoringComments) { + throw new PdfException(ExceptionTestUtil.getXxeTestMessage()); + } +} diff --git a/forms/src/test/java/com/itextpdf/forms/xfdf/SecurityTestXmlParserFactory.java b/forms/src/test/java/com/itextpdf/forms/xfdf/SecurityTestXmlParserFactory.java new file mode 100644 index 0000000000..7493f2d71d --- /dev/null +++ b/forms/src/test/java/com/itextpdf/forms/xfdf/SecurityTestXmlParserFactory.java @@ -0,0 +1,72 @@ +/* + This file is part of the iText (R) project. + Copyright (c) 1998-2021 iText Group NV + Authors: iText Software. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License version 3 + as published by the Free Software Foundation with the addition of the + following permission added to Section 15 as permitted in Section 7(a): + FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY + ITEXT GROUP. ITEXT GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT + OF THIRD PARTY RIGHTS + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Affero General Public License for more details. + You should have received a copy of the GNU Affero General Public License + along with this program; if not, see http://www.gnu.org/licenses or write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA, 02110-1301 USA, or download the license from the following URL: + http://itextpdf.com/terms-of-use/ + + The interactive user interfaces in modified source and object code versions + of this program must display Appropriate Legal Notices, as required under + Section 5 of the GNU Affero General Public License. + + In accordance with Section 7(b) of the GNU Affero General Public License, + a covered work must retain the producer line in every PDF that is created + or manipulated using iText. + + You can be released from the requirements of the license by purchasing + a commercial license. Buying such a license is mandatory as soon as you + develop commercial activities involving the iText software without + disclosing the source code of your own applications. + These activities include: offering paid services to customers as an ASP, + serving PDFs on the fly in a web application, shipping iText with a closed + source product. + + For more information, please contact iText Software Corp. at this + address: sales@itextpdf.com + */ +package com.itextpdf.forms.xfdf; + +import com.itextpdf.kernel.PdfException; +import com.itextpdf.kernel.utils.DefaultSafeXmlParserFactory; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import org.xml.sax.EntityResolver; +import org.xml.sax.InputSource; + +class SecurityTestXmlParserFactory extends DefaultSafeXmlParserFactory { + @Override + public DocumentBuilder createDocumentBuilderInstance(boolean namespaceAware, boolean ignoringComments) { + DocumentBuilder db; + try { + db = DocumentBuilderFactory.newInstance().newDocumentBuilder(); + } catch (ParserConfigurationException e) { + throw new PdfException(e.getMessage(), e); + } + db.setEntityResolver(new TestEntityResolver()); + return db; + } + + private static class TestEntityResolver implements EntityResolver { + public InputSource resolveEntity(String publicId, String systemId) { + throw new PdfException("Test message"); + } + } +} \ No newline at end of file diff --git a/forms/src/test/java/com/itextpdf/forms/xfdf/XfdfSecurityTest.java b/forms/src/test/java/com/itextpdf/forms/xfdf/XfdfSecurityTest.java new file mode 100644 index 0000000000..5ae919cd8b --- /dev/null +++ b/forms/src/test/java/com/itextpdf/forms/xfdf/XfdfSecurityTest.java @@ -0,0 +1,110 @@ +/* + This file is part of the iText (R) project. + Copyright (c) 1998-2021 iText Group NV + Authors: iText Software. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License version 3 + as published by the Free Software Foundation with the addition of the + following permission added to Section 15 as permitted in Section 7(a): + FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY + ITEXT GROUP. ITEXT GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT + OF THIRD PARTY RIGHTS + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Affero General Public License for more details. + You should have received a copy of the GNU Affero General Public License + along with this program; if not, see http://www.gnu.org/licenses or write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA, 02110-1301 USA, or download the license from the following URL: + http://itextpdf.com/terms-of-use/ + + The interactive user interfaces in modified source and object code versions + of this program must display Appropriate Legal Notices, as required under + Section 5 of the GNU Affero General Public License. + + In accordance with Section 7(b) of the GNU Affero General Public License, + a covered work must retain the producer line in every PDF that is created + or manipulated using iText. + + You can be released from the requirements of the license by purchasing + a commercial license. Buying such a license is mandatory as soon as you + develop commercial activities involving the iText software without + disclosing the source code of your own applications. + These activities include: offering paid services to customers as an ASP, + serving PDFs on the fly in a web application, shipping iText with a closed + source product. + + For more information, please contact iText Software Corp. at this + address: sales@itextpdf.com + */ +package com.itextpdf.forms.xfdf; + +import com.itextpdf.kernel.PdfException; +import com.itextpdf.kernel.utils.DefaultSafeXmlParserFactory; +import com.itextpdf.kernel.utils.XmlProcessorCreator; +import com.itextpdf.test.ExceptionTestUtil; +import com.itextpdf.test.ExtendedITextTest; +import com.itextpdf.test.annotations.type.UnitTest; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import org.junit.Assert; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +@Category(UnitTest.class) +public class XfdfSecurityTest extends ExtendedITextTest { + + private static final String XFDF_WITH_XXE = " \n" + + " ]>\n" + + "\n" + + "\n" + + "ABCDEFGH&xxe;\n" + + "\n" + + ""; + + @Test + public void xxeVulnerabilityXfdfTest() + throws IOException { + XmlProcessorCreator.setXmlParserFactory(new DefaultSafeXmlParserFactory()); + try (InputStream inputStream = new ByteArrayInputStream(XFDF_WITH_XXE.getBytes(StandardCharsets.UTF_8))) { + Exception e = Assert.assertThrows(PdfException.class, + () -> XfdfFileUtils.createXfdfDocumentFromStream(inputStream) + ); + Assert.assertEquals(ExceptionTestUtil.getDoctypeIsDisallowedExceptionMessage(), e.getMessage()); + } + } + + @Test + public void xxeVulnerabilityXfdfCustomXmlParserTest() + throws IOException { + XmlProcessorCreator.setXmlParserFactory(new SecurityTestXmlParserFactory()); + try (InputStream inputStream = new ByteArrayInputStream(XFDF_WITH_XXE.getBytes(StandardCharsets.UTF_8))) { + Exception e = Assert.assertThrows(PdfException.class, + () -> XfdfFileUtils.createXfdfDocumentFromStream(inputStream) + ); + Assert.assertEquals("Test message", e.getMessage()); + } + } + + @Test + public void customXmlParserCreateNewXfdfDocumentExceptionTest() + throws IOException { + XmlProcessorCreator.setXmlParserFactory(new ExceptionTestXmlParserFactory()); + Exception e = Assert.assertThrows(PdfException.class, + () -> XfdfFileUtils.createNewXfdfDocument() + ); + Assert.assertEquals(ExceptionTestUtil.getXxeTestMessage(), e.getMessage()); + } +} diff --git a/forms/src/test/resources/com/itextpdf/forms/PdfFormFieldMultilineTextTest/cmp_multilineFormFieldNewLineFontType3Test.pdf b/forms/src/test/resources/com/itextpdf/forms/PdfFormFieldMultilineTextTest/cmp_multilineFormFieldNewLineFontType3Test.pdf index 30e4628074..42461a60ad 100644 Binary files a/forms/src/test/resources/com/itextpdf/forms/PdfFormFieldMultilineTextTest/cmp_multilineFormFieldNewLineFontType3Test.pdf and b/forms/src/test/resources/com/itextpdf/forms/PdfFormFieldMultilineTextTest/cmp_multilineFormFieldNewLineFontType3Test.pdf differ diff --git a/forms/src/test/resources/com/itextpdf/forms/xfa/XXEVulnerabilityTest/cmp_outXfaExternalConnection.pdf b/forms/src/test/resources/com/itextpdf/forms/xfa/XXEVulnerabilityTest/cmp_outXfaExternalConnection.pdf deleted file mode 100644 index a6ae0b7359..0000000000 Binary files a/forms/src/test/resources/com/itextpdf/forms/xfa/XXEVulnerabilityTest/cmp_outXfaExternalConnection.pdf and /dev/null differ diff --git a/forms/src/test/resources/com/itextpdf/forms/xfa/XXEVulnerabilityTest/xfaExternalConnection.pdf b/forms/src/test/resources/com/itextpdf/forms/xfa/XfaSecurityTest/xfaExternalConnection.pdf similarity index 100% rename from forms/src/test/resources/com/itextpdf/forms/xfa/XXEVulnerabilityTest/xfaExternalConnection.pdf rename to forms/src/test/resources/com/itextpdf/forms/xfa/XfaSecurityTest/xfaExternalConnection.pdf diff --git a/forms/src/test/resources/com/itextpdf/forms/xfa/XXEVulnerabilityTest/xfaExternalFile.pdf b/forms/src/test/resources/com/itextpdf/forms/xfa/XfaSecurityTest/xfaExternalFile.pdf similarity index 100% rename from forms/src/test/resources/com/itextpdf/forms/xfa/XXEVulnerabilityTest/xfaExternalFile.pdf rename to forms/src/test/resources/com/itextpdf/forms/xfa/XfaSecurityTest/xfaExternalFile.pdf diff --git a/forms/src/test/resources/com/itextpdf/forms/xfa/XXEVulnerabilityTest/cmp_outXfaExternalFile.pdf b/forms/src/test/resources/com/itextpdf/forms/xfa/XfaSecurityTest/xfaInternalEntity.pdf similarity index 92% rename from forms/src/test/resources/com/itextpdf/forms/xfa/XXEVulnerabilityTest/cmp_outXfaExternalFile.pdf rename to forms/src/test/resources/com/itextpdf/forms/xfa/XfaSecurityTest/xfaInternalEntity.pdf index 5a77104c62..e28a0a914a 100644 Binary files a/forms/src/test/resources/com/itextpdf/forms/xfa/XXEVulnerabilityTest/cmp_outXfaExternalFile.pdf and b/forms/src/test/resources/com/itextpdf/forms/xfa/XfaSecurityTest/xfaInternalEntity.pdf differ diff --git a/hyph/pom.xml b/hyph/pom.xml index 3d33c1b32c..9d129de9c3 100644 --- a/hyph/pom.xml +++ b/hyph/pom.xml @@ -4,7 +4,7 @@ com.itextpdf root - 7.1.15 + 7.1.16 hyph iText 7 - hyph diff --git a/hyph/src/main/resources/com/itextpdf/hyph/da.xml b/hyph/src/main/resources/com/itextpdf/hyph/da.xml index 44174cf558..5caa986a94 100644 --- a/hyph/src/main/resources/com/itextpdf/hyph/da.xml +++ b/hyph/src/main/resources/com/itextpdf/hyph/da.xml @@ -15,7 +15,6 @@ limitations under the License. --> - diff --git a/hyph/src/main/resources/com/itextpdf/hyph/it.xml b/hyph/src/main/resources/com/itextpdf/hyph/it.xml index 948a1c2bb8..fa5cf39618 100644 --- a/hyph/src/main/resources/com/itextpdf/hyph/it.xml +++ b/hyph/src/main/resources/com/itextpdf/hyph/it.xml @@ -1,5 +1,4 @@ - diff --git a/hyph/src/main/resources/com/itextpdf/hyph/nl.xml b/hyph/src/main/resources/com/itextpdf/hyph/nl.xml index 2877794b2d..008d06e24f 100644 --- a/hyph/src/main/resources/com/itextpdf/hyph/nl.xml +++ b/hyph/src/main/resources/com/itextpdf/hyph/nl.xml @@ -1,5 +1,4 @@ - - аРdiff --git a/hyph/src/main/resources/com/itextpdf/hyph/sk.xml b/hyph/src/main/resources/com/itextpdf/hyph/sk.xml index e990d1cb9e..a04d48775b 100644 --- a/hyph/src/main/resources/com/itextpdf/hyph/sk.xml +++ b/hyph/src/main/resources/com/itextpdf/hyph/sk.xml @@ -1,5 +1,4 @@ - diff --git a/io/pom.xml b/io/pom.xml index 76bbf8f43b..d55bb95f87 100644 --- a/io/pom.xml +++ b/io/pom.xml @@ -4,7 +4,7 @@ com.itextpdf root - 7.1.15 + 7.1.16 io iText 7 - io diff --git a/io/src/main/java/com/itextpdf/io/LogMessageConstant.java b/io/src/main/java/com/itextpdf/io/LogMessageConstant.java index f1928dffda..2e1199d16b 100644 --- a/io/src/main/java/com/itextpdf/io/LogMessageConstant.java +++ b/io/src/main/java/com/itextpdf/io/LogMessageConstant.java @@ -82,6 +82,11 @@ public final class LogMessageConstant { public static final String COMB_FLAG_MAY_BE_SET_ONLY_IF_MAXLEN_IS_PRESENT = "The Comb flag may be set only if the MaxLen entry is present in the text field dictionary and if the Multiline, Password, and FileSelect flags are clear."; public static final String COULD_NOT_FIND_GLYPH_WITH_CODE = "Could not find glyph with the following code: {0}"; public static final String CREATED_ROOT_TAG_HAS_MAPPING = "Created root tag has role mapping: \"/Document\" role{0} is mapped{1}. Resulting tag structure might have invalid root tag."; + public static final String CREATE_COPY_SHOULD_BE_OVERRIDDEN = "While processing an instance of TextRenderer, " + + "iText uses createCopy() to create glyph lines of specific fonts, which represent its parts. " + + "So if one extends TextRenderer, one should override createCopy, otherwise if FontSelector " + + "related logic is triggered, copies of this TextRenderer will have the default behavior " + + "rather than the custom one."; public static final String DESTINATION_NOT_PERMITTED_WHEN_ACTION_IS_SET = "Destinations are not permitted for link annotations that already have actions. The old action will be removed."; public static final String DIRECTONLY_OBJECT_CANNOT_BE_INDIRECT = "DirectOnly object cannot be indirect"; public static final String DOCFONT_HAS_ILLEGAL_DIFFERENCES = "Document Font has illegal differences array. Entry {0} references a glyph ID over 255 and will be ignored."; @@ -110,6 +115,8 @@ public final class LogMessageConstant { public static final String FAILED_TO_PROCESS_A_TRANSFORMATION_MATRIX = "Failed to process a transformation matrix which is noninvertible. Some content may be placed not as expected."; public static final String FIELD_VALUE_IS_NOT_CONTAINED_IN_OPT_ARRAY = "Value \"{0}\" is not contained in /Opt array of field \"{1}\"."; public static final String FILE_CHANNEL_CLOSING_FAILED = "Closing of the file channel this source is based on failed."; + public static final String FLEX_ITEM_LAYOUT_RESULT_IS_NOT_FULL = + "Flex item layout result isn't full, but it must be. The cross size of the flex item will be 0."; public static final String FLUSHED_OBJECT_CONTAINS_FREE_REFERENCE = "Flushed object contains indirect reference which is free. Null object will be written instead."; public static final String FLUSHED_OBJECT_CONTAINS_REFERENCE_WHICH_NOT_REFER_TO_ANY_OBJECT = "Flushed object contains indirect reference which doesn't refer to any other object. Null object will be written instead."; public static final String FONT_DICTIONARY_WITH_NO_FONT_DESCRIPTOR = "Font dictionary does not contain required /FontDescriptor entry."; @@ -120,6 +127,10 @@ public final class LogMessageConstant { public static final String FONT_SUBSET_ISSUE = "Font subset issue. Full font will be embedded."; public static final String FORBID_RELEASE_IS_SET = "ForbidRelease flag is set and release is called. Releasing will not be performed."; public static final String FORM_FIELD_WAS_FLUSHED = "A form field was flushed. There's no way to create this field in the AcroForm dictionary."; + public static final String GET_NEXT_RENDERER_SHOULD_BE_OVERRIDDEN = "If a renderer overflows, " + + "iText uses this method to create another renderer for the overflow part. So if one wants " + + "to extend the renderer, one should override this method: otherwise the default method " + + "will be used and thus the default rather than the custom renderer will be created."; public static final String GPOS_LOOKUP_SUBTABLE_FORMAT_NOT_SUPPORTED = "Subtable format {0} of GPOS Lookup Type {1} is not supported yet"; public static final String GRAPHICS_STATE_WAS_DELETED = "Graphics state is always deleted after event dispatching. If you want to preserve it in renderer info, use preserveGraphicsState method after receiving renderer info."; @@ -143,6 +154,7 @@ public final class LogMessageConstant { public static final String INDIRECT_REFERENCE_USED_IN_FLUSHED_OBJECT_MADE_FREE = "An attempt is made to free an indirect reference which was already used in the flushed object. Indirect reference wasn't freed."; public static final String INLINE_BLOCK_ELEMENT_WILL_BE_CLIPPED = "Inline block element does not fit into parent element and will be clipped"; public static final String INPUT_STREAM_CONTENT_IS_LOST_ON_PDFSTREAM_SERIALIZATION = "PdfStream contains not null input stream. It's content will be lost in serialized object."; + public static final String INVALID_DISTRIBUTION_POINT = "Skipped CRL: {0}"; public static final String INVALID_DESTINATION_TYPE = "When destination's not associated with a Remote or Embedded Go-To action, it shall specify page dictionary instead of page number. Otherwise destination might be considered invalid"; public static final String INVALID_INDIRECT_REFERENCE = "Invalid indirect reference {0} {1} R"; public static final String INVALID_KEY_VALUE_KEY_0_HAS_NULL_VALUE = "Invalid key value: key {0} has null value."; diff --git a/io/src/main/java/com/itextpdf/io/font/FontMetrics.java b/io/src/main/java/com/itextpdf/io/font/FontMetrics.java index 32cbd3a4cd..926d3e1a5c 100644 --- a/io/src/main/java/com/itextpdf/io/font/FontMetrics.java +++ b/io/src/main/java/com/itextpdf/io/font/FontMetrics.java @@ -118,14 +118,39 @@ public int[] getGlyphWidths() { return glyphWidths; } + /** + * Gets typo (a.k.a. sTypo or OS/2) vertical metric corresponding to ascender. + * + *

+ * Typo vertical metrics are the primary source for iText ascender/descender calculations. + * + * @return typo ascender value in normalized 1000-units + */ public int getTypoAscender() { return typoAscender; } + /** + * Gets typo (a.k.a. sTypo or OS/2) vertical metric corresponding to descender. + * + *

+ * Typo vertical metrics are the primary source for iText ascender/descender calculations. + * + * @return typo descender value in normalized 1000-units + */ public int getTypoDescender() { return typoDescender; } + /** + * Gets the capital letters height. + * + *

+ * This property defines the vertical coordinate of the top of flat capital letters, + * measured from the baseline. + * + * @return cap height in 1000-units + */ public int getCapHeight() { return capHeight; } @@ -237,14 +262,39 @@ protected void setGlyphWidths(int[] glyphWidths) { this.glyphWidths = glyphWidths; } + /** + * Sets typo (a.k.a. sTypo or OS/2) vertical metric corresponding to ascender. + * + *

+ * Typo vertical metrics are the primary source for iText ascender/descender calculations. + * + * @param typoAscender typo ascender value in normalized 1000-units + */ protected void setTypoAscender(int typoAscender) { this.typoAscender = (int) (typoAscender * normalizationCoef); } - protected void setTypoDescender(int typoDesctender) { - this.typoDescender = (int) (typoDesctender * normalizationCoef); - } - + /** + * Sets typo (a.k.a. sTypo or OS/2) vertical metric corresponding to descender. + * + *

+ * Typo vertical metrics are the primary source for iText ascender/descender calculations. + * + * @param typoDescender typo descender value in normalized 1000-units + */ + protected void setTypoDescender(int typoDescender) { + this.typoDescender = (int) (typoDescender * normalizationCoef); + } + + /** + * Sets the capital letters height. + * + *

+ * This property defines the vertical coordinate of the top of flat capital letters, + * measured from the baseline. + * + * @param capHeight cap height in 1000-units + */ protected void setCapHeight(int capHeight) { this.capHeight = (int) (capHeight * normalizationCoef); } diff --git a/io/src/main/java/com/itextpdf/io/font/FontProgram.java b/io/src/main/java/com/itextpdf/io/font/FontProgram.java index 0b0bc5bda2..2aa0afa25d 100644 --- a/io/src/main/java/com/itextpdf/io/font/FontProgram.java +++ b/io/src/main/java/com/itextpdf/io/font/FontProgram.java @@ -200,14 +200,29 @@ static String trimFontStyle(String name) { } } + /** + * Sets typo ascender. See also {@link FontMetrics#setTypoAscender(int)}. + * + * @param ascender typo ascender value in 1000-units + */ protected void setTypoAscender(int ascender) { fontMetrics.setTypoAscender(ascender); } + /** + * Sets typo descender. See also {@link FontMetrics#setTypoDescender(int)}. + * + * @param descender typo descender value in 1000-units + */ protected void setTypoDescender(int descender) { fontMetrics.setTypoDescender(descender); } + /** + * Sets the capital letters height. See also {@link FontMetrics#setCapHeight(int)}. + * + * @param capHeight cap height in 1000-units + */ protected void setCapHeight(int capHeight) { fontMetrics.setCapHeight(capHeight); } @@ -217,7 +232,8 @@ protected void setXHeight(int xHeight) { } /** - * Sets the PostScript italic angel. + * Sets the PostScript italic angle. + * *

* Italic angle in counter-clockwise degrees from the vertical. Zero for upright text, negative for text that leans to the right (forward). * diff --git a/io/src/main/java/com/itextpdf/io/image/ImageTypeDetector.java b/io/src/main/java/com/itextpdf/io/image/ImageTypeDetector.java index d4ad102369..b9f7305ee8 100644 --- a/io/src/main/java/com/itextpdf/io/image/ImageTypeDetector.java +++ b/io/src/main/java/com/itextpdf/io/image/ImageTypeDetector.java @@ -49,7 +49,8 @@ private ImageTypeDetector() { } /** - * Detect image type by magic bytes given the byte array source + * Detect image type by magic bytes given the byte array source. + * * @param source image bytes * @return detected image type, see{@link ImageType}. Returns {@link ImageType#NONE} if image type is unknown */ @@ -59,7 +60,8 @@ public static ImageType detectImageType(byte[] source) { } /** - * Detect image type by magic bytes given the source URL + * Detect image type by magic bytes given the source URL. + * * @param source image URL * @return detected image type, see{@link ImageType}. Returns {@link ImageType#NONE} if image type is unknown */ @@ -68,6 +70,17 @@ public static ImageType detectImageType(URL source) { return detectImageTypeByHeader(header); } + /** + * Detect image type by magic bytes given the input stream. + * + * @param stream image stream + * @return detected image type, see{@link ImageType}. Returns {@link ImageType#NONE} if image type is unknown + */ + public static ImageType detectImageType(InputStream stream) { + byte[] header = readImageType(stream); + return detectImageTypeByHeader(header); + } + private static ImageType detectImageTypeByHeader(byte[] header) { if (imageTypeIs(header, gif)) { return ImageType.GIF; @@ -99,6 +112,14 @@ private static boolean imageTypeIs(byte[] imageType, byte[] compareWith) { private static byte[] readImageType(URL source) { try (InputStream stream = UrlUtil.openStream(source)) { + return readImageType(stream); + } catch (java.io.IOException e) { + throw new IOException(IOException.IoException, e); + } + } + + private static byte[] readImageType(InputStream stream) { + try { byte[] bytes = new byte[8]; stream.read(bytes); return bytes; diff --git a/io/src/main/java/com/itextpdf/io/util/GhostscriptHelper.java b/io/src/main/java/com/itextpdf/io/util/GhostscriptHelper.java index 9ae020245c..7aeaf05c15 100644 --- a/io/src/main/java/com/itextpdf/io/util/GhostscriptHelper.java +++ b/io/src/main/java/com/itextpdf/io/util/GhostscriptHelper.java @@ -47,6 +47,16 @@ This file is part of the iText (R) project. import java.io.IOException; +/** + * A utility class that is used as an interface to run 3rd-party tool Ghostscript. + * Ghostscript is an interpreter for the PostScript language and PDF files, it allows to render them + * as images. + * + *

+ * The Ghostscript needs to be installed independently on the system. This class provides a convenient + * way to run it by passing a terminal command. The command can either be specified explicitly or by a mean + * of environment variable {@link #GHOSTSCRIPT_ENVIRONMENT_VARIABLE}. + */ public class GhostscriptHelper { /** * The name of the environment variable with the command to execute Ghostscript operations. @@ -62,10 +72,19 @@ public class GhostscriptHelper { private String gsExec; + /** + * Creates new instance that will rely on Ghostscript execution command defined by {@link + * #GHOSTSCRIPT_ENVIRONMENT_VARIABLE} environment variable. + */ public GhostscriptHelper() { this(null); } + /** + * Creates new instance that will rely on Ghostscript execution command defined as passed argument. + * + * @param newGsExec the Ghostscript execution command; if null - environment variables will be used instead + */ public GhostscriptHelper(String newGsExec) { gsExec = newGsExec; if (gsExec == null) { @@ -98,10 +117,12 @@ public String getCliExecutionCommand() { * @param pdf Path to the pdf file. * @param outDir Path to the output directory * @param image Path to the generated image + * * @throws IOException if there are file's reading/writing issues * @throws InterruptedException if there is thread interruption while executing GhostScript. */ - public void runGhostScriptImageGeneration(String pdf, String outDir, String image) throws IOException, InterruptedException { + public void runGhostScriptImageGeneration(String pdf, String outDir, String image) + throws IOException, InterruptedException { runGhostScriptImageGeneration(pdf, outDir, image, null); } @@ -114,13 +135,15 @@ public void runGhostScriptImageGeneration(String pdf, String outDir, String imag * @param pageList String with numbers of the required pages to extract as image. Should be formatted as string with * numbers, separated by commas, without whitespaces. Can be null, if it is required to extract * all pages as images. + * * @throws IOException if there are file's reading/writing issues * @throws InterruptedException if there is thread interruption while executing GhostScript. */ public void runGhostScriptImageGeneration(String pdf, String outDir, String image, String pageList) throws IOException, InterruptedException { if (!FileUtil.directoryExists(outDir)) { - throw new IllegalArgumentException(IoExceptionMessage.CANNOT_OPEN_OUTPUT_DIRECTORY.replace("", pdf)); + throw new IllegalArgumentException( + IoExceptionMessage.CANNOT_OPEN_OUTPUT_DIRECTORY.replace("", pdf)); } pageList = (pageList == null) ? "" : "-sPageList=".replace("", pageList); diff --git a/io/src/main/java/com/itextpdf/io/util/ImageMagickHelper.java b/io/src/main/java/com/itextpdf/io/util/ImageMagickHelper.java index f01a20d036..58588158ab 100644 --- a/io/src/main/java/com/itextpdf/io/util/ImageMagickHelper.java +++ b/io/src/main/java/com/itextpdf/io/util/ImageMagickHelper.java @@ -47,6 +47,15 @@ This file is part of the iText (R) project. import java.io.IOException; +/** + * A utility class that is used as an interface to run 3rd-party tool ImageMagick. + * ImageMagick among other things allows to compare images and this class provides means to utilize this feature. + * + *

+ * The ImageMagick needs to be installed independently on the system. This class provides a convenient + * way to run it by passing a terminal command. The command can either be specified explicitly or by a mean + * of environment variable {@link #MAGICK_COMPARE_ENVIRONMENT_VARIABLE}. + */ public class ImageMagickHelper { /** * The name of the environment variable with the command to execute ImageMagic comparison operations. @@ -60,10 +69,19 @@ public class ImageMagickHelper { private String compareExec; + /** + * Creates new instance that will rely on ImageMagick execution command defined by {@link + * #MAGICK_COMPARE_ENVIRONMENT_VARIABLE} environment variable. + */ public ImageMagickHelper() { this(null); } + /** + * Creates new instance that will rely on ImageMagick execution command defined as passed argument. + * + * @param newCompareExec the ImageMagick execution command; if null - environment variables will be used instead + */ public ImageMagickHelper(String newCompareExec) { compareExec = newCompareExec; if (compareExec == null) { @@ -95,7 +113,9 @@ public String getCliExecutionCommand() { * @param outImageFilePath Path to the output image file * @param cmpImageFilePath Path to the cmp image file * @param diffImageName Path to the difference output image file + * * @return boolean result of comparing: true - images are visually equal + * * @throws IOException if there are file's reading/writing issues * @throws InterruptedException if there is thread interruption while executing ImageMagick. */ @@ -112,13 +132,14 @@ public boolean runImageMagickImageCompare(String outImageFilePath, String cmpIma * @param diffImageName Path to the difference output image file * @param fuzzValue String fuzziness value to compare images. Should be formatted as string with integer * or decimal number. Can be null, if it is not required to use fuzziness + * * @return boolean result of comparing: true - images are visually equal + * * @throws IOException if there are file's reading/writing issues * @throws InterruptedException if there is thread interruption while executing ImageMagick. */ public boolean runImageMagickImageCompare(String outImageFilePath, String cmpImageFilePath, - String diffImageName, String fuzzValue) - throws IOException, InterruptedException { + String diffImageName, String fuzzValue) throws IOException, InterruptedException { fuzzValue = (fuzzValue == null) ? "" : " -metric AE -fuzz %".replace("", fuzzValue); StringBuilder currCompareParams = new StringBuilder(); diff --git a/io/src/test/java/com/itextpdf/io/font/FontCacheNoFontAsianTest.java b/io/src/test/java/com/itextpdf/io/font/FontCacheNoFontAsianTest.java index add58374b0..eff2ce55b2 100644 --- a/io/src/test/java/com/itextpdf/io/font/FontCacheNoFontAsianTest.java +++ b/io/src/test/java/com/itextpdf/io/font/FontCacheNoFontAsianTest.java @@ -43,25 +43,19 @@ This file is part of the iText (R) project. package com.itextpdf.io.font; import com.itextpdf.io.IOException; -import com.itextpdf.io.font.cmap.CMapCidUni; import com.itextpdf.io.font.otf.Glyph; -import com.itextpdf.io.util.MessageFormatUtil; import com.itextpdf.test.ExtendedITextTest; import com.itextpdf.test.annotations.type.UnitTest; + import java.nio.charset.StandardCharsets; import org.junit.Assert; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(UnitTest.class) public class FontCacheNoFontAsianTest extends ExtendedITextTest { - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Before public void before() { FontCache.clearSavedFonts(); @@ -151,38 +145,30 @@ public void getRegistryNamesNoFontAsian() { @Test public void getCid2UniCMapNoFontAsian() { - junitExpectedException.expect(IOException.class); - // Without font-asian module in the class path // no CMap can be found. - FontCache.getCid2UniCmap("UniJIS-UTF16-H"); + Assert.assertThrows(IOException.class, () -> FontCache.getCid2UniCmap("UniJIS-UTF16-H")); } @Test public void getUni2CidCMapNoFontAsian() { - junitExpectedException.expect(IOException.class); - // Without font-asian module in the class path // no CMap can be found. - FontCache.getUni2CidCmap("UniJIS-UTF16-H"); + Assert.assertThrows(IOException.class, () -> FontCache.getUni2CidCmap("UniJIS-UTF16-H")); } @Test public void getByte2CidCMapNoFontAsian() { - junitExpectedException.expect(IOException.class); - // Without font-asian module in the class path // no CMap can be found. - FontCache.getByte2CidCmap("78ms-RKSJ-H"); + Assert.assertThrows(IOException.class, () -> FontCache.getByte2CidCmap("78ms-RKSJ-H")); } @Test public void getCid2ByteCMapNoFontAsian() { - junitExpectedException.expect(IOException.class); - // Without font-asian module in the class path // no CMap can be found. - FontCache.getCid2Byte("78ms-RKSJ-H"); + Assert.assertThrows(IOException.class, () -> FontCache.getCid2Byte("78ms-RKSJ-H")); } private static class FontProgramMock extends FontProgram { diff --git a/io/src/test/java/com/itextpdf/io/font/FontProgramTest.java b/io/src/test/java/com/itextpdf/io/font/FontProgramTest.java index 71fe3b3ad2..e30dce695f 100644 --- a/io/src/test/java/com/itextpdf/io/font/FontProgramTest.java +++ b/io/src/test/java/com/itextpdf/io/font/FontProgramTest.java @@ -43,32 +43,28 @@ This file is part of the iText (R) project. package com.itextpdf.io.font; import com.itextpdf.io.font.constants.StandardFonts; +import com.itextpdf.io.util.MessageFormatUtil; import com.itextpdf.test.ExtendedITextTest; import com.itextpdf.test.annotations.type.UnitTest; + import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; - import java.io.IOException; import java.lang.reflect.Field; import java.util.Map; -import com.itextpdf.io.util.MessageFormatUtil; @Category(UnitTest.class) public class FontProgramTest extends ExtendedITextTest { private static final String notExistingFont = "some-font.ttf"; - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void exceptionMessageTest() throws IOException { - junitExpectedException.expect(java.io.IOException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(com.itextpdf.io.IOException._1NotFoundAsFileOrResource, notExistingFont)); - FontProgramFactory.createFont(notExistingFont); + Exception e = Assert.assertThrows(java.io.IOException.class, + () -> FontProgramFactory.createFont(notExistingFont) + ); + Assert.assertEquals(MessageFormatUtil.format(com.itextpdf.io.IOException._1NotFoundAsFileOrResource, notExistingFont), e.getMessage()); } @Test diff --git a/io/src/test/java/com/itextpdf/io/image/GifTest.java b/io/src/test/java/com/itextpdf/io/image/GifTest.java index c7897a31d7..cfd68613ac 100644 --- a/io/src/test/java/com/itextpdf/io/image/GifTest.java +++ b/io/src/test/java/com/itextpdf/io/image/GifTest.java @@ -52,18 +52,13 @@ This file is part of the iText (R) project. import java.io.FileInputStream; import java.util.List; import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(UnitTest.class) public class GifTest extends ExtendedITextTest { public static final String sourceFolder = "./src/test/resources/com/itextpdf/io/image/GifTest/"; - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void gifImageTest() throws IOException, java.io.IOException { try (FileInputStream file = new FileInputStream(sourceFolder + "WP_20140410_001.gif")) { @@ -76,9 +71,9 @@ public void gifImageTest() throws IOException, java.io.IOException { @Test public void gifImageFrameOutOfBoundsTest() throws java.io.IOException { - junitExpectedException.expect(IOException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(IOException.CannotFind1Frame, 2)); - ImageDataFactory.createGifFrame(UrlUtil.toURL(sourceFolder + "image-2frames.gif"), 3); + Exception e = Assert.assertThrows(IOException.class, + () -> ImageDataFactory.createGifFrame(UrlUtil.toURL(sourceFolder + "image-2frames.gif"), 3)); + Assert.assertEquals(MessageFormatUtil.format(IOException.CannotFind1Frame, 2), e.getMessage()); } @Test diff --git a/io/src/test/java/com/itextpdf/io/image/ImageTypeDetectorTest.java b/io/src/test/java/com/itextpdf/io/image/ImageTypeDetectorTest.java index 41d242be1e..a75837c58b 100644 --- a/io/src/test/java/com/itextpdf/io/image/ImageTypeDetectorTest.java +++ b/io/src/test/java/com/itextpdf/io/image/ImageTypeDetectorTest.java @@ -22,10 +22,15 @@ This file is part of the iText (R) project. */ package com.itextpdf.io.image; +import com.itextpdf.io.util.StreamUtil; import com.itextpdf.io.util.UrlUtil; import com.itextpdf.test.ExtendedITextTest; import com.itextpdf.test.annotations.type.UnitTest; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import org.junit.Assert; @@ -39,32 +44,113 @@ public class ImageTypeDetectorTest extends ExtendedITextTest { private static final String IMAGE_NAME = "image"; @Test - public void testUnknown() throws MalformedURLException { - test(UrlUtil.toURL(SOURCE_FOLDER + IMAGE_NAME + ".txt"), ImageType.NONE); + public void testUrlUnknown() throws MalformedURLException { + testURL(UrlUtil.toURL(SOURCE_FOLDER + IMAGE_NAME + ".txt"), ImageType.NONE); } @Test - public void testGif() throws MalformedURLException { - test(UrlUtil.toURL(SOURCE_FOLDER + IMAGE_NAME + ".gif"), ImageType.GIF); + public void testUrlGif() throws MalformedURLException { + testURL(UrlUtil.toURL(SOURCE_FOLDER + IMAGE_NAME + ".gif"), ImageType.GIF); } @Test - public void testJpeg() throws MalformedURLException { - test(UrlUtil.toURL(SOURCE_FOLDER + IMAGE_NAME + ".jpg"), ImageType.JPEG); + public void testUrlJpeg() throws MalformedURLException { + testURL(UrlUtil.toURL(SOURCE_FOLDER + IMAGE_NAME + ".jpg"), ImageType.JPEG); } @Test - public void testTiff() throws MalformedURLException { - test(UrlUtil.toURL(SOURCE_FOLDER + IMAGE_NAME + ".tiff"), ImageType.TIFF); + public void testUrlTiff() throws MalformedURLException { + testURL(UrlUtil.toURL(SOURCE_FOLDER + IMAGE_NAME + ".tiff"), ImageType.TIFF); } @Test - public void testWmf() throws MalformedURLException { - test(UrlUtil.toURL(SOURCE_FOLDER + IMAGE_NAME + ".wmf"), ImageType.WMF); + public void testUrlWmf() throws MalformedURLException { + testURL(UrlUtil.toURL(SOURCE_FOLDER + IMAGE_NAME + ".wmf"), ImageType.WMF); } - private void test(URL location, ImageType expectedType) { + @Test + public void testNullUrl() throws MalformedURLException { + URL url = UrlUtil.toURL("not existing path"); + + Assert.assertThrows(com.itextpdf.io.IOException.class, + () -> ImageTypeDetector.detectImageType(url) + ); + } + + @Test + public void testStreamUnknown() throws FileNotFoundException { + testStream(new FileInputStream(SOURCE_FOLDER + IMAGE_NAME + ".txt"), ImageType.NONE); + } + + @Test + public void testStreamGif() throws FileNotFoundException { + testStream(new FileInputStream(SOURCE_FOLDER + IMAGE_NAME + ".gif"), ImageType.GIF); + } + + @Test + public void testStreamJpeg() throws FileNotFoundException { + testStream(new FileInputStream(SOURCE_FOLDER + IMAGE_NAME + ".jpg"), ImageType.JPEG); + } + + @Test + public void testStreamTiff() throws FileNotFoundException { + testStream(new FileInputStream(SOURCE_FOLDER + IMAGE_NAME + ".tiff"), ImageType.TIFF); + } + + @Test + public void testStreamWmf() throws FileNotFoundException { + testStream(new FileInputStream(SOURCE_FOLDER + IMAGE_NAME + ".wmf"), ImageType.WMF); + } + + @Test + public void testStreamClosed() throws IOException { + InputStream stream = new FileInputStream(SOURCE_FOLDER + IMAGE_NAME + ".wmf"); + stream.close(); + + // A common exception is expected instead of com.itextpdf.io.IOException, because in .NET + // the thrown exception is different + Assert.assertThrows(Exception.class, () -> ImageTypeDetector.detectImageType(stream)); + } + + @Test + public void testBytesUnknown() throws IOException { + testBytes(StreamUtil.inputStreamToArray(new FileInputStream(SOURCE_FOLDER + IMAGE_NAME + ".txt")), + ImageType.NONE); + } + + @Test + public void testBytesGif() throws IOException { + testBytes(StreamUtil.inputStreamToArray(new FileInputStream(SOURCE_FOLDER + IMAGE_NAME + ".gif")), + ImageType.GIF); + } + + @Test + public void testBytesJpeg() throws IOException { + testBytes(StreamUtil.inputStreamToArray(new FileInputStream(SOURCE_FOLDER + IMAGE_NAME + ".jpg")), + ImageType.JPEG); + } + + @Test + public void testBytesTiff() throws IOException { + testBytes(StreamUtil.inputStreamToArray(new FileInputStream(SOURCE_FOLDER + IMAGE_NAME + ".tiff")), + ImageType.TIFF); + } + + @Test + public void testBytesWmf() throws IOException { + testBytes(StreamUtil.inputStreamToArray(new FileInputStream(SOURCE_FOLDER + IMAGE_NAME + ".wmf")), + ImageType.WMF); + } + + private static void testURL(URL location, ImageType expectedType) { Assert.assertEquals(expectedType, ImageTypeDetector.detectImageType(location)); } + private static void testStream(InputStream stream, ImageType expectedType) { + Assert.assertEquals(expectedType, ImageTypeDetector.detectImageType(stream)); + } + + private static void testBytes(byte[] bytes, ImageType expectedType) { + Assert.assertEquals(expectedType, ImageTypeDetector.detectImageType(bytes)); + } } diff --git a/io/src/test/java/com/itextpdf/io/source/PdfTokenizerTest.java b/io/src/test/java/com/itextpdf/io/source/PdfTokenizerTest.java index bef403a50f..0e81b59197 100644 --- a/io/src/test/java/com/itextpdf/io/source/PdfTokenizerTest.java +++ b/io/src/test/java/com/itextpdf/io/source/PdfTokenizerTest.java @@ -50,18 +50,13 @@ This file is part of the iText (R) project. import java.io.IOException; import java.nio.charset.StandardCharsets; import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; import static com.itextpdf.io.IOException.ErrorAtFilePointer1; @Category(UnitTest.class) public class PdfTokenizerTest extends ExtendedITextTest { - @Rule - public ExpectedException expectedException = ExpectedException.none(); - private static final String sourceFolder = "./src/test/resources/com/itextpdf/io/util/"; @Test @@ -262,14 +257,14 @@ public void getDecodedStringContentHexTest() throws IOException { @Test public void throwErrorTest() { - expectedException.expect(com.itextpdf.io.IOException.class); - expectedException.expectMessage(MessageFormatUtil.format(ErrorAtFilePointer1, 0)); - RandomAccessSourceFactory factory = new RandomAccessSourceFactory(); PdfTokenizer tok = new PdfTokenizer(new RandomAccessFileOrArray( factory.createSource("/Name1".getBytes(StandardCharsets.ISO_8859_1)))); - tok.throwError(ErrorAtFilePointer1, 0); + Exception e = Assert.assertThrows(com.itextpdf.io.IOException.class, + () -> tok.throwError(ErrorAtFilePointer1, 0) + ); + Assert.assertEquals(MessageFormatUtil.format(ErrorAtFilePointer1, 0), e.getMessage()); } @Test diff --git a/io/src/test/java/com/itextpdf/io/source/RAFRandomAccessSourceTest.java b/io/src/test/java/com/itextpdf/io/source/RAFRandomAccessSourceTest.java index 756e055683..ae06bfe4f3 100644 --- a/io/src/test/java/com/itextpdf/io/source/RAFRandomAccessSourceTest.java +++ b/io/src/test/java/com/itextpdf/io/source/RAFRandomAccessSourceTest.java @@ -47,22 +47,16 @@ This file is part of the iText (R) project. import com.itextpdf.test.annotations.type.UnitTest; import java.io.File; -import java.io.FileNotFoundException; import java.io.IOException; import java.io.RandomAccessFile; import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(UnitTest.class) public class RAFRandomAccessSourceTest extends ExtendedITextTest { private final static String SOURCE_FILE = "./src/test/resources/com/itextpdf/io/source/RAF.txt"; - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - private final byte[] content = "Hello, world!".getBytes(); @Test diff --git a/io/src/test/java/com/itextpdf/io/util/GhostscriptHelperTest.java b/io/src/test/java/com/itextpdf/io/util/GhostscriptHelperTest.java index 1d7628ae10..5f7a768c96 100644 --- a/io/src/test/java/com/itextpdf/io/util/GhostscriptHelperTest.java +++ b/io/src/test/java/com/itextpdf/io/util/GhostscriptHelperTest.java @@ -45,28 +45,23 @@ This file is part of the iText (R) project. import com.itextpdf.io.IoExceptionMessage; import com.itextpdf.test.ExtendedITextTest; import com.itextpdf.test.annotations.type.IntegrationTest; + import org.junit.Assert; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; - import java.io.File; import java.io.IOException; @Category(IntegrationTest.class) public class GhostscriptHelperTest extends ExtendedITextTest { - private final static String sourceFolder = "./src/test/resources/com/itextpdf/io/util/GhostscriptHelperTest/"; - private static final String destinationFolder = "./target/test/com/itextpdf/io/GhostscriptHelperTest/"; - - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); + private final static String SOURCE_FOLDER = "./src/test/resources/com/itextpdf/io/util/GhostscriptHelperTest/"; + private static final String DESTINATION_FOLDER = "./target/test/com/itextpdf/io/GhostscriptHelperTest/"; @Before public void setUp() { - createOrClearDestinationFolder(destinationFolder); + createOrClearDestinationFolder(DESTINATION_FOLDER); } @Test @@ -96,136 +91,111 @@ public void ghostScriptEnvVarIsNull() { @Test public void ghostScriptEnvVarIsIncorrect() { - junitExpectedException.expect(IllegalArgumentException.class); - junitExpectedException.expectMessage(IoExceptionMessage.GS_ENVIRONMENT_VARIABLE_IS_NOT_SPECIFIED); - - GhostscriptHelper ghostscriptHelper = new GhostscriptHelper("-"); + Exception e = Assert.assertThrows(IllegalArgumentException.class, + () -> new GhostscriptHelper("-") + ); + Assert.assertEquals(IoExceptionMessage.GS_ENVIRONMENT_VARIABLE_IS_NOT_SPECIFIED, e.getMessage()); } @Test public void runGhostScriptIncorrectOutputDirectory() throws IOException, InterruptedException { - String inputPdf = sourceFolder + "imageHandlerUtilTest.pdf"; + String inputPdf = SOURCE_FOLDER + "imageHandlerUtilTest.pdf"; String exceptionMessage = "Cannot open output directory for " + inputPdf; - junitExpectedException.expect(IllegalArgumentException.class); - junitExpectedException.expectMessage(exceptionMessage); - GhostscriptHelper ghostscriptHelper = new GhostscriptHelper(); - ghostscriptHelper.runGhostScriptImageGeneration(inputPdf, "-", - "outputPageImage.png", "1"); + + Exception e = Assert.assertThrows(IllegalArgumentException.class, + () -> ghostscriptHelper.runGhostScriptImageGeneration(inputPdf, "-", + "outputPageImage.png", "1") + ); + Assert.assertEquals(exceptionMessage, e.getMessage()); } @Test public void runGhostScriptIncorrectParams() throws IOException, InterruptedException { - String inputPdf = sourceFolder + "imageHandlerUtilTest.pdf"; + String inputPdf = SOURCE_FOLDER + "imageHandlerUtilTest.pdf"; String exceptionMessage = "GhostScript failed for " + inputPdf; - junitExpectedException.expect(GhostscriptHelper.GhostscriptExecutionException.class); - junitExpectedException.expectMessage(exceptionMessage); - GhostscriptHelper ghostscriptHelper = new GhostscriptHelper(); - ghostscriptHelper.runGhostScriptImageGeneration(inputPdf, destinationFolder, - "outputPageImage.png", "q@W"); + + Exception e = Assert.assertThrows(GhostscriptHelper.GhostscriptExecutionException.class, + () -> ghostscriptHelper.runGhostScriptImageGeneration(inputPdf, DESTINATION_FOLDER, + "outputPageImage.png", "q@W") + ); + Assert.assertEquals(exceptionMessage, e.getMessage()); } @Test public void runGhostScriptTestForSpecificPage() throws IOException, InterruptedException { - String inputPdf = sourceFolder + "imageHandlerUtilTest.pdf"; + String inputPdf = SOURCE_FOLDER + "imageHandlerUtilTest.pdf"; GhostscriptHelper ghostscriptHelper = new GhostscriptHelper(); - ghostscriptHelper.runGhostScriptImageGeneration(inputPdf, destinationFolder, + ghostscriptHelper.runGhostScriptImageGeneration(inputPdf, DESTINATION_FOLDER, "specificPage.png", "1"); - Assert.assertEquals(1, FileUtil.listFilesInDirectory(destinationFolder, true).length); - Assert.assertTrue(FileUtil.fileExists(destinationFolder + "specificPage.png")); + Assert.assertEquals(1, FileUtil.listFilesInDirectory(DESTINATION_FOLDER, true).length); + Assert.assertTrue(FileUtil.fileExists(DESTINATION_FOLDER + "specificPage.png")); } @Test public void runGhostScriptTestForSeveralSpecificPages() throws IOException, InterruptedException { - String inputPdf = sourceFolder + "imageHandlerUtilTest.pdf"; + String inputPdf = SOURCE_FOLDER + "imageHandlerUtilTest.pdf"; GhostscriptHelper ghostscriptHelper = new GhostscriptHelper(); String imageFileName = new File(inputPdf).getName() + "_severalSpecificPages-%03d.png"; - ghostscriptHelper.runGhostScriptImageGeneration(inputPdf, destinationFolder, + ghostscriptHelper.runGhostScriptImageGeneration(inputPdf, DESTINATION_FOLDER, imageFileName, "1,3"); - Assert.assertEquals(2, FileUtil.listFilesInDirectory(destinationFolder, true).length); - Assert.assertTrue(FileUtil.fileExists(destinationFolder + "imageHandlerUtilTest.pdf_severalSpecificPages-001.png")); - Assert.assertTrue(FileUtil.fileExists(destinationFolder + "imageHandlerUtilTest.pdf_severalSpecificPages-002.png")); + Assert.assertEquals(2, FileUtil.listFilesInDirectory(DESTINATION_FOLDER, true).length); + Assert.assertTrue(FileUtil.fileExists(DESTINATION_FOLDER + "imageHandlerUtilTest.pdf_severalSpecificPages-001.png")); + Assert.assertTrue(FileUtil.fileExists(DESTINATION_FOLDER + "imageHandlerUtilTest.pdf_severalSpecificPages-002.png")); } @Test public void runGhostScriptTestForAllPages() throws IOException, InterruptedException { - String inputPdf = sourceFolder + "imageHandlerUtilTest.pdf"; + String inputPdf = SOURCE_FOLDER + "imageHandlerUtilTest.pdf"; GhostscriptHelper ghostscriptHelper = new GhostscriptHelper(); String imageFileName = new File(inputPdf).getName() + "_allPages-%03d.png"; - ghostscriptHelper.runGhostScriptImageGeneration(inputPdf, destinationFolder, imageFileName); + ghostscriptHelper.runGhostScriptImageGeneration(inputPdf, DESTINATION_FOLDER, imageFileName); - Assert.assertEquals(3, FileUtil.listFilesInDirectory(destinationFolder, true).length); - Assert.assertTrue(FileUtil.fileExists(destinationFolder + "imageHandlerUtilTest.pdf_allPages-001.png")); - Assert.assertTrue(FileUtil.fileExists(destinationFolder + "imageHandlerUtilTest.pdf_allPages-002.png")); - Assert.assertTrue(FileUtil.fileExists(destinationFolder + "imageHandlerUtilTest.pdf_allPages-003.png")); + Assert.assertEquals(3, FileUtil.listFilesInDirectory(DESTINATION_FOLDER, true).length); + Assert.assertTrue(FileUtil.fileExists(DESTINATION_FOLDER + "imageHandlerUtilTest.pdf_allPages-001.png")); + Assert.assertTrue(FileUtil.fileExists(DESTINATION_FOLDER + "imageHandlerUtilTest.pdf_allPages-002.png")); + Assert.assertTrue(FileUtil.fileExists(DESTINATION_FOLDER + "imageHandlerUtilTest.pdf_allPages-003.png")); } @Test public void dSaferParamInGhostScriptHelperTest() throws IOException, InterruptedException { - String cmpPdf = sourceFolder + "maliciousPsInvokingCalcExe.ps"; - String maliciousPsInvokingCalcExe = destinationFolder + "maliciousPsInvokingCalcExe.png"; - int majorVersion = 0; - int minorVersion = 0; - boolean isWindows = identifyOsType().toLowerCase().contains("win"); - if (isWindows) { - String gsExec = SystemUtil.getPropertyOrEnvironmentVariable(GhostscriptHelper.GHOSTSCRIPT_ENVIRONMENT_VARIABLE); - if (gsExec == null) { - gsExec = SystemUtil.getPropertyOrEnvironmentVariable(GhostscriptHelper.GHOSTSCRIPT_ENVIRONMENT_VARIABLE_LEGACY); - } - String[] pathParts = gsExec.split("\\d\\.\\d\\d"); - for (int i = 0; i < pathParts.length; i++) { - gsExec = gsExec.replace(pathParts[i], ""); - } - String[] version = gsExec.split("\\."); - majorVersion = Integer.parseInt(version[0]); - minorVersion = Integer.parseInt(version[1]); - } + String input = SOURCE_FOLDER + "unsafePostScript.ps"; + String outputName = "unsafePostScript.png"; + String maliciousResult1 = DESTINATION_FOLDER + "output1.txt"; + String maliciousResult2 = DESTINATION_FOLDER + "output2.txt"; try { GhostscriptHelper ghostscriptHelper = new GhostscriptHelper(); - ghostscriptHelper.runGhostScriptImageGeneration(cmpPdf, destinationFolder, "maliciousPsInvokingCalcExe.png"); - if (isWindows) { - Assert.assertTrue((majorVersion > 9 || (majorVersion == 9 && minorVersion >= 50))); - } + ghostscriptHelper.runGhostScriptImageGeneration(input, DESTINATION_FOLDER, outputName); } catch (GhostscriptHelper.GhostscriptExecutionException e) { - if (isWindows) { - Assert.assertTrue((majorVersion < 9 || (majorVersion == 9 && minorVersion < 50))); - } + System.out.println("Error code was returned on processing of malicious script with -dSAFER option enabled. " + + "This is expected for some environments and ghostscript versions. " + + "We assert only the absence of malicious script result (created file).\n"); } - Assert.assertFalse(FileUtil.fileExists(maliciousPsInvokingCalcExe)); + Assert.assertFalse(FileUtil.fileExists(maliciousResult1)); + Assert.assertFalse(FileUtil.fileExists(maliciousResult2)); } @Test public void ghostScriptImageGenerationTest() throws IOException, InterruptedException { String filename = "resultantImage.png"; - String psFile = sourceFolder + "simple.ps"; - String resultantImage = destinationFolder + filename; - String cmpResultantImage = sourceFolder + "cmp_" + filename; - String diff = destinationFolder + "diff_" + filename; + String psFile = SOURCE_FOLDER + "simple.ps"; + String resultantImage = DESTINATION_FOLDER + filename; + String cmpResultantImage = SOURCE_FOLDER + "cmp_" + filename; + String diff = DESTINATION_FOLDER + "diff_" + filename; GhostscriptHelper ghostscriptHelper = new GhostscriptHelper(); - ghostscriptHelper.runGhostScriptImageGeneration(psFile, destinationFolder, filename); + ghostscriptHelper.runGhostScriptImageGeneration(psFile, DESTINATION_FOLDER, filename); Assert.assertTrue(FileUtil.fileExists(resultantImage)); ImageMagickHelper imageMagickHelper = new ImageMagickHelper(); Assert.assertTrue(imageMagickHelper.runImageMagickImageCompare(resultantImage, cmpResultantImage, diff)); } - - /** - * Identifies type of current OS and return it (win, linux). - * - * @return type of current os as {@link java.lang.String} - */ - private static String identifyOsType() { - String os = System.getProperty("os.name") == null - ? System.getProperty("OS") : System.getProperty("os.name"); - return os.toLowerCase(); - } } diff --git a/io/src/test/java/com/itextpdf/io/util/ImageMagickHelperTest.java b/io/src/test/java/com/itextpdf/io/util/ImageMagickHelperTest.java index 2e31959b6f..e71cfdb03e 100644 --- a/io/src/test/java/com/itextpdf/io/util/ImageMagickHelperTest.java +++ b/io/src/test/java/com/itextpdf/io/util/ImageMagickHelperTest.java @@ -45,26 +45,21 @@ This file is part of the iText (R) project. import com.itextpdf.io.IoExceptionMessage; import com.itextpdf.test.ExtendedITextTest; import com.itextpdf.test.annotations.type.IntegrationTest; + import org.junit.Assert; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; - import java.io.IOException; @Category(IntegrationTest.class) public class ImageMagickHelperTest extends ExtendedITextTest { - private final static String sourceFolder = "./src/test/resources/com/itextpdf/io/util/ImageMagickHelperTest/"; - private static final String destinationFolder = "./target/test/com/itextpdf/io/ImageMagickHelperTest/"; - - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); + private final static String SOURCE_FOLDER = "./src/test/resources/com/itextpdf/io/util/ImageMagickHelperTest/"; + private static final String DESTINATION_FOLDER = "./target/test/com/itextpdf/io/ImageMagickHelperTest/"; @Before public void setUp() { - createOrClearDestinationFolder(destinationFolder); + createOrClearDestinationFolder(DESTINATION_FOLDER); } @Test @@ -87,9 +82,9 @@ public void imageMagickEnvVarIsExplicitlySpecified() { @Test public void imageMagickEnvVarIsNull() throws IOException, InterruptedException { - String inputImage = sourceFolder + "image.png"; - String cmpImage = sourceFolder + "cmp_image.png"; - String diff = destinationFolder + "diff.png"; + String inputImage = SOURCE_FOLDER + "image.png"; + String cmpImage = SOURCE_FOLDER + "cmp_image.png"; + String diff = DESTINATION_FOLDER + "diff.png"; ImageMagickHelper imageMagickHelper = new ImageMagickHelper(null); boolean result = imageMagickHelper.runImageMagickImageCompare(inputImage, cmpImage, diff); @@ -100,17 +95,17 @@ public void imageMagickEnvVarIsNull() throws IOException, InterruptedException { @Test public void imageMagickEnvVarIsIncorrect() { - junitExpectedException.expect(IllegalArgumentException.class); - junitExpectedException.expectMessage(IoExceptionMessage.COMPARE_COMMAND_SPECIFIED_INCORRECTLY); - - ImageMagickHelper imageMagickHelper = new ImageMagickHelper("-"); + Exception e = Assert.assertThrows(IllegalArgumentException.class, + () -> new ImageMagickHelper("-") + ); + Assert.assertEquals(IoExceptionMessage.COMPARE_COMMAND_SPECIFIED_INCORRECTLY, e.getMessage()); } @Test public void runImageMagickForEqualImages() throws IOException, InterruptedException { - String inputImage = sourceFolder + "image.png"; - String cmpImage = sourceFolder + "cmp_image.png"; - String diff = destinationFolder + "diff_equalImages.png"; + String inputImage = SOURCE_FOLDER + "image.png"; + String cmpImage = SOURCE_FOLDER + "cmp_image.png"; + String diff = DESTINATION_FOLDER + "diff_equalImages.png"; ImageMagickHelper imageMagickHelper = new ImageMagickHelper(); boolean result = imageMagickHelper.runImageMagickImageCompare(inputImage, cmpImage, diff); @@ -121,9 +116,9 @@ public void runImageMagickForEqualImages() throws IOException, InterruptedExcept @Test public void runImageMagickForEqualImagesWithFuzzParam() throws IOException, InterruptedException { - String inputImage = sourceFolder + "image.png"; - String cmpImage = sourceFolder + "cmp_image.png"; - String diff = destinationFolder + "diff_equalImagesFuzzParam.png"; + String inputImage = SOURCE_FOLDER + "image.png"; + String cmpImage = SOURCE_FOLDER + "cmp_image.png"; + String diff = DESTINATION_FOLDER + "diff_equalImagesFuzzParam.png"; ImageMagickHelper imageMagickHelper = new ImageMagickHelper(); boolean result = imageMagickHelper.runImageMagickImageCompare(inputImage, cmpImage, diff, "0.5"); @@ -134,9 +129,9 @@ public void runImageMagickForEqualImagesWithFuzzParam() throws IOException, Inte @Test public void runImageMagickForDifferentImages() throws IOException, InterruptedException { - String inputImage = sourceFolder + "Im1_1.jpg"; - String cmpImage = sourceFolder + "cmp_Im1_1.jpg"; - String diff = destinationFolder + "diff_differentImages.png"; + String inputImage = SOURCE_FOLDER + "Im1_1.jpg"; + String cmpImage = SOURCE_FOLDER + "cmp_Im1_1.jpg"; + String diff = DESTINATION_FOLDER + "diff_differentImages.png"; ImageMagickHelper imageMagickHelper = new ImageMagickHelper(); boolean result = imageMagickHelper.runImageMagickImageCompare(inputImage, cmpImage, diff); @@ -147,9 +142,9 @@ public void runImageMagickForDifferentImages() throws IOException, InterruptedEx @Test public void runImageMagickForDifferentImagesWithFuzzParamNotEqual() throws IOException, InterruptedException { - String inputImage = sourceFolder + "Im1_1.jpg"; - String cmpImage = sourceFolder + "cmp_Im1_1.jpg"; - String diff = destinationFolder + "diff_differentImagesFuzzNotEnough.png"; + String inputImage = SOURCE_FOLDER + "Im1_1.jpg"; + String cmpImage = SOURCE_FOLDER + "cmp_Im1_1.jpg"; + String diff = DESTINATION_FOLDER + "diff_differentImagesFuzzNotEnough.png"; ImageMagickHelper imageMagickHelper = new ImageMagickHelper(); boolean result = imageMagickHelper.runImageMagickImageCompare(inputImage, cmpImage, diff, "0.1"); @@ -160,12 +155,12 @@ public void runImageMagickForDifferentImagesWithFuzzParamNotEqual() throws IOExc @Test public void runImageMagickForDifferentImagesWithFuzzParamEqual() throws IOException, InterruptedException { - String inputImage = sourceFolder + "Im1_1.jpg"; - String cmpImage = sourceFolder + "cmp_Im1_1.jpg"; - String diff = destinationFolder + "diff_differentImagesFuzzEnough.png"; + String inputImage = SOURCE_FOLDER + "Im1_1.jpg"; + String cmpImage = SOURCE_FOLDER + "cmp_Im1_1.jpg"; + String diff = DESTINATION_FOLDER + "diff_differentImagesFuzzEnough.png"; ImageMagickHelper imageMagickHelper = new ImageMagickHelper(); - boolean result = imageMagickHelper.runImageMagickImageCompare(inputImage, cmpImage, diff, "1.2"); + boolean result = imageMagickHelper.runImageMagickImageCompare(inputImage, cmpImage, diff, "2.1"); Assert.assertTrue(result); Assert.assertTrue(FileUtil.fileExists(diff)); diff --git a/io/src/test/java/com/itextpdf/io/util/MatcherTest.java b/io/src/test/java/com/itextpdf/io/util/MatcherTest.java index 352a2d5f48..3b7b8e5aec 100644 --- a/io/src/test/java/com/itextpdf/io/util/MatcherTest.java +++ b/io/src/test/java/com/itextpdf/io/util/MatcherTest.java @@ -28,10 +28,8 @@ This file is part of the iText (R) project. import java.util.regex.Matcher; import java.util.regex.Pattern; import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; /** * At the moment there is no com.itextpdf.io.util.Matcher class in Java (as we use @@ -44,9 +42,6 @@ public class MatcherTest extends ExtendedITextTest { private static final Pattern PATTERN = Pattern.compile(PATTERN_STRING); private static final Pattern FULL_MATCH_PATTERN = Pattern.compile("^" + PATTERN_STRING + "$"); - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void matchesTest() { Matcher matched = FULL_MATCH_PATTERN.matcher("aaabbb"); @@ -94,8 +89,7 @@ public void twoGroupsFindWithIndexTest() { public void startBeforeSearchTest() { Matcher matcher = PATTERN.matcher("aabb"); - junitExpectedException.expect(IllegalStateException.class); - matcher.start(); + Assert.assertThrows(IllegalStateException.class, () -> matcher.start()); } @Test @@ -104,16 +98,15 @@ public void startWhenFindFailsTest() { while (matcher.find()) { } - junitExpectedException.expect(IllegalStateException.class); - matcher.start(); + + Assert.assertThrows(IllegalStateException.class, () -> matcher.start()); } @Test public void endBeforeSearchTest() { Matcher matcher = PATTERN.matcher("aabb"); - junitExpectedException.expect(IllegalStateException.class); - matcher.end(); + Assert.assertThrows(IllegalStateException.class, () -> matcher.end()); } @Test @@ -122,16 +115,15 @@ public void endWhenFindFailsTest() { while (matcher.find()) { } - junitExpectedException.expect(IllegalStateException.class); - matcher.end(); + + Assert.assertThrows(IllegalStateException.class, () -> matcher.end()); } @Test public void groupBeforeSearchTest() { Matcher matcher = PATTERN.matcher("aabb"); - junitExpectedException.expect(IllegalStateException.class); - matcher.group(); + Assert.assertThrows(IllegalStateException.class, () -> matcher.group()); } @Test @@ -140,16 +132,15 @@ public void groupWhenFindFailsTest() { while (matcher.find()) { } - junitExpectedException.expect(IllegalStateException.class); - matcher.group(); + + Assert.assertThrows(IllegalStateException.class, () -> matcher.group()); } @Test public void groupWithIndexBeforeSearchTest() { Matcher matcher = PATTERN.matcher("aabb"); - junitExpectedException.expect(IllegalStateException.class); - matcher.group(0); + Assert.assertThrows(IllegalStateException.class, () -> matcher.group(0)); } @Test @@ -158,8 +149,8 @@ public void groupWithIndexWhenFindFailsTest() { while (matcher.find()) { } - junitExpectedException.expect(IllegalStateException.class); - matcher.group(0); + + Assert.assertThrows(IllegalStateException.class, () -> matcher.group(0)); } @Test @@ -167,8 +158,7 @@ public void groupNegativeIndexTest() { Matcher matcher = PATTERN.matcher("aabb"); Assert.assertTrue(matcher.find()); - junitExpectedException.expect(IndexOutOfBoundsException.class); - matcher.group(-1); + Assert.assertThrows(IndexOutOfBoundsException.class, () -> matcher.group(-1)); } @Test @@ -176,16 +166,14 @@ public void groupIndexGraterThanGroupCountTest() { Matcher matcher = PATTERN.matcher("aabb"); Assert.assertTrue(matcher.find()); - junitExpectedException.expect(IndexOutOfBoundsException.class); - matcher.group(3); + Assert.assertThrows(IndexOutOfBoundsException.class, () -> matcher.group(3)); } @Test public void findNegativeIndexTest() { Matcher matcher = PATTERN.matcher("aabb"); - junitExpectedException.expect(IndexOutOfBoundsException.class); - matcher.find(-1); + Assert.assertThrows(IndexOutOfBoundsException.class, () -> matcher.find(-1)); } @Test @@ -193,8 +181,7 @@ public void findIndexGraterThanInputLengthTest() { String input = "aabb"; Matcher matcher = PATTERN.matcher(input); - junitExpectedException.expect(IndexOutOfBoundsException.class); - matcher.find(input.length() + 1); + Assert.assertThrows(IndexOutOfBoundsException.class, () -> matcher.find(input.length() + 1)); } @Test @@ -261,8 +248,7 @@ public void groupOutOfBoundsTest() { Assert.assertEquals("123", matcher.group(0)); Assert.assertEquals("123", matcher.group(1)); - junitExpectedException.expect(IndexOutOfBoundsException.class); - matcher.group(2); + Assert.assertThrows(IndexOutOfBoundsException.class, () -> matcher.group(2)); } @Test @@ -272,8 +258,7 @@ public void groupWhenNoMatchTest() { Matcher matcher = Pattern.compile(testPattern).matcher(input); Assert.assertFalse(matcher.find()); - junitExpectedException.expect(IllegalStateException.class); - matcher.group(0); + Assert.assertThrows(IllegalStateException.class, () -> matcher.group(0)); } @Test @@ -305,10 +290,9 @@ public void startIndexNotFoundTest() { String testPattern = "ef"; String input = "abcde"; Matcher matcher = Pattern.compile(testPattern).matcher(input); - Assert.assertFalse(matcher.find()); - junitExpectedException.expect(IllegalStateException.class); - matcher.start(); + Assert.assertFalse(matcher.find()); + Assert.assertThrows(IllegalStateException.class, () -> matcher.start()); } @Test @@ -316,10 +300,9 @@ public void endIndexNotFoundTest() { String testPattern = "ef"; String input = "abcde"; Matcher matcher = Pattern.compile(testPattern).matcher(input); - Assert.assertFalse(matcher.find()); - junitExpectedException.expect(IllegalStateException.class); - matcher.end(); + Assert.assertFalse(matcher.find()); + Assert.assertThrows(IllegalStateException.class, () -> matcher.end()); } @Test @@ -376,8 +359,7 @@ public void findMatchStartingFromIndexOutOfBoundsTest() { int startIndex = 4; Matcher matcher = Pattern.compile(testPattern).matcher(input); - junitExpectedException.expect(IndexOutOfBoundsException.class); - matcher.find(startIndex); + Assert.assertThrows(IndexOutOfBoundsException.class, () -> matcher.find(startIndex)); } @Test @@ -389,8 +371,8 @@ public void findNextMatchStartingFromIndexOutOfBoundsTest() { Assert.assertTrue(matcher.find()); int startIndex = 4; - junitExpectedException.expect(IndexOutOfBoundsException.class); - matcher.find(startIndex); + + Assert.assertThrows(IndexOutOfBoundsException.class, () -> matcher.find(startIndex)); } @Test @@ -400,8 +382,7 @@ public void findMatchStartingFromNegativeIndexTest() { int startIndex = -1; Matcher matcher = Pattern.compile(testPattern).matcher(input); - junitExpectedException.expect(IndexOutOfBoundsException.class); - matcher.find(startIndex); + Assert.assertThrows(IndexOutOfBoundsException.class, () -> matcher.find(startIndex)); } @Test @@ -413,8 +394,8 @@ public void findNextMatchStartingFromNegativeIndexTest() { Assert.assertTrue(matcher.find()); int startIndex = -1; - junitExpectedException.expect(IndexOutOfBoundsException.class); - matcher.find(startIndex); + + Assert.assertThrows(IndexOutOfBoundsException.class, () -> matcher.find(startIndex)); } @Test @@ -552,36 +533,36 @@ public void stringMatchesButRegionDoesNotMatchTest() { @Test public void negativeStartOfRegionTest() { Matcher matcher = PATTERN.matcher("abbbbbbbbbbbbbbbbbbbbb"); - junitExpectedException.expect(IndexOutOfBoundsException.class); - matcher.region(-1, 10); + + Assert.assertThrows(IndexOutOfBoundsException.class, () -> matcher.region(-1, 10)); } @Test public void tooLargeStartOfRegionTest() { Matcher matcher = PATTERN.matcher("abbbbbbbbbbbbbbbbbbbbb"); - junitExpectedException.expect(IndexOutOfBoundsException.class); - matcher.region(24, 24); + + Assert.assertThrows(IndexOutOfBoundsException.class, () -> matcher.region(24, 24)); } @Test public void negativeEndOfRegionTest() { Matcher matcher = PATTERN.matcher("abbbbbbbbbbbbbbbbbbbbb"); - junitExpectedException.expect(IndexOutOfBoundsException.class); - matcher.region(1, -1); + + Assert.assertThrows(IndexOutOfBoundsException.class, () -> matcher.region(1, -1)); } @Test public void tooLargeEndOfRegionTest() { Matcher matcher = PATTERN.matcher("abbbbbbbbbbbbbbbbbbbbb"); - junitExpectedException.expect(IndexOutOfBoundsException.class); - matcher.region(1, 24); + + Assert.assertThrows(IndexOutOfBoundsException.class, () -> matcher.region(1, 24)); } @Test public void endGreaterThenStartRegionTest() { Matcher matcher = PATTERN.matcher("abbbbbbbbbbbbbbbbbbbbb"); - junitExpectedException.expect(IndexOutOfBoundsException.class); - matcher.region(10, 9); + + Assert.assertThrows(IndexOutOfBoundsException.class, () -> matcher.region(10, 9)); } @Test @@ -644,8 +625,7 @@ public void startRegionDoesNotMatchesTest() { matcher.region(6, 13); Assert.assertFalse(matcher.find()); - junitExpectedException.expect(IllegalStateException.class); - matcher.start(); + Assert.assertThrows(IllegalStateException.class, () -> matcher.start()); } @Test @@ -654,8 +634,7 @@ public void endRegionDoesNotMatchesTest() { matcher.region(6, 13); Assert.assertFalse(matcher.find()); - junitExpectedException.expect(IllegalStateException.class); - matcher.end(); + Assert.assertThrows(IllegalStateException.class, () -> matcher.end()); } @Test @@ -706,8 +685,7 @@ public void startAfterRegionThrowsExceptionTest() { matcher.find(); matcher.region(6, 13); - junitExpectedException.expect(IllegalStateException.class); - matcher.start(); + Assert.assertThrows(IllegalStateException.class, () -> matcher.start()); } @Test @@ -716,8 +694,7 @@ public void endAfterRegionThrowsExceptionTest() { matcher.find(); matcher.region(6, 13); - junitExpectedException.expect(IllegalStateException.class); - matcher.end(); + Assert.assertThrows(IllegalStateException.class, () -> matcher.end()); } @Test @@ -726,8 +703,7 @@ public void groupAfterRegionThrowsExceptionTest() { matcher.find(); matcher.region(6, 13); - junitExpectedException.expect(IllegalStateException.class); - matcher.group(); + Assert.assertThrows(IllegalStateException.class, () -> matcher.group()); } } diff --git a/io/src/test/resources/com/itextpdf/io/util/GhostscriptHelperTest/maliciousPsInvokingCalcExe.ps b/io/src/test/resources/com/itextpdf/io/util/GhostscriptHelperTest/maliciousPsInvokingCalcExe.ps deleted file mode 100644 index c7790c1cdc..0000000000 Binary files a/io/src/test/resources/com/itextpdf/io/util/GhostscriptHelperTest/maliciousPsInvokingCalcExe.ps and /dev/null differ diff --git a/io/src/test/resources/com/itextpdf/io/util/GhostscriptHelperTest/unsafePostScript.ps b/io/src/test/resources/com/itextpdf/io/util/GhostscriptHelperTest/unsafePostScript.ps new file mode 100644 index 0000000000..7b4444ca49 Binary files /dev/null and b/io/src/test/resources/com/itextpdf/io/util/GhostscriptHelperTest/unsafePostScript.ps differ diff --git a/itextcore/pom.xml b/itextcore/pom.xml index 99aedc13bd..1130598a07 100644 --- a/itextcore/pom.xml +++ b/itextcore/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.itextpdf itext7-core - 7.1.15 + 7.1.16 pom iText 7 Core A Free Java-PDF library @@ -134,16 +134,4 @@ ${project.version} - - - - com.github.spotbugs - spotbugs-maven-plugin - 3.1.11 - - true - - - - - \ No newline at end of file + diff --git a/kernel/pom.xml b/kernel/pom.xml index 341718a4e8..425a8687d9 100644 --- a/kernel/pom.xml +++ b/kernel/pom.xml @@ -4,7 +4,7 @@ com.itextpdf root - 7.1.15 + 7.1.16 kernel iText 7 - kernel diff --git a/kernel/src/main/java/com/itextpdf/kernel/KernelLogMessageConstant.java b/kernel/src/main/java/com/itextpdf/kernel/KernelLogMessageConstant.java index 77fb2e2f6b..a4dddff731 100644 --- a/kernel/src/main/java/com/itextpdf/kernel/KernelLogMessageConstant.java +++ b/kernel/src/main/java/com/itextpdf/kernel/KernelLogMessageConstant.java @@ -51,6 +51,9 @@ public final class KernelLogMessageConstant { public static final String DCTDECODE_FILTER_DECODING = "DCTDecode filter decoding into the " + "bit map is not supported. The stream data would be left in JPEG baseline format"; + public static final String FEATURE_IS_NOT_SUPPORTED = + "Exception was thrown: {0}. The feature {1} is probably not supported by your XML processor."; + public static final String FULL_COMPRESSION_APPEND_MODE_XREF_TABLE_INCONSISTENCY = "Full compression mode requested " + "in append mode but the original document has cross-reference table, not cross-reference stream. " + "Falling back to cross-reference table in appended document and switching full compression off"; diff --git a/kernel/src/main/java/com/itextpdf/kernel/PdfException.java b/kernel/src/main/java/com/itextpdf/kernel/PdfException.java index c43242b0b5..0d6c5e1db2 100644 --- a/kernel/src/main/java/com/itextpdf/kernel/PdfException.java +++ b/kernel/src/main/java/com/itextpdf/kernel/PdfException.java @@ -168,6 +168,8 @@ public class PdfException extends RuntimeException { public static final String EncryptedPayloadFileSpecShallHaveTypeEqualToFilespec = "Encrypted payload file spec shall have 'Type' key. The value of such key shall be 'Filespec'."; public static final String EncryptedPayloadShallHaveTypeEqualsToEncryptedPayloadIfPresent = "Encrypted payload dictionary shall have field 'Type' equal to 'EncryptedPayload' if present"; public static final String EncryptedPayloadShallHaveSubtype = "Encrypted payload shall have 'Subtype' field specifying crypto filter"; + public static final String ExternalEntityElementFoundInXml = + "External entity element found in XML. This entity will not be parsed to prevent XML attacks."; public static final String FailedToGetTsaResponseFrom1 = "Failed to get TSA response from {0}."; public static final String FieldFlatteningIsNotSupportedInAppendMode = "Field flattening is not supported in append mode."; diff --git a/kernel/src/main/java/com/itextpdf/kernel/Version.java b/kernel/src/main/java/com/itextpdf/kernel/Version.java index e8b7ac60cf..8fd945bafb 100644 --- a/kernel/src/main/java/com/itextpdf/kernel/Version.java +++ b/kernel/src/main/java/com/itextpdf/kernel/Version.java @@ -78,7 +78,7 @@ public final class Version { * This String contains the version number of this iText release. * For debugging purposes, we request you NOT to change this constant. */ - private static final String release = "7.1.15"; + private static final String release = "7.1.16"; /** * This String contains the iText version as shown in the producer line. * iText is a product developed by iText Group NV. @@ -109,27 +109,31 @@ public Version() { /** * Gets an instance of the iText version that is currently used. + * *

* Note that iText Group requests that you retain the iText producer line * in every PDF that is created or manipulated using iText. * @return an instance of {@link Version}. */ public static Version getInstance() { - synchronized (staticLock) { - if (version != null) { - try { - licenseScheduledCheck(); - } catch (Exception e) { - // If any exception occurs during scheduled check of core license, - // then it means that license is not valid yet, so roll back to AGPL. - // The key value is null as it is similar to case - // when an exception has been thrown during initial license loading - atomicSetVersion(initAGPLVersion(e, null)); - } - return version; + Version localVersion = version; + // It's crucial to work with 'localVersion' local variable, because 'version' field can be + // changed by some other thread. We also don't want to block Version class lock when calling + // for scheduled check in order to avoid synchronization issues with parallel loading license. + if (localVersion != null) { + try { + licenseScheduledCheck(localVersion); + return localVersion; + } catch (Exception e) { + // If any exception occurs during scheduled check of core license it means that + // license is not valid, in this particular case we want to reset to AGPL Version, + // however "normal" initialization logic will not switch to AGPL unless license is + // unloaded. + + // not saving this AGPL version in order to avoid race condition with loaded proper license + return initAGPLVersion(e, null); } } - Version localVersion; String key = null; try { String coreVersion = release; @@ -386,8 +390,8 @@ private static Version atomicSetVersion(Version newVersion) { } } - private static void licenseScheduledCheck() { - if (version.isAGPL()) { + private static void licenseScheduledCheck(Version localVersion) { + if (localVersion.isAGPL()) { return; } diff --git a/kernel/src/main/java/com/itextpdf/kernel/counter/data/EventDataHandler.java b/kernel/src/main/java/com/itextpdf/kernel/counter/data/EventDataHandler.java index f690f6d517..d7b0781846 100644 --- a/kernel/src/main/java/com/itextpdf/kernel/counter/data/EventDataHandler.java +++ b/kernel/src/main/java/com/itextpdf/kernel/counter/data/EventDataHandler.java @@ -71,6 +71,7 @@ This file is part of the iText (R) project. * @param data type */ public abstract class EventDataHandler> { + private final Object createLock = new Object(); private final Object processLock = new Object(); private final IEventDataCache cache; @@ -97,8 +98,7 @@ public List clear() { public void register(IEvent event, IMetaInfo metaInfo) { V data; - //Synchronization is left here mostly in consistency with cache and process, but factories are usually not thread safe anyway. - synchronized (factory) { + synchronized (createLock) { data = factory.create(event, metaInfo); } if (data != null) { diff --git a/kernel/src/main/java/com/itextpdf/kernel/font/FontUtil.java b/kernel/src/main/java/com/itextpdf/kernel/font/FontUtil.java index 6275863802..f2c8417a92 100644 --- a/kernel/src/main/java/com/itextpdf/kernel/font/FontUtil.java +++ b/kernel/src/main/java/com/itextpdf/kernel/font/FontUtil.java @@ -58,6 +58,7 @@ This file is part of the iText (R) project. import com.itextpdf.kernel.pdf.PdfObject; import com.itextpdf.kernel.pdf.PdfStream; +import java.util.Arrays; import java.util.HashMap; import org.slf4j.Logger; @@ -127,9 +128,7 @@ static String createRandomFontName() { static int[] convertSimpleWidthsArray(PdfArray widthsArray, int first, int missingWidth) { int[] res = new int[256]; - for (int i = 0; i < res.length; i++) { - res[i] = missingWidth; - } + Arrays.fill(res, missingWidth); if (widthsArray == null) { Logger logger = LoggerFactory.getLogger(FontUtil.class); logger.warn(LogMessageConstant.FONT_DICTIONARY_WITH_NO_WIDTHS); diff --git a/kernel/src/main/java/com/itextpdf/kernel/font/PdfFont.java b/kernel/src/main/java/com/itextpdf/kernel/font/PdfFont.java index fbaacb57f1..edce902806 100644 --- a/kernel/src/main/java/com/itextpdf/kernel/font/PdfFont.java +++ b/kernel/src/main/java/com/itextpdf/kernel/font/PdfFont.java @@ -77,6 +77,8 @@ public abstract class PdfFont extends PdfObjectWrapper { protected FontProgram fontProgram; protected static final byte[] EMPTY_BYTES = new byte[0]; + + @Deprecated protected static final double[] DEFAULT_FONT_MATRIX = {0.001, 0, 0, 0.001, 0, 0}; protected Map notdefGlyphs = new HashMap<>(); @@ -208,6 +210,19 @@ public boolean appendDecodedCodesToGlyphsList(List list, PdfString charac public abstract void writeText(String text, PdfOutputStream stream); + /** + * Gets the transformation matrix that defines relation between text and glyph spaces. + * + * @return the font matrix + * + * @deprecated Use {@link FontProgram#UNITS_NORMALIZATION} constant for conversion between text and glyph space. + * For now we opted to always expect that all {@link PdfFont} metrics in glyph-space + * are related to text space as 1 to 1000, as it is defined for the majority of fonts. For fonts + * which don't necessary follow this rule (see {@link PdfType3Font}), we perform internal normalization + * of font metrics in order to adhere to this common expectation. + * This method will be removed in next major release. + */ + @Deprecated public double[] getFontMatrix() { return DEFAULT_FONT_MATRIX; } diff --git a/kernel/src/main/java/com/itextpdf/kernel/font/PdfSimpleFont.java b/kernel/src/main/java/com/itextpdf/kernel/font/PdfSimpleFont.java index 5b2d867446..5fe96906aa 100644 --- a/kernel/src/main/java/com/itextpdf/kernel/font/PdfSimpleFont.java +++ b/kernel/src/main/java/com/itextpdf/kernel/font/PdfSimpleFont.java @@ -439,17 +439,7 @@ protected void flushFontData(String fontName, PdfName subtype) { if (isForceWidthsOutput() || !isBuiltInFont() || fontEncoding.hasDifferences()) { getPdfObject().put(PdfName.FirstChar, new PdfNumber(firstChar)); getPdfObject().put(PdfName.LastChar, new PdfNumber(lastChar)); - PdfArray wd = new PdfArray(); - for (int k = firstChar; k <= lastChar; ++k) { - if (shortTag[k] == 0) { - wd.add(new PdfNumber(0)); - } else { - //prevent lost of widths info - int uni = fontEncoding.getUnicode(k); - Glyph glyph = uni > -1 ? getGlyph(uni) : fontProgram.getGlyphByCode(k); - wd.add(new PdfNumber(getGlyphWidth(glyph))); - } - } + PdfArray wd = buildWidthsArray(firstChar, lastChar); getPdfObject().put(PdfName.Widths, wd); } PdfDictionary fontDescriptor = !isBuiltInFont() ? getFontDescriptor(fontName) : null; @@ -514,12 +504,39 @@ protected PdfDictionary getFontDescriptor(String fontName) { return fontDescriptor; } + protected PdfArray buildWidthsArray(int firstChar, int lastChar) { + PdfArray wd = new PdfArray(); + for (int k = firstChar; k <= lastChar; ++k) { + if (shortTag[k] == 0) { + wd.add(new PdfNumber(0)); + } else { + int uni = fontEncoding.getUnicode(k); + Glyph glyph = uni > -1 ? getGlyph(uni) : fontProgram.getGlyphByCode(k); + wd.add(new PdfNumber(glyph != null ? glyph.getWidth() : 0)); + } + } + return wd; + } + protected abstract void addFontStream(PdfDictionary fontDescriptor); protected void setFontProgram(T fontProgram) { this.fontProgram = fontProgram; } + /** + * Gets glyph width which us ready to be written to the output file. + * + * @param glyph the glyph which widths is required to be written to the output file + * + * @return glyph width in glyph-space + * + * @deprecated This method was introduced to allow overriding of widths array entry writing to + * output file. It's now replaced by more specific {@link #buildWidthsArray(int, int)} in order to + * avoid confusion between this method and {@link Glyph#getWidth()}. + * This method will be removed in the next major release. + */ + @Deprecated protected double getGlyphWidth(Glyph glyph) { return glyph != null ? glyph.getWidth() : 0; } diff --git a/kernel/src/main/java/com/itextpdf/kernel/font/PdfTrueTypeFont.java b/kernel/src/main/java/com/itextpdf/kernel/font/PdfTrueTypeFont.java index 82b12e0785..262f455b92 100644 --- a/kernel/src/main/java/com/itextpdf/kernel/font/PdfTrueTypeFont.java +++ b/kernel/src/main/java/com/itextpdf/kernel/font/PdfTrueTypeFont.java @@ -120,11 +120,10 @@ public class PdfTrueTypeFont extends PdfSimpleFont { public Glyph getGlyph(int unicode) { if (fontEncoding.canEncode(unicode)) { Glyph glyph = getFontProgram().getGlyph(fontEncoding.getUnicodeDifference(unicode)); - //TODO TrueType what if font is specific? if (glyph == null && (glyph = notdefGlyphs.get(unicode)) == null) { - Glyph notdef = getFontProgram().getGlyphByCode(0); + final Glyph notdef = getFontProgram().getGlyphByCode(0); if (notdef != null) { - glyph = new Glyph(getFontProgram().getGlyphByCode(0), unicode); + glyph = new Glyph(notdef, unicode); notdefGlyphs.put(unicode, glyph); } } @@ -149,7 +148,6 @@ public void flush() { return; } ensureUnderlyingObjectHasIndirectReference(); - //TODO make subtype class member and simplify this method if (newFont) { PdfName subtype; String fontName; diff --git a/kernel/src/main/java/com/itextpdf/kernel/font/PdfType3Font.java b/kernel/src/main/java/com/itextpdf/kernel/font/PdfType3Font.java index f568a35c5c..bd415947b9 100644 --- a/kernel/src/main/java/com/itextpdf/kernel/font/PdfType3Font.java +++ b/kernel/src/main/java/com/itextpdf/kernel/font/PdfType3Font.java @@ -48,6 +48,7 @@ This file is part of the iText (R) project. import com.itextpdf.io.font.FontEncoding; import com.itextpdf.io.font.FontMetrics; import com.itextpdf.io.font.FontNames; +import com.itextpdf.io.font.FontProgram; import com.itextpdf.io.font.constants.FontDescriptorFlags; import com.itextpdf.io.font.constants.FontStretches; import com.itextpdf.io.font.constants.FontWeights; @@ -72,26 +73,48 @@ This file is part of the iText (R) project. * In Type 3 fonts, glyphs are defined by streams of PDF graphics operators. * These streams are associated with character names. A separate encoding entry * maps character codes to the appropriate character names for the glyphs. + * + *

+ * Note, that this class operates in a special way with glyph space units. + * In the code when working with fonts, iText expects that 1000 units of glyph-space correspond + * to 1 unit of text space. For Type3 fonts this is not always the case and depends on FontMatrix. + * That's why in {@link PdfType3Font} the font matrix and all font metrics in glyph space units + * are "normalized" in such way, that 1 to 1000 relation is preserved. This is done on + * Type3 font initialization, and is reverted back on font flushing, because the actual content + * streams of type3 font glyphs are left with original coordinates based on original font matrix. + * See also ISO-32000-2, 9.2.4 "Glyph positioning and metrics": + * + *

+ * "The glyph coordinate system is the space in which an individual character’s glyph is defined. All path + * coordinates and metrics shall be interpreted in glyph space. For all font types except Type 3, the units + * of glyph space are one-thousandth of a unit of text space; for a Type 3 font, the transformation from + * glyph space to text space shall be defined by a font matrix specified in an explicit FontMatrix entry in + * the font." + * + *

+ * Note, that because of this when processing Type3 glyphs content streams either process them completely independent + * from this class or take this normalization into account. + * *

- *

* To be able to be wrapped with this {@link PdfObjectWrapper} the {@link PdfObject} * must be indirect. */ public class PdfType3Font extends PdfSimpleFont { private static final long serialVersionUID = 4940119184993066859L; + + private static final int FONT_BBOX_LLX = 0; + private static final int FONT_BBOX_LLY = 1; + private static final int FONT_BBOX_URX = 2; + private static final int FONT_BBOX_URY = 3; + + @Deprecated private double[] fontMatrix = DEFAULT_FONT_MATRIX; /** - * Used to normalize the values of glyphs widths and bBox measurements. - * iText process glyph width and bBox width and height in integer values from 0 to 1000. - * Such behaviour is based on the assumption that this is the most common way to store such values. It also implies - * that the fontMatrix contains the following values: [0.001, 0, 0, 0.001, 0, 0]. - * However for the other cases of font matrix the values stored inside pdfWidth and bBox arrays need to be normalized - * by multiplying them by fontMatrix[0] * 1000 to be processed correctly. The opposite procedure, division by - * dimensionsMultiplier is performed on font flush in order to maintain correct pdfObject for underlysing font. + * Used to normalize font metrics expressed in glyph space units. See {@link PdfType3Font}. */ - private double dimensionsMultiplier; + private double glyphSpaceNormalizationFactor; /** * Creates a Type 3 font. @@ -105,7 +128,7 @@ public class PdfType3Font extends PdfSimpleFont { embedded = true; fontProgram = new Type3Font(colorized); fontEncoding = FontEncoding.createEmptyFontEncoding(); - dimensionsMultiplier = 1.0f; + setGlyphSpaceNormalizationFactor(1.0f); } /** @@ -120,7 +143,7 @@ public class PdfType3Font extends PdfSimpleFont { this(document, colorized); ((Type3Font) fontProgram).setFontName(fontName); ((Type3Font) fontProgram).setFontFamily(fontFamily); - dimensionsMultiplier = 1.0f; + setGlyphSpaceNormalizationFactor(1.0f); } /** @@ -134,22 +157,36 @@ public class PdfType3Font extends PdfSimpleFont { embedded = true; fontProgram = new Type3Font(false); fontEncoding = DocFontEncoding.createDocFontEncoding(fontDictionary.get(PdfName.Encoding), toUnicode); + + double[] fontMatrixArray = readFontMatrix(); + double[] fontBBoxRect = readFontBBox(); + double[] widthsArray = readWidths(fontDictionary); + + setGlyphSpaceNormalizationFactor(fontMatrixArray[0] * FontProgram.UNITS_NORMALIZATION); + PdfDictionary charProcsDic = fontDictionary.getAsDictionary(PdfName.CharProcs); PdfDictionary encoding = fontDictionary.getAsDictionary(PdfName.Encoding); PdfArray differences = encoding != null ? encoding.getAsArray(PdfName.Differences) : null; if (charProcsDic == null || differences == null) { LoggerFactory.getLogger(getClass()).warn(LogMessageConstant.TYPE3_FONT_INITIALIZATION_ISSUE); } + fillFontDescriptor(fontDictionary.getAsDictionary(PdfName.FontDescriptor)); - calculateAndSetFontMatrix(); - calculateAndSetBBox(); + normalize1000UnitsToGlyphSpaceUnits(fontMatrixArray); + normalizeGlyphSpaceUnitsTo1000Units(fontBBoxRect); + normalizeGlyphSpaceUnitsTo1000Units(widthsArray); - int firstChar = calculateShortTag(fontDictionary); - int[] widths = calculateWidth(fontDictionary, firstChar); + int firstChar = initializeShortTag(fontDictionary); + fontMatrix = fontMatrixArray; + initializeFontBBox(fontBBoxRect); + initializeTypoAscenderDescender(fontBBoxRect); + + int[] widths = new int[256]; + for (int i = 0; i < widthsArray.length && firstChar + i < 256; i++) { + widths[firstChar + i] = (int) (widthsArray[i]); + } addGlyphsFromDifferences(differences, charProcsDic, widths); addGlyphsFromCharProcs(charProcsDic, widths); - - fillFontDescriptor(fontDictionary.getAsDictionary(PdfName.FontDescriptor)); } /** @@ -179,6 +216,15 @@ public void setFontWeight(int fontWeight) { ((Type3Font) fontProgram).setFontWeight(fontWeight); } + /** + * Sets cap height. + * + * @param capHeight integer in glyph-space 1000-units + */ + public void setCapHeight(int capHeight) { + ((Type3Font) fontProgram).setCapHeight(capHeight); + } + /** * Sets the PostScript italic angle. *

@@ -235,6 +281,13 @@ public double[] getFontMatrix() { return this.fontMatrix; } + /** + * Sets font matrix, mapping glyph space to text space. Must be identity matrix divided by 1000. + * @param fontMatrix an array of six numbers specifying the font matrix, + * mapping glyph space to text space. + * @deprecated will be made internal in next major release + */ + @Deprecated public void setFontMatrix(double[] fontMatrix) { this.fontMatrix = fontMatrix; } @@ -326,7 +379,9 @@ protected PdfDictionary getFontDescriptor(String fontName) { fontDescriptor.put(PdfName.Type, PdfName.FontDescriptor); FontMetrics fontMetrics = fontProgram.getFontMetrics(); - fontDescriptor.put(PdfName.CapHeight, new PdfNumber(fontMetrics.getCapHeight())); + + int capHeight = fontMetrics.getCapHeight(); + fontDescriptor.put(PdfName.CapHeight, new PdfNumber(normalize1000UnitsToGlyphSpaceUnits(capHeight))); fontDescriptor.put(PdfName.ItalicAngle, new PdfNumber(fontMetrics.getItalicAngle())); FontNames fontNames = fontProgram.getFontNames(); @@ -353,6 +408,23 @@ && getPdfObject().getIndirectReference().getDocument().isTagged()) { return null; } + @Override + protected PdfArray buildWidthsArray(int firstChar, int lastChar) { + double[] widths = new double[lastChar - firstChar + 1]; + for (int k = firstChar; k <= lastChar; ++k) { + int i = k - firstChar; + if (shortTag[k] == 0) { + widths[i] = 0; + } else { + int uni = getFontEncoding().getUnicode(k); + Glyph glyph = uni > -1 ? getGlyph(uni) : getFontProgram().getGlyphByCode(k); + widths[i] = glyph != null ? glyph.getWidth() : 0; + } + } + normalize1000UnitsToGlyphSpaceUnits(widths); + return new PdfArray(widths); + } + @Override protected void addFontStream(PdfDictionary fontDescriptor) { } @@ -363,19 +435,15 @@ protected PdfDocument getDocument() { @Override protected double getGlyphWidth(Glyph glyph) { - return glyph != null ? glyph.getWidth()/this.getDimensionsMultiplier() : 0; + return glyph != null ? glyph.getWidth() / this.getGlyphSpaceNormalizationFactor() : 0; } - /** - * Gets dimensionsMultiplier for normalizing glyph width, fontMatrix values and bBox dimensions. - * @return dimensionsMultiplier double value - */ - double getDimensionsMultiplier() { - return dimensionsMultiplier; + final double getGlyphSpaceNormalizationFactor() { + return glyphSpaceNormalizationFactor; } - void setDimensionsMultiplier(double dimensionsMultiplier) { - this.dimensionsMultiplier = dimensionsMultiplier; + final void setGlyphSpaceNormalizationFactor(double glyphSpaceNormalizationFactor) { + this.glyphSpaceNormalizationFactor = glyphSpaceNormalizationFactor; } private void addGlyphsFromDifferences(PdfArray differences, PdfDictionary charProcsDic, int[] widths) { @@ -460,11 +528,18 @@ private void flushFontData() { } } getPdfObject().put(PdfName.CharProcs, charProcs); - for (int i = 0; i < fontMatrix.length; i++) { - fontMatrix[i] *= getDimensionsMultiplier(); - } - getPdfObject().put(PdfName.FontMatrix, new PdfArray(getFontMatrix())); - getPdfObject().put(PdfName.FontBBox, normalizeBBox(fontProgram.getFontMetrics().getBbox())); + + double[] fontMatrixDouble = getFontMatrix(); + int[] fontBBoxInt = getFontProgram().getFontMetrics().getBbox(); + double[] fontBBoxDouble = new double[] { + fontBBoxInt[FONT_BBOX_LLX], fontBBoxInt[FONT_BBOX_LLY], + fontBBoxInt[FONT_BBOX_URX], fontBBoxInt[FONT_BBOX_URY]}; + + normalizeGlyphSpaceUnitsTo1000Units(fontMatrixDouble); + normalize1000UnitsToGlyphSpaceUnits(fontBBoxDouble); + + getPdfObject().put(PdfName.FontMatrix, new PdfArray(fontMatrixDouble)); + getPdfObject().put(PdfName.FontBBox, new PdfArray(fontBBoxDouble)); String fontName = fontProgram.getFontNames().getFontName(); super.flushFontData(fontName, PdfName.Type3); makeObjectIndirect(getPdfObject().get(PdfName.Widths)); @@ -472,22 +547,22 @@ private void flushFontData() { getPdfObject().remove(PdfName.BaseFont); } - private int[] calculateWidth(PdfDictionary fontDictionary, int firstChar) { + private double[] readWidths(PdfDictionary fontDictionary) { PdfArray pdfWidths = fontDictionary.getAsArray(PdfName.Widths); if (pdfWidths == null) { throw new PdfException(PdfException.MissingRequiredFieldInFontDictionary).setMessageParams(PdfName.Widths); } - double[] multipliedWidths = new double[pdfWidths.size()]; + double[] widths = new double[pdfWidths.size()]; for (int i = 0; i < pdfWidths.size(); i++) { - multipliedWidths[i] = pdfWidths.getAsNumber(i).doubleValue() * getDimensionsMultiplier(); + PdfNumber n = pdfWidths.getAsNumber(i); + widths[i] = n != null ? n.doubleValue() : 0; } - PdfArray multipliedPdfWidths = new PdfArray(multipliedWidths); - return FontUtil.convertSimpleWidthsArray(multipliedPdfWidths, firstChar, 0); + return widths; } - private int calculateShortTag(PdfDictionary fontDictionary) { + private int initializeShortTag(PdfDictionary fontDictionary) { int firstChar = normalizeFirstLastChar(fontDictionary.getAsNumber(PdfName.FirstChar), 0); int lastChar = normalizeFirstLastChar(fontDictionary.getAsNumber(PdfName.LastChar), PdfFont.SIMPLE_FONT_MAX_CHAR_CODE_VALUE); @@ -497,19 +572,21 @@ private int calculateShortTag(PdfDictionary fontDictionary) { return firstChar; } - private void calculateAndSetBBox() { - if (getPdfObject().containsKey(PdfName.FontBBox)) { - PdfArray fontBBox = getPdfObject().getAsArray(PdfName.FontBBox); - fontProgram.getFontMetrics().setBbox((int)(fontBBox.getAsNumber(0).doubleValue() * getDimensionsMultiplier()), - (int)(fontBBox.getAsNumber(1).doubleValue() * getDimensionsMultiplier()), - (int)(fontBBox.getAsNumber(2).doubleValue() * getDimensionsMultiplier()), - (int)(fontBBox.getAsNumber(3).doubleValue() * getDimensionsMultiplier())); - } else { - fontProgram.getFontMetrics().setBbox(0, 0, 0, 0); + private double[] readFontBBox() { + PdfArray fontBBox = getPdfObject().getAsArray(PdfName.FontBBox); + if (fontBBox != null) { + double llx = fontBBox.getAsNumber(FONT_BBOX_LLX).doubleValue(); + double lly = fontBBox.getAsNumber(FONT_BBOX_LLY).doubleValue(); + double urx = fontBBox.getAsNumber(FONT_BBOX_URX).doubleValue(); + double ury = fontBBox.getAsNumber(FONT_BBOX_URY).doubleValue(); + + return new double[] {llx, lly, urx, ury}; } + + return new double[] {0, 0, 0, 0}; } - private void calculateAndSetFontMatrix() { + private double[] readFontMatrix() { PdfArray fontMatrixArray = getPdfObject().getAsArray(PdfName.FontMatrix); if (fontMatrixArray == null) { throw new PdfException(PdfException.MissingRequiredFieldInFontDictionary) @@ -519,18 +596,55 @@ private void calculateAndSetFontMatrix() { for (int i = 0; i < fontMatrixArray.size(); i++) { fontMatrix[i] = ((PdfNumber) fontMatrixArray.get(i)).getValue(); } - setDimensionsMultiplier(fontMatrix[0] * 1000); - for (int i = 0; i < 6; i++) { - fontMatrix[i] /= getDimensionsMultiplier(); + return fontMatrix; + } + + private void initializeTypoAscenderDescender(double[] fontBBoxRect) { + // iText uses typo ascender/descender for text extraction, that's why we need to set + // them here to values relative to actual glyph metrics values. + ((Type3Font) fontProgram).setTypoAscender((int) fontBBoxRect[FONT_BBOX_URY]); + ((Type3Font) fontProgram).setTypoDescender((int) fontBBoxRect[FONT_BBOX_LLY]); + } + + private void initializeFontBBox(double[] fontBBoxRect) { + fontProgram.getFontMetrics().setBbox( + (int) fontBBoxRect[FONT_BBOX_LLX], + (int) fontBBoxRect[FONT_BBOX_LLY], + (int) fontBBoxRect[FONT_BBOX_URX], + (int) fontBBoxRect[FONT_BBOX_URY] + ); + } + + private void normalizeGlyphSpaceUnitsTo1000Units(double[] array) { + for (int i = 0; i < array.length; i++) { + array[i] = normalizeGlyphSpaceUnitsTo1000Units(array[i]);; + } + } + + private double normalizeGlyphSpaceUnitsTo1000Units(double value) { + return value * getGlyphSpaceNormalizationFactor(); + } + + private void normalize1000UnitsToGlyphSpaceUnits(double[] array) { + for (int i = 0; i < array.length; i++) { + array[i] = normalize1000UnitsToGlyphSpaceUnits(array[i]); } - setFontMatrix(fontMatrix); + } + + private double normalize1000UnitsToGlyphSpaceUnits(double value) { + return value / getGlyphSpaceNormalizationFactor(); } private void fillFontDescriptor(PdfDictionary fontDesc) { if (fontDesc == null) { return; } - PdfNumber v = fontDesc.getAsNumber(PdfName.ItalicAngle); + PdfNumber v = fontDesc.getAsNumber(PdfName.CapHeight); + if (v != null) { + double capHeight = v.doubleValue(); + setCapHeight((int) normalizeGlyphSpaceUnitsTo1000Units(capHeight)); + } + v = fontDesc.getAsNumber(PdfName.ItalicAngle); if (v != null) { setItalicAngle(v.intValue()); } @@ -560,12 +674,4 @@ private int normalizeFirstLastChar(PdfNumber firstLast, int defaultValue) { int result = firstLast.intValue(); return result < 0 || result > PdfFont.SIMPLE_FONT_MAX_CHAR_CODE_VALUE ? defaultValue : result; } - - private PdfArray normalizeBBox(int[] bBox) { - double [] normalizedBBox = new double [4]; - for (int i = 0; i < 4; i++) { - normalizedBBox[i] = bBox[i] / getDimensionsMultiplier(); - } - return new PdfArray(normalizedBBox); - } } diff --git a/kernel/src/main/java/com/itextpdf/kernel/font/Type3Font.java b/kernel/src/main/java/com/itextpdf/kernel/font/Type3Font.java index 7b4a938dd7..9895f55a5a 100644 --- a/kernel/src/main/java/com/itextpdf/kernel/font/Type3Font.java +++ b/kernel/src/main/java/com/itextpdf/kernel/font/Type3Font.java @@ -147,7 +147,7 @@ public int getNumberOfGlyphs() { */ @Override protected void setFontName(String fontName) { - //This dummy override allows PdfType3Font to set font name because of different modules. + // This dummy override allows PdfType3Font to use setter from different module. super.setFontName(fontName); } @@ -158,7 +158,7 @@ protected void setFontName(String fontName) { */ @Override protected void setFontFamily(String fontFamily) { - //This dummy override allows PdfType3Font to set font name because of different modules. + // This dummy override allows PdfType3Font to use setter from different module. super.setFontFamily(fontFamily); } @@ -169,7 +169,7 @@ protected void setFontFamily(String fontFamily) { */ @Override protected void setFontWeight(int fontWeight) { - //This dummy override allows PdfType3Font to set font name because of different modules. + // This dummy override allows PdfType3Font to use setter from different module. super.setFontWeight(fontWeight); } @@ -180,23 +180,46 @@ protected void setFontWeight(int fontWeight) { */ @Override protected void setFontStretch(String fontWidth) { - //This dummy override allows PdfType3Font to set font name because of different modules. + // This dummy override allows PdfType3Font to use setter from different module. super.setFontStretch(fontWidth); } /** - * Sets the PostScript italic angel. - *

- * Italic angle in counter-clockwise degrees from the vertical. Zero for upright text, negative for text that leans to the right (forward). - * - * @param italicAngle in counter-clockwise degrees from the vertical + * {@inheritDoc} */ - @Override //This dummy override allows PdfType3Font to set the PostScript italicAngel because of different modules. + @Override + protected void setCapHeight(int capHeight) { + // This dummy override allows PdfType3Font to use setter from different module. + super.setCapHeight(capHeight); + } + + /** + * {@inheritDoc} + */ + @Override protected void setItalicAngle(int italicAngle) { - //This dummy override allows PdfType3Font to set font name because of different modules. + // This dummy override allows PdfType3Font to use setter from different module. super.setItalicAngle(italicAngle); } + /** + * {@inheritDoc} + */ + @Override + protected void setTypoAscender(int ascender) { + // This dummy override allows PdfType3Font to use setter from different module. + super.setTypoAscender(ascender); + } + + /** + * {@inheritDoc} + */ + @Override + protected void setTypoDescender(int descender) { + // This dummy override allows PdfType3Font to use setter from different module. + super.setTypoDescender(descender); + } + /** * Sets Font descriptor flags. * @see FontDescriptorFlags diff --git a/kernel/src/main/java/com/itextpdf/kernel/pdf/EncryptedEmbeddedStreamsHandler.java b/kernel/src/main/java/com/itextpdf/kernel/pdf/EncryptedEmbeddedStreamsHandler.java new file mode 100644 index 0000000000..95f2ac8203 --- /dev/null +++ b/kernel/src/main/java/com/itextpdf/kernel/pdf/EncryptedEmbeddedStreamsHandler.java @@ -0,0 +1,83 @@ +/* + This file is part of the iText (R) project. + Copyright (c) 1998-2021 iText Group NV + Authors: iText Software. + + This program is offered under a commercial and under the AGPL license. + For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below. + + AGPL licensing: + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + */ +package com.itextpdf.kernel.pdf; + +import java.io.Serializable; +import java.util.HashSet; +import java.util.Set; + +class EncryptedEmbeddedStreamsHandler implements Serializable { + + private static final long serialVersionUID = -4542644924377740467L; + + private final PdfDocument document; + + private final Set embeddedStreams = new HashSet<>(); + + /** + * Creates {@link EncryptedEmbeddedStreamsHandler} instance. + * + * @param document {@link PdfDocument} associated with this handler + */ + EncryptedEmbeddedStreamsHandler(PdfDocument document) { + this.document = document; + } + + /** + * Stores all embedded streams present in the {@link PdfDocument}. + * Note that during this method we traverse through every indirect object of the document. + */ + void storeAllEmbeddedStreams() { + for (int i = 0; i < document.getNumberOfPdfObjects(); ++i) { + PdfObject indirectObject = document.getPdfObject(i); + if (indirectObject instanceof PdfDictionary) { + PdfStream embeddedStream = getEmbeddedFileStreamFromDictionary((PdfDictionary) indirectObject); + if (embeddedStream != null) { + storeEmbeddedStream(embeddedStream); + } + } + } + } + + void storeEmbeddedStream(PdfStream embeddedStream) { + embeddedStreams.add(embeddedStream); + } + + /** + * Checks, whether this {@link PdfStream} was stored as embedded stream. + * + * @param stream to be checked + * @return true if this stream is embedded, false otherwise + */ + boolean isStreamStoredAsEmbedded(PdfStream stream) { + return embeddedStreams.contains(stream); + } + + private static PdfStream getEmbeddedFileStreamFromDictionary(PdfDictionary dictionary) { + PdfDictionary embeddedFileDictionary = dictionary.getAsDictionary(PdfName.EF); + if (PdfName.Filespec.equals(dictionary.getAsName(PdfName.Type)) && embeddedFileDictionary != null) { + return embeddedFileDictionary.getAsStream(PdfName.F); + } + return null; + } +} diff --git a/kernel/src/main/java/com/itextpdf/kernel/pdf/PdfAConformanceLevel.java b/kernel/src/main/java/com/itextpdf/kernel/pdf/PdfAConformanceLevel.java index d6ae15136c..1ea00a114e 100644 --- a/kernel/src/main/java/com/itextpdf/kernel/pdf/PdfAConformanceLevel.java +++ b/kernel/src/main/java/com/itextpdf/kernel/pdf/PdfAConformanceLevel.java @@ -120,7 +120,7 @@ public static PdfAConformanceLevel getConformanceLevel(XMPMeta meta) { try { conformanceXmpProperty = meta.getProperty(XMPConst.NS_PDFA_ID, XMPConst.CONFORMANCE); partXmpProperty = meta.getProperty(XMPConst.NS_PDFA_ID, XMPConst.PART); - } catch (XMPException exc) { + } catch (XMPException ignored) { } if (conformanceXmpProperty == null || partXmpProperty == null) { return null; diff --git a/kernel/src/main/java/com/itextpdf/kernel/pdf/PdfDocument.java b/kernel/src/main/java/com/itextpdf/kernel/pdf/PdfDocument.java index 1300aa9dbd..9cb1212602 100644 --- a/kernel/src/main/java/com/itextpdf/kernel/pdf/PdfDocument.java +++ b/kernel/src/main/java/com/itextpdf/kernel/pdf/PdfDocument.java @@ -44,6 +44,7 @@ This file is part of the iText (R) project. package com.itextpdf.kernel.pdf; import com.itextpdf.io.LogMessageConstant; +import com.itextpdf.io.font.PdfEncodings; import com.itextpdf.io.source.ByteArrayOutputStream; import com.itextpdf.io.source.ByteUtils; import com.itextpdf.io.source.RandomAccessFileOrArray; @@ -229,6 +230,8 @@ public class PdfDocument implements IEventDispatcher, Closeable, Serializable { */ MemoryLimitsAwareHandler memoryLimitsAwareHandler = null; + private EncryptedEmbeddedStreamsHandler encryptedEmbeddedStreamsHandler; + /** * Open PDF document in reading mode. * @@ -459,6 +462,17 @@ public PdfPage getLastPage() { return getPage(getNumberOfPages()); } + /** + * Marks {@link PdfStream} object as embedded file stream. Note that this method is for internal usage. + * To add an embedded file to the PDF document please use specialized API for file attachments. + * (e.g. {@link PdfDocument#addFileAttachment(String, PdfFileSpec)}, {@link PdfPage#addAnnotation(PdfAnnotation)}) + * + * @param stream to be marked as embedded file stream + */ + public void markStreamAsEmbeddedFile(PdfStream stream) { + encryptedEmbeddedStreamsHandler.storeEmbeddedStream(stream); + } + /** * Creates and adds new page to the end of document. * @@ -664,11 +678,18 @@ public void removePage(int pageNum) { /** * Gets document information dictionary. + * {@link PdfDocument#info} is lazy initialized. It will be initialized during the first call of this method. * * @return document information dictionary. */ public PdfDocumentInfo getDocumentInfo() { checkClosingStatus(); + if (info == null) { + PdfObject infoDict = trailer.get(PdfName.Info); + info = new PdfDocumentInfo( + infoDict instanceof PdfDictionary ? (PdfDictionary) infoDict : new PdfDictionary(), this); + XmpMetaInfoConverter.appendMetadataToInfo(xmpMetadata, info); + } return info; } @@ -839,7 +860,7 @@ public void close() { // In PDF 2.0, all the values except CreationDate and ModDate are deprecated. Remove them now if (pdfVersion.compareTo(PdfVersion.PDF_2_0) >= 0) { for (PdfName deprecatedKey : PdfDocumentInfo.PDF20_DEPRECATED_KEYS) { - info.getPdfObject().remove(deprecatedKey); + getDocumentInfo().getPdfObject().remove(deprecatedKey); } } if (getXmpMetadata() != null) { @@ -892,8 +913,8 @@ public void close() { } - if (info.getPdfObject().isModified()) { - info.getPdfObject().flush(false); + if (getDocumentInfo().getPdfObject().isModified()) { + getDocumentInfo().getPdfObject().flush(false); } flushFonts(); @@ -941,7 +962,7 @@ public void close() { tryFlushTagStructure(false); } catalog.getPdfObject().flush(false); - info.getPdfObject().flush(false); + getDocumentInfo().getPdfObject().flush(false); flushFonts(); if (writer.crypto != null) { @@ -977,7 +998,7 @@ public void close() { // entries existing in the trailer object and corresponding fields. This inconsistency // may appear when user gets trailer and explicitly sets new root or info dictionaries. trailer.put(PdfName.Root, catalog.getPdfObject()); - trailer.put(PdfName.Info, info.getPdfObject()); + trailer.put(PdfName.Info, getDocumentInfo().getPdfObject()); //By this time original and modified document ids should always be not null due to initializing in @@ -1056,7 +1077,8 @@ public PdfDocument setTagged() { /** * Gets {@link PdfStructTreeRoot} of tagged document. * - * @return {@link PdfStructTreeRoot} in case tagged document, otherwise false. + * @return {@link PdfStructTreeRoot} in case document is tagged, otherwise it returns null. + * * @see #isTagged() * @see #getNextStructParentIndex() */ @@ -1068,6 +1090,7 @@ public PdfStructTreeRoot getStructTreeRoot() { * Gets next parent index of tagged document. * * @return -1 if document is not tagged, or >= 0 if tagged. + * * @see #isTagged() * @see #getNextStructParentIndex() */ @@ -1905,9 +1928,11 @@ protected void flushObject(PdfObject pdfObject, boolean canBeInObjStm) throws IO */ protected void open(PdfVersion newPdfVersion) { this.fingerPrint = new FingerPrint(); + this.encryptedEmbeddedStreamsHandler = new EncryptedEmbeddedStreamsHandler(this); try { EventCounterHandler.getInstance().onEvent(CoreEvent.PROCESS, properties.metaInfo, getClass()); + boolean embeddedStreamsSavedOnReading = false; if (reader != null) { if (reader.pdfDocument != null) { throw new PdfException(PdfException.PdfReaderHasBeenAlreadyUtilized); @@ -1918,6 +1943,10 @@ protected void open(PdfVersion newPdfVersion) { memoryLimitsAwareHandler = new MemoryLimitsAwareHandler(reader.tokens.getSafeFile().length()); } reader.readPdf(); + if (reader.decrypt != null && reader.decrypt.isEmbeddedFilesOnly()) { + encryptedEmbeddedStreamsHandler.storeAllEmbeddedStreams(); + embeddedStreamsSavedOnReading = true; + } for (ICounter counter : getCounters()) { counter.onDocumentRead(reader.getFileLength()); } @@ -1931,14 +1960,13 @@ protected void open(PdfVersion newPdfVersion) { PdfStream xmpMetadataStream = catalog.getPdfObject().getAsStream(PdfName.Metadata); if (xmpMetadataStream != null) { xmpMetadata = xmpMetadataStream.getBytes(); - try { - reader.pdfAConformanceLevel = PdfAConformanceLevel.getConformanceLevel(XMPMetaFactory.parseFromBuffer(xmpMetadata)); - } catch (XMPException ignored) { + if (!this.getClass().equals(PdfDocument.class)) { + // TODO DEVSIX-5292 If somebody extends PdfDocument we have to initialize document info + // and conformance level to provide compatibility. This code block shall be removed + reader.getPdfAConformanceLevel(); + getDocumentInfo(); } } - PdfObject infoDict = trailer.get(PdfName.Info); - info = new PdfDocumentInfo(infoDict instanceof PdfDictionary ? (PdfDictionary) infoDict : new PdfDictionary(), this); - XmpMetaInfoConverter.appendMetadataToInfo(xmpMetadata, info); PdfDictionary str = catalog.getPdfObject().getAsDictionary(PdfName.StructTreeRoot); if (str != null) { @@ -1964,10 +1992,10 @@ protected void open(PdfVersion newPdfVersion) { info = new PdfDocumentInfo(this).addCreationDate(); } updateProducerInInfoDictionary(); - info.addModDate(); + getDocumentInfo().addModDate(); trailer = new PdfDictionary(); trailer.put(PdfName.Root, catalog.getPdfObject().getIndirectReference()); - trailer.put(PdfName.Info, info.getPdfObject().getIndirectReference()); + trailer.put(PdfName.Info, getDocumentInfo().getPdfObject().getIndirectReference()); if (reader != null) { // If the reader's trailer contains an ID entry, let's copy it over to the new trailer @@ -2046,6 +2074,9 @@ protected void open(PdfVersion newPdfVersion) { writer.initCryptoIfSpecified(pdfVersion); } if (writer.crypto != null) { + if (!embeddedStreamsSavedOnReading && writer.crypto.isEmbeddedFilesOnly()) { + encryptedEmbeddedStreamsHandler.storeAllEmbeddedStreams(); + } if (writer.crypto.getCryptoMode() < EncryptionConstants.ENCRYPTION_AES_256) { VersionConforming.validatePdfVersionForDeprecatedFeatureLogWarn(this, PdfVersion.PDF_2_0, VersionConforming.DEPRECATED_ENCRYPTION_ALGORITHMS); } else if (writer.crypto.getCryptoMode() == EncryptionConstants.ENCRYPTION_AES_256) { @@ -2093,7 +2124,7 @@ protected void updateXmpMetadata() { */ protected XMPMeta updateDefaultXmpMetadata() throws XMPException { XMPMeta xmpMeta = XMPMetaFactory.parseFromBuffer(getXmpMetadata(true)); - XmpMetaInfoConverter.appendDocumentInfoToMetadata(info, xmpMeta); + XmpMetaInfoConverter.appendDocumentInfoToMetadata(getDocumentInfo(), xmpMeta); if (isTagged() && writer.properties.addUAXmpMetadata && !isXmpMetaHasProperty(xmpMeta, XMPConst.NS_PDFUA_ID, XMPConst.PART)) { xmpMeta.setPropertyInteger(XMPConst.NS_PDFUA_ID, XMPConst.PART, 1, new PropertyOptions(PropertyOptions.SEPARATE_NODE)); @@ -2188,6 +2219,10 @@ long getDocumentId() { return documentId; } + boolean doesStreamBelongToEmbeddedFile(PdfStream stream) { + return encryptedEmbeddedStreamsHandler.isStreamStoredAsEmbedded(stream); + } + /** * Gets iText version info. * @@ -2203,16 +2238,18 @@ boolean hasAcroForm() { private void updateProducerInInfoDictionary() { String producer = null; + PdfDictionary documentInfoObject = getDocumentInfo().getPdfObject(); if (reader == null) { producer = versionInfo.getVersion(); } else { - if (info.getPdfObject().containsKey(PdfName.Producer)) { - final PdfString producerPdfStr = info.getPdfObject().getAsString(PdfName.Producer); + if (documentInfoObject.containsKey(PdfName.Producer)) { + final PdfString producerPdfStr = documentInfoObject.getAsString(PdfName.Producer); producer = producerPdfStr == null ? null : producerPdfStr.toUnicodeString(); } producer = addModifiedPostfix(producer); } - info.getPdfObject().put(PdfName.Producer, new PdfString(producer)); + + documentInfoObject.put(PdfName.Producer, new PdfString(producer, PdfEncodings.UNICODE_BIG)); } /** diff --git a/kernel/src/main/java/com/itextpdf/kernel/pdf/PdfEncryption.java b/kernel/src/main/java/com/itextpdf/kernel/pdf/PdfEncryption.java index cb03f594ca..d6421c2787 100644 --- a/kernel/src/main/java/com/itextpdf/kernel/pdf/PdfEncryption.java +++ b/kernel/src/main/java/com/itextpdf/kernel/pdf/PdfEncryption.java @@ -484,7 +484,6 @@ private int setCryptoMode(int mode, int length) { revision = STANDARD_ENCRYPTION_40; break; case EncryptionConstants.STANDARD_ENCRYPTION_128: - embeddedFilesOnly = false; if (length > 0) { setKeyLength(length); } else { @@ -514,6 +513,7 @@ private int readAndSetCryptoModeForStdHandler(PdfDictionary encDict) { if (rValue == null) throw new PdfException(PdfException.IllegalRValue); int revision = rValue.intValue(); + boolean embeddedFilesOnlyMode = readEmbeddedFilesOnlyFromEncryptDictionary(encDict); switch (revision) { case 2: cryptoMode = EncryptionConstants.STANDARD_ENCRYPTION_40; @@ -545,6 +545,9 @@ private int readAndSetCryptoModeForStdHandler(PdfDictionary encDict) { if (em != null && !em.getValue()) { cryptoMode |= EncryptionConstants.DO_NOT_ENCRYPT_METADATA; } + if (embeddedFilesOnlyMode) { + cryptoMode |= EncryptionConstants.EMBEDDED_FILES_ONLY; + } break; case 5: case 6: @@ -553,6 +556,9 @@ private int readAndSetCryptoModeForStdHandler(PdfDictionary encDict) { if (em5 != null && !em5.getValue()) { cryptoMode |= EncryptionConstants.DO_NOT_ENCRYPT_METADATA; } + if (embeddedFilesOnlyMode) { + cryptoMode |= EncryptionConstants.EMBEDDED_FILES_ONLY; + } break; default: throw new PdfException(PdfException.UnknownEncryptionTypeREq1).setMessageParams(rValue); @@ -570,6 +576,7 @@ private int readAndSetCryptoModeForPubSecHandler(PdfDictionary encDict) { if (vValue == null) throw new PdfException(PdfException.IllegalVValue); int v = vValue.intValue(); + boolean embeddedFilesOnlyMode = readEmbeddedFilesOnlyFromEncryptDictionary(encDict); switch (v) { case 1: cryptoMode = EncryptionConstants.STANDARD_ENCRYPTION_40; @@ -608,6 +615,9 @@ private int readAndSetCryptoModeForPubSecHandler(PdfDictionary encDict) { if (em != null && !em.getValue()) { cryptoMode |= EncryptionConstants.DO_NOT_ENCRYPT_METADATA; } + if (embeddedFilesOnlyMode) { + cryptoMode |= EncryptionConstants.EMBEDDED_FILES_ONLY; + } break; default: throw new PdfException(PdfException.UnknownEncryptionTypeVEq1, vValue); @@ -615,6 +625,23 @@ private int readAndSetCryptoModeForPubSecHandler(PdfDictionary encDict) { return setCryptoMode(cryptoMode, length); } + static boolean readEmbeddedFilesOnlyFromEncryptDictionary(PdfDictionary encDict) { + PdfName embeddedFilesFilter = encDict.getAsName(PdfName.EFF); + boolean encryptEmbeddedFiles = !PdfName.Identity.equals(embeddedFilesFilter) && embeddedFilesFilter != null; + boolean encryptStreams = !PdfName.Identity.equals(encDict.getAsName(PdfName.StmF)); + boolean encryptStrings = !PdfName.Identity.equals(encDict.getAsName(PdfName.StrF)); + if (encryptStreams || encryptStrings || !encryptEmbeddedFiles) { + return false; + } + + PdfDictionary cfDictionary = encDict.getAsDictionary(PdfName.CF); + if (cfDictionary != null) { + // Here we check if the crypt filter for embedded files and the filter in the CF dictionary are the same + return cfDictionary.getAsDictionary(embeddedFilesFilter) != null; + } + return false; + } + private int fixAccessibilityPermissionPdf20(int permissions) { // This bit was previously used to determine whether // content could be extracted for the purposes of accessibility, diff --git a/kernel/src/main/java/com/itextpdf/kernel/pdf/PdfEncryptor.java b/kernel/src/main/java/com/itextpdf/kernel/pdf/PdfEncryptor.java index 4c12e6d0f7..5b25587319 100644 --- a/kernel/src/main/java/com/itextpdf/kernel/pdf/PdfEncryptor.java +++ b/kernel/src/main/java/com/itextpdf/kernel/pdf/PdfEncryptor.java @@ -43,6 +43,7 @@ This file is part of the iText (R) project. */ package com.itextpdf.kernel.pdf; +import java.io.IOException; import java.io.OutputStream; import java.security.PrivateKey; import java.util.Map; @@ -241,12 +242,15 @@ public PdfEncryptor setEncryptionProperties(EncryptionProperties properties) { public void encrypt(PdfReader reader, OutputStream os, Map newInfo) { WriterProperties writerProperties = new WriterProperties(); writerProperties.encryptionProperties = properties; - PdfWriter writer = new PdfWriter(os, writerProperties); StampingProperties stampingProperties = new StampingProperties(); stampingProperties.setEventCountingMetaInfo(metaInfo); - PdfDocument document = new PdfDocument(reader, writer, stampingProperties); - document.getDocumentInfo().setMoreInfo(newInfo); - document.close(); + try (PdfWriter writer = new PdfWriter(os, writerProperties); + PdfDocument document = new PdfDocument(reader, writer, stampingProperties)) { + document.getDocumentInfo().setMoreInfo(newInfo); + } catch (IOException e) { + //The close() method of OutputStream throws an exception, but we don't need to do anything in this case, + // because OutputStream#close() does nothing. + } } /** diff --git a/kernel/src/main/java/com/itextpdf/kernel/pdf/PdfOutputStream.java b/kernel/src/main/java/com/itextpdf/kernel/pdf/PdfOutputStream.java index f972f6a5e7..5d2337d3b7 100644 --- a/kernel/src/main/java/com/itextpdf/kernel/pdf/PdfOutputStream.java +++ b/kernel/src/main/java/com/itextpdf/kernel/pdf/PdfOutputStream.java @@ -298,7 +298,8 @@ private void write(PdfStream pdfStream) { java.io.OutputStream fout = this; DeflaterOutputStream def = null; OutputStreamEncryption ose = null; - if (crypto != null && !crypto.isEmbeddedFilesOnly()) { + if (crypto != null && + (!crypto.isEmbeddedFilesOnly() || document.doesStreamBelongToEmbeddedFile(pdfStream))) { fout = ose = crypto.getEncryptionStream(fout); } if (toCompress && (allowCompression || userDefinedCompression)) { @@ -390,7 +391,7 @@ private void write(PdfStream pdfStream) { } protected boolean checkEncryption(PdfStream pdfStream) { - if (crypto == null || crypto.isEmbeddedFilesOnly()) { + if (crypto == null || (crypto.isEmbeddedFilesOnly() && !document.doesStreamBelongToEmbeddedFile(pdfStream))) { return false; } else if (isXRefStream(pdfStream)) { // The cross-reference stream shall not be encrypted diff --git a/kernel/src/main/java/com/itextpdf/kernel/pdf/PdfReader.java b/kernel/src/main/java/com/itextpdf/kernel/pdf/PdfReader.java index a9c2393554..85aa1f65db 100644 --- a/kernel/src/main/java/com/itextpdf/kernel/pdf/PdfReader.java +++ b/kernel/src/main/java/com/itextpdf/kernel/pdf/PdfReader.java @@ -64,6 +64,9 @@ This file is part of the iText (R) project. import java.io.InputStream; import java.io.Serializable; import java.util.Map; + +import com.itextpdf.kernel.xmp.XMPException; +import com.itextpdf.kernel.xmp.XMPMetaFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -387,7 +390,8 @@ public byte[] readStreamBytesRaw(PdfStream stream) throws IOException { file.seek(stream.getOffset()); bytes = new byte[length]; file.readFully(bytes); - if (decrypt != null && !decrypt.isEmbeddedFilesOnly()) { + boolean embeddedStream = pdfDocument.doesStreamBelongToEmbeddedFile(stream); + if (decrypt != null && (!decrypt.isEmbeddedFilesOnly() || embeddedStream)) { PdfObject filter = stream.get(PdfName.Filter, true); boolean skip = false; if (filter != null) { @@ -605,13 +609,24 @@ public int getCryptoMode() { } /** - * Gets the declared Pdf/A conformance level of the source document that is being read. + * Gets the declared PDF/A conformance level of the source document that is being read. * Note that this information is provided via XMP metadata and is not verified by iText. + * {@link PdfReader#pdfAConformanceLevel} is lazy initialized. + * It will be initialized during the first call of this method. * - * @return conformance level of the source document, or {@code null} if no Pdf/A + * @return conformance level of the source document, or {@code null} if no PDF/A * conformance level information is specified. */ public PdfAConformanceLevel getPdfAConformanceLevel() { + if (pdfAConformanceLevel == null) { + if (pdfDocument != null && pdfDocument.getXmpMetadata() != null) { + try { + pdfAConformanceLevel = PdfAConformanceLevel.getConformanceLevel( + XMPMetaFactory.parseFromBuffer(pdfDocument.getXmpMetadata())); + } catch (XMPException ignored) { + } + } + } return pdfAConformanceLevel; } @@ -1297,8 +1312,19 @@ private void readDecryptObj() { * @throws IOException if there is a problem reading the byte source */ private static PdfTokenizer getOffsetTokeniser(IRandomAccessSource byteSource) throws IOException { + com.itextpdf.io.IOException possibleException = null; PdfTokenizer tok = new PdfTokenizer(new RandomAccessFileOrArray(byteSource)); - int offset = tok.getHeaderOffset(); + int offset; + try { + offset = tok.getHeaderOffset(); + } catch (com.itextpdf.io.IOException ex) { + possibleException = ex; + throw possibleException; + } finally { + if (possibleException != null) { + tok.close(); + } + } if (offset != 0) { IRandomAccessSource offsetSource = new WindowRandomAccessSource(byteSource, offset); tok = new PdfTokenizer(new RandomAccessFileOrArray(offsetSource)); diff --git a/kernel/src/main/java/com/itextpdf/kernel/pdf/action/PdfAction.java b/kernel/src/main/java/com/itextpdf/kernel/pdf/action/PdfAction.java index eb54361233..c1ae813148 100644 --- a/kernel/src/main/java/com/itextpdf/kernel/pdf/action/PdfAction.java +++ b/kernel/src/main/java/com/itextpdf/kernel/pdf/action/PdfAction.java @@ -709,6 +709,12 @@ private static void validateRemoteDestination(PdfDestination destination) { } } + /** + * Validates not remote destination against the PDF specification and in case of invalidity logs a warning. + * See section 12.3.2.2 of ISO 32000-1. + * + * @param destination the {@link PdfDestination destination} to be validated + */ public static void validateNotRemoteDestination(PdfDestination destination) { if (destination instanceof PdfExplicitRemoteGoToDestination) { LoggerFactory.getLogger(PdfAction.class).warn(LogMessageConstant.INVALID_DESTINATION_TYPE); diff --git a/kernel/src/main/java/com/itextpdf/kernel/pdf/annot/Pdf3DAnnotation.java b/kernel/src/main/java/com/itextpdf/kernel/pdf/annot/Pdf3DAnnotation.java index a4312881af..aee7f7ae68 100644 --- a/kernel/src/main/java/com/itextpdf/kernel/pdf/annot/Pdf3DAnnotation.java +++ b/kernel/src/main/java/com/itextpdf/kernel/pdf/annot/Pdf3DAnnotation.java @@ -50,53 +50,139 @@ This file is part of the iText (R) project. import com.itextpdf.kernel.pdf.PdfName; import com.itextpdf.kernel.pdf.PdfObject; - +/** + * This class represents 3D annotations by which 3D artwork shall be represented in a PDF document. + * See also ISO-32000-2 13.6.2 "3D annotations". + */ public class Pdf3DAnnotation extends PdfAnnotation { private static final long serialVersionUID = 3823509772499230844L; + /** + * Creates a {@link Pdf3DAnnotation} instance. + * + * @param rect the annotation rectangle, defining the location of the annotation on the page + * in default user space units. See {@link PdfAnnotation#setRectangle(PdfArray)}. + * @param artwork 3D artwork which is represented by the annotation + */ public Pdf3DAnnotation(Rectangle rect, PdfObject artwork) { super(rect); put(PdfName._3DD, artwork); } + /** + * Instantiates a new {@link Pdf3DAnnotation} instance based on {@link PdfDictionary} + * instance, that represents existing annotation object in the document. + * + * @param pdfObject the {@link PdfDictionary} representing annotation object + * @see PdfAnnotation#makeAnnotation(PdfObject) + */ public Pdf3DAnnotation(PdfDictionary pdfObject) { super(pdfObject); } + /** + * {@inheritDoc} + */ @Override public PdfName getSubtype() { return PdfName._3D; } + /** + * Sets the default initial view of the 3D artwork that shall be used when the annotation is activated. + * + * @param initialView the default initial view of the 3D artwork that shall be used + * when the annotation is activated + * @return this {@link Pdf3DAnnotation} instance + */ public Pdf3DAnnotation setDefaultInitialView(PdfObject initialView) { return (Pdf3DAnnotation) put(PdfName._3DV, initialView); } + /** + * Gets the default initial view of the 3D artwork that shall be used when the annotation is activated. + * + * @return the default initial view of the 3D artwork that shall be used when the annotation is activated + */ public PdfObject getDefaultInitialView() { return getPdfObject().get(PdfName._3DV); } + /** + * Sets the activation dictionary that defines the times at which the annotation shall be + * activated and deactivated and the state of the 3D artwork instance at those times. + * + * @param activationDictionary dictionary that defines the times at which the annotation + * shall be activated and deactivated and the state of the 3D artwork + * instance at those times. + * @return this {@link Pdf3DAnnotation} instance + */ public Pdf3DAnnotation setActivationDictionary(PdfDictionary activationDictionary) { return (Pdf3DAnnotation) put(PdfName._3DA, activationDictionary); } + /** + * Gets the activation dictionary that defines the times at which the annotation shall be + * activated and deactivated and the state of the 3D artwork instance at those times. + * + * @return the activation dictionary that defines the times at which the annotation shall be + * activated and deactivated and the state of the 3D artwork instance at those times. + */ public PdfDictionary getActivationDictionary() { return getPdfObject().getAsDictionary(PdfName._3DA); } + /** + * Sets the primary use of the 3D annotation. + * + *

+ * If true, it is intended to be interactive; if false, it is intended to be manipulated programmatically, + * as with an ECMAScript animation. Interactive PDF processors may present different user interface controls + * for interactive 3D annotations (for example, to rotate, pan, or zoom the artwork) than for those + * managed by a script or other mechanism. + * + *

+ * Default value: true. + * + * @param interactive if true, it is intended to be interactive; if false, it is intended to be + * manipulated programmatically + * @return this {@link Pdf3DAnnotation} instance + */ public Pdf3DAnnotation setInteractive(boolean interactive) { return (Pdf3DAnnotation) put(PdfName._3DI, PdfBoolean.valueOf(interactive)); } + /** + * Indicates whether the 3D annotation is intended to be interactive or not. + * + * @return whether the 3D annotation is intended to be interactive or not + */ public PdfBoolean isInteractive() { return getPdfObject().getAsBoolean(PdfName._3DI); } + /** + * Sets the 3D view box, which is the rectangular area in which the 3D artwork shall be drawn. + * It shall be within the rectangle specified by the annotation’s Rect entry and shall be expressed + * in the annotation’s target coordinate system. + * + *

+ * Default value: the annotation’s Rect entry, expressed in the target coordinate system. + * This value is [-w/2 -h/2 w/2 h/2], where w and h are the width and height, respectively, of Rect. + * + * @param viewBox the rectangular area in which the 3D artwork shall be drawn + * @return this {@link Pdf3DAnnotation} instance + */ public Pdf3DAnnotation setViewBox(Rectangle viewBox) { return (Pdf3DAnnotation) put(PdfName._3DB, new PdfArray(viewBox)); } + /** + * Gets the 3D view box, which is the rectangular area in which the 3D artwork shall be drawn. + * + * @return the 3D view box, which is the rectangular area in which the 3D artwork shall be drawn. + */ public Rectangle getViewBox() { return getPdfObject().getAsRectangle(PdfName._3DB); } diff --git a/kernel/src/main/java/com/itextpdf/kernel/pdf/annot/da/AnnotationDefaultAppearance.java b/kernel/src/main/java/com/itextpdf/kernel/pdf/annot/da/AnnotationDefaultAppearance.java index 3b628ee2f7..2c730b4bb7 100644 --- a/kernel/src/main/java/com/itextpdf/kernel/pdf/annot/da/AnnotationDefaultAppearance.java +++ b/kernel/src/main/java/com/itextpdf/kernel/pdf/annot/da/AnnotationDefaultAppearance.java @@ -53,7 +53,16 @@ This file is part of the iText (R) project. import java.util.Map; /** - * Helper class for setting + * Helper class for setting annotation default appearance. The class provides setters for + * font color, font size and font itself. + * + *

+ * Note that only standard font names that do not require font resources are supported. + * + *

+ * Note that it is possible to create annotation with custom font name in DA, but this require + * manual resource modifications (you have to put font in DR of AcroForm and use + * its resource name in DA) and only Acrobat supports that workflow. */ public class AnnotationDefaultAppearance { @@ -92,41 +101,93 @@ public class AnnotationDefaultAppearance { private String rawFontName = "/Helv"; private float fontSize = 0; + /** + * Creates the default instance of {@link AnnotationDefaultAppearance}. + * + *

+ * The default font is {@link StandardAnnotationFont#Helvetica}. The default font size is 12. + */ public AnnotationDefaultAppearance() { setFont(StandardAnnotationFont.Helvetica); setFontSize(12); } + /** + * Sets the {@link AnnotationDefaultAppearance}'s default font. + * + * @param font one of {@link StandardAnnotationFont standard annotation fonts} to be set as + * the default one for this {@link AnnotationDefaultAppearance} + * @return this {@link AnnotationDefaultAppearance} + */ public AnnotationDefaultAppearance setFont(StandardAnnotationFont font) { setRawFontName(stdAnnotFontNames.get(font)); return this; } + /** + * Sets the {@link AnnotationDefaultAppearance}'s default font. + * + * @param font one of {@link ExtendedAnnotationFont extended annotation fonts} to be set as + * the default one for this {@link AnnotationDefaultAppearance} + * @return this {@link AnnotationDefaultAppearance} + */ public AnnotationDefaultAppearance setFont(ExtendedAnnotationFont font) { setRawFontName(extAnnotFontNames.get(font)); return this; } + /** + * Sets the {@link AnnotationDefaultAppearance}'s default font size. + * + * @param fontSize font size to be set as the {@link AnnotationDefaultAppearance}'s default font size + * @return this {@link AnnotationDefaultAppearance} + */ public AnnotationDefaultAppearance setFontSize(float fontSize) { this.fontSize = fontSize; return this; } + /** + * Sets the {@link AnnotationDefaultAppearance}'s default font color. + * + * @param rgbColor {@link DeviceRgb} to be set as the {@link AnnotationDefaultAppearance}'s + * default font color + * @return this {@link AnnotationDefaultAppearance} + */ public AnnotationDefaultAppearance setColor(DeviceRgb rgbColor) { setColorOperand(rgbColor.getColorValue(), "rg"); return this; } + /** + * Sets the {@link AnnotationDefaultAppearance}'s default font color. + * + * @param cmykColor {@link DeviceCmyk} to be set as the {@link AnnotationDefaultAppearance}'s + * default font color + * @return this {@link AnnotationDefaultAppearance} + */ public AnnotationDefaultAppearance setColor(DeviceCmyk cmykColor) { setColorOperand(cmykColor.getColorValue(), "k"); return this; } + /** + * Sets the {@link AnnotationDefaultAppearance}'s default font color. + * + * @param grayColor {@link DeviceGray} to be set as the {@link AnnotationDefaultAppearance}'s + * default font color + * @return this {@link AnnotationDefaultAppearance} + */ public AnnotationDefaultAppearance setColor(DeviceGray grayColor) { setColorOperand(grayColor.getColorValue(), "g"); return this; } + /** + * Gets the {@link AnnotationDefaultAppearance}'s representation as {@link PdfString}. + * + * @return the {@link PdfString} representation of this {@link AnnotationDefaultAppearance} + */ public PdfString toPdfString() { return new PdfString(MessageFormatUtil.format("{0} {1} Tf {2}", rawFontName, fontSize, colorOperand)); } diff --git a/kernel/src/main/java/com/itextpdf/kernel/pdf/canvas/PdfCanvas.java b/kernel/src/main/java/com/itextpdf/kernel/pdf/canvas/PdfCanvas.java index d096a28f8e..8076632dd9 100644 --- a/kernel/src/main/java/com/itextpdf/kernel/pdf/canvas/PdfCanvas.java +++ b/kernel/src/main/java/com/itextpdf/kernel/pdf/canvas/PdfCanvas.java @@ -1036,17 +1036,27 @@ public PdfCanvas curveFromTo(double x1, double y1, double x3, double y3) { */ public PdfCanvas arc(double x1, double y1, double x2, double y2, double startAng, double extent) { - List ar = bezierArc(x1, y1, x2, y2, startAng, extent); - if (ar.isEmpty()) - return this; - double[] pt = ar.get(0); - moveTo(pt[0], pt[1]); - for (int i = 0; i < ar.size(); ++i) { - pt = ar.get(i); - curveTo(pt[2], pt[3], pt[4], pt[5], pt[6], pt[7]); - } + return drawArc(x1, y1, x2, y2, startAng, extent, false); + } - return this; + /** + * Draws a partial ellipse with the preceding line to the start of the arc to prevent path + * broking. The target arc is inscribed within the rectangle x1,y1,x2,y2, starting + * at startAng degrees and covering extent degrees. Angles start with 0 to the right (+x) + * and increase counter-clockwise. + * + * @param x1 a corner of the enclosing rectangle + * @param y1 a corner of the enclosing rectangle + * @param x2 a corner of the enclosing rectangle + * @param y2 a corner of the enclosing rectangle + * @param startAng starting angle in degrees + * @param extent angle extent in degrees + * + * @return the current canvas + */ + public PdfCanvas arcContinuous(double x1, double y1, double x2, double y2, + double startAng, double extent) { + return drawArc(x1, y1, x2, y2, startAng, extent, true); } /** @@ -2069,7 +2079,6 @@ public PdfXObject addImageAt(ImageData image, float x, float y, boolean asInline public PdfXObject addImage(ImageData image, float x, float y, float width, boolean asInline) { if (image.getOriginalType() == ImageType.WMF) { WmfImageHelper wmf = new WmfImageHelper(image); - // TODO add matrix parameters PdfXObject xObject = wmf.createFormXObject(document); addImageWithTransformationMatrix(xObject, width, 0, 0, width, x, y); return xObject; @@ -2789,6 +2798,26 @@ private void applyRotation(PdfPage page) { } } + private PdfCanvas drawArc(double x1, double y1, double x2, double y2, + double startAng, double extent, boolean continuous) { + List ar = bezierArc(x1, y1, x2, y2, startAng, extent); + if (ar.isEmpty()) { + return this; + } + + double[] pt = ar.get(0); + if (continuous) { + lineTo(pt[0], pt[1]); + } else { + moveTo(pt[0], pt[1]); + } + for (int index = 0; index < ar.size(); ++index) { + pt = ar.get(index); + curveTo(pt[2], pt[3], pt[4], pt[5], pt[6], pt[7]); + } + return this; + } + private static PdfStream getPageStream(PdfPage page) { PdfStream stream = page.getLastContentStream(); return stream == null || stream.getOutputStream() == null || stream.containsKey(PdfName.Filter) ? page.newContentStreamAfter() : stream; diff --git a/kernel/src/main/java/com/itextpdf/kernel/pdf/canvas/parser/data/TextRenderInfo.java b/kernel/src/main/java/com/itextpdf/kernel/pdf/canvas/parser/data/TextRenderInfo.java index 8f691d38d2..10ced895a6 100644 --- a/kernel/src/main/java/com/itextpdf/kernel/pdf/canvas/parser/data/TextRenderInfo.java +++ b/kernel/src/main/java/com/itextpdf/kernel/pdf/canvas/parser/data/TextRenderInfo.java @@ -43,6 +43,7 @@ This file is part of the iText (R) project. */ package com.itextpdf.kernel.pdf.canvas.parser.data; +import com.itextpdf.io.font.FontProgram; import com.itextpdf.io.font.otf.GlyphLine; import com.itextpdf.kernel.colors.Color; import com.itextpdf.kernel.font.PdfFont; @@ -78,7 +79,6 @@ public class TextRenderInfo extends AbstractRenderInfo { private final Matrix textToUserSpaceTransformMatrix; private final Matrix textMatrix; private float unscaledWidth = Float.NaN; - private double[] fontMatrix = null; /** * Hierarchy of nested canvas tags for the text from the most inner (nearest to text) tag to the most outer. @@ -99,11 +99,10 @@ public TextRenderInfo(PdfString str, CanvasGraphicsState gs, Matrix textMatrix, this.textToUserSpaceTransformMatrix = textMatrix.multiply(gs.getCtm()); this.textMatrix = textMatrix; this.canvasTagHierarchy = Collections.unmodifiableList(new ArrayList<>(canvasTagHierarchy)); - this.fontMatrix = gs.getFont().getFontMatrix(); } /** - * Used for creating sub-TextRenderInfos for each individual character + * Used for creating sub-TextRenderInfos for each individual character. * * @param parent the parent TextRenderInfo * @param str the content of a TextRenderInfo @@ -116,10 +115,11 @@ private TextRenderInfo(TextRenderInfo parent, PdfString str, float horizontalOff this.textToUserSpaceTransformMatrix = offsetMatrix.multiply(parent.textToUserSpaceTransformMatrix); this.textMatrix = offsetMatrix.multiply(parent.textMatrix); this.canvasTagHierarchy = parent.canvasTagHierarchy; - this.fontMatrix = parent.gs.getFont().getFontMatrix(); } /** + * Gets the text to be rendered according to canvas operators. + * * @return the text to render */ public String getText() { @@ -465,7 +465,7 @@ private float getUnscaledFontSpaceWidth() { if (charWidth == 0) { charWidth = gs.getFont().getFontProgram().getAvgWidth(); } - float w = (float) (charWidth * fontMatrix[0]); + float w = (float) ((double) charWidth / FontProgram.UNITS_NORMALIZATION); return (w * gs.getFontSize() + gs.getCharSpacing() + gs.getWordSpacing()) * gs.getHorizontalScaling() / 100f; } @@ -501,7 +501,7 @@ private float[] getWidthAndWordSpacing(PdfString string) { checkGraphicsState(); float[] result = new float[2]; - result[0] = (float) ((gs.getFont().getContentWidth(string) * fontMatrix[0])); + result[0] = (float) ((double) gs.getFont().getContentWidth(string) / FontProgram.UNITS_NORMALIZATION); result[1] = " ".equals(string.getValue()) ? gs.getWordSpacing() : 0; return result; } diff --git a/kernel/src/main/java/com/itextpdf/kernel/pdf/canvas/parser/util/InlineImageParsingUtils.java b/kernel/src/main/java/com/itextpdf/kernel/pdf/canvas/parser/util/InlineImageParsingUtils.java index b609448966..be8e8012a8 100644 --- a/kernel/src/main/java/com/itextpdf/kernel/pdf/canvas/parser/util/InlineImageParsingUtils.java +++ b/kernel/src/main/java/com/itextpdf/kernel/pdf/canvas/parser/util/InlineImageParsingUtils.java @@ -166,6 +166,39 @@ public static PdfStream parse(PdfCanvasParser ps, PdfDictionary colorSpaceDic) t return inlineImageAsStreamObject; } + /** + * @param colorSpaceName the name of the color space. If null, a bi-tonal (black and white) color space is assumed. + * @return the components per pixel for the specified color space + */ + static int getComponentsPerPixel(PdfName colorSpaceName, PdfDictionary colorSpaceDic) { + if (colorSpaceName == null) + return 1; + if (colorSpaceName.equals(PdfName.DeviceGray)) + return 1; + if (colorSpaceName.equals(PdfName.DeviceRGB)) + return 3; + if (colorSpaceName.equals(PdfName.DeviceCMYK)) + return 4; + + if (colorSpaceDic != null) { + PdfArray colorSpace = colorSpaceDic.getAsArray(colorSpaceName); + if (colorSpace != null) { + if (PdfName.Indexed.equals(colorSpace.getAsName(0))) { + return 1; + } else if (PdfName.ICCBased.equals(colorSpace.getAsName(0))) { + return colorSpace.getAsStream(1).getAsNumber(PdfName.N).intValue(); + } + } else { + PdfName tempName = colorSpaceDic.getAsName(colorSpaceName); + if (tempName != null) { + return getComponentsPerPixel(tempName, colorSpaceDic); + } + } + } + + throw new InlineImageParseException(PdfException.UnexpectedColorSpace1).setMessageParams(colorSpaceName); + } + /** * Parses the next inline image dictionary from the parser. The parser must be positioned immediately following the BI operator. * The parser will be left with position immediately following the whitespace character that follows the ID operator that ends the inline image dictionary. @@ -226,37 +259,6 @@ private static PdfObject getAlternateValue(PdfName key, PdfObject value) { return value; } - /** - * @param colorSpaceName the name of the color space. If null, a bi-tonal (black and white) color space is assumed. - * @return the components per pixel for the specified color space - */ - private static int getComponentsPerPixel(PdfName colorSpaceName, PdfDictionary colorSpaceDic) { - if (colorSpaceName == null) - return 1; - if (colorSpaceName.equals(PdfName.DeviceGray)) - return 1; - if (colorSpaceName.equals(PdfName.DeviceRGB)) - return 3; - if (colorSpaceName.equals(PdfName.DeviceCMYK)) - return 4; - - if (colorSpaceDic != null) { - PdfArray colorSpace = colorSpaceDic.getAsArray(colorSpaceName); - if (colorSpace != null) { - if (PdfName.Indexed.equals(colorSpace.getAsName(0))) { - return 1; - } - } else { - PdfName tempName = colorSpaceDic.getAsName(colorSpaceName); - if (tempName != null) { - return getComponentsPerPixel(tempName, colorSpaceDic); - } - } - } - - throw new InlineImageParseException(PdfException.UnexpectedColorSpace1).setMessageParams(colorSpaceName); - } - /** * Computes the number of unfiltered bytes that each row of the image will contain. * If the number of bytes results in a partial terminating byte, this number is rounded up diff --git a/kernel/src/main/java/com/itextpdf/kernel/pdf/filespec/PdfFileSpec.java b/kernel/src/main/java/com/itextpdf/kernel/pdf/filespec/PdfFileSpec.java index 17bf323494..47c91961b2 100644 --- a/kernel/src/main/java/com/itextpdf/kernel/pdf/filespec/PdfFileSpec.java +++ b/kernel/src/main/java/com/itextpdf/kernel/pdf/filespec/PdfFileSpec.java @@ -387,6 +387,7 @@ private static PdfFileSpec createEmbeddedFileSpec(PdfDocument doc, PdfStream str ef.put(PdfName.F, stream); ef.put(PdfName.UF, stream); dict.put(PdfName.EF, ef); + doc.markStreamAsEmbeddedFile(stream); return (PdfFileSpec) new PdfFileSpec(dict).makeIndirect(doc); } diff --git a/kernel/src/main/java/com/itextpdf/kernel/pdf/tagging/PdfStructTreeRoot.java b/kernel/src/main/java/com/itextpdf/kernel/pdf/tagging/PdfStructTreeRoot.java index 1dbec30ba8..01e93a8e89 100644 --- a/kernel/src/main/java/com/itextpdf/kernel/pdf/tagging/PdfStructTreeRoot.java +++ b/kernel/src/main/java/com/itextpdf/kernel/pdf/tagging/PdfStructTreeRoot.java @@ -68,6 +68,9 @@ This file is part of the iText (R) project. import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +/** + * Represents a wrapper-class for structure tree root dictionary. See ISO-32000-1 "14.7.2 Structure hierarchy". + */ public class PdfStructTreeRoot extends PdfObjectWrapper implements IStructureNode { private static final long serialVersionUID = 2168384302241193868L; @@ -77,21 +80,40 @@ public class PdfStructTreeRoot extends PdfObjectWrapper implement private static Map staticRoleNames = new ConcurrentHashMap<>(); + /** + * Creates a new structure tree root instance, this initializes empty logical structure in the document. + * This class also handles global state of parent tree, so it's not expected to create multiple instances + * of this class. Instead, use {@link PdfDocument#getStructTreeRoot()}. + * + * @param document a document to which new instance of struct tree root will be bound + */ public PdfStructTreeRoot(PdfDocument document) { this((PdfDictionary) new PdfDictionary().makeIndirect(document), document); getPdfObject().put(PdfName.Type, PdfName.StructTreeRoot); } - public PdfStructTreeRoot(PdfDictionary pdfObject, PdfDocument document) { - super(pdfObject); + /** + * Creates wrapper instance for already existing logical structure tree root in the document. + * This class also handles global state of parent tree, so it's not expected to create multiple instances + * of this class. Instead, use {@link PdfDocument#getStructTreeRoot()}. + * + * @param structTreeRootDict a dictionary that defines document structure tree root + * @param document a document, which contains given structure tree root dictionary + */ + public PdfStructTreeRoot(PdfDictionary structTreeRootDict, PdfDocument document) { + super(structTreeRootDict); this.document = document; if (this.document == null) { - ensureObjectIsAddedToDocument(pdfObject); - this.document = pdfObject.getIndirectReference().getDocument(); + ensureObjectIsAddedToDocument(structTreeRootDict); + this.document = structTreeRootDict.getIndirectReference().getDocument(); } setForbidRelease(); parentTreeHandler = new ParentTreeHandler(this); - // TODO may be remove? + + // Always init role map dictionary in order to avoid inconsistency, because + // iText often initializes it during role mapping resolution anyway. + // In future, better way might be to not write it to the document needlessly + // and avoid possible redundant modifications in append mode. getRoleMap(); } diff --git a/kernel/src/main/java/com/itextpdf/kernel/pdf/tagutils/TagStructureContext.java b/kernel/src/main/java/com/itextpdf/kernel/pdf/tagutils/TagStructureContext.java index 6fcc32d1b8..71ff994d89 100644 --- a/kernel/src/main/java/com/itextpdf/kernel/pdf/tagutils/TagStructureContext.java +++ b/kernel/src/main/java/com/itextpdf/kernel/pdf/tagutils/TagStructureContext.java @@ -643,7 +643,8 @@ private void removePageTagFromParent(IStructureNode pageTag, IStructureNode pare removePageTagFromParent(structParent, parent.getParent()); PdfIndirectReference indRef = parentStructDict.getIndirectReference(); if (indRef != null) { - // TODO how about possible references to structure element from refs or structure destination for instance? + // TODO DEVSIX-5472 need to clean references to structure element from + // other structure elements /Ref entries and structure destinations indRef.setFree(); } } diff --git a/kernel/src/main/java/com/itextpdf/kernel/pdf/tagutils/TagTreePointer.java b/kernel/src/main/java/com/itextpdf/kernel/pdf/tagutils/TagTreePointer.java index 272179b549..423e20d9d9 100644 --- a/kernel/src/main/java/com/itextpdf/kernel/pdf/tagutils/TagTreePointer.java +++ b/kernel/src/main/java/com/itextpdf/kernel/pdf/tagutils/TagTreePointer.java @@ -359,7 +359,8 @@ public TagTreePointer removeTag() { PdfIndirectReference indRef = currentStructElem.getPdfObject().getIndirectReference(); if (indRef != null) { - // TODO how about possible references to structure element from refs or structure destination for instance? + // TODO DEVSIX-5472 need to clean references to structure element from + // other structure elements /Ref entries and structure destinations indRef.setFree(); } diff --git a/kernel/src/main/java/com/itextpdf/kernel/utils/CompareTool.java b/kernel/src/main/java/com/itextpdf/kernel/utils/CompareTool.java index 8b6f7c90c1..a55a70a3e6 100644 --- a/kernel/src/main/java/com/itextpdf/kernel/utils/CompareTool.java +++ b/kernel/src/main/java/com/itextpdf/kernel/utils/CompareTool.java @@ -718,11 +718,12 @@ public String compareXmp(String outPdf, String cmpPdf) { */ public String compareXmp(String outPdf, String cmpPdf, boolean ignoreDateAndProducerProperties) { init(outPdf, cmpPdf); - PdfDocument cmpDocument = null; - PdfDocument outDocument = null; - try { - cmpDocument = new PdfDocument(new PdfReader(this.cmpPdf), new DocumentProperties().setEventCountingMetaInfo(metaInfo)); - outDocument = new PdfDocument(new PdfReader(this.outPdf), new DocumentProperties().setEventCountingMetaInfo(metaInfo)); + try (PdfReader readerCmp = new PdfReader(this.cmpPdf); + PdfDocument cmpDocument = new PdfDocument(readerCmp, + new DocumentProperties().setEventCountingMetaInfo(metaInfo)); + PdfReader readerOut = new PdfReader(this.outPdf); + PdfDocument outDocument = new PdfDocument(readerOut, + new DocumentProperties().setEventCountingMetaInfo(metaInfo))) { byte[] cmpBytes = cmpDocument.getXmpMetadata(), outBytes = outDocument.getXmpMetadata(); if (ignoreDateAndProducerProperties) { XMPMeta xmpMeta = XMPMetaFactory.parseFromBuffer(cmpBytes, new ParseOptions().setOmitNormalization(true)); @@ -748,11 +749,6 @@ public String compareXmp(String outPdf, String cmpPdf, boolean ignoreDateAndProd } } catch (Exception ex) { return "XMP parsing failure!"; - } finally { - if (cmpDocument != null) - cmpDocument.close(); - if (outDocument != null) - outDocument.close(); } return null; } @@ -809,19 +805,21 @@ public String compareDocumentInfo(String outPdf, String cmpPdf, byte[] outPass, System.out.print("[itext] INFO Comparing document info......."); String message = null; setPassword(outPass, cmpPass); - PdfDocument outDocument = new PdfDocument(new PdfReader(outPdf, getOutReaderProperties()), new DocumentProperties().setEventCountingMetaInfo(metaInfo)); - PdfDocument cmpDocument = new PdfDocument(new PdfReader(cmpPdf, getCmpReaderProperties()), new DocumentProperties().setEventCountingMetaInfo(metaInfo)); - String[] cmpInfo = convertInfo(cmpDocument.getDocumentInfo()); - String[] outInfo = convertInfo(outDocument.getDocumentInfo()); - for (int i = 0; i < cmpInfo.length; ++i) { - if (!cmpInfo[i].equals(outInfo[i])) { - message = MessageFormatUtil.format("Document info fail. Expected: \"{0}\", actual: \"{1}\"", cmpInfo[i], outInfo[i]); - break; + try (PdfReader readerOut = new PdfReader(outPdf, getOutReaderProperties()); + PdfDocument outDocument = new PdfDocument(readerOut, + new DocumentProperties().setEventCountingMetaInfo(metaInfo)); + PdfReader readerCmp = new PdfReader(cmpPdf, getCmpReaderProperties()); + PdfDocument cmpDocument = new PdfDocument(readerCmp, + new DocumentProperties().setEventCountingMetaInfo(metaInfo))) { + String[] cmpInfo = convertInfo(cmpDocument.getDocumentInfo()); + String[] outInfo = convertInfo(outDocument.getDocumentInfo()); + for (int i = 0; i < cmpInfo.length; ++i) { + if (!cmpInfo[i].equals(outInfo[i])) { + message = MessageFormatUtil.format("Document info fail. Expected: \"{0}\", actual: \"{1}\"", cmpInfo[i], outInfo[i]); + break; + } } } - outDocument.close(); - cmpDocument.close(); - if (message == null) System.out.println("OK"); else @@ -853,25 +851,28 @@ public String compareDocumentInfo(String outPdf, String cmpPdf) throws IOExcepti public String compareLinkAnnotations(String outPdf, String cmpPdf) throws IOException { System.out.print("[itext] INFO Comparing link annotations...."); String message = null; - PdfDocument outDocument = new PdfDocument(new PdfReader(outPdf), new DocumentProperties().setEventCountingMetaInfo(metaInfo)); - PdfDocument cmpDocument = new PdfDocument(new PdfReader(cmpPdf), new DocumentProperties().setEventCountingMetaInfo(metaInfo)); - for (int i = 0; i < outDocument.getNumberOfPages() && i < cmpDocument.getNumberOfPages(); i++) { - List outLinks = getLinkAnnotations(i + 1, outDocument); - List cmpLinks = getLinkAnnotations(i + 1, cmpDocument); - - if (cmpLinks.size() != outLinks.size()) { - message = MessageFormatUtil.format("Different number of links on page {0}.", i + 1); - break; - } - for (int j = 0; j < cmpLinks.size(); j++) { - if (!compareLinkAnnotations(cmpLinks.get(j), outLinks.get(j), cmpDocument, outDocument)) { - message = MessageFormatUtil.format("Different links on page {0}.\n{1}\n{2}", i + 1, cmpLinks.get(j).toString(), outLinks.get(j).toString()); + try (PdfReader readerOut = new PdfReader(outPdf); + PdfDocument outDocument = new PdfDocument(readerOut, + new DocumentProperties().setEventCountingMetaInfo(metaInfo)); + PdfReader readerCmp = new PdfReader(cmpPdf); + PdfDocument cmpDocument = new PdfDocument(readerCmp, + new DocumentProperties().setEventCountingMetaInfo(metaInfo))){ + for (int i = 0; i < outDocument.getNumberOfPages() && i < cmpDocument.getNumberOfPages(); i++) { + List outLinks = getLinkAnnotations(i + 1, outDocument); + List cmpLinks = getLinkAnnotations(i + 1, cmpDocument); + + if (cmpLinks.size() != outLinks.size()) { + message = MessageFormatUtil.format("Different number of links on page {0}.", i + 1); break; } + for (int j = 0; j < cmpLinks.size(); j++) { + if (!compareLinkAnnotations(cmpLinks.get(j), outLinks.get(j), cmpDocument, outDocument)) { + message = MessageFormatUtil.format("Different links on page {0}.\n{1}\n{2}", i + 1, cmpLinks.get(j).toString(), outLinks.get(j).toString()); + break; + } + } } } - outDocument.close(); - cmpDocument.close(); if (message == null) System.out.println("OK"); else @@ -902,20 +903,18 @@ public String compareTagStructures(String outPdf, String cmpPdf) throws IOExcept String cmpXmlPath = outPdf.replace(".pdf", ".cmp.xml"); String message = null; - - PdfReader readerOut = new PdfReader(outPdf); - PdfDocument docOut = new PdfDocument(readerOut, new DocumentProperties().setEventCountingMetaInfo(metaInfo)); - FileOutputStream xmlOut = new FileOutputStream(outXmlPath); - new TaggedPdfReaderTool(docOut).setRootTag("root").convertToXml(xmlOut); - docOut.close(); - xmlOut.close(); - - PdfReader readerCmp = new PdfReader(cmpPdf); - PdfDocument docCmp = new PdfDocument(readerCmp, new DocumentProperties().setEventCountingMetaInfo(metaInfo)); - FileOutputStream xmlCmp = new FileOutputStream(cmpXmlPath); - new TaggedPdfReaderTool(docCmp).setRootTag("root").convertToXml(xmlCmp); - docCmp.close(); - xmlCmp.close(); + try (PdfReader readerOut = new PdfReader(outPdf); + PdfDocument docOut = new PdfDocument(readerOut, + new DocumentProperties().setEventCountingMetaInfo(metaInfo)); + FileOutputStream xmlOut = new FileOutputStream(outXmlPath)) { + new TaggedPdfReaderTool(docOut).setRootTag("root").convertToXml(xmlOut); + } + try (PdfReader readerCmp = new PdfReader(cmpPdf); + PdfDocument docCmp = new PdfDocument(readerCmp, + new DocumentProperties().setEventCountingMetaInfo(metaInfo)); + FileOutputStream xmlCmp = new FileOutputStream(cmpXmlPath)) { + new TaggedPdfReaderTool(docCmp).setRootTag("root").convertToXml(xmlCmp); + } if (!compareXmls(outXmlPath, cmpXmlPath)) { message = "The tag structures are different."; @@ -1000,7 +999,7 @@ private String compareVisually(String outPath, String differenceImagePrefix, Map GhostscriptHelper ghostscriptHelper = null; try { - ghostscriptHelper = new GhostscriptHelper(gsExec); + ghostscriptHelper = new GhostscriptHelper(gsExec); } catch (IllegalArgumentException e) { throw new CompareToolExecutionException(e.getMessage()); } @@ -1094,36 +1093,34 @@ private String listDiffPagesAsString(List diffPages) { } private void createIgnoredAreasPdfs(String outPath, Map> ignoredAreas) throws IOException { - PdfWriter outWriter = new PdfWriter(outPath + IGNORED_AREAS_PREFIX + outPdfName); - PdfWriter cmpWriter = new PdfWriter(outPath + IGNORED_AREAS_PREFIX + cmpPdfName); - StampingProperties properties = new StampingProperties(); properties.setEventCountingMetaInfo(metaInfo); - PdfDocument pdfOutDoc = new PdfDocument(new PdfReader(outPdf), outWriter, properties); - PdfDocument pdfCmpDoc = new PdfDocument(new PdfReader(cmpPdf), cmpWriter, properties); - - for (Map.Entry> entry : ignoredAreas.entrySet()) { - int pageNumber = entry.getKey(); - List rectangles = entry.getValue(); - - if (rectangles != null && !rectangles.isEmpty()) { - PdfCanvas outCanvas = new PdfCanvas(pdfOutDoc.getPage(pageNumber)); - PdfCanvas cmpCanvas = new PdfCanvas(pdfCmpDoc.getPage(pageNumber)); - - outCanvas.saveState(); - cmpCanvas.saveState(); - for (Rectangle rect : rectangles) { - outCanvas.rectangle(rect).fill(); - cmpCanvas.rectangle(rect).fill(); + try (PdfWriter outWriter = new PdfWriter(outPath + IGNORED_AREAS_PREFIX + outPdfName); + PdfReader readerOut = new PdfReader(outPdf); + PdfDocument pdfOutDoc = new PdfDocument(readerOut, outWriter, properties); + PdfWriter cmpWriter = new PdfWriter(outPath + IGNORED_AREAS_PREFIX + cmpPdfName); + PdfReader readerCmp = new PdfReader(cmpPdf); + PdfDocument pdfCmpDoc = new PdfDocument(readerCmp, cmpWriter, properties)) { + for (Map.Entry> entry : ignoredAreas.entrySet()) { + int pageNumber = entry.getKey(); + List rectangles = entry.getValue(); + + if (rectangles != null && !rectangles.isEmpty()) { + PdfCanvas outCanvas = new PdfCanvas(pdfOutDoc.getPage(pageNumber)); + PdfCanvas cmpCanvas = new PdfCanvas(pdfCmpDoc.getPage(pageNumber)); + + outCanvas.saveState(); + cmpCanvas.saveState(); + for (Rectangle rect : rectangles) { + outCanvas.rectangle(rect).fill(); + cmpCanvas.rectangle(rect).fill(); + } + outCanvas.restoreState(); + cmpCanvas.restoreState(); } - outCanvas.restoreState(); - cmpCanvas.restoreState(); } } - pdfOutDoc.close(); - pdfCmpDoc.close(); - init(outPath + IGNORED_AREAS_PREFIX + outPdfName, outPath + IGNORED_AREAS_PREFIX + cmpPdfName); } @@ -1161,69 +1158,61 @@ private void printOutCmpDirectories() { private String compareByContent(String outPath, String differenceImagePrefix, Map> ignoredAreas) throws InterruptedException, IOException { printOutCmpDirectories(); System.out.print("Comparing by content.........."); - PdfDocument outDocument; - try { - outDocument = new PdfDocument(new PdfReader(outPdf, getOutReaderProperties()), new DocumentProperties().setEventCountingMetaInfo(metaInfo)); - } catch (IOException e) { - throw new IOException("File \"" + outPdf + "\" not found", e); - } - List outPages = new ArrayList<>(); - outPagesRef = new ArrayList<>(); - loadPagesFromReader(outDocument, outPages, outPagesRef); - - PdfDocument cmpDocument; - try { - cmpDocument = new PdfDocument(new PdfReader(cmpPdf, getCmpReaderProperties()), new DocumentProperties().setEventCountingMetaInfo(metaInfo)); - } catch (IOException e) { - throw new IOException("File \"" + cmpPdf + "\" not found", e); - } - List cmpPages = new ArrayList<>(); - cmpPagesRef = new ArrayList<>(); - loadPagesFromReader(cmpDocument, cmpPages, cmpPagesRef); - - if (outPages.size() != cmpPages.size()) - return compareVisuallyAndCombineReports("Documents have different numbers of pages.", outPath, differenceImagePrefix, ignoredAreas, null); - - CompareResult compareResult = new CompareResult(compareByContentErrorsLimit); - List equalPages = new ArrayList<>(cmpPages.size()); - for (int i = 0; i < cmpPages.size(); i++) { - ObjectPath currentPath = new ObjectPath(cmpPagesRef.get(i), outPagesRef.get(i)); - if (compareDictionariesExtended(outPages.get(i), cmpPages.get(i), currentPath, compareResult)) - equalPages.add(i); - } - - ObjectPath catalogPath = new ObjectPath(cmpDocument.getCatalog().getPdfObject().getIndirectReference(), - outDocument.getCatalog().getPdfObject().getIndirectReference()); - Set ignoredCatalogEntries = new LinkedHashSet<>(Arrays.asList(PdfName.Pages, PdfName.Metadata)); - compareDictionariesExtended(outDocument.getCatalog().getPdfObject(), cmpDocument.getCatalog().getPdfObject(), - catalogPath, compareResult, ignoredCatalogEntries); - - if (encryptionCompareEnabled) { - compareDocumentsEncryption(outDocument, cmpDocument, compareResult); - } - - outDocument.close(); - cmpDocument.close(); + try (PdfReader readerOut = new PdfReader(outPdf, getOutReaderProperties()); + PdfDocument outDocument = new PdfDocument(readerOut, + new DocumentProperties().setEventCountingMetaInfo(metaInfo)); + PdfReader readerCmp = new PdfReader(cmpPdf, getCmpReaderProperties()); + PdfDocument cmpDocument = new PdfDocument(readerCmp, + new DocumentProperties().setEventCountingMetaInfo(metaInfo))) { + + List outPages = new ArrayList<>(); + outPagesRef = new ArrayList<>(); + loadPagesFromReader(outDocument, outPages, outPagesRef); + + List cmpPages = new ArrayList<>(); + cmpPagesRef = new ArrayList<>(); + loadPagesFromReader(cmpDocument, cmpPages, cmpPagesRef); + + if (outPages.size() != cmpPages.size()) + return compareVisuallyAndCombineReports("Documents have different numbers of pages.", outPath, differenceImagePrefix, ignoredAreas, null); + + CompareResult compareResult = new CompareResult(compareByContentErrorsLimit); + List equalPages = new ArrayList<>(cmpPages.size()); + for (int i = 0; i < cmpPages.size(); i++) { + ObjectPath currentPath = new ObjectPath(cmpPagesRef.get(i), outPagesRef.get(i)); + if (compareDictionariesExtended(outPages.get(i), cmpPages.get(i), currentPath, compareResult)) + equalPages.add(i); + } + + ObjectPath catalogPath = new ObjectPath(cmpDocument.getCatalog().getPdfObject().getIndirectReference(), + outDocument.getCatalog().getPdfObject().getIndirectReference()); + Set ignoredCatalogEntries = new LinkedHashSet<>(Arrays.asList(PdfName.Pages, PdfName.Metadata)); + compareDictionariesExtended(outDocument.getCatalog().getPdfObject(), cmpDocument.getCatalog().getPdfObject(), + catalogPath, compareResult, ignoredCatalogEntries); + + if (encryptionCompareEnabled) { + compareDocumentsEncryption(outDocument, cmpDocument, compareResult); + } + if (generateCompareByContentXmlReport) { + String outPdfName = new File(outPdf).getName(); + FileOutputStream xml = new FileOutputStream(outPath + "/" + outPdfName.substring(0, outPdfName.length() - 3) + "report.xml"); + try { + compareResult.writeReportToXml(xml); + } catch (Exception e) { + throw new RuntimeException(e.getMessage(), e); + } finally { + xml.close(); + } - if (generateCompareByContentXmlReport) { - String outPdfName = new File(outPdf).getName(); - FileOutputStream xml = new FileOutputStream(outPath + "/" + outPdfName.substring(0, outPdfName.length() - 3) + "report.xml"); - try { - compareResult.writeReportToXml(xml); - } catch (Exception e) { - throw new RuntimeException(e.getMessage(), e); - } finally { - xml.close(); } - } - - if (equalPages.size() == cmpPages.size() && compareResult.isOk()) { - System.out.println("OK"); - System.out.flush(); - return null; - } else { - return compareVisuallyAndCombineReports(compareResult.getReport(), outPath, differenceImagePrefix, ignoredAreas, equalPages); + if (equalPages.size() == cmpPages.size() && compareResult.isOk()) { + System.out.println("OK"); + System.out.flush(); + return null; + } else { + return compareVisuallyAndCombineReports(compareResult.getReport(), outPath, differenceImagePrefix, ignoredAreas, equalPages); + } } } diff --git a/kernel/src/main/java/com/itextpdf/kernel/utils/DefaultSafeXmlParserFactory.java b/kernel/src/main/java/com/itextpdf/kernel/utils/DefaultSafeXmlParserFactory.java new file mode 100644 index 0000000000..2d54edc76d --- /dev/null +++ b/kernel/src/main/java/com/itextpdf/kernel/utils/DefaultSafeXmlParserFactory.java @@ -0,0 +1,192 @@ +/* + This file is part of the iText (R) project. + Copyright (c) 1998-2021 iText Group NV + Authors: iText Software. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License version 3 + as published by the Free Software Foundation with the addition of the + following permission added to Section 15 as permitted in Section 7(a): + FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY + ITEXT GROUP. ITEXT GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT + OF THIRD PARTY RIGHTS + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Affero General Public License for more details. + You should have received a copy of the GNU Affero General Public License + along with this program; if not, see http://www.gnu.org/licenses or write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA, 02110-1301 USA, or download the license from the following URL: + http://itextpdf.com/terms-of-use/ + + The interactive user interfaces in modified source and object code versions + of this program must display Appropriate Legal Notices, as required under + Section 5 of the GNU Affero General Public License. + + In accordance with Section 7(b) of the GNU Affero General Public License, + a covered work must retain the producer line in every PDF that is created + or manipulated using iText. + + You can be released from the requirements of the license by purchasing + a commercial license. Buying such a license is mandatory as soon as you + develop commercial activities involving the iText software without + disclosing the source code of your own applications. + These activities include: offering paid services to customers as an ASP, + serving PDFs on the fly in a web application, shipping iText with a closed + source product. + + For more information, please contact iText Software Corp. at this + address: sales@itextpdf.com + */ +package com.itextpdf.kernel.utils; + +import com.itextpdf.io.util.MessageFormatUtil; +import com.itextpdf.kernel.KernelLogMessageConstant; +import com.itextpdf.kernel.PdfException; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.xml.sax.EntityResolver; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.SAXNotRecognizedException; +import org.xml.sax.SAXNotSupportedException; +import org.xml.sax.XMLReader; + +/** + * Implementation of {@link IXmlParserFactory} for creating safe xml parser objects. + * Creates parsers with configuration to prevent XML bombs and XXE attacks. + */ +public class DefaultSafeXmlParserFactory implements IXmlParserFactory { + + private static final Logger LOGGER = LoggerFactory.getLogger(DefaultSafeXmlParserFactory.class); + + /** + * Feature for disallowing DOCTYPE declaration. + * + *

+ * Xerces 2 only - http://xerces.apache.org/xerces2-j/features.html#disallow-doctype-decl + */ + private final static String DISALLOW_DOCTYPE_DECL = "http://apache.org/xml/features/disallow-doctype-decl"; + + /** + * If you can't disable DOCTYPE declarations, then at least disable external entities. + * Must be used with the {@link DefaultSafeXmlParserFactory#EXTERNAL_PARAMETER_ENTITIES}, otherwise has no effect. + * + *

+ * Xerces 1 - http://xerces.apache.org/xerces-j/features.html#external-general-entities + * Xerces 2 - http://xerces.apache.org/xerces2-j/features.html#external-general-entities + * JDK7+ - http://xml.org/sax/features/external-general-entities + */ + private final static String EXTERNAL_GENERAL_ENTITIES = "http://xml.org/sax/features/external-general-entities"; + + /** + * Must be used with the {@link DefaultSafeXmlParserFactory#EXTERNAL_GENERAL_ENTITIES}, otherwise has no effect. + * + *

+ * Xerces 1 - http://xerces.apache.org/xerces-j/features.html#external-parameter-entities + * Xerces 2 - http://xerces.apache.org/xerces2-j/features.html#external-parameter-entities + * JDK7+ - http://xml.org/sax/features/external-parameter-entities + */ + private final static String EXTERNAL_PARAMETER_ENTITIES = "http://xml.org/sax/features/external-parameter-entities"; + + /** + * Disable external DTDs. + */ + private final static String LOAD_EXTERNAL_DTD = "http://apache.org/xml/features/nonvalidating/load-external-dtd"; + + /** + * Creates instance of {@link DefaultSafeXmlParserFactory}. + */ + public DefaultSafeXmlParserFactory() { + // empty constructor + } + + @Override + public DocumentBuilder createDocumentBuilderInstance(boolean namespaceAware, boolean ignoringComments) { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + configureSafeDocumentBuilderFactory(factory); + factory.setNamespaceAware(namespaceAware); + factory.setIgnoringComments(ignoringComments); + DocumentBuilder db; + try { + db = factory.newDocumentBuilder(); + } catch (ParserConfigurationException e) { + throw new PdfException(e.getMessage(), e); + } + db.setEntityResolver(new SafeEmptyEntityResolver()); + return db; + } + + @Override + public XMLReader createXMLReaderInstance(boolean namespaceAware, boolean validating) { + SAXParserFactory factory = SAXParserFactory.newInstance(); + factory.setNamespaceAware(namespaceAware); + factory.setValidating(validating); + configureSafeSAXParserFactory(factory); + XMLReader xmlReader; + try { + SAXParser saxParser = factory.newSAXParser(); + xmlReader = saxParser.getXMLReader(); + } catch (ParserConfigurationException | SAXException e) { + throw new PdfException(e.getMessage(), e); + } + xmlReader.setEntityResolver(new SafeEmptyEntityResolver()); + return xmlReader; + } + + private void configureSafeDocumentBuilderFactory(DocumentBuilderFactory factory) { + tryToSetFeature(factory, DISALLOW_DOCTYPE_DECL, true); + tryToSetFeature(factory, EXTERNAL_GENERAL_ENTITIES, false); + tryToSetFeature(factory, EXTERNAL_PARAMETER_ENTITIES, false); + tryToSetFeature(factory, LOAD_EXTERNAL_DTD, false); + // recommendations from Timothy Morgan's 2014 paper: "XML Schema, DTD, and Entity Attacks" + factory.setXIncludeAware(false); + factory.setExpandEntityReferences(false); + } + + private void configureSafeSAXParserFactory(SAXParserFactory factory) { + tryToSetFeature(factory, DISALLOW_DOCTYPE_DECL, true); + tryToSetFeature(factory, EXTERNAL_GENERAL_ENTITIES, false); + tryToSetFeature(factory, EXTERNAL_PARAMETER_ENTITIES, false); + tryToSetFeature(factory, LOAD_EXTERNAL_DTD, false); + // recommendations from Timothy Morgan's 2014 paper: "XML Schema, DTD, and Entity Attacks" + factory.setXIncludeAware(false); + } + + private void tryToSetFeature(DocumentBuilderFactory factory, String feature, boolean value) { + try { + factory.setFeature(feature, value); + } catch (ParserConfigurationException e) { + LOGGER.info(MessageFormatUtil + .format(KernelLogMessageConstant.FEATURE_IS_NOT_SUPPORTED, e.getMessage(), feature)); + } + } + + private void tryToSetFeature(SAXParserFactory factory, String feature, boolean value) { + try { + factory.setFeature(feature, value); + } catch (ParserConfigurationException | SAXNotRecognizedException | SAXNotSupportedException e) { + LOGGER.info(MessageFormatUtil + .format(KernelLogMessageConstant.FEATURE_IS_NOT_SUPPORTED, e.getMessage(), feature)); + } + } + + // Prevents XXE attacks + private static class SafeEmptyEntityResolver implements EntityResolver { + public SafeEmptyEntityResolver() { + // empty constructor + } + + public InputSource resolveEntity(String publicId, String systemId) { + throw new PdfException(PdfException.ExternalEntityElementFoundInXml); + } + } +} diff --git a/kernel/src/main/java/com/itextpdf/kernel/utils/IXmlParserFactory.java b/kernel/src/main/java/com/itextpdf/kernel/utils/IXmlParserFactory.java new file mode 100644 index 0000000000..57c3fa29c5 --- /dev/null +++ b/kernel/src/main/java/com/itextpdf/kernel/utils/IXmlParserFactory.java @@ -0,0 +1,72 @@ +/* + + This file is part of the iText (R) project. + Copyright (c) 1998-2021 iText Group NV + Authors: Bruno Lowagie, Paulo Soares, et al. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License version 3 + as published by the Free Software Foundation with the addition of the + following permission added to Section 15 as permitted in Section 7(a): + FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY + ITEXT GROUP. ITEXT GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT + OF THIRD PARTY RIGHTS + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Affero General Public License for more details. + You should have received a copy of the GNU Affero General Public License + along with this program; if not, see http://www.gnu.org/licenses or write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA, 02110-1301 USA, or download the license from the following URL: + http://itextpdf.com/terms-of-use/ + + The interactive user interfaces in modified source and object code versions + of this program must display Appropriate Legal Notices, as required under + Section 5 of the GNU Affero General Public License. + + In accordance with Section 7(b) of the GNU Affero General Public License, + a covered work must retain the producer line in every PDF that is created + or manipulated using iText. + + You can be released from the requirements of the license by purchasing + a commercial license. Buying such a license is mandatory as soon as you + develop commercial activities involving the iText software without + disclosing the source code of your own applications. + These activities include: offering paid services to customers as an ASP, + serving PDFs on the fly in a web application, shipping iText with a closed + source product. + + For more information, please contact iText Software Corp. at this + address: sales@itextpdf.com + */ +package com.itextpdf.kernel.utils; + +import javax.xml.parsers.DocumentBuilder; +import org.xml.sax.XMLReader; + +/** + * The interface in which methods for creating xml parsers are declared. + */ +public interface IXmlParserFactory { + /** + * Creates the instance of the {@link DocumentBuilder}. + * + * @param namespaceAware specifies whether the parser should be namespace aware + * @param ignoringComments specifies whether the parser should ignore comments + * + * @return instance of the {@link DocumentBuilder} + */ + DocumentBuilder createDocumentBuilderInstance(boolean namespaceAware, boolean ignoringComments); + + /** + * Creates the instance of the {@link XMLReader}. + * + * @param namespaceAware specifies whether the parser should be namespace aware + * @param validating specifies whether the parser should validate documents as they are parsed + * + * @return instance of the {@link XMLReader} + */ + XMLReader createXMLReaderInstance(boolean namespaceAware, boolean validating); +} diff --git a/kernel/src/main/java/com/itextpdf/kernel/utils/XmlProcessorCreator.java b/kernel/src/main/java/com/itextpdf/kernel/utils/XmlProcessorCreator.java new file mode 100644 index 0000000000..776ea8dd56 --- /dev/null +++ b/kernel/src/main/java/com/itextpdf/kernel/utils/XmlProcessorCreator.java @@ -0,0 +1,115 @@ +/* + This file is part of the iText (R) project. + Copyright (c) 1998-2021 iText Group NV + Authors: Bruno Lowagie, Paulo Soares, et al. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License version 3 + as published by the Free Software Foundation with the addition of the + following permission added to Section 15 as permitted in Section 7(a): + FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY + ITEXT GROUP. ITEXT GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT + OF THIRD PARTY RIGHTS + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Affero General Public License for more details. + You should have received a copy of the GNU Affero General Public License + along with this program; if not, see http://www.gnu.org/licenses or write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA, 02110-1301 USA, or download the license from the following URL: + http://itextpdf.com/terms-of-use/ + + The interactive user interfaces in modified source and object code versions + of this program must display Appropriate Legal Notices, as required under + Section 5 of the GNU Affero General Public License. + + In accordance with Section 7(b) of the GNU Affero General Public License, + a covered work must retain the producer line in every PDF that is created + or manipulated using iText. + + You can be released from the requirements of the license by purchasing + a commercial license. Buying such a license is mandatory as soon as you + develop commercial activities involving the iText software without + disclosing the source code of your own applications. + These activities include: offering paid services to customers as an ASP, + serving PDFs on the fly in a web application, shipping iText with a closed + source product. + + For more information, please contact iText Software Corp. at this + address: sales@itextpdf.com + */ +package com.itextpdf.kernel.utils; + +import javax.xml.parsers.DocumentBuilder; +import org.xml.sax.XMLReader; + +/** + * Utility class for creating XML processors. + */ +public final class XmlProcessorCreator { + + private static IXmlParserFactory xmlParserFactory; + + static { + xmlParserFactory = new DefaultSafeXmlParserFactory(); + } + + private XmlProcessorCreator() { + } + + /** + * Specifies an {@link IXmlParserFactory} implementation that will be used to create the xml + * parsers in the {@link XmlProcessorCreator}. Pass {@link DefaultSafeXmlParserFactory} to use default safe + * factory that should prevent XML attacks like XML bombs and XXE attacks. This will definitely + * throw an exception if the XXE object is present in the XML. Also it is configured to throw + * an exception even in case of any DTD in XML file, but this option depends on the parser + * implementation on your system, it may not work if your parser implementation + * does not support the corresponding functionality. In this case declare your own + * {@link IXmlParserFactory} implementation and pass it to this method. + * + * @param factory factory to be used to create xml parsers. If the passed factory is {@code null}, + * the {@link DefaultSafeXmlParserFactory} will be used. + */ + public static void setXmlParserFactory(IXmlParserFactory factory) { + if (factory == null) { + xmlParserFactory = new DefaultSafeXmlParserFactory(); + } else { + xmlParserFactory = factory; + } + } + + /** + * Creates {@link DocumentBuilder} instance. + * The default implementation is configured to prevent + * possible XML attacks (see {@link DefaultSafeXmlParserFactory}). + * But you can use {@link XmlProcessorCreator#setXmlParserFactory} to set your specific + * factory for creating xml parsers. + * + * @param namespaceAware specifies whether the parser should be namespace aware + * @param ignoringComments specifies whether the parser should ignore comments + * + * @return safe {@link DocumentBuilder} instance + */ + public static DocumentBuilder createSafeDocumentBuilder(boolean namespaceAware, boolean ignoringComments) { + return xmlParserFactory.createDocumentBuilderInstance(namespaceAware, ignoringComments); + } + + + /** + * Creates {@link XMLReader} instance. + * The default implementation is configured to prevent + * possible XML attacks (see {@link DefaultSafeXmlParserFactory}). + * But you can use {@link XmlProcessorCreator#setXmlParserFactory} to set your specific + * factory for creating xml parsers. + * + * @param namespaceAware specifies whether the parser should be namespace aware + * @param validating specifies whether the parser should validate documents as they are parsed + * + * @return safe {@link XMLReader} instance + */ + public static XMLReader createSafeXMLReader(boolean namespaceAware, boolean validating) { + return xmlParserFactory.createXMLReaderInstance(namespaceAware, validating); + } +} diff --git a/kernel/src/main/java/com/itextpdf/kernel/utils/XmlUtils.java b/kernel/src/main/java/com/itextpdf/kernel/utils/XmlUtils.java index 00d49a6289..9a4ae16d5e 100644 --- a/kernel/src/main/java/com/itextpdf/kernel/utils/XmlUtils.java +++ b/kernel/src/main/java/com/itextpdf/kernel/utils/XmlUtils.java @@ -42,14 +42,11 @@ This file is part of the iText (R) project. */ package com.itextpdf.kernel.utils; -import org.w3c.dom.Document; -import org.xml.sax.EntityResolver; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; - +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; import javax.xml.XMLConstants; import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; @@ -57,10 +54,8 @@ This file is part of the iText (R) project. import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.StringReader; +import org.w3c.dom.Document; +import org.xml.sax.SAXException; final class XmlUtils { public static void writeXmlDocToStream(Document xmlReport, OutputStream stream) throws TransformerException { @@ -78,13 +73,7 @@ public static void writeXmlDocToStream(Document xmlReport, OutputStream stream) } public static boolean compareXmls(InputStream xml1, InputStream xml2) throws ParserConfigurationException, SAXException, IOException { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware(true); - dbf.setCoalescing(true); - dbf.setIgnoringElementContentWhitespace(true); - dbf.setIgnoringComments(true); - DocumentBuilder db = dbf.newDocumentBuilder(); - db.setEntityResolver(new SafeEmptyEntityResolver()); + DocumentBuilder db = XmlProcessorCreator.createSafeDocumentBuilder(true, true); Document doc1 = db.parse(xml1); doc1.normalizeDocument(); @@ -96,14 +85,7 @@ public static boolean compareXmls(InputStream xml1, InputStream xml2) throws Par } public static Document initNewXmlDocument() throws ParserConfigurationException { - return DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); + DocumentBuilder db = XmlProcessorCreator.createSafeDocumentBuilder(false, false); + return db.newDocument(); } - - // Prevents XXE attacks - private static class SafeEmptyEntityResolver implements EntityResolver { - public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException { - return new InputSource(new StringReader("")); - } - } - } diff --git a/kernel/src/main/java/com/itextpdf/kernel/xmp/impl/XMPMetaParser.java b/kernel/src/main/java/com/itextpdf/kernel/xmp/impl/XMPMetaParser.java index b3b287a727..6714300b30 100644 --- a/kernel/src/main/java/com/itextpdf/kernel/xmp/impl/XMPMetaParser.java +++ b/kernel/src/main/java/com/itextpdf/kernel/xmp/impl/XMPMetaParser.java @@ -30,6 +30,7 @@ package com.itextpdf.kernel.xmp.impl; +import com.itextpdf.kernel.utils.XmlProcessorCreator; import com.itextpdf.kernel.xmp.XMPConst; import com.itextpdf.kernel.xmp.XMPError; import com.itextpdf.kernel.xmp.XMPException; @@ -42,17 +43,11 @@ import java.io.Reader; import java.io.StringReader; import java.io.UnsupportedEncodingException; - -import javax.xml.XMLConstants; import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; - import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.w3c.dom.ProcessingInstruction; -import org.xml.sax.EntityResolver; import org.xml.sax.InputSource; import org.xml.sax.SAXException; @@ -68,8 +63,6 @@ public class XMPMetaParser { /** */ private static final Object XMP_RDF = new Object(); - /** the DOM Parser Factory, options are set */ - private static DocumentBuilderFactory factory = createDocumentBuilderFactory(); /** * Hidden constructor, initialises the SAX parser handler. @@ -286,26 +279,14 @@ private static Document parseXmlFromString(String input, ParseOptions options) * @return Returns an XML DOM-Document. * @throws XMPException Wraps parsing and I/O-exceptions into an XMPException. */ - private static Document parseInputSource(InputSource source) throws XMPException - { - try - { - DocumentBuilder builder = factory.newDocumentBuilder(); + private static Document parseInputSource(InputSource source) throws XMPException { + try { + DocumentBuilder builder = XmlProcessorCreator.createSafeDocumentBuilder(true, true); builder.setErrorHandler(null); - builder.setEntityResolver(new SafeEmptyEntityResolver()); return builder.parse(source); - } - catch (SAXException e) - { - throw new XMPException("XML parsing failure", XMPError.BADXML, e); - } - catch (ParserConfigurationException e) - { - throw new XMPException("XML Parser not correctly configured", - XMPError.UNKNOWN, e); - } - catch (IOException e) - { + } catch (SAXException e) { + throw new XMPException(e.getMessage(), XMPError.BADXML, e); + } catch (IOException e) { throw new XMPException("Error reading the XML-file", XMPError.BADSTREAM, e); } } @@ -406,36 +387,4 @@ else if (!xmpmetaRequired && return null; // is extracted here in the C++ Toolkit } - - - /** - * @return Creates, configures and returnes the document builder factory for - * the Metadata Parser. - */ - private static DocumentBuilderFactory createDocumentBuilderFactory() - { - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - factory.setNamespaceAware(true); - factory.setIgnoringComments(true); - - try - { - // honor System parsing limits, e.g. - // System.setProperty("entityExpansionLimit", "10"); - factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); - } - catch (Exception e) - { - // Ignore IllegalArgumentException and ParserConfigurationException - // in case the configured XML-Parser does not implement the feature. - } - return factory; - } - - // Prevents XXE attacks - private static class SafeEmptyEntityResolver implements EntityResolver { - public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException { - return new InputSource(new StringReader("")); - } - } } diff --git a/kernel/src/test/java/com/itextpdf/kernel/VersionTest.java b/kernel/src/test/java/com/itextpdf/kernel/VersionTest.java index f25658db43..6a120b2c84 100644 --- a/kernel/src/test/java/com/itextpdf/kernel/VersionTest.java +++ b/kernel/src/test/java/com/itextpdf/kernel/VersionTest.java @@ -26,17 +26,12 @@ This file is part of the iText (R) project. import com.itextpdf.test.annotations.type.UnitTest; import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(UnitTest.class) public class VersionTest extends ExtendedITextTest { - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void parseCurrentVersionTest() { Version instance = Version.getInstance(); @@ -71,20 +66,20 @@ public void parseCustomCorrectVersionTest() { @Test public void parseVersionIncorrectMajorTest() { - junitExpectedException.expect(LicenseVersionException.class); - junitExpectedException.expectMessage(LicenseVersionException.MAJOR_VERSION_IS_NOT_NUMERIC); - // the line below is expected to produce an exception - String[] parseResults = Version.parseVersionString("a.9.11"); + Exception e = Assert.assertThrows(LicenseVersionException.class, + () -> Version.parseVersionString("a.9.11") + ); + Assert.assertEquals(LicenseVersionException.MAJOR_VERSION_IS_NOT_NUMERIC, e.getMessage()); } @Test public void parseVersionIncorrectMinorTest() { - junitExpectedException.expect(LicenseVersionException.class); - junitExpectedException.expectMessage(LicenseVersionException.MINOR_VERSION_IS_NOT_NUMERIC); - // the line below is expected to produce an exception - Version.parseVersionString("1.a.11"); + Exception e = Assert.assertThrows(LicenseVersionException.class, + () -> Version.parseVersionString("1.a.11") + ); + Assert.assertEquals(LicenseVersionException.MINOR_VERSION_IS_NOT_NUMERIC, e.getMessage()); } @Test diff --git a/kernel/src/test/java/com/itextpdf/kernel/colors/ColorTest.java b/kernel/src/test/java/com/itextpdf/kernel/colors/ColorTest.java index 9944805eca..23ef6a8f65 100644 --- a/kernel/src/test/java/com/itextpdf/kernel/colors/ColorTest.java +++ b/kernel/src/test/java/com/itextpdf/kernel/colors/ColorTest.java @@ -53,18 +53,14 @@ This file is part of the iText (R) project. import com.itextpdf.kernel.pdf.colorspace.PdfSpecialCs; import com.itextpdf.test.ExtendedITextTest; import com.itextpdf.test.annotations.type.UnitTest; + import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(UnitTest.class) public class ColorTest extends ExtendedITextTest { - @Rule - public ExpectedException expectedException = ExpectedException.none(); - private static final float EPS = 1e-4f; @Test @@ -85,13 +81,13 @@ public void convertRgbToCmykTest() { @Test public void setColorValueIncorrectComponentsNumberTest() { - expectedException.expect(PdfException.class); - expectedException.expectMessage(PdfException.IncorrectNumberOfComponents); - float[] colorValues = new float[]{0.0f, 0.5f, 0.1f}; Color color = Color.makeColor(PdfColorSpace.makeColorSpace(PdfName.DeviceRGB), colorValues); - color.setColorValue(new float[]{0.1f, 0.2f}); + Exception e = Assert.assertThrows(PdfException.class, + () -> color.setColorValue(new float[]{0.1f, 0.2f}) + ); + Assert.assertEquals(PdfException.IncorrectNumberOfComponents, e.getMessage()); } @Test @@ -162,11 +158,10 @@ public void notEqualsDifferentClassesTest() { @Test public void nullColorSpaceTest() { - expectedException.expect(PdfException.class); - expectedException.expectMessage("Unknown color space."); - float[] colorValues = new float[]{0.0f, 0.5f, 0.1f}; - Color color = Color.makeColor(null, colorValues); + + Exception e = Assert.assertThrows(PdfException.class, () -> Color.makeColor(null, colorValues)); + Assert.assertEquals("Unknown color space.", e.getMessage()); } @Test @@ -209,10 +204,8 @@ public void makeDeviceCmykTest() { @Test public void unknownDeviceCsTest() { - expectedException.expect(PdfException.class); - expectedException.expectMessage("Unknown color space."); - - Color color = Color.makeColor(new CustomDeviceCs(null)); + Exception e = Assert.assertThrows(PdfException.class, () -> Color.makeColor(new CustomDeviceCs(null))); + Assert.assertEquals("Unknown color space.", e.getMessage()); } @Test @@ -310,10 +303,10 @@ public void makeLabTest() { @Test public void unknownCieBasedCsTest() { - expectedException.expect(PdfException.class); - expectedException.expectMessage("Unknown color space."); - - Color color = Color.makeColor(new CustomPdfCieBasedCs(new PdfArray())); + Exception e = Assert.assertThrows(PdfException.class, + () -> Color.makeColor(new CustomPdfCieBasedCs(new PdfArray())) + ); + Assert.assertEquals("Unknown color space.", e.getMessage()); } @Test @@ -380,10 +373,10 @@ public void makeIndexedTest() { @Test public void unknownSpecialCsTest() { - expectedException.expect(PdfException.class); - expectedException.expectMessage("Unknown color space."); - - Color color = Color.makeColor(new CustomPdfSpecialCs(new PdfArray())); + Exception e = Assert.assertThrows(PdfException.class, + () -> Color.makeColor(new CustomPdfSpecialCs(new PdfArray())) + ); + Assert.assertEquals("Unknown color space.", e.getMessage()); } private static class CustomDeviceCs extends PdfDeviceCs { diff --git a/kernel/src/test/java/com/itextpdf/kernel/counter/DataHandlerCounterTest.java b/kernel/src/test/java/com/itextpdf/kernel/counter/DataHandlerCounterTest.java index b07b0c2366..af74cc5db7 100644 --- a/kernel/src/test/java/com/itextpdf/kernel/counter/DataHandlerCounterTest.java +++ b/kernel/src/test/java/com/itextpdf/kernel/counter/DataHandlerCounterTest.java @@ -40,17 +40,12 @@ This file is part of the iText (R) project. import java.util.concurrent.atomic.AtomicLong; import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(UnitTest.class) public class DataHandlerCounterTest extends ExtendedITextTest { - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void disableHooksTest() throws InterruptedException { final int betweenChecksSleepTime = 500; @@ -84,9 +79,8 @@ public void onEventAfterDisableTest() throws InterruptedException { counter.close(); - junitExpectedException.expect(IllegalStateException.class); - junitExpectedException.expectMessage(PdfException.DataHandlerCounterHasBeenDisabled); - counter.onEvent(testEvent, null); + Exception e = Assert.assertThrows(IllegalStateException.class, () -> counter.onEvent(testEvent, null)); + Assert.assertEquals(PdfException.DataHandlerCounterHasBeenDisabled, e.getMessage()); } @Test diff --git a/kernel/src/test/java/com/itextpdf/kernel/crypto/PdfEncryptionTest.java b/kernel/src/test/java/com/itextpdf/kernel/crypto/PdfEncryptionTest.java index 3b7586f937..506eb14692 100644 --- a/kernel/src/test/java/com/itextpdf/kernel/crypto/PdfEncryptionTest.java +++ b/kernel/src/test/java/com/itextpdf/kernel/crypto/PdfEncryptionTest.java @@ -71,13 +71,12 @@ This file is part of the iText (R) project. import com.itextpdf.test.annotations.LogMessage; import com.itextpdf.test.annotations.LogMessages; import com.itextpdf.test.annotations.type.IntegrationTest; + import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; import java.io.FileInputStream; import java.io.IOException; @@ -127,9 +126,6 @@ public class PdfEncryptionTest extends ExtendedITextTest { */ public static byte[] OWNER = "World".getBytes(StandardCharsets.ISO_8859_1); - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - private PrivateKey privateKey; @BeforeClass @@ -253,95 +249,98 @@ public void encryptWithCertificateAes256NoCompression() throws IOException, Inte @Test public void openEncryptedDocWithoutPassword() throws IOException { - junitExpectedException.expect(BadPasswordException.class); - junitExpectedException.expectMessage(BadPasswordException.BadUserPassword); - - PdfDocument doc = new PdfDocument(new PdfReader(sourceFolder + "encryptedWithPasswordStandard40.pdf")); - doc.close(); + try (PdfReader reader = new PdfReader(sourceFolder + "encryptedWithPasswordStandard40.pdf")) { + Exception e = Assert.assertThrows(BadPasswordException.class, () -> new PdfDocument(reader)); + Assert.assertEquals(BadPasswordException.BadUserPassword, e.getMessage()); + } } @Test public void openEncryptedDocWithWrongPassword() throws IOException { - junitExpectedException.expect(BadPasswordException.class); - junitExpectedException.expectMessage(BadPasswordException.BadUserPassword); + try (PdfReader reader = new PdfReader(sourceFolder + "encryptedWithPasswordStandard40.pdf", + new ReaderProperties().setPassword("wrong_password".getBytes(StandardCharsets.ISO_8859_1)))) { - PdfReader reader = new PdfReader(sourceFolder + "encryptedWithPasswordStandard40.pdf", - new ReaderProperties().setPassword("wrong_password".getBytes(StandardCharsets.ISO_8859_1))); - PdfDocument doc = new PdfDocument(reader); - doc.close(); + Exception e = Assert.assertThrows(BadPasswordException.class, () -> new PdfDocument(reader)); + Assert.assertEquals(BadPasswordException.BadUserPassword, e.getMessage()); + } } @Test public void openEncryptedDocWithoutCertificate() throws IOException { - junitExpectedException.expect(PdfException.class); - junitExpectedException.expectMessage(PdfException.CertificateIsNotProvidedDocumentIsEncryptedWithPublicKeyCertificate); + try (PdfReader reader = new PdfReader(sourceFolder + "encryptedWithCertificateAes128.pdf")) { - PdfDocument doc = new PdfDocument(new PdfReader(sourceFolder + "encryptedWithCertificateAes128.pdf")); - doc.close(); + Exception e = Assert.assertThrows(PdfException.class, () -> new PdfDocument(reader)); + Assert.assertEquals(PdfException.CertificateIsNotProvidedDocumentIsEncryptedWithPublicKeyCertificate, + e.getMessage()); + } } @Test public void openEncryptedDocWithoutPrivateKey() throws IOException, CertificateException { - junitExpectedException.expect(PdfException.class); - junitExpectedException.expectMessage(PdfException.BadCertificateAndKey); - - PdfReader reader = new PdfReader(sourceFolder + "encryptedWithCertificateAes128.pdf", + try (PdfReader reader = new PdfReader(sourceFolder + "encryptedWithCertificateAes128.pdf", new ReaderProperties() .setPublicKeySecurityParams( getPublicCertificate(sourceFolder + "wrong.cer"), null, "BC", - null)); - PdfDocument doc = new PdfDocument(reader); - doc.close(); + null))) { + + Exception e = Assert.assertThrows(PdfException.class, + () -> new PdfDocument(reader) + ); + Assert.assertEquals(PdfException.BadCertificateAndKey, e.getMessage()); + } } @Test public void openEncryptedDocWithWrongCertificate() throws IOException, GeneralSecurityException { - junitExpectedException.expect(PdfException.class); - junitExpectedException.expectMessage(PdfException.BadCertificateAndKey); - - PdfReader reader = new PdfReader(sourceFolder + "encryptedWithCertificateAes128.pdf", + try (PdfReader reader = new PdfReader(sourceFolder + "encryptedWithCertificateAes128.pdf", new ReaderProperties() .setPublicKeySecurityParams( getPublicCertificate(sourceFolder + "wrong.cer"), getPrivateKey(), "BC", - null)); - PdfDocument doc = new PdfDocument(reader); - doc.close(); + null))) { + + Exception e = Assert.assertThrows(PdfException.class, + () -> new PdfDocument(reader) + ); + Assert.assertEquals(PdfException.BadCertificateAndKey, e.getMessage()); + } } @Test public void openEncryptedDocWithWrongPrivateKey() throws IOException, GeneralSecurityException { - junitExpectedException.expect(PdfException.class); - junitExpectedException.expectMessage(PdfException.PdfDecryption); - - PdfReader reader = new PdfReader(sourceFolder + "encryptedWithCertificateAes128.pdf", + try (PdfReader reader = new PdfReader(sourceFolder + "encryptedWithCertificateAes128.pdf", new ReaderProperties() .setPublicKeySecurityParams( getPublicCertificate(CERT), CryptoUtil.readPrivateKeyFromPKCS12KeyStore(new FileInputStream(sourceFolder + "wrong.p12"), "demo", "password".toCharArray()), "BC", - null)); - PdfDocument doc = new PdfDocument(reader); - doc.close(); + null))) { + + Exception e = Assert.assertThrows(PdfException.class, + () -> new PdfDocument(reader) + ); + Assert.assertEquals(PdfException.PdfDecryption, e.getMessage()); + } } @Test public void openEncryptedDocWithWrongCertificateAndPrivateKey() throws IOException, GeneralSecurityException { - junitExpectedException.expect(PdfException.class); - junitExpectedException.expectMessage(PdfException.BadCertificateAndKey); - - PdfReader reader = new PdfReader(sourceFolder + "encryptedWithCertificateAes128.pdf", + try (PdfReader reader = new PdfReader(sourceFolder + "encryptedWithCertificateAes128.pdf", new ReaderProperties() .setPublicKeySecurityParams( getPublicCertificate(sourceFolder + "wrong.cer"), CryptoUtil.readPrivateKeyFromPKCS12KeyStore(new FileInputStream(sourceFolder + "wrong.p12"), "demo", "password".toCharArray()), "BC", - null)); - PdfDocument doc = new PdfDocument(reader); - doc.close(); + null))) { + + Exception e = Assert.assertThrows(PdfException.class, + () -> new PdfDocument(reader) + ); + Assert.assertEquals(PdfException.BadCertificateAndKey, e.getMessage()); + } } @Test @@ -389,12 +388,14 @@ public void openDocNoUserPassword() throws IOException { @Test public void stampDocNoUserPassword() throws IOException { - junitExpectedException.expect(BadPasswordException.class); - junitExpectedException.expectMessage(BadPasswordException.PdfReaderNotOpenedWithOwnerPassword); - String fileName = "stampedNoPassword.pdf"; - PdfDocument document = new PdfDocument(new PdfReader(sourceFolder + "noUserPassword.pdf"), new PdfWriter(destinationFolder + fileName)); - document.close(); + + try (PdfReader reader = new PdfReader(sourceFolder + "noUserPassword.pdf"); + PdfWriter writer = new PdfWriter(destinationFolder + fileName)) { + + Exception e = Assert.assertThrows(BadPasswordException.class, () -> new PdfDocument(reader, writer)); + Assert.assertEquals(BadPasswordException.PdfReaderNotOpenedWithOwnerPassword, e.getMessage()); + } } @Test @@ -421,9 +422,9 @@ public void encryptWithPasswordAes128EmbeddedFilesOnly() throws IOException { document.close(); - //NOTE: Specific crypto filters for EFF StmF and StrF are not supported at the moment. iText don't distinguish objects based on their semantic role - // because of this we can't read streams correctly and corrupt such documents on stamping. - boolean ERROR_IS_EXPECTED = true; + //TODO DEVSIX-5355 Specific crypto filters for EFF StmF and StrF are not supported at the moment. + // However we can read embedded files only mode. + boolean ERROR_IS_EXPECTED = false; checkDecryptedWithPasswordContent(destinationFolder + filename, OWNER, textContent, ERROR_IS_EXPECTED); checkDecryptedWithPasswordContent(destinationFolder + filename, USER, textContent, ERROR_IS_EXPECTED); } diff --git a/kernel/src/test/java/com/itextpdf/kernel/crypto/PdfReaderCustomFilterTest.java b/kernel/src/test/java/com/itextpdf/kernel/crypto/PdfReaderCustomFilterTest.java index fd64930dec..0533570e8f 100644 --- a/kernel/src/test/java/com/itextpdf/kernel/crypto/PdfReaderCustomFilterTest.java +++ b/kernel/src/test/java/com/itextpdf/kernel/crypto/PdfReaderCustomFilterTest.java @@ -30,25 +30,20 @@ This file is part of the iText (R) project. import com.itextpdf.test.annotations.type.IntegrationTest; import java.io.IOException; -import org.junit.Rule; +import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(IntegrationTest.class) public class PdfReaderCustomFilterTest extends ExtendedITextTest { public static final String sourceFolder = "./src/test/resources/com/itextpdf/kernel/crypto/PdfReaderCustomFilterTest/"; - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void encryptedDocumentCustomFilterStandartTest() throws IOException { - junitExpectedException.expect(UnsupportedSecurityHandlerException.class); - junitExpectedException.expectMessage(MessageFormatUtil. - format(UnsupportedSecurityHandlerException.UnsupportedSecurityHandler, "/Standart")); - - PdfDocument doc = new PdfDocument(new PdfReader(sourceFolder + "customSecurityHandler.pdf")); - doc.close(); + try (PdfReader reader = new PdfReader(sourceFolder + "customSecurityHandler.pdf")) { + Exception e = Assert.assertThrows(UnsupportedSecurityHandlerException.class, () -> new PdfDocument(reader)); + Assert.assertEquals(MessageFormatUtil.format(UnsupportedSecurityHandlerException.UnsupportedSecurityHandler, + "/Standart"), e.getMessage()); + } } } diff --git a/kernel/src/test/java/com/itextpdf/kernel/font/PdfFontFactoryTest.java b/kernel/src/test/java/com/itextpdf/kernel/font/PdfFontFactoryTest.java index c1f0a642de..7674efac9c 100644 --- a/kernel/src/test/java/com/itextpdf/kernel/font/PdfFontFactoryTest.java +++ b/kernel/src/test/java/com/itextpdf/kernel/font/PdfFontFactoryTest.java @@ -38,26 +38,22 @@ This file is part of the iText (R) project. import java.io.IOException; import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(UnitTest.class) public class PdfFontFactoryTest extends ExtendedITextTest { public static final String sourceFolder = "./src/test/resources/com/itextpdf/kernel/font/"; - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void standardFontForceEmbeddedTest() throws IOException { Type1Font fontProgram = (Type1Font) FontProgramFactory.createFont(StandardFonts.HELVETICA); - junitExpectedException.expect(PdfException.class); - junitExpectedException.expectMessage(PdfException.CannotEmbedStandardFont); - PdfFontFactory.createFont(fontProgram, PdfEncodings.UTF8, EmbeddingStrategy.FORCE_EMBEDDED); + Exception e = Assert.assertThrows(PdfException.class, + () -> PdfFontFactory.createFont(fontProgram, PdfEncodings.UTF8, EmbeddingStrategy.FORCE_EMBEDDED) + ); + Assert.assertEquals(PdfException.CannotEmbedStandardFont, e.getMessage()); } @Test @@ -174,9 +170,11 @@ public void trueTypeFontProgramUTF8AllowEmbeddingEncodingForceNotEmbeddedTest() public void trueTypeFontProgramUTF8NotAllowEmbeddingEncodingForceEmbeddedTest() { TrueTypeFont fontProgram = new CustomTrueTypeFontProgram(false); - junitExpectedException.expect(PdfException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(PdfException.CannotBeEmbeddedDueToLicensingRestrictions, "CustomNameCustomStyle")); - PdfFontFactory.createFont(fontProgram, PdfEncodings.UTF8, EmbeddingStrategy.FORCE_EMBEDDED); + Exception e = Assert.assertThrows(PdfException.class, + () -> PdfFontFactory.createFont(fontProgram, PdfEncodings.UTF8, EmbeddingStrategy.FORCE_EMBEDDED) + ); + Assert.assertEquals(MessageFormatUtil.format(PdfException.CannotBeEmbeddedDueToLicensingRestrictions, "CustomNameCustomStyle"), + e.getMessage()); } @Test @@ -243,49 +241,54 @@ public void trueTypeFontProgramIdentityHAllowEmbeddingEncodingPreferNotEmbeddedT public void trueTypeFontProgramIdentityHAllowEmbeddingEncodingForceNotEmbeddedTest() { TrueTypeFont fontProgram = new CustomTrueTypeFontProgram(true); - junitExpectedException.expect(PdfException.class); - junitExpectedException.expectMessage(PdfException.CannotCreateType0FontWithTrueTypeFontProgramWithoutEmbedding); - PdfFontFactory.createFont(fontProgram, PdfEncodings.IDENTITY_H, EmbeddingStrategy.FORCE_NOT_EMBEDDED); + Exception e = Assert.assertThrows(PdfException.class, + () -> PdfFontFactory.createFont(fontProgram, PdfEncodings.IDENTITY_H, EmbeddingStrategy.FORCE_NOT_EMBEDDED) + ); + Assert.assertEquals(PdfException.CannotCreateType0FontWithTrueTypeFontProgramWithoutEmbedding, e.getMessage()); } @Test public void trueTypeFontProgramIdentityHNotAllowEmbeddingEncodingForceEmbeddedTest() { TrueTypeFont fontProgram = new CustomTrueTypeFontProgram(false); - junitExpectedException.expect(PdfException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format( - PdfException.CannotBeEmbeddedDueToLicensingRestrictions, "CustomNameCustomStyle")); - PdfFontFactory.createFont(fontProgram, PdfEncodings.IDENTITY_H, EmbeddingStrategy.FORCE_EMBEDDED); + Exception e = Assert.assertThrows(PdfException.class, + () -> PdfFontFactory.createFont(fontProgram, PdfEncodings.IDENTITY_H, EmbeddingStrategy.FORCE_EMBEDDED) + ); + Assert.assertEquals(MessageFormatUtil.format(PdfException.CannotBeEmbeddedDueToLicensingRestrictions, + "CustomNameCustomStyle"), e.getMessage()); } @Test public void trueTypeFontProgramIdentityHNotAllowEmbeddingEncodingPreferEmbeddedTest() { TrueTypeFont fontProgram = new CustomTrueTypeFontProgram(false); - junitExpectedException.expect(PdfException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format( - PdfException.CannotBeEmbeddedDueToLicensingRestrictions, "CustomNameCustomStyle")); - PdfFontFactory.createFont(fontProgram, PdfEncodings.IDENTITY_H, EmbeddingStrategy.PREFER_EMBEDDED); + Exception e = Assert.assertThrows(PdfException.class, + () -> PdfFontFactory.createFont(fontProgram, PdfEncodings.IDENTITY_H, EmbeddingStrategy.PREFER_EMBEDDED) + ); + Assert.assertEquals(MessageFormatUtil.format(PdfException.CannotBeEmbeddedDueToLicensingRestrictions, + "CustomNameCustomStyle"), e.getMessage()); } @Test public void trueTypeFontProgramIdentityHNotAllowEmbeddingEncodingPreferNotEmbeddedTest() { TrueTypeFont fontProgram = new CustomTrueTypeFontProgram(false); - junitExpectedException.expect(PdfException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format( - PdfException.CannotBeEmbeddedDueToLicensingRestrictions, "CustomNameCustomStyle")); - PdfFontFactory.createFont(fontProgram, PdfEncodings.IDENTITY_H, EmbeddingStrategy.PREFER_NOT_EMBEDDED); + Exception e = Assert.assertThrows(PdfException.class, + () -> PdfFontFactory.createFont(fontProgram, PdfEncodings.IDENTITY_H, EmbeddingStrategy.PREFER_NOT_EMBEDDED) + ); + Assert.assertEquals(MessageFormatUtil.format(PdfException.CannotBeEmbeddedDueToLicensingRestrictions, + "CustomNameCustomStyle"), e.getMessage()); } @Test public void trueTypeFontProgramIdentityHNotAllowEmbeddingEncodingForceNotEmbeddedTest() { TrueTypeFont fontProgram = new CustomTrueTypeFontProgram(false); - junitExpectedException.expect(PdfException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format( - PdfException.CannotBeEmbeddedDueToLicensingRestrictions, "CustomNameCustomStyle")); - PdfFontFactory.createFont(fontProgram, PdfEncodings.IDENTITY_H, EmbeddingStrategy.FORCE_NOT_EMBEDDED); + Exception e = Assert.assertThrows(PdfException.class, + () -> PdfFontFactory.createFont(fontProgram, PdfEncodings.IDENTITY_H, EmbeddingStrategy.FORCE_NOT_EMBEDDED) + ); + Assert.assertEquals(MessageFormatUtil.format(PdfException.CannotBeEmbeddedDueToLicensingRestrictions, + "CustomNameCustomStyle"), e.getMessage()); } @Test @@ -303,18 +306,16 @@ public void standardFontCachedWithoutDocumentTest() throws IOException { public void createFontFromNullDictionaryTest() { PdfDictionary dictionary = null; - junitExpectedException.expect(PdfException.class); - junitExpectedException.expectMessage(PdfException.CannotCreateFontFromNullFontDictionary); - PdfFontFactory.createFont(dictionary); + Exception e = Assert.assertThrows(PdfException.class, () -> PdfFontFactory.createFont(dictionary)); + Assert.assertEquals(PdfException.CannotCreateFontFromNullFontDictionary, e.getMessage()); } @Test public void createFontFromEmptyDictionaryTest() { PdfDictionary dictionary = new PdfDictionary(); - junitExpectedException.expect(PdfException.class); - junitExpectedException.expectMessage(PdfException.DictionaryDoesntHaveSupportedFontData); - PdfFontFactory.createFont(dictionary); + Exception e = Assert.assertThrows(PdfException.class, () -> PdfFontFactory.createFont(dictionary)); + Assert.assertEquals(PdfException.DictionaryDoesntHaveSupportedFontData, e.getMessage()); } @Test diff --git a/kernel/src/test/java/com/itextpdf/kernel/font/PdfFontUnitTest.java b/kernel/src/test/java/com/itextpdf/kernel/font/PdfFontUnitTest.java index 277a655805..279c1f0a8a 100644 --- a/kernel/src/test/java/com/itextpdf/kernel/font/PdfFontUnitTest.java +++ b/kernel/src/test/java/com/itextpdf/kernel/font/PdfFontUnitTest.java @@ -60,10 +60,8 @@ This file is part of the iText (R) project. import java.util.List; import java.util.regex.Pattern; import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(UnitTest.class) public class PdfFontUnitTest extends ExtendedITextTest { @@ -204,9 +202,6 @@ public TestFontMetrics() { } } - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void constructorWithoutParamsTest() { TestFont font = new TestFont(); @@ -569,9 +564,10 @@ public void updateEmbeddedSubsetPrefixTest() { public void getEmptyPdfStreamTest() { TestFont font = new TestFont(); - junitExpectedException.expect(PdfException.class); - junitExpectedException.expectMessage(PdfException.FontEmbeddingIssue); - font.getPdfFontStream(null, null); + Exception e = Assert.assertThrows(PdfException.class, + () -> font.getPdfFontStream(null, null) + ); + Assert.assertEquals(PdfException.FontEmbeddingIssue, e.getMessage()); } @Test diff --git a/kernel/src/test/java/com/itextpdf/kernel/font/PdfType0FontTest.java b/kernel/src/test/java/com/itextpdf/kernel/font/PdfType0FontTest.java index 5ac485f774..532080f760 100644 --- a/kernel/src/test/java/com/itextpdf/kernel/font/PdfType0FontTest.java +++ b/kernel/src/test/java/com/itextpdf/kernel/font/PdfType0FontTest.java @@ -35,19 +35,14 @@ This file is part of the iText (R) project. import java.io.IOException; import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(UnitTest.class) public class PdfType0FontTest extends ExtendedITextTest { public static final String sourceFolder = "./src/test/resources/com/itextpdf/kernel/font/PdfType0FontTest/"; - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void trueTypeFontAndCmapConstructorTest() throws IOException { TrueTypeFont ttf = new TrueTypeFont(sourceFolder + "NotoSerif-Regular_v1.7.ttf"); @@ -68,11 +63,12 @@ public void trueTypeFontAndCmapConstructorTest() throws IOException { @Test public void unsupportedCmapTest() throws IOException { - junitExpectedException.expect(PdfException.class); - junitExpectedException.expectMessage(PdfException.OnlyIdentityCMapsSupportsWithTrueType); - TrueTypeFont ttf = new TrueTypeFont(sourceFolder + "NotoSerif-Regular_v1.7.ttf"); - PdfType0Font type0Font = new PdfType0Font(ttf, PdfEncodings.WINANSI); + + Exception e = Assert.assertThrows(PdfException.class, + () -> new PdfType0Font(ttf, PdfEncodings.WINANSI) + ); + Assert.assertEquals(PdfException.OnlyIdentityCMapsSupportsWithTrueType, e.getMessage()); } @Test diff --git a/kernel/src/test/java/com/itextpdf/kernel/font/PdfType3FontTest.java b/kernel/src/test/java/com/itextpdf/kernel/font/PdfType3FontTest.java index 27d15c0c19..5cd0a64236 100644 --- a/kernel/src/test/java/com/itextpdf/kernel/font/PdfType3FontTest.java +++ b/kernel/src/test/java/com/itextpdf/kernel/font/PdfType3FontTest.java @@ -37,19 +37,15 @@ This file is part of the iText (R) project. import com.itextpdf.test.annotations.LogMessage; import com.itextpdf.test.annotations.LogMessages; import com.itextpdf.test.annotations.type.UnitTest; + import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(UnitTest.class) public class PdfType3FontTest extends ExtendedITextTest { private static final float EPS = 1e-4f; - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test @LogMessages(messages = {@LogMessage(messageTemplate = LogMessageConstant.TYPE3_FONT_INITIALIZATION_ISSUE)}) public void addDifferentGlyphsInConstructorTest() { @@ -176,8 +172,6 @@ protected PdfDocument getDocument() { @Test @LogMessages(messages = {@LogMessage(messageTemplate = LogMessageConstant.TYPE3_FONT_INITIALIZATION_ISSUE)}) public void flushExceptionTest() { - junitExpectedException.expect(PdfException.class); - junitExpectedException.expectMessage(PdfException.NoGlyphsDefinedForType3Font); PdfDictionary dictionary = new PdfDictionary(); dictionary.put(PdfName.FontMatrix, new PdfArray()); PdfDictionary charProcs = new PdfDictionary(); @@ -185,7 +179,10 @@ public void flushExceptionTest() { dictionary.put(PdfName.Widths, new PdfArray()); PdfType3Font type3Font = new DisableEnsureUnderlyingObjectHasIndirectReference(dictionary); - type3Font.flush(); + Exception e = Assert.assertThrows(PdfException.class, + () -> type3Font.flush() + ); + Assert.assertEquals(PdfException.NoGlyphsDefinedForType3Font, e.getMessage()); } @Test @@ -248,31 +245,30 @@ public void noDifferenceTest() { } @Test - @LogMessages(messages = {@LogMessage(messageTemplate = LogMessageConstant.TYPE3_FONT_INITIALIZATION_ISSUE)}) public void missingFontMatrixTest() { PdfDictionary dictionary = new PdfDictionary(); dictionary.put(PdfName.Widths, new PdfArray()); dictionary.put(PdfName.ToUnicode, PdfName.IdentityH); dictionary.put(PdfName.Encoding, new PdfName("zapfdingbatsencoding")); - junitExpectedException.expect(PdfException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format( - PdfException.MissingRequiredFieldInFontDictionary, PdfName.FontMatrix)); - new PdfType3Font(dictionary); + Exception e = Assert.assertThrows(PdfException.class, + () -> new PdfType3Font(dictionary) + ); + Assert.assertEquals(MessageFormatUtil.format(PdfException.MissingRequiredFieldInFontDictionary, PdfName.FontMatrix), e.getMessage()); } @Test - @LogMessages(messages = {@LogMessage(messageTemplate = LogMessageConstant.TYPE3_FONT_INITIALIZATION_ISSUE)}) public void missingWidthsTest() { PdfDictionary dictionary = new PdfDictionary(); dictionary.put(PdfName.FontMatrix, new PdfArray()); dictionary.put(PdfName.ToUnicode, PdfName.IdentityH); dictionary.put(PdfName.Encoding, new PdfName("zapfdingbatsencoding")); - junitExpectedException.expect(PdfException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format( - PdfException.MissingRequiredFieldInFontDictionary, PdfName.Widths)); - new PdfType3Font(dictionary); + Exception e = Assert.assertThrows(PdfException.class, + () -> new PdfType3Font(dictionary) + ); + Assert.assertEquals(MessageFormatUtil.format( + PdfException.MissingRequiredFieldInFontDictionary, PdfName.Widths), e.getMessage()); } @Test diff --git a/kernel/src/test/java/com/itextpdf/kernel/pdf/EncryptedEmbeddedStreamsHandlerTest.java b/kernel/src/test/java/com/itextpdf/kernel/pdf/EncryptedEmbeddedStreamsHandlerTest.java new file mode 100644 index 0000000000..ab5ed5cf59 --- /dev/null +++ b/kernel/src/test/java/com/itextpdf/kernel/pdf/EncryptedEmbeddedStreamsHandlerTest.java @@ -0,0 +1,170 @@ +/* + This file is part of the iText (R) project. + Copyright (c) 1998-2021 iText Group NV + Authors: iText Software. + + This program is offered under a commercial and under the AGPL license. + For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below. + + AGPL licensing: + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + */ +package com.itextpdf.kernel.pdf; + +import com.itextpdf.kernel.geom.Rectangle; +import com.itextpdf.kernel.pdf.annot.PdfFileAttachmentAnnotation; +import com.itextpdf.kernel.pdf.filespec.PdfFileSpec; +import com.itextpdf.kernel.utils.CompareTool; +import com.itextpdf.test.ExtendedITextTest; +import com.itextpdf.test.annotations.type.IntegrationTest; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import java.io.IOException; + +@Category(IntegrationTest.class) +public class EncryptedEmbeddedStreamsHandlerTest extends ExtendedITextTest { + + public static final String sourceFolder = "./src/test/resources/com/itextpdf/kernel/pdf/EncryptedEmbeddedStreamsHandlerTest/"; + public static final String destinationFolder = "./target/test/com/itextpdf/kernel/pdf/EncryptedEmbeddedStreamsHandlerTest/"; + + @BeforeClass + public static void beforeClass() { + createDestinationFolder(destinationFolder); + } + + @Test + public void noReaderStandardEncryptionAddFileAttachment() throws IOException, InterruptedException { + String outFileName = destinationFolder + "noReaderStandardEncryptionAddFileAttachment.pdf"; + String cmpFileName = sourceFolder + "cmp_noReaderStandardEncryptionAddFileAttachment.pdf"; + + PdfDocument pdfDocument = createEncryptedDocument(EncryptionConstants.STANDARD_ENCRYPTION_128, outFileName); + PdfFileSpec fs = PdfFileSpec.createEmbeddedFileSpec( + pdfDocument, "file".getBytes(), "description", "file.txt", null, null, null); + pdfDocument.addFileAttachment("file.txt", fs); + + pdfDocument.addNewPage(); + pdfDocument.close(); + + Assert.assertNull(new CompareTool().compareByContent(outFileName, cmpFileName, destinationFolder, "diff", "password".getBytes(), "password".getBytes())); + } + + @Test + public void noReaderAesEncryptionAddFileAttachment() throws IOException, InterruptedException { + String outFileName = destinationFolder + "noReaderAesEncryptionAddFileAttachment.pdf"; + String cmpFileName = sourceFolder + "cmp_noReaderAesEncryptionAddFileAttachment.pdf"; + + PdfDocument pdfDocument = createEncryptedDocument(EncryptionConstants.ENCRYPTION_AES_128, outFileName); + PdfFileSpec fs = PdfFileSpec.createEmbeddedFileSpec( + pdfDocument, "file".getBytes(), "description", "file.txt", null, null, null); + pdfDocument.addFileAttachment("file.txt", fs); + + pdfDocument.addNewPage(); + pdfDocument.close(); + + Assert.assertNull(new CompareTool().compareByContent(outFileName, cmpFileName, destinationFolder, "diff", "password".getBytes(), "password".getBytes())); + } + + @Test + public void withReaderStandardEncryptionAddFileAttachment() throws IOException, InterruptedException { + String outFileName = destinationFolder + "withReaderStandardEncryptionAddFileAttachment.pdf"; + String cmpFileName = sourceFolder + "cmp_withReaderStandardEncryptionAddFileAttachment.pdf"; + + PdfReader reader = new PdfReader(sourceFolder + "pdfWithFileAttachments.pdf", new ReaderProperties().setPassword("password".getBytes())); + // Setting compression level to zero doesn't affect the encryption at any level. + // We do it to simplify observation of the resultant PDF. + PdfDocument pdfDocument = new PdfDocument(reader, new PdfWriter(outFileName).setCompressionLevel(0)); + PdfFileSpec fs = PdfFileSpec.createEmbeddedFileSpec( + pdfDocument, "file".getBytes(), "description", "file.txt", null, null, null); + pdfDocument.addFileAttachment("file.txt", fs); + + pdfDocument.addNewPage(); + pdfDocument.close(); + + Assert.assertNull(new CompareTool().compareByContent(outFileName, cmpFileName, destinationFolder, "diff")); + } + + @Test + public void noReaderStandardEncryptionAddAnnotation() throws IOException, InterruptedException { + String outFileName = destinationFolder + "noReaderStandardEncryptionAddAnnotation.pdf"; + String cmpFileName = sourceFolder + "cmp_noReaderStandardEncryptionAddAnnotation.pdf"; + + PdfDocument pdfDocument = createEncryptedDocument(EncryptionConstants.STANDARD_ENCRYPTION_128, outFileName); + pdfDocument.addNewPage(); + PdfFileSpec fs = PdfFileSpec.createEmbeddedFileSpec( + pdfDocument, "file".getBytes(), "description", "file.txt", null, null, null); + pdfDocument.getPage(1).addAnnotation(new PdfFileAttachmentAnnotation(new Rectangle(100, 100), fs)); + + pdfDocument.close(); + + Assert.assertNull(new CompareTool().compareByContent(outFileName, cmpFileName, destinationFolder, "diff", "password".getBytes(), "password".getBytes())); + } + + @Test + public void withReaderStandardEncryptionAddAnnotation() throws IOException, InterruptedException { + String outFileName = destinationFolder + "withReaderStandardEncryptionAddAnnotation.pdf"; + String cmpFileName = sourceFolder + "cmp_withReaderStandardEncryptionAddAnnotation.pdf"; + + PdfReader reader = new PdfReader(sourceFolder + "pdfWithFileAttachmentAnnotations.pdf", new ReaderProperties().setPassword("password".getBytes())); + // Setting compression level to zero doesn't affect the encryption at any level. + // We do it to simplify observation of the resultant PDF. + PdfDocument pdfDocument = new PdfDocument(reader, new PdfWriter(outFileName).setCompressionLevel(0)); + pdfDocument.addNewPage(); + PdfFileSpec fs = PdfFileSpec.createEmbeddedFileSpec( + pdfDocument, "file".getBytes(), "description", "file.txt", null, null, null); + pdfDocument.getPage(1).addAnnotation(new PdfFileAttachmentAnnotation(new Rectangle(100, 100), fs)); + + pdfDocument.close(); + + Assert.assertNull(new CompareTool().compareByContent(outFileName, cmpFileName, destinationFolder, "diff")); + } + + @Test + public void readerWithoutEncryptionWriterStandardEncryption() throws IOException, InterruptedException { + String outFileName = destinationFolder + "readerWithoutEncryptionWriterStandardEncryption.pdf"; + String cmpFileName = sourceFolder + "cmp_readerWithoutEncryptionWriterStandardEncryption.pdf"; + + PdfReader reader = new PdfReader(sourceFolder + "pdfWithUnencryptedAttachmentAnnotations.pdf"); + PdfDocument pdfDocument = createEncryptedDocument(reader, EncryptionConstants.STANDARD_ENCRYPTION_128, outFileName); + PdfFileSpec fs = PdfFileSpec.createEmbeddedFileSpec( + pdfDocument, "file".getBytes(), "description", "file.txt", null, null, null); + pdfDocument.addFileAttachment("new attachment", fs); + + pdfDocument.close(); + + Assert.assertNull(new CompareTool().compareByContent(outFileName, cmpFileName, destinationFolder, "diff", "password".getBytes(), "password".getBytes())); + } + + private PdfDocument createEncryptedDocument(int encryptionAlgorithm, String outFileName) throws IOException { + PdfWriter writer = new PdfWriter(outFileName, + new WriterProperties().setStandardEncryption( + "password".getBytes(), "password".getBytes(), 0, encryptionAlgorithm | EncryptionConstants.EMBEDDED_FILES_ONLY)); + // Setting compression level to zero doesn't affect the encryption at any level. + // We do it to simplify observation of the resultant PDF. + writer.setCompressionLevel(0); + return new PdfDocument(writer); + } + + private PdfDocument createEncryptedDocument(PdfReader reader, int encryptionAlgorithm, String outFileName) throws IOException { + PdfWriter writer = new PdfWriter(outFileName, + new WriterProperties().setStandardEncryption( + "password".getBytes(), "password".getBytes(), 0, encryptionAlgorithm | EncryptionConstants.EMBEDDED_FILES_ONLY)); + // Setting compression level to zero doesn't affect the encryption at any level. + // We do it to simplify observation of the resultant PDF. + writer.setCompressionLevel(0); + return new PdfDocument(reader, writer); + } +} diff --git a/kernel/src/test/java/com/itextpdf/kernel/pdf/MemoryLimitsAwareOutputStreamTest.java b/kernel/src/test/java/com/itextpdf/kernel/pdf/MemoryLimitsAwareOutputStreamTest.java index d218e8b524..e59bdf06ad 100644 --- a/kernel/src/test/java/com/itextpdf/kernel/pdf/MemoryLimitsAwareOutputStreamTest.java +++ b/kernel/src/test/java/com/itextpdf/kernel/pdf/MemoryLimitsAwareOutputStreamTest.java @@ -45,20 +45,14 @@ This file is part of the iText (R) project. import com.itextpdf.test.ExtendedITextTest; import com.itextpdf.test.annotations.type.UnitTest; import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(UnitTest.class) public class MemoryLimitsAwareOutputStreamTest extends ExtendedITextTest { - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void testMaxSize() { - junitExpectedException.expect(MemoryLimitsAwareException.class); byte[] bigArray = new byte[70]; byte[] smallArray = new byte[31]; @@ -68,28 +62,27 @@ public void testMaxSize() { Assert.assertEquals(100, stream.getMaxStreamSize()); stream.write(bigArray, 0, bigArray.length); - Assert.assertEquals(bigArray.length, stream.size()); - stream.write(smallArray, 0, smallArray.length); + Assert.assertEquals(bigArray.length, stream.size()); + Assert.assertThrows(MemoryLimitsAwareException.class, () -> stream.write(smallArray, 0, smallArray.length)); } @Test public void testNegativeSize() { - junitExpectedException.expect(MemoryLimitsAwareException.class); byte[] zeroArray = new byte[0]; MemoryLimitsAwareOutputStream stream = new MemoryLimitsAwareOutputStream(); stream.setMaxStreamSize(-100); - Assert.assertEquals(-100, stream.getMaxStreamSize()); - stream.write(zeroArray, 0, zeroArray.length); + Assert.assertEquals(-100, stream.getMaxStreamSize()); + Assert.assertThrows(MemoryLimitsAwareException.class, () -> stream.write(zeroArray, 0, zeroArray.length)); } @Test public void testIncorrectLength() { - junitExpectedException.expect(IndexOutOfBoundsException.class); MemoryLimitsAwareOutputStream stream = new MemoryLimitsAwareOutputStream(); - stream.write(new byte[1],0, -1); + + Assert.assertThrows(IndexOutOfBoundsException.class, () -> stream.write(new byte[1],0, -1)); } } diff --git a/kernel/src/test/java/com/itextpdf/kernel/pdf/PageFlushingTest.java b/kernel/src/test/java/com/itextpdf/kernel/pdf/PageFlushingTest.java index 173ca15833..df8df342ef 100644 --- a/kernel/src/test/java/com/itextpdf/kernel/pdf/PageFlushingTest.java +++ b/kernel/src/test/java/com/itextpdf/kernel/pdf/PageFlushingTest.java @@ -127,7 +127,7 @@ public void baseReading01() throws IOException { int total = 817; int flushedExpected = 0; // link annots, line annots, actions and images: one hundred of each - int notReadExpected = 401; + int notReadExpected = 402; test("baseReading01.pdf", DocMode.READING, FlushMode.NONE, PagesOp.READ, total, flushedExpected, notReadExpected); @@ -137,7 +137,7 @@ public void baseReading01() throws IOException { public void releaseDeepReading01() throws IOException { int total = 817; int flushedExpected = 0; - int notReadExpected = 803; + int notReadExpected = 804; test("releaseDeepReading01.pdf", DocMode.READING, FlushMode.RELEASE_DEEP, PagesOp.READ, total, flushedExpected, notReadExpected); diff --git a/kernel/src/test/java/com/itextpdf/kernel/pdf/PdfCopyTest.java b/kernel/src/test/java/com/itextpdf/kernel/pdf/PdfCopyTest.java index af0c61246b..16af0001f3 100644 --- a/kernel/src/test/java/com/itextpdf/kernel/pdf/PdfCopyTest.java +++ b/kernel/src/test/java/com/itextpdf/kernel/pdf/PdfCopyTest.java @@ -53,17 +53,14 @@ This file is part of the iText (R) project. import com.itextpdf.test.annotations.type.IntegrationTest; import java.io.ByteArrayInputStream; -import java.io.FileNotFoundException; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; @@ -73,9 +70,6 @@ public class PdfCopyTest extends ExtendedITextTest { public static final String destinationFolder = "./target/test/com/itextpdf/kernel/pdf/PdfCopyTest/"; public static final String sourceFolder = "./src/test/resources/com/itextpdf/kernel/pdf/PdfCopyTest/"; - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @BeforeClass public static void beforeClass() { createOrClearDestinationFolder(destinationFolder); @@ -381,10 +375,8 @@ public void copyDifferentRangesOfPagesWithBookmarksTest() throws IOException, In } @Test - // TODO DEVSIX-577. Update cmp, remove junitExpectedException after fix + // TODO DEVSIX-577. Update cmp public void copyPagesLinkAnnotationTest() throws IOException, InterruptedException { - junitExpectedException.expect(AssertionError.class); - String outFileName = destinationFolder + "copyPagesLinkAnnotationTest.pdf"; String cmpFileName = sourceFolder + "cmp_copyPagesLinkAnnotationTest.pdf"; PdfDocument targetPdf = new PdfDocument(new PdfWriter(outFileName)); @@ -397,7 +389,7 @@ public void copyPagesLinkAnnotationTest() throws IOException, InterruptedExcepti linkAnotPdf.copyPagesTo(1, 2, targetPdf); List annotations = getPdfAnnotations(targetPdf); - Assert.assertEquals("The number of merged annotations are not the same.", 1, annotations.size()); + Assert.assertEquals("The number of merged annotations are not the same.", 0, annotations.size()); linkAnotPdf.close(); targetPdf.close(); diff --git a/kernel/src/test/java/com/itextpdf/kernel/pdf/PdfDocumentIdTest.java b/kernel/src/test/java/com/itextpdf/kernel/pdf/PdfDocumentIdTest.java index 9566e8ce3c..3fffcc24c1 100644 --- a/kernel/src/test/java/com/itextpdf/kernel/pdf/PdfDocumentIdTest.java +++ b/kernel/src/test/java/com/itextpdf/kernel/pdf/PdfDocumentIdTest.java @@ -58,10 +58,8 @@ This file is part of the iText (R) project. import com.itextpdf.test.annotations.type.IntegrationTest; import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; /** * @author Michael Demey @@ -71,9 +69,6 @@ public class PdfDocumentIdTest extends ExtendedITextTest { public static final String sourceFolder = "./src/test/resources/com/itextpdf/kernel/pdf/PdfDocumentTestID/"; public static final String destinationFolder = "./target/test/com/itextpdf/kernel/pdf/PdfDocumentTestID/"; - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @BeforeClass public static void beforeClass() { createOrClearDestinationFolder(destinationFolder); @@ -386,9 +381,8 @@ public void readPdfWithNoIdAndConservativeReadingTest() throws IOException{ try (PdfReader reader = new PdfReader(sourceFolder + "pdfWithNoId.pdf") .setStrictnessLevel(StrictnessLevel.CONSERVATIVE)) { - junitExpectedException.expect(PdfException.class); - junitExpectedException.expectMessage(LogMessageConstant.DOCUMENT_IDS_ARE_CORRUPTED); - new PdfDocument(reader); + Exception e = Assert.assertThrows(PdfException.class, () -> new PdfDocument(reader)); + Assert.assertEquals(LogMessageConstant.DOCUMENT_IDS_ARE_CORRUPTED, e.getMessage()); } } diff --git a/kernel/src/test/java/com/itextpdf/kernel/pdf/PdfDocumentTest.java b/kernel/src/test/java/com/itextpdf/kernel/pdf/PdfDocumentTest.java index 361d2729ad..6d8d3810d8 100644 --- a/kernel/src/test/java/com/itextpdf/kernel/pdf/PdfDocumentTest.java +++ b/kernel/src/test/java/com/itextpdf/kernel/pdf/PdfDocumentTest.java @@ -74,10 +74,8 @@ This file is part of the iText (R) project. import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(IntegrationTest.class) public class PdfDocumentTest extends ExtendedITextTest { @@ -85,9 +83,6 @@ public class PdfDocumentTest extends ExtendedITextTest { public static final String SOURCE_FOLDER = "./src/test/resources/com/itextpdf/kernel/pdf/PdfDocumentTest/"; public static final String DESTINATION_FOLDER = "./target/test/com/itextpdf/kernel/pdf/PdfDocumentTest/"; - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @BeforeClass public static void beforeClass() { createOrClearDestinationFolder(DESTINATION_FOLDER); @@ -550,9 +545,10 @@ public void openDocumentWithInvalidCatalogVersionAndConservativeStrictnessReadin try (PdfReader reader = new PdfReader(SOURCE_FOLDER + "sample-with-invalid-catalog-version.pdf") .setStrictnessLevel(StrictnessLevel.CONSERVATIVE)) { - junitExpectedException.expect(PdfException.class); - junitExpectedException.expectMessage(LogMessageConstant.DOCUMENT_VERSION_IN_CATALOG_CORRUPTED); - new PdfDocument(reader); + Exception e = Assert.assertThrows(PdfException.class, + () -> new PdfDocument(reader) + ); + Assert.assertEquals(LogMessageConstant.DOCUMENT_VERSION_IN_CATALOG_CORRUPTED, e.getMessage()); } } diff --git a/kernel/src/test/java/com/itextpdf/kernel/pdf/PdfDocumentUnitTest.java b/kernel/src/test/java/com/itextpdf/kernel/pdf/PdfDocumentUnitTest.java index cf2a016ae1..d5c89af12c 100644 --- a/kernel/src/test/java/com/itextpdf/kernel/pdf/PdfDocumentUnitTest.java +++ b/kernel/src/test/java/com/itextpdf/kernel/pdf/PdfDocumentUnitTest.java @@ -46,6 +46,7 @@ This file is part of the iText (R) project. import com.itextpdf.io.LogMessageConstant; import com.itextpdf.io.font.AdobeGlyphList; import com.itextpdf.io.source.ByteArrayOutputStream; +import com.itextpdf.kernel.PdfException; import com.itextpdf.kernel.font.PdfType3Font; import com.itextpdf.kernel.pdf.layer.PdfLayer; import com.itextpdf.kernel.pdf.layer.PdfOCProperties; @@ -62,15 +63,12 @@ This file is part of the iText (R) project. import java.util.List; import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(UnitTest.class) public class PdfDocumentUnitTest extends ExtendedITextTest { - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); + public static final String sourceFolder = "./src/test/resources/com/itextpdf/kernel/pdf/PdfDocumentUnitTest/"; @Test @LogMessages(messages = { @@ -235,6 +233,94 @@ public void copyPagesFlushedResources() throws IOException { } } + @Test + public void pdfDocumentInstanceNoWriterInfoAndConformanceLevelInitialization() throws IOException { + PdfDocument pdfDocument = new PdfDocument(new PdfReader(sourceFolder + "pdfWithMetadata.pdf")); + + Assert.assertNull(pdfDocument.info); + Assert.assertNull(pdfDocument.reader.pdfAConformanceLevel); + + pdfDocument.close(); + + Assert.assertNull(pdfDocument.info); + Assert.assertNull(pdfDocument.reader.pdfAConformanceLevel); + } + + @Test + public void pdfDocumentInstanceWriterInfoAndConformanceLevelInitialization() throws IOException { + PdfDocument pdfDocument = new PdfDocument( + new PdfReader(sourceFolder + "pdfWithMetadata.pdf"), new PdfWriter(new ByteArrayOutputStream())); + + Assert.assertNotNull(pdfDocument.info); + Assert.assertNull(pdfDocument.reader.pdfAConformanceLevel); + + pdfDocument.close(); + + Assert.assertNotNull(pdfDocument.info); + Assert.assertNull(pdfDocument.reader.pdfAConformanceLevel); + } + + @Test + public void extendedPdfDocumentNoWriterInfoAndConformanceLevelInitialization() throws IOException { + PdfDocument pdfDocument = new PdfDocument(new PdfReader(sourceFolder + "pdfWithMetadata.pdf")) { + // This class instance extends pdfDocument + }; + + // TODO DEVSIX-5292 These fields shouldn't be initialized during the document's opening + Assert.assertNotNull(pdfDocument.info); + Assert.assertNotNull(pdfDocument.reader.pdfAConformanceLevel); + + pdfDocument.close(); + + Assert.assertNotNull(pdfDocument.info); + Assert.assertNotNull(pdfDocument.reader.pdfAConformanceLevel); + } + + @Test + public void extendedPdfDocumentWriterInfoAndConformanceLevelInitialization() throws IOException { + PdfDocument pdfDocument = new PdfDocument( + new PdfReader(sourceFolder + "pdfWithMetadata.pdf"), new PdfWriter(new ByteArrayOutputStream())) { + // This class instance extends pdfDocument + }; + + Assert.assertNotNull(pdfDocument.info); + // TODO DEVSIX-5292 pdfAConformanceLevel shouldn't be initialized during the document's opening + Assert.assertNotNull(pdfDocument.reader.pdfAConformanceLevel); + + pdfDocument.close(); + + Assert.assertNotNull(pdfDocument.info); + Assert.assertNotNull(pdfDocument.reader.pdfAConformanceLevel); + } + + @Test + public void getDocumentInfoAlreadyClosedTest() throws IOException { + PdfDocument pdfDocument = new PdfDocument(new PdfReader(sourceFolder + "pdfWithMetadata.pdf")); + pdfDocument.close(); + + Assert.assertThrows(PdfException.class, () -> pdfDocument.getDocumentInfo()); + } + + @Test + public void getDocumentInfoNotInitializedTest() throws IOException { + PdfDocument pdfDocument = new PdfDocument(new PdfReader(sourceFolder + "pdfWithMetadata.pdf")); + + Assert.assertNull(pdfDocument.info); + Assert.assertNotNull(pdfDocument.getDocumentInfo()); + + pdfDocument.close(); + } + + @Test + public void getPdfAConformanceLevelNotInitializedTest() throws IOException { + PdfDocument pdfDocument = new PdfDocument(new PdfReader(sourceFolder + "pdfWithMetadata.pdf")); + + Assert.assertNull(pdfDocument.reader.pdfAConformanceLevel); + Assert.assertNotNull(pdfDocument.reader.getPdfAConformanceLevel()); + + pdfDocument.close(); + } + private static void assertLayerNames(PdfDocument outDocument, List layerNames) { Assert.assertNotNull(outDocument.getCatalog()); PdfOCProperties ocProperties = outDocument.getCatalog().getOCProperties(true); diff --git a/kernel/src/test/java/com/itextpdf/kernel/pdf/PdfEncryptionUnitTest.java b/kernel/src/test/java/com/itextpdf/kernel/pdf/PdfEncryptionUnitTest.java new file mode 100644 index 0000000000..3b0916bd35 --- /dev/null +++ b/kernel/src/test/java/com/itextpdf/kernel/pdf/PdfEncryptionUnitTest.java @@ -0,0 +1,97 @@ +/* + This file is part of the iText (R) project. + Copyright (c) 1998-2021 iText Group NV + Authors: iText Software. + + This program is offered under a commercial and under the AGPL license. + For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below. + + AGPL licensing: + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + */ +package com.itextpdf.kernel.pdf; + +import com.itextpdf.test.ExtendedITextTest; +import com.itextpdf.test.annotations.type.UnitTest; +import org.junit.Assert; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +@Category(UnitTest.class) +public class PdfEncryptionUnitTest extends ExtendedITextTest { + @Test + public void readEncryptEmbeddedFilesOnlyFromPdfDocumentCorrectEntryTest() { + PdfDictionary cryptDictionary = new PdfDictionary(); + cryptDictionary.put(PdfName.EFF, PdfName.StdCF); + cryptDictionary.put(PdfName.StmF, PdfName.Identity); + cryptDictionary.put(PdfName.StrF, PdfName.Identity); + PdfDictionary cfDictionary = new PdfDictionary(); + cfDictionary.put(PdfName.StdCF, new PdfDictionary()); + cryptDictionary.put(PdfName.CF, cfDictionary); + + Assert.assertTrue(PdfEncryption.readEmbeddedFilesOnlyFromEncryptDictionary(cryptDictionary)); + } + + @Test + public void readEncryptEmbeddedFilesOnlyFromPdfDocumentIncorrectEffTest() { + PdfDictionary cryptDictionary = new PdfDictionary(); + cryptDictionary.put(PdfName.EFF, PdfName.Identity); + cryptDictionary.put(PdfName.StmF, PdfName.Identity); + cryptDictionary.put(PdfName.StrF, PdfName.Identity); + PdfDictionary cfDictionary = new PdfDictionary(); + cfDictionary.put(PdfName.StdCF, new PdfDictionary()); + cryptDictionary.put(PdfName.CF, cfDictionary); + + Assert.assertFalse(PdfEncryption.readEmbeddedFilesOnlyFromEncryptDictionary(cryptDictionary)); + } + + @Test + public void readEncryptEmbeddedFilesOnlyFromPdfDocumentIncorrectStmFTest() { + PdfDictionary cryptDictionary = new PdfDictionary(); + cryptDictionary.put(PdfName.EFF, PdfName.StdCF); + cryptDictionary.put(PdfName.StmF, PdfName.StdCF); + cryptDictionary.put(PdfName.StrF, PdfName.Identity); + PdfDictionary cfDictionary = new PdfDictionary(); + cfDictionary.put(PdfName.StdCF, new PdfDictionary()); + cryptDictionary.put(PdfName.CF, cfDictionary); + + Assert.assertFalse(PdfEncryption.readEmbeddedFilesOnlyFromEncryptDictionary(cryptDictionary)); + } + + @Test + public void readEncryptEmbeddedFilesOnlyFromPdfDocumentIncorrectStrFTest() { + PdfDictionary cryptDictionary = new PdfDictionary(); + cryptDictionary.put(PdfName.EFF, PdfName.StdCF); + cryptDictionary.put(PdfName.StmF, PdfName.Identity); + cryptDictionary.put(PdfName.StrF, PdfName.StdCF); + PdfDictionary cfDictionary = new PdfDictionary(); + cfDictionary.put(PdfName.StdCF, new PdfDictionary()); + cryptDictionary.put(PdfName.CF, cfDictionary); + + Assert.assertFalse(PdfEncryption.readEmbeddedFilesOnlyFromEncryptDictionary(cryptDictionary)); + } + + @Test + public void readEncryptEmbeddedFilesOnlyFromPdfDocumentIncorrectCfTest() { + PdfDictionary cryptDictionary = new PdfDictionary(); + cryptDictionary.put(PdfName.EFF, PdfName.StdCF); + cryptDictionary.put(PdfName.StmF, PdfName.Identity); + cryptDictionary.put(PdfName.StrF, PdfName.Identity); + PdfDictionary cfDictionary = new PdfDictionary(); + cfDictionary.put(PdfName.DefaultCryptFilter, new PdfDictionary()); + cryptDictionary.put(PdfName.CF, cfDictionary); + + Assert.assertFalse(PdfEncryption.readEmbeddedFilesOnlyFromEncryptDictionary(cryptDictionary)); + } +} diff --git a/forms/src/test/java/com/itextpdf/forms/xfa/XXEVulnerabilityTest.java b/kernel/src/test/java/com/itextpdf/kernel/pdf/PdfEncryptorTest.java similarity index 51% rename from forms/src/test/java/com/itextpdf/forms/xfa/XXEVulnerabilityTest.java rename to kernel/src/test/java/com/itextpdf/kernel/pdf/PdfEncryptorTest.java index d9389a6de2..16252e1837 100644 --- a/forms/src/test/java/com/itextpdf/forms/xfa/XXEVulnerabilityTest.java +++ b/kernel/src/test/java/com/itextpdf/kernel/pdf/PdfEncryptorTest.java @@ -40,17 +40,12 @@ This file is part of the iText (R) project. For more information, please contact iText Software Corp. at this address: sales@itextpdf.com */ -package com.itextpdf.forms.xfa; +package com.itextpdf.kernel.pdf; -import com.itextpdf.forms.PdfAcroForm; -import com.itextpdf.kernel.pdf.CompressionConstants; -import com.itextpdf.kernel.pdf.PdfDocument; -import com.itextpdf.kernel.pdf.PdfReader; -import com.itextpdf.kernel.pdf.PdfWriter; -import com.itextpdf.kernel.utils.CompareTool; import com.itextpdf.test.ExtendedITextTest; import com.itextpdf.test.annotations.type.IntegrationTest; +import java.io.FileOutputStream; import java.io.IOException; import org.junit.Assert; import org.junit.BeforeClass; @@ -58,47 +53,36 @@ This file is part of the iText (R) project. import org.junit.experimental.categories.Category; @Category(IntegrationTest.class) -public class XXEVulnerabilityTest extends ExtendedITextTest { +public class PdfEncryptorTest extends ExtendedITextTest { - public static final String sourceFolder = "./src/test/resources/com/itextpdf/forms/xfa/XXEVulnerabilityTest/"; - public static final String destinationFolder = "./target/test/com/itextpdf/forms/xfa/XXEVulnerabilityTest/"; + public static final String SOURCE_FOLDER = "./src/test/resources/com/itextpdf/kernel/pdf/PdfEncryptorTest/"; + public static final String DESTINATION_FOLDER = "./target/test/com/itextpdf/kernel/pdf/PdfEncryptorTest/"; - @BeforeClass - public static void initialize() { - createDestinationFolder(destinationFolder); - } - - @Test - public void xfaExternalFileTest() throws IOException, InterruptedException { - String inFileName = sourceFolder + "xfaExternalFile.pdf"; - String outFileName = destinationFolder + "outXfaExternalFile.pdf"; - String cmpFileName = sourceFolder + "cmp_outXfaExternalFile.pdf"; - try (PdfDocument pdfDoc = new PdfDocument(new PdfReader(inFileName), - new PdfWriter(outFileName).setCompressionLevel(CompressionConstants.NO_COMPRESSION))) { - PdfAcroForm form = PdfAcroForm.getAcroForm(pdfDoc, true); - // server fills out a field - form.getField("TestField").setValue("testvalue"); - form.getXfaForm().write(pdfDoc); - } - - Assert.assertNull(new CompareTool().compareByContent(outFileName, cmpFileName, destinationFolder)); + @BeforeClass + public static void beforeClass() { + createDestinationFolder(DESTINATION_FOLDER); } @Test - public void xfaExternalConnectionTest() throws IOException, InterruptedException { - String inFileName = sourceFolder + "xfaExternalConnection.pdf"; - String outFileName = destinationFolder + "outXfaExternalConnection.pdf"; - String cmpFileName = sourceFolder + "cmp_outXfaExternalConnection.pdf"; - - try (PdfDocument pdfDoc = new PdfDocument(new PdfReader(inFileName), - new PdfWriter(outFileName).setCompressionLevel(CompressionConstants.NO_COMPRESSION))) { - PdfAcroForm form = PdfAcroForm.getAcroForm(pdfDoc, true); - // server fills out a field - form.getField("TestField").setValue("testvalue"); - form.getXfaForm().write(pdfDoc); + public void encryptFileTest() throws IOException { + String outFileName = DESTINATION_FOLDER + "encryptFileTest.pdf"; + String initialFileName = SOURCE_FOLDER + "initial.pdf"; + PdfEncryptor encryptor = new PdfEncryptor(); + EncryptionProperties encryptionProperties = new EncryptionProperties(); + encryptionProperties.setStandardEncryption(new byte[16], new byte[16], 0, 0); + encryptor.setEncryptionProperties(encryptionProperties); + + try (PdfReader initialFile = new PdfReader(initialFileName); + FileOutputStream outputStream = new FileOutputStream(outFileName)) { + encryptor.encrypt(initialFile, outputStream); } - Assert.assertNull(new CompareTool().compareByContent(outFileName, cmpFileName, destinationFolder)); + ReaderProperties readerProperties = new ReaderProperties(); + readerProperties.setPassword(new byte[16]); + PdfReader outFile = new PdfReader(outFileName, readerProperties); + PdfDocument doc = new PdfDocument(outFile); + doc.close(); + Assert.assertTrue(outFile.isEncrypted()); } -} +} \ No newline at end of file diff --git a/kernel/src/test/java/com/itextpdf/kernel/pdf/PdfObjectReleaseTest.java b/kernel/src/test/java/com/itextpdf/kernel/pdf/PdfObjectReleaseTest.java index 5750c243ed..d55577e4eb 100644 --- a/kernel/src/test/java/com/itextpdf/kernel/pdf/PdfObjectReleaseTest.java +++ b/kernel/src/test/java/com/itextpdf/kernel/pdf/PdfObjectReleaseTest.java @@ -35,10 +35,8 @@ This file is part of the iText (R) project. import java.io.IOException; import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(IntegrationTest.class) public class PdfObjectReleaseTest extends ExtendedITextTest { @@ -51,9 +49,6 @@ public static void beforeClass() { createOrClearDestinationFolder(destinationFolder); } - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test @LogMessages(messages = @LogMessage(messageTemplate = LogMessageConstant.FORBID_RELEASE_IS_SET, count = 108)) public void releaseObjectsInDocWithStructTreeRootTest() throws IOException, InterruptedException { @@ -153,10 +148,11 @@ public void addingReleasedObjectToDocumentTest() throws IOException { doc.getCatalog().put(PdfName.Outlines, releasedObj); } finally { - junitExpectedException.expect(PdfException.class); - junitExpectedException.expectMessage("Cannot write object after it was released." - + " In normal situation the object must be read once again before being written."); - doc.close(); + Exception e = Assert.assertThrows(PdfException.class, + () -> doc.close() + ); + Assert.assertEquals("Cannot write object after it was released." + + " In normal situation the object must be read once again before being written.", e.getMessage()); } } diff --git a/kernel/src/test/java/com/itextpdf/kernel/pdf/PdfOutlineTest.java b/kernel/src/test/java/com/itextpdf/kernel/pdf/PdfOutlineTest.java index 7646f258e4..afdd1e081e 100644 --- a/kernel/src/test/java/com/itextpdf/kernel/pdf/PdfOutlineTest.java +++ b/kernel/src/test/java/com/itextpdf/kernel/pdf/PdfOutlineTest.java @@ -48,27 +48,20 @@ This file is part of the iText (R) project. import com.itextpdf.kernel.pdf.navigation.PdfStringDestination; import com.itextpdf.kernel.utils.CompareTool; import com.itextpdf.test.ExtendedITextTest; -import com.itextpdf.test.LogLevelConstants; import com.itextpdf.test.annotations.LogMessage; import com.itextpdf.test.annotations.LogMessages; import com.itextpdf.test.annotations.type.IntegrationTest; import org.xml.sax.SAXException; - import javax.xml.parsers.ParserConfigurationException; - import java.io.FileOutputStream; import java.io.IOException; - import java.util.ArrayList; import java.util.List; - import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(IntegrationTest.class) public class PdfOutlineTest extends ExtendedITextTest { @@ -76,9 +69,6 @@ public class PdfOutlineTest extends ExtendedITextTest { public static final String SOURCE_FOLDER = "./src/test/resources/com/itextpdf/kernel/pdf/PdfOutlineTest/"; public static final String DESTINATION_FOLDER = "./target/test/com/itextpdf/kernel/pdf/PdfOutlineTest/"; - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @BeforeClass public static void before() { createOrClearDestinationFolder(DESTINATION_FOLDER); @@ -226,12 +216,14 @@ public void updateOutlineTitle() throws IOException, InterruptedException { @Test public void getOutlinesInvalidParentLink() throws IOException, InterruptedException { - junitExpectedException.expect(NullPointerException.class); PdfReader reader = new PdfReader(SOURCE_FOLDER + "outlinesInvalidParentLink.pdf"); String filename = "updateOutlineTitleInvalidParentLink.pdf"; PdfWriter writer = new PdfWriter(DESTINATION_FOLDER + filename); PdfDocument pdfDoc = new PdfDocument(reader, writer); - PdfOutline outlines = pdfDoc.getOutlines(false); + + Assert.assertThrows(NullPointerException.class, + () -> pdfDoc.getOutlines(false) + ); } @Test diff --git a/kernel/src/test/java/com/itextpdf/kernel/pdf/PdfPagesTest.java b/kernel/src/test/java/com/itextpdf/kernel/pdf/PdfPagesTest.java index 5f6495d6a4..ea2019a926 100644 --- a/kernel/src/test/java/com/itextpdf/kernel/pdf/PdfPagesTest.java +++ b/kernel/src/test/java/com/itextpdf/kernel/pdf/PdfPagesTest.java @@ -60,10 +60,8 @@ This file is part of the iText (R) project. import com.itextpdf.test.annotations.type.IntegrationTest; import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -81,9 +79,6 @@ public class PdfPagesTest extends ExtendedITextTest { private static final PdfName PageNum = new PdfName("PageNum"); private static final PdfName PageNum5 = new PdfName("PageNum"); - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @BeforeClass public static void setup() { createDestinationFolder(destinationFolder); @@ -228,9 +223,10 @@ public void insertFlushedPageTest() { page.flush(); pdfDoc.removePage(page); - junitExpectedException.expect(PdfException.class); - junitExpectedException.expectMessage(PdfException.FlushedPageCannotBeAddedOrInserted); - pdfDoc.addPage(1, page); + Exception e = Assert.assertThrows(PdfException.class, + () -> pdfDoc.addPage(1, page) + ); + Assert.assertEquals(PdfException.FlushedPageCannotBeAddedOrInserted, e.getMessage()); } @Test @@ -244,9 +240,10 @@ public void addFlushedPageTest() { page.flush(); pdfDoc.removePage(page); - junitExpectedException.expect(PdfException.class); - junitExpectedException.expectMessage(PdfException.FlushedPageCannotBeAddedOrInserted); - pdfDoc.addPage(page); + Exception e = Assert.assertThrows(PdfException.class, + () -> pdfDoc.addPage(page) + ); + Assert.assertEquals(PdfException.FlushedPageCannotBeAddedOrInserted, e.getMessage()); } @Test @@ -284,9 +281,10 @@ public void removeFlushedPageFromTaggedDocument() { pdfDocument.addNewPage(); pdfDocument.getPage(1).flush(); - junitExpectedException.expect(PdfException.class); - junitExpectedException.expectMessage(PdfException.FLUSHED_PAGE_CANNOT_BE_REMOVED); - pdfDocument.removePage(1); + Exception e = Assert.assertThrows(PdfException.class, + () -> pdfDocument.removePage(1) + ); + Assert.assertEquals(PdfException.FLUSHED_PAGE_CANNOT_BE_REMOVED, e.getMessage()); } } @@ -297,9 +295,10 @@ public void removeFlushedPageFromDocumentWithAcroForm() { pdfDocument.addNewPage(); pdfDocument.getPage(1).flush(); - junitExpectedException.expect(PdfException.class); - junitExpectedException.expectMessage(PdfException.FLUSHED_PAGE_CANNOT_BE_REMOVED); - pdfDocument.removePage(1); + Exception e = Assert.assertThrows(PdfException.class, + () -> pdfDocument.removePage(1) + ); + Assert.assertEquals(PdfException.FLUSHED_PAGE_CANNOT_BE_REMOVED, e.getMessage()); } } @@ -555,10 +554,8 @@ public void pageGetMediaBoxNotEnoughArgumentsTest() throws IOException { PdfDocument pdfDoc = new PdfDocument(reader); PdfPage pageOne = pdfDoc.getPage(1); - junitExpectedException.expect(PdfException.class); - junitExpectedException - .expectMessage(MessageFormatUtil.format(PdfException.WRONGMEDIABOXSIZETOOFEWARGUMENTS, 3)); - pageOne.getPageSize(); + Exception e = Assert.assertThrows(PdfException.class, () -> pageOne.getPageSize()); + Assert.assertEquals(MessageFormatUtil.format(PdfException.WRONGMEDIABOXSIZETOOFEWARGUMENTS, 3), e.getMessage()); } @Test diff --git a/kernel/src/test/java/com/itextpdf/kernel/pdf/PdfReaderDecodeTest.java b/kernel/src/test/java/com/itextpdf/kernel/pdf/PdfReaderDecodeTest.java index aed4412d1d..6009fc3d9d 100644 --- a/kernel/src/test/java/com/itextpdf/kernel/pdf/PdfReaderDecodeTest.java +++ b/kernel/src/test/java/com/itextpdf/kernel/pdf/PdfReaderDecodeTest.java @@ -53,19 +53,14 @@ This file is part of the iText (R) project. import java.io.FileInputStream; import java.io.IOException; import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(IntegrationTest.class) public class PdfReaderDecodeTest extends ExtendedITextTest { public static final String sourceFolder = "./src/test/resources/com/itextpdf/kernel/pdf/PdfReaderDecodeTest/"; - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void noMemoryHandlerTest() throws IOException { try (PdfDocument pdfDocument = new PdfDocument(new PdfWriter(new ByteArrayOutputStream())); @@ -132,10 +127,6 @@ public void customMemoryHandlerSingleTest() throws IOException { MemoryLimitsAwareHandler handler = new MemoryLimitsAwareHandler(); handler.setMaxSizeOfSingleDecompressedPdfStream(1000); - junitExpectedException.expect(MemoryLimitsAwareException.class); - junitExpectedException - .expectMessage(PdfException.DuringDecompressionSingleStreamOccupiedMoreMemoryThanAllowed); - try (PdfDocument pdfDocument = new PdfDocument( new PdfReader(sourceFolder + "timing.pdf", new ReaderProperties().setMemoryLimitsAwareHandler(handler)), @@ -157,7 +148,10 @@ public void customMemoryHandlerSingleTest() throws IOException { array.add(PdfName.Fl); - PdfReader.decodeBytes(b, stream); + Exception e = Assert.assertThrows(MemoryLimitsAwareException.class, + () -> PdfReader.decodeBytes(b, stream) + ); + Assert.assertEquals(PdfException.DuringDecompressionSingleStreamOccupiedMoreMemoryThanAllowed, e.getMessage()); } } @@ -196,10 +190,6 @@ public void oneFilterCustomMemoryHandlerSingleTest() throws IOException { @LogMessage(messageTemplate = LogMessageConstant.XREF_ERROR_WHILE_READING_TABLE_WILL_BE_REBUILT) }) public void overriddenMemoryHandlerAllStreamsAreSuspiciousTest() throws IOException { - - junitExpectedException.expect(MemoryLimitsAwareException.class); - junitExpectedException.expectMessage(PdfException.DuringDecompressionSingleStreamOccupiedMoreMemoryThanAllowed); - MemoryLimitsAwareHandler handler = new MemoryLimitsAwareHandler() { @Override public boolean isMemoryLimitsAwarenessRequiredOnDecompression(PdfArray filters) { @@ -221,7 +211,10 @@ public boolean isMemoryLimitsAwarenessRequiredOnDecompression(PdfArray filters) array.add(PdfName.Fl); // Limit is reached, and the stream with one filter is considered to be suspicious - PdfReader.decodeBytes(b, stream); + Exception e = Assert.assertThrows(MemoryLimitsAwareException.class, + () -> PdfReader.decodeBytes(b, stream) + ); + Assert.assertEquals(PdfException.DuringDecompressionSingleStreamOccupiedMoreMemoryThanAllowed, e.getMessage()); } } @@ -284,10 +277,6 @@ public void customMemoryHandlerSumTest() throws IOException { MemoryLimitsAwareHandler handler = new MemoryLimitsAwareHandler(); handler.setMaxSizeOfDecompressedPdfStreamsSum(100000); - junitExpectedException.expect(MemoryLimitsAwareException.class); - junitExpectedException - .expectMessage(PdfException.DuringDecompressionMultipleStreamsInSumOccupiedMoreMemoryThanAllowed); - try (PdfDocument pdfDocument = new PdfDocument( new PdfReader(sourceFolder + "timing.pdf", new ReaderProperties().setMemoryLimitsAwareHandler(handler)), @@ -296,7 +285,10 @@ public void customMemoryHandlerSumTest() throws IOException { PdfStream stream = pdfDocument.getFirstPage().getContentStream(0); byte[] b = stream.getBytes(false); - PdfReader.decodeBytes(b, stream); + Exception e = Assert.assertThrows(MemoryLimitsAwareException.class, + () -> PdfReader.decodeBytes(b, stream) + ); + Assert.assertEquals(PdfException.DuringDecompressionMultipleStreamsInSumOccupiedMoreMemoryThanAllowed, e.getMessage()); } } @@ -309,16 +301,15 @@ public void pageSumTest() throws IOException { MemoryLimitsAwareHandler handler = new MemoryLimitsAwareHandler(); handler.setMaxSizeOfDecompressedPdfStreamsSum(1500000); - junitExpectedException.expect(MemoryLimitsAwareException.class); - junitExpectedException - .expectMessage(PdfException.DuringDecompressionMultipleStreamsInSumOccupiedMoreMemoryThanAllowed); - try (PdfDocument pdfDocument = new PdfDocument( new PdfReader(sourceFolder + "timing.pdf", new ReaderProperties().setMemoryLimitsAwareHandler(handler)), new PdfWriter(new ByteArrayOutputStream()))) { - pdfDocument.getFirstPage().getContentBytes(); + Exception e = Assert.assertThrows(MemoryLimitsAwareException.class, + () -> pdfDocument.getFirstPage().getContentBytes() + ); + Assert.assertEquals(PdfException.DuringDecompressionMultipleStreamsInSumOccupiedMoreMemoryThanAllowed, e.getMessage()); } } @@ -331,15 +322,15 @@ public void pageAsSingleStreamTest() throws IOException { MemoryLimitsAwareHandler handler = new MemoryLimitsAwareHandler(); handler.setMaxSizeOfSingleDecompressedPdfStream(1500000); - junitExpectedException.expect(MemoryLimitsAwareException.class); - junitExpectedException.expectMessage(PdfException.DuringDecompressionSingleStreamOccupiedMoreMemoryThanAllowed); - try (PdfDocument pdfDocument = new PdfDocument( new PdfReader(sourceFolder + "timing.pdf", new ReaderProperties().setMemoryLimitsAwareHandler(handler)), new PdfWriter(new ByteArrayOutputStream()))) { - pdfDocument.getFirstPage().getContentBytes(); + Exception e = Assert.assertThrows(MemoryLimitsAwareException.class, + () -> pdfDocument.getFirstPage().getContentBytes() + ); + Assert.assertEquals(PdfException.DuringDecompressionSingleStreamOccupiedMoreMemoryThanAllowed, e.getMessage()); } } } diff --git a/kernel/src/test/java/com/itextpdf/kernel/pdf/PdfReaderTest.java b/kernel/src/test/java/com/itextpdf/kernel/pdf/PdfReaderTest.java index 29c0b3d68a..710f103fcc 100644 --- a/kernel/src/test/java/com/itextpdf/kernel/pdf/PdfReaderTest.java +++ b/kernel/src/test/java/com/itextpdf/kernel/pdf/PdfReaderTest.java @@ -56,10 +56,8 @@ This file is part of the iText (R) project. import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Ignore; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; import java.io.File; import java.io.IOException; @@ -79,9 +77,6 @@ public class PdfReaderTest extends ExtendedITextTest { static final String creator = "iText 6"; static final String title = "Empty iText 6 Document"; - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @BeforeClass public static void beforeClass() { createDestinationFolder(destinationFolder); @@ -1674,14 +1669,15 @@ public void wrongStructureFlushingTest() throws IOException { @Test public void readerReuseTest() throws IOException { - junitExpectedException.expect(PdfException.class); - junitExpectedException.expectMessage(PdfException.PdfReaderHasBeenAlreadyUtilized); - String filename = sourceFolder + "hello.pdf"; PdfReader reader = new PdfReader(filename); PdfDocument pdfDoc1 = new PdfDocument(reader); - PdfDocument pdfDoc2 = new PdfDocument(reader); + + Exception e = Assert.assertThrows(PdfException.class, + () -> new PdfDocument(reader) + ); + Assert.assertEquals(PdfException.PdfReaderHasBeenAlreadyUtilized, e.getMessage()); } @Test @@ -1732,11 +1728,10 @@ private boolean objectTypeEqualTo(PdfObject object, PdfName type) { @Test public void hasRebuiltXrefPdfDocumentNotReadTest() throws IOException { - junitExpectedException.expect(PdfException.class); - junitExpectedException.expectMessage(PdfException.DocumentHasNotBeenReadYet); - PdfReader hasRebuiltXrefReader = pdfDocumentNotReadTestInit(); - hasRebuiltXrefReader.hasRebuiltXref(); + + Exception e = Assert.assertThrows(PdfException.class, () -> hasRebuiltXrefReader.hasRebuiltXref()); + Assert.assertEquals(PdfException.DocumentHasNotBeenReadYet, e.getMessage()); } @Test @@ -1756,11 +1751,10 @@ protected void readPdf() throws IOException { @Test public void hasHybridXrefPdfDocumentNotReadTest() throws IOException { - junitExpectedException.expect(PdfException.class); - junitExpectedException.expectMessage(PdfException.DocumentHasNotBeenReadYet); - PdfReader hasHybridXrefPdfReader = pdfDocumentNotReadTestInit(); - hasHybridXrefPdfReader.hasHybridXref(); + + Exception e = Assert.assertThrows(PdfException.class, () -> hasHybridXrefPdfReader.hasHybridXref()); + Assert.assertEquals(PdfException.DocumentHasNotBeenReadYet, e.getMessage()); } @Test @@ -1780,11 +1774,10 @@ protected void readPdf() throws IOException { @Test public void hasXrefStmPdfDocumentNotReadTest() throws IOException { - junitExpectedException.expect(PdfException.class); - junitExpectedException.expectMessage(PdfException.DocumentHasNotBeenReadYet); - PdfReader hasXrefStmReader = pdfDocumentNotReadTestInit(); - hasXrefStmReader.hasXrefStm(); + + Exception e = Assert.assertThrows(PdfException.class, () -> hasXrefStmReader.hasXrefStm()); + Assert.assertEquals(PdfException.DocumentHasNotBeenReadYet, e.getMessage()); } @Test @@ -1804,11 +1797,10 @@ protected void readPdf() throws IOException { @Test public void hasFixedXrefPdfDocumentNotReadTest() throws IOException { - junitExpectedException.expect(PdfException.class); - junitExpectedException.expectMessage(PdfException.DocumentHasNotBeenReadYet); - PdfReader hasFixedXrefReader = pdfDocumentNotReadTestInit(); - hasFixedXrefReader.hasFixedXref(); + + Exception e = Assert.assertThrows(PdfException.class, () -> hasFixedXrefReader.hasFixedXref()); + Assert.assertEquals(PdfException.DocumentHasNotBeenReadYet, e.getMessage()); } @Test @@ -1828,11 +1820,10 @@ protected void readPdf() throws IOException { @Test public void getLastXrefPdfDocumentNotReadTest() throws IOException { - junitExpectedException.expect(PdfException.class); - junitExpectedException.expectMessage(PdfException.DocumentHasNotBeenReadYet); - PdfReader getLastXrefReader = pdfDocumentNotReadTestInit(); - getLastXrefReader.getLastXref(); + + Exception e = Assert.assertThrows(PdfException.class, () -> getLastXrefReader.getLastXref()); + Assert.assertEquals(PdfException.DocumentHasNotBeenReadYet, e.getMessage()); } @Test @@ -1852,11 +1843,10 @@ protected void readPdf() throws IOException { @Test public void getPermissionsPdfDocumentNotReadTest() throws IOException { - junitExpectedException.expect(PdfException.class); - junitExpectedException.expectMessage(PdfException.DocumentHasNotBeenReadYet); - PdfReader getPermissionsReader = pdfDocumentNotReadTestInit(); - getPermissionsReader.getPermissions(); + + Exception e = Assert.assertThrows(PdfException.class, () -> getPermissionsReader.getPermissions()); + Assert.assertEquals(PdfException.DocumentHasNotBeenReadYet, e.getMessage()); } @Test @@ -1876,11 +1866,12 @@ protected void readPdf() throws IOException { @Test public void isOpenedWithFullPPdfDocumentNotReadTest() throws IOException { - junitExpectedException.expect(PdfException.class); - junitExpectedException.expectMessage(PdfException.DocumentHasNotBeenReadYet); - PdfReader isOpenedWithFullPReader = pdfDocumentNotReadTestInit(); - isOpenedWithFullPReader.isOpenedWithFullPermission(); + + Exception e = Assert.assertThrows(PdfException.class, + () -> isOpenedWithFullPReader.isOpenedWithFullPermission() + ); + Assert.assertEquals(PdfException.DocumentHasNotBeenReadYet, e.getMessage()); } @Test @@ -1900,11 +1891,10 @@ protected void readPdf() throws IOException { @Test public void getCryptoModePdfDocumentNotReadTest() throws IOException { - junitExpectedException.expect(PdfException.class); - junitExpectedException.expectMessage(PdfException.DocumentHasNotBeenReadYet); - PdfReader getCryptoModeReader = pdfDocumentNotReadTestInit(); - getCryptoModeReader.getCryptoMode(); + + Exception e = Assert.assertThrows(PdfException.class, () -> getCryptoModeReader.getCryptoMode()); + Assert.assertEquals(PdfException.DocumentHasNotBeenReadYet, e.getMessage()); } @Test @@ -1924,11 +1914,12 @@ protected void readPdf() throws IOException { @Test public void computeUserPasswordPdfDocumentNotReadTest() throws IOException { - junitExpectedException.expect(PdfException.class); - junitExpectedException.expectMessage(PdfException.DocumentHasNotBeenReadYet); - PdfReader computeUserPasswordReader = pdfDocumentNotReadTestInit(); - computeUserPasswordReader.computeUserPassword(); + + Exception e = Assert.assertThrows(PdfException.class, + () -> computeUserPasswordReader.computeUserPassword() + ); + Assert.assertEquals(PdfException.DocumentHasNotBeenReadYet, e.getMessage()); } @Test @@ -1948,11 +1939,10 @@ protected void readPdf() throws IOException { @Test public void getOriginalFileIdPdfDocumentNotReadTest() throws IOException { - junitExpectedException.expect(PdfException.class); - junitExpectedException.expectMessage(PdfException.DocumentHasNotBeenReadYet); - PdfReader getOriginalFileIdReader = pdfDocumentNotReadTestInit(); - getOriginalFileIdReader.getOriginalFileId(); + + Exception e = Assert.assertThrows(PdfException.class, () -> getOriginalFileIdReader.getOriginalFileId()); + Assert.assertEquals(PdfException.DocumentHasNotBeenReadYet, e.getMessage()); } @Test @@ -1972,11 +1962,10 @@ protected void readPdf() throws IOException { @Test public void getModifiedFileIdPdfDocumentNotReadTest() throws IOException { - junitExpectedException.expect(PdfException.class); - junitExpectedException.expectMessage(PdfException.DocumentHasNotBeenReadYet); - PdfReader getModifiedFileIdReader = pdfDocumentNotReadTestInit(); - getModifiedFileIdReader.getModifiedFileId(); + + Exception e = Assert.assertThrows(PdfException.class, () -> getModifiedFileIdReader.getModifiedFileId()); + Assert.assertEquals(PdfException.DocumentHasNotBeenReadYet, e.getMessage()); } @Test @@ -1996,11 +1985,10 @@ protected void readPdf() throws IOException { @Test public void isEncryptedPdfDocumentNotReadTest() throws IOException { - junitExpectedException.expect(PdfException.class); - junitExpectedException.expectMessage(PdfException.DocumentHasNotBeenReadYet); - PdfReader isEncryptedReader = pdfDocumentNotReadTestInit(); - isEncryptedReader.isEncrypted(); + + Exception e = Assert.assertThrows(PdfException.class, () -> isEncryptedReader.isEncrypted()); + Assert.assertEquals(PdfException.DocumentHasNotBeenReadYet, e.getMessage()); } @Test @@ -2031,10 +2019,8 @@ private PdfReader pdfDocumentNotReadTestInit() throws IOException { } private void readingNotCompletedTest(PdfReader reader) { - junitExpectedException.expect(PdfException.class); - junitExpectedException.expectMessage(PdfException.DocumentHasNotBeenReadYet); - - PdfDocument document = new PdfDocument(reader); + Exception e = Assert.assertThrows(PdfException.class, () -> new PdfDocument(reader)); + Assert.assertEquals(PdfException.DocumentHasNotBeenReadYet, e.getMessage()); } /** diff --git a/kernel/src/test/java/com/itextpdf/kernel/pdf/PdfStreamDecodeTest.java b/kernel/src/test/java/com/itextpdf/kernel/pdf/PdfStreamDecodeTest.java index 33941486d1..55ddf6d8d5 100644 --- a/kernel/src/test/java/com/itextpdf/kernel/pdf/PdfStreamDecodeTest.java +++ b/kernel/src/test/java/com/itextpdf/kernel/pdf/PdfStreamDecodeTest.java @@ -33,10 +33,8 @@ This file is part of the iText (R) project. import java.util.Arrays; import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(UnitTest.class) public class PdfStreamDecodeTest extends ExtendedITextTest { @@ -67,9 +65,6 @@ public class PdfStreamDecodeTest extends ExtendedITextTest { (byte) 0x16, (byte) 0xad }; - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test @LogMessages(messages = { @LogMessage(messageTemplate = KernelLogMessageConstant.DCTDECODE_FILTER_DECODING, logLevel = LogLevelConstants.INFO) @@ -86,11 +81,10 @@ public void testJBIG2DecodeFilter() { PdfStream pdfStream = new PdfStream(FLATE_DECODED_BYTES); pdfStream.put(PdfName.Filter, new PdfArray(Arrays.asList((PdfObject) PdfName.FlateDecode, (PdfObject) PdfName.JBIG2Decode))); - junitExpectedException.expect(PdfException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format( - PdfException.Filter1IsNotSupported, PdfName.JBIG2Decode)); - - pdfStream.getBytes(true); + Exception e = Assert.assertThrows(PdfException.class, + () -> pdfStream.getBytes(true) + ); + Assert.assertEquals(MessageFormatUtil.format(PdfException.Filter1IsNotSupported, PdfName.JBIG2Decode), e.getMessage()); } @Test diff --git a/kernel/src/test/java/com/itextpdf/kernel/pdf/PdfStreamTest.java b/kernel/src/test/java/com/itextpdf/kernel/pdf/PdfStreamTest.java index 6400d07d84..ecdb258f27 100644 --- a/kernel/src/test/java/com/itextpdf/kernel/pdf/PdfStreamTest.java +++ b/kernel/src/test/java/com/itextpdf/kernel/pdf/PdfStreamTest.java @@ -54,10 +54,8 @@ This file is part of the iText (R) project. import java.util.Collections; import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(IntegrationTest.class) public class PdfStreamTest extends ExtendedITextTest { @@ -65,9 +63,6 @@ public class PdfStreamTest extends ExtendedITextTest { public static final String sourceFolder = "./src/test/resources/com/itextpdf/kernel/pdf/PdfStreamTest/"; public static final String destinationFolder = "./target/test/com/itextpdf/kernel/pdf/PdfStreamTest/"; - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @BeforeClass public static void before() { createOrClearDestinationFolder(destinationFolder); @@ -146,19 +141,18 @@ public void indirectRefInFilterAndNoTaggedPdfTest() throws IOException { } @Test - // TODO DEVSIX-1193 remove junitExpectedException and expected NullPointerException after fix + // TODO DEVSIX-1193 remove NullPointerException after fix public void indirectFilterInCatalogTest() throws IOException { String inFile = sourceFolder + "indFilterInCatalog.pdf"; PdfDocument doc = new PdfDocument(new PdfReader(inFile), new PdfWriter(destinationFolder + "indFilterInCatalog.pdf")); - junitExpectedException.expect(NullPointerException.class); - doc.close(); + Assert.assertThrows(NullPointerException.class, () -> doc.close()); } @Test - // TODO DEVSIX-1193 remove junitExpectedException after fix + // TODO DEVSIX-1193 remove NullPointerException after fix public void indirectFilterFlushedBeforeStreamTest() throws IOException { String inFile = sourceFolder + "indFilterInCatalog.pdf"; String out = destinationFolder + "indirectFilterFlushedBeforeStreamTest.pdf"; @@ -170,12 +164,11 @@ public void indirectFilterFlushedBeforeStreamTest() throws IOException { PdfObject filterObject = pdfDoc.getPdfObject(6); filterObject.flush(); - junitExpectedException.expect(NullPointerException.class); - pdfDoc.close(); + Assert.assertThrows(NullPointerException.class, () -> pdfDoc.close()); } @Test - // TODO DEVSIX-1193 remove junitExpectedException after fix + // TODO DEVSIX-1193 remove NullPointerException after fix public void indirectFilterMarkedToBeFlushedBeforeStreamTest() throws IOException { String inFile = sourceFolder + "indFilterInCatalog.pdf"; String out = destinationFolder + "indirectFilterMarkedToBeFlushedBeforeStreamTest.pdf"; @@ -190,9 +183,9 @@ public void indirectFilterMarkedToBeFlushedBeforeStreamTest() throws IOException // The image stream will be marked as MUST_BE_FLUSHED after page is flushed. pdfDoc.getFirstPage().getPdfObject().getIndirectReference().setState(PdfObject.MUST_BE_FLUSHED); - junitExpectedException.expect(NullPointerException.class); - writer.flushWaitingObjects(Collections.emptySet()); - - pdfDoc.close(); + Assert.assertThrows(NullPointerException.class, + () -> writer.flushWaitingObjects(Collections.emptySet()) + ); + Assert.assertThrows(NullPointerException.class, () -> pdfDoc.close()); } } diff --git a/kernel/src/test/java/com/itextpdf/kernel/pdf/PdfXObjectTest.java b/kernel/src/test/java/com/itextpdf/kernel/pdf/PdfXObjectTest.java index 7a7fa3f86c..80d485ee18 100644 --- a/kernel/src/test/java/com/itextpdf/kernel/pdf/PdfXObjectTest.java +++ b/kernel/src/test/java/com/itextpdf/kernel/pdf/PdfXObjectTest.java @@ -61,7 +61,6 @@ This file is part of the iText (R) project. import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; @@ -72,16 +71,12 @@ This file is part of the iText (R) project. import java.util.ArrayList; import java.util.HashMap; import java.util.List; -import org.junit.rules.ExpectedException; @Category(IntegrationTest.class) public class PdfXObjectTest extends ExtendedITextTest{ public static final String SOURCE_FOLDER = "./src/test/resources/com/itextpdf/kernel/pdf/PdfXObjectTest/"; public static final String DESTINATION_FOLDER = "./target/test/com/itextpdf/kernel/pdf/PdfXObjectTest/"; - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - public static final String[] images = new String[]{SOURCE_FOLDER + "WP_20140410_001.bmp", SOURCE_FOLDER + "WP_20140410_001.JPC", SOURCE_FOLDER + "WP_20140410_001.jpg", @@ -309,10 +304,12 @@ public void calculateProportionallyFitRectangleWithWidthTest() throws IOExceptio @Test @Category(UnitTest.class) public void calculateProportionallyFitRectangleWithWidthForCustomXObjectTest() { - junitExpectedException.expect(IllegalArgumentException.class); - junitExpectedException.expectMessage("PdfFormXObject or PdfImageXObject expected."); PdfXObject pdfXObject = new CustomPdfXObject(new PdfStream()); - PdfXObject.calculateProportionallyFitRectangleWithWidth(pdfXObject, 0, 0, 20); + + Exception e = Assert.assertThrows(IllegalArgumentException.class, + () -> PdfXObject.calculateProportionallyFitRectangleWithWidth(pdfXObject, 0, 0, 20) + ); + Assert.assertEquals("PdfFormXObject or PdfImageXObject expected.", e.getMessage()); } @Test @@ -348,10 +345,12 @@ public void calculateProportionallyFitRectangleWithHeightTest() throws IOExcepti @Test @Category(UnitTest.class) public void calculateProportionallyFitRectangleWithHeightForCustomXObjectTest() { - junitExpectedException.expect(IllegalArgumentException.class); - junitExpectedException.expectMessage("PdfFormXObject or PdfImageXObject expected."); PdfXObject pdfXObject = new CustomPdfXObject(new PdfStream()); - PdfXObject.calculateProportionallyFitRectangleWithHeight(pdfXObject, 0, 0, 20); + + Exception e = Assert.assertThrows(IllegalArgumentException.class, + () -> PdfXObject.calculateProportionallyFitRectangleWithHeight(pdfXObject, 0, 0, 20) + ); + Assert.assertEquals("PdfFormXObject or PdfImageXObject expected.", e.getMessage()); } private static class CustomPdfXObject extends PdfXObject { diff --git a/kernel/src/test/java/com/itextpdf/kernel/pdf/action/PdfTargetTest.java b/kernel/src/test/java/com/itextpdf/kernel/pdf/action/PdfTargetTest.java index ba052c3156..06f88594e4 100644 --- a/kernel/src/test/java/com/itextpdf/kernel/pdf/action/PdfTargetTest.java +++ b/kernel/src/test/java/com/itextpdf/kernel/pdf/action/PdfTargetTest.java @@ -62,15 +62,11 @@ This file is part of the iText (R) project. import java.io.ByteArrayOutputStream; import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(UnitTest.class) public class PdfTargetTest extends ExtendedITextTest { - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); @Test public void createInstanceTest() { @@ -209,9 +205,6 @@ public void setAnnotationWhichIsMissedOnThePageTest() { @Test public void setAnnotationWithoutPageTest() { - junitExpectedException.expect(PdfException.class); - junitExpectedException.expectMessage(PdfException.AnnotationShallHaveReferenceToPage); - try (PdfDocument document = new PdfDocument(new PdfWriter(new ByteArrayOutputStream()))) { document.addNewPage(); @@ -219,7 +212,11 @@ public void setAnnotationWithoutPageTest() { new Rectangle(0,0, 20, 20)); PdfTarget target = PdfTarget.create(new PdfDictionary()); - target.setAnnotation(annotation, document); + + Exception e = Assert.assertThrows(PdfException.class, + () -> target.setAnnotation(annotation, document) + ); + Assert.assertEquals(PdfException.AnnotationShallHaveReferenceToPage, e.getMessage()); } } diff --git a/kernel/src/test/java/com/itextpdf/kernel/pdf/canvas/ImageMasksTest.java b/kernel/src/test/java/com/itextpdf/kernel/pdf/canvas/ImageMasksTest.java index 17f819c656..6f07448b18 100644 --- a/kernel/src/test/java/com/itextpdf/kernel/pdf/canvas/ImageMasksTest.java +++ b/kernel/src/test/java/com/itextpdf/kernel/pdf/canvas/ImageMasksTest.java @@ -58,19 +58,14 @@ This file is part of the iText (R) project. import java.io.IOException; import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(IntegrationTest.class) public class ImageMasksTest extends ExtendedITextTest { private static final String sourceFolder = "./src/test/resources/com/itextpdf/kernel/pdf/canvas/ImageMasksTest/"; private static final String destinationFolder = "./target/test/com/itextpdf/kernel/pdf/canvas/ImageMasksTest/"; - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @BeforeClass public static void beforeClass() { createOrClearDestinationFolder(destinationFolder); @@ -209,9 +204,10 @@ public void sMaskMatteDifferentSizeOfImgTest() throws IOException, InterruptedEx @Test public void imageWithInvalidMaskTest() throws IOException { ImageData mask = ImageDataFactory.create(sourceFolder + "mask.png"); - junitExpectedException.expect(com.itextpdf.io.IOException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format - (com.itextpdf.io.IOException.ThisImageCanNotBeAnImageMask)); - mask.makeMask(); + + Exception e = Assert.assertThrows(com.itextpdf.io.IOException.class, + () -> mask.makeMask() + ); + Assert.assertEquals(MessageFormatUtil.format(com.itextpdf.io.IOException.ThisImageCanNotBeAnImageMask), e.getMessage()); } } diff --git a/kernel/src/test/java/com/itextpdf/kernel/pdf/canvas/PdfCanvasColorTest.java b/kernel/src/test/java/com/itextpdf/kernel/pdf/canvas/PdfCanvasColorTest.java index b6995daabe..cba0e56c6f 100644 --- a/kernel/src/test/java/com/itextpdf/kernel/pdf/canvas/PdfCanvasColorTest.java +++ b/kernel/src/test/java/com/itextpdf/kernel/pdf/canvas/PdfCanvasColorTest.java @@ -85,19 +85,14 @@ This file is part of the iText (R) project. import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(IntegrationTest.class) public class PdfCanvasColorTest extends ExtendedITextTest { public static final String SOURCE_FOLDER = "./src/test/resources/com/itextpdf/kernel/pdf/canvas/PdfCanvasColorTest/"; public static final String DESTINATION_FOLDER = "./target/test/com/itextpdf/kernel/pdf/canvas/PdfCanvasColorTest/"; - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @BeforeClass public static void beforeClass() { createOrClearDestinationFolder(DESTINATION_FOLDER); @@ -616,27 +611,26 @@ public void patternColorUncoloredSetTwiceTest() throws Exception { @Test public void patternColorUncoloredPatternCsUnitTest() { - junitExpectedException.expect(IllegalArgumentException.class); - PdfDocument doc = new PdfDocument(new PdfWriter(new java.io.ByteArrayOutputStream())); PdfPattern.Tiling circle = new PdfPattern.Tiling(15, 15, 10, 20, false); new PdfPatternCanvas(circle, doc).circle(7.5f, 7.5f, 2.5f).fill().release(); - new PatternColor(circle, new PdfSpecialCs.Pattern(), new float[0]); + Assert.assertThrows(IllegalArgumentException.class, + () -> new PatternColor(circle, new PdfSpecialCs.Pattern(), new float[0]) + ); } @Test public void patternColorUncoloredPatternColorUnitTest() { - junitExpectedException.expect(IllegalArgumentException.class); - PdfDocument doc = new PdfDocument(new PdfWriter(new java.io.ByteArrayOutputStream())); PdfPattern.Tiling circle = new PdfPattern.Tiling(15, 15, 10, 20, false); new PdfPatternCanvas(circle, doc).circle(7.5f, 7.5f, 2.5f).fill().release(); PatternColor redCirclePattern = new PatternColor(circle, ColorConstants.RED); - new PatternColor(circle, redCirclePattern); + + Assert.assertThrows(IllegalArgumentException.class, () -> new PatternColor(circle, redCirclePattern)); } private static int countSubstringOccurrences(String str, String findStr) { diff --git a/kernel/src/test/java/com/itextpdf/kernel/pdf/canvas/PdfCanvasTest.java b/kernel/src/test/java/com/itextpdf/kernel/pdf/canvas/PdfCanvasTest.java index 28ebd47dc9..1bfe11bf14 100644 --- a/kernel/src/test/java/com/itextpdf/kernel/pdf/canvas/PdfCanvasTest.java +++ b/kernel/src/test/java/com/itextpdf/kernel/pdf/canvas/PdfCanvasTest.java @@ -42,7 +42,6 @@ This file is part of the iText (R) project. */ package com.itextpdf.kernel.pdf.canvas; -import com.itextpdf.io.LogMessageConstant; import com.itextpdf.io.font.constants.StandardFonts; import com.itextpdf.io.image.ImageData; import com.itextpdf.io.image.ImageDataFactory; @@ -51,8 +50,8 @@ This file is part of the iText (R) project. import com.itextpdf.io.util.StreamUtil; import com.itextpdf.io.util.UrlUtil; import com.itextpdf.kernel.PdfException; +import com.itextpdf.kernel.colors.ColorConstants; import com.itextpdf.kernel.font.PdfFontFactory; -import com.itextpdf.kernel.pdf.CompressionConstants; import com.itextpdf.kernel.pdf.PdfDictionary; import com.itextpdf.kernel.pdf.PdfDocument; import com.itextpdf.kernel.pdf.PdfName; @@ -60,20 +59,16 @@ This file is part of the iText (R) project. import com.itextpdf.kernel.pdf.PdfObject; import com.itextpdf.kernel.pdf.PdfPage; import com.itextpdf.kernel.pdf.PdfReader; -import com.itextpdf.kernel.pdf.PdfVersion; import com.itextpdf.kernel.pdf.PdfWriter; import com.itextpdf.kernel.pdf.WriterProperties; import com.itextpdf.kernel.pdf.canvas.wmf.WmfImageData; import com.itextpdf.kernel.pdf.extgstate.PdfExtGState; -import com.itextpdf.kernel.pdf.xobject.PdfImageXObject; import com.itextpdf.kernel.utils.CompareTool; import com.itextpdf.test.ExtendedITextTest; -import com.itextpdf.test.annotations.LogMessage; -import com.itextpdf.test.annotations.LogMessages; import com.itextpdf.test.annotations.type.IntegrationTest; + import java.awt.Toolkit; import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; @@ -81,7 +76,6 @@ This file is part of the iText (R) project. import java.util.List; import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Ignore; import org.junit.Test; import org.junit.experimental.categories.Category; @@ -106,7 +100,7 @@ public static void beforeClass() { } @Test - public void createSimpleCanvas() throws IOException, FileNotFoundException { + public void createSimpleCanvas() throws IOException { final String author = "Alexander Chingarev"; final String creator = "iText 6"; @@ -135,6 +129,38 @@ public void createSimpleCanvas() throws IOException, FileNotFoundException { reader.close(); } + @Test + public void canvasDrawArcsTest() throws IOException, InterruptedException { + String fileName = "canvasDrawArcsTest.pdf"; + String output = destinationFolder + fileName; + String cmp = sourceFolder + "cmp_" + fileName; + + try (PdfDocument doc = new PdfDocument(new PdfWriter(output))) { + PdfPage page = doc.addNewPage(); + PdfCanvas canvas = new PdfCanvas(page); + + canvas.setLineWidth(5); + + canvas.setStrokeColor(ColorConstants.BLUE); + canvas.moveTo(10, 300); + canvas.lineTo(50, 300); + canvas.arc(100, 550, 200, 600, 90, -135); + canvas.closePath(); + canvas.stroke(); + + canvas.setStrokeColor(ColorConstants.RED); + canvas.moveTo(210, 300); + canvas.lineTo(250, 300); + canvas.arcContinuous(300, 550, 400, 600, 90, -135); + canvas.closePath(); + canvas.stroke(); + + canvas.release(); + } + + Assert.assertNull(new CompareTool().compareByContent(output, cmp, destinationFolder, "diff_")); + } + @Test public void createSimpleCanvasWithDrawing() throws IOException { diff --git a/kernel/src/test/java/com/itextpdf/kernel/pdf/canvas/PdfCanvasXObjectTest.java b/kernel/src/test/java/com/itextpdf/kernel/pdf/canvas/PdfCanvasXObjectTest.java index 096b92dc8e..eb7d595ebc 100644 --- a/kernel/src/test/java/com/itextpdf/kernel/pdf/canvas/PdfCanvasXObjectTest.java +++ b/kernel/src/test/java/com/itextpdf/kernel/pdf/canvas/PdfCanvasXObjectTest.java @@ -65,19 +65,14 @@ This file is part of the iText (R) project. import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(IntegrationTest.class) public class PdfCanvasXObjectTest extends ExtendedITextTest { public static final String SOURCE_FOLDER = "./src/test/resources/com/itextpdf/kernel/pdf/canvas/PdfCanvasXObjectTest/"; public static final String DESTINATION_FOLDER = "./target/test/com/itextpdf/kernel/pdf/canvas/PdfCanvasXObjectTest/"; - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @BeforeClass public static void beforeClass() { createDestinationFolder(DESTINATION_FOLDER); @@ -154,11 +149,14 @@ public void addImageXObjectAtTest() throws IOException, InterruptedException { @Test @Category(UnitTest.class) public void addCustomXObjectAtTest() { - junitExpectedException.expect(IllegalArgumentException.class); - junitExpectedException.expectMessage("PdfFormXObject or PdfImageXObject expected."); PdfXObject pdfXObject = new CustomPdfXObject(new PdfStream()); PdfDocument document = new PdfDocument(new PdfWriter(new ByteArrayOutputStream())); - new PdfCanvas(document.addNewPage()).addXObjectAt(pdfXObject, 0, 0); + + PdfCanvas canvas = new PdfCanvas(document.addNewPage()); + Exception e = Assert.assertThrows(IllegalArgumentException.class, + () -> canvas.addXObjectAt(pdfXObject, 0, 0) + ); + Assert.assertEquals("PdfFormXObject or PdfImageXObject expected.", e.getMessage()); } // addXObjectFittedIntoRectangle(PdfXObject, Rectangle) test block (use PdfXObject#calculateProportionallyFitRectangleWithWidth) @@ -448,11 +446,14 @@ public void addFormXObjectRectangleLargerWithMatrixTest() throws IOException, I @Test @Category(UnitTest.class) public void addCustomXObjectFittedIntoRectangleTest() { - junitExpectedException.expect(IllegalArgumentException.class); - junitExpectedException.expectMessage("PdfFormXObject or PdfImageXObject expected."); PdfXObject pdfXObject = new CustomPdfXObject(new PdfStream()); PdfDocument document = new PdfDocument(new PdfWriter(new ByteArrayOutputStream())); - new PdfCanvas(document.addNewPage()).addXObjectFittedIntoRectangle(pdfXObject, new Rectangle(0, 0, 0, 0)); + + PdfCanvas pdfCanvas = new PdfCanvas(document.addNewPage()); + Exception e = Assert.assertThrows(IllegalArgumentException.class, + () -> pdfCanvas.addXObjectFittedIntoRectangle(pdfXObject, new Rectangle(0, 0, 0, 0)) + ); + Assert.assertEquals("PdfFormXObject or PdfImageXObject expected.", e.getMessage()); } // addXObject(PdfXObject) test block @@ -571,11 +572,14 @@ public void addImageXObjectWithTransformationMatrixTest() throws IOException, I @Test @Category(UnitTest.class) public void addCustomXObjectTest() { - junitExpectedException.expect(IllegalArgumentException.class); - junitExpectedException.expectMessage("PdfFormXObject or PdfImageXObject expected."); PdfXObject pdfXObject = new CustomPdfXObject(new PdfStream()); PdfDocument document = new PdfDocument(new PdfWriter(new ByteArrayOutputStream())); - new PdfCanvas(document.addNewPage()).addXObject(pdfXObject); + + PdfCanvas canvas = new PdfCanvas(document.addNewPage()); + Exception e = Assert.assertThrows(IllegalArgumentException.class, + () -> canvas.addXObject(pdfXObject) + ); + Assert.assertEquals("PdfFormXObject or PdfImageXObject expected.", e.getMessage()); } private static class CustomPdfXObject extends PdfXObject { diff --git a/kernel/src/test/java/com/itextpdf/kernel/pdf/canvas/parser/GlyphBboxCalculationTest.java b/kernel/src/test/java/com/itextpdf/kernel/pdf/canvas/parser/GlyphBboxCalculationTest.java index a56af9e998..9ac15b8477 100644 --- a/kernel/src/test/java/com/itextpdf/kernel/pdf/canvas/parser/GlyphBboxCalculationTest.java +++ b/kernel/src/test/java/com/itextpdf/kernel/pdf/canvas/parser/GlyphBboxCalculationTest.java @@ -22,7 +22,9 @@ This file is part of the iText (R) project. */ package com.itextpdf.kernel.pdf.canvas.parser; +import com.itextpdf.kernel.colors.ColorConstants; import com.itextpdf.kernel.geom.Rectangle; +import com.itextpdf.kernel.geom.Vector; import com.itextpdf.kernel.pdf.PdfDocument; import com.itextpdf.kernel.pdf.PdfPage; import com.itextpdf.kernel.pdf.PdfReader; @@ -30,10 +32,13 @@ This file is part of the iText (R) project. import com.itextpdf.kernel.pdf.canvas.PdfCanvas; import com.itextpdf.kernel.pdf.canvas.parser.data.IEventData; import com.itextpdf.kernel.pdf.canvas.parser.data.TextRenderInfo; +import com.itextpdf.kernel.pdf.canvas.parser.listener.IEventListener; import com.itextpdf.kernel.pdf.canvas.parser.listener.ITextExtractionStrategy; import com.itextpdf.kernel.utils.CompareTool; import com.itextpdf.test.ExtendedITextTest; import com.itextpdf.test.annotations.type.IntegrationTest; + +import java.util.ArrayList; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; @@ -110,6 +115,28 @@ public void type3FontsWithIdentityFontMatrixAndMultiplier() throws IOException, Assert.assertNull(new CompareTool().compareByContent(outputPdf, sourceFolder + "cmp_type3FontsWithIdentityFontMatrixAndMultiplier.pdf", destinationFolder, "diff_")); } + @Test + public void type3FontCustomFontMatrixAndFontBBoxTest() throws IOException { + String inputPdf = sourceFolder + "type3FontCustomFontMatrixAndFontBBox.pdf"; + + // Resultant rectangle is expected to be a bounding box over the text on the page. + Rectangle expectedRectangle = new Rectangle(10f, 97.84f, 14.400002f, 8.880005f); + List actualRectangles; + + try (PdfDocument pdfDoc = new PdfDocument(new PdfReader(inputPdf))) { + TextBBoxEventListener eventListener = new TextBBoxEventListener(); + PdfCanvasProcessor canvasProcessor = new PdfCanvasProcessor(eventListener); + + PdfPage page = pdfDoc.getPage(1); + canvasProcessor.processPageContent(page); + + actualRectangles = eventListener.getRectangles(); + } + + Assert.assertEquals(1, actualRectangles.size()); + Assert.assertTrue(expectedRectangle.equalsWithEpsilon(actualRectangles.get(0))); + } + private static class CharacterPositionEventListener implements ITextExtractionStrategy { float glyphWidth; TextRenderInfo firstTextRenderInfo; @@ -141,4 +168,31 @@ public Set getSupportedEvents() { } } + private static class TextBBoxEventListener implements IEventListener { + private final List rectangles = new ArrayList<>(); + + public List getRectangles() { + return rectangles; + } + + @Override + public void eventOccurred(IEventData data, EventType type) { + if (EventType.RENDER_TEXT.equals(type)) { + TextRenderInfo renderInfo = (TextRenderInfo) data; + Vector startPoint = renderInfo.getDescentLine().getStartPoint(); + Vector endPoint = renderInfo.getAscentLine().getEndPoint(); + float x1 = Math.min(startPoint.get(0), endPoint.get(0)); + float x2 = Math.max(startPoint.get(0), endPoint.get(0)); + float y1 = Math.min(startPoint.get(1), endPoint.get(1)); + float y2 = Math.max(startPoint.get(1), endPoint.get(1)); + rectangles.add(new Rectangle(x1, y1, x2 - x1, y2 - y1)); + } + } + + @Override + public Set getSupportedEvents() { + return null; + } + } + } diff --git a/kernel/src/test/java/com/itextpdf/kernel/pdf/canvas/parser/PdfCanvasProcessorIntegrationTest.java b/kernel/src/test/java/com/itextpdf/kernel/pdf/canvas/parser/PdfCanvasProcessorIntegrationTest.java index 4d04238e5a..1ec03d2f1c 100644 --- a/kernel/src/test/java/com/itextpdf/kernel/pdf/canvas/parser/PdfCanvasProcessorIntegrationTest.java +++ b/kernel/src/test/java/com/itextpdf/kernel/pdf/canvas/parser/PdfCanvasProcessorIntegrationTest.java @@ -58,6 +58,7 @@ This file is part of the iText (R) project. import com.itextpdf.kernel.pdf.canvas.parser.data.TextRenderInfo; import com.itextpdf.kernel.pdf.canvas.parser.listener.IEventListener; import com.itextpdf.kernel.pdf.canvas.parser.listener.LocationTextExtractionStrategy; +import com.itextpdf.kernel.pdf.canvas.parser.util.InlineImageParsingUtils.InlineImageParseException; import com.itextpdf.kernel.pdf.colorspace.PdfColorSpace; import com.itextpdf.kernel.pdf.colorspace.PdfSpecialCs; import com.itextpdf.test.AssertUtil; @@ -74,26 +75,28 @@ This file is part of the iText (R) project. import java.util.Map; import java.util.HashMap; import org.junit.Assert; +import org.junit.BeforeClass; import org.junit.Ignore; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; - import java.io.IOException; import java.util.Set; -import org.junit.rules.ExpectedException; @Category(IntegrationTest.class) public class PdfCanvasProcessorIntegrationTest extends ExtendedITextTest { - public static final String sourceFolder = "./src/test/resources/com/itextpdf/kernel/parser/PdfCanvasProcessorTest/"; + private static final String SOURCE_FOLDER = "./src/test/resources/com/itextpdf/kernel/parser/PdfCanvasProcessorTest/"; + + private static final String DESTINATION_FOLDER = "./target/test/com/itextpdf/kernel/parser/PdfCanvasProcessorTest/"; - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); + @BeforeClass + public static void setUp() { + createDestinationFolder(DESTINATION_FOLDER); + } @Test public void contentStreamProcessorTest() throws IOException { - PdfDocument document = new PdfDocument(new PdfReader(sourceFolder + "tableWithImageAndText.pdf"), new PdfWriter(new ByteArrayOutputStream())); + PdfDocument document = new PdfDocument(new PdfReader(SOURCE_FOLDER + "tableWithImageAndText.pdf"), new PdfWriter(new ByteArrayOutputStream())); StringBuilder pageEventsLog = new StringBuilder(); for (int i = 1; i <= document.getNumberOfPages(); ++i) { @@ -105,7 +108,7 @@ public void contentStreamProcessorTest() throws IOException { } - byte[] logBytes = Files.readAllBytes(Paths.get(sourceFolder + "contentStreamProcessorTest_events_log.dat")); + byte[] logBytes = Files.readAllBytes(Paths.get(SOURCE_FOLDER + "contentStreamProcessorTest_events_log.dat")); String expectedPageEventsLog = new String(logBytes, StandardCharsets.UTF_8); Assert.assertEquals(expectedPageEventsLog, pageEventsLog.toString()); @@ -113,7 +116,7 @@ public void contentStreamProcessorTest() throws IOException { @Test public void processGraphicsStateResourceOperatorFillOpacityTest() throws IOException { - PdfDocument document = new PdfDocument(new PdfReader(sourceFolder + "transparentText.pdf")); + PdfDocument document = new PdfDocument(new PdfReader(SOURCE_FOLDER + "transparentText.pdf")); Float expOpacity = 0.5f; Map textRenderInfo = new HashMap<>(); @@ -127,7 +130,7 @@ public void processGraphicsStateResourceOperatorFillOpacityTest() throws IOExcep @Test public void processGraphicsStateResourceOperatorStrokeOpacityTest() throws IOException { - PdfDocument document = new PdfDocument(new PdfReader(sourceFolder + "hiddenText.pdf")); + PdfDocument document = new PdfDocument(new PdfReader(SOURCE_FOLDER + "hiddenText.pdf")); Float expOpacity = 0.0f; Map textRenderInfo = new HashMap<>(); @@ -142,7 +145,7 @@ public void processGraphicsStateResourceOperatorStrokeOpacityTest() throws IOExc @Test public void testClosingEmptyPath() throws IOException { String fileName = "closingEmptyPath.pdf"; - PdfDocument document = new PdfDocument(new PdfReader(sourceFolder + fileName)); + PdfDocument document = new PdfDocument(new PdfReader(SOURCE_FOLDER + fileName)); PdfCanvasProcessor processor = new PdfCanvasProcessor(new NoOpEventListener()); // Assert than no exception is thrown when an empty path is handled AssertUtil.doesNotThrow(() -> processor.processPageContent(document.getPage(1))); @@ -152,7 +155,7 @@ public void testClosingEmptyPath() throws IOException { @LogMessages(messages = @LogMessage(messageTemplate = LogMessageConstant.FAILED_TO_PROCESS_A_TRANSFORMATION_MATRIX, count = 1)) public void testNoninvertibleMatrix() throws IOException { String fileName = "noninvertibleMatrix.pdf"; - PdfDocument pdfDocument = new PdfDocument(new PdfReader(sourceFolder + fileName)); + PdfDocument pdfDocument = new PdfDocument(new PdfReader(SOURCE_FOLDER + fileName)); LocationTextExtractionStrategy strategy = new LocationTextExtractionStrategy(); PdfCanvasProcessor processor = new PdfCanvasProcessor(strategy); @@ -168,23 +171,20 @@ public void testNoninvertibleMatrix() throws IOException { @Test @Ignore("DEVSIX-3608: this test currently throws StackOverflowError, which cannot be caught in .NET") public void parseCircularReferencesInResourcesTest() throws IOException { - junitExpectedException.expect(StackOverflowError.class); - String fileName = "circularReferencesInResources.pdf"; - PdfDocument pdfDocument = new PdfDocument(new PdfReader(sourceFolder + fileName)); - - PdfCanvasProcessor processor = new PdfCanvasProcessor(new NoOpEventListener()); - PdfPage page = pdfDocument.getFirstPage(); + try (PdfDocument pdfDocument = new PdfDocument(new PdfReader(SOURCE_FOLDER + fileName))) { - processor.processPageContent(page); + PdfCanvasProcessor processor = new PdfCanvasProcessor(new NoOpEventListener()); + PdfPage page = pdfDocument.getFirstPage(); - pdfDocument.close(); + Assert.assertThrows(StackOverflowError.class, () -> processor.processPageContent(page)); + } } @Test @LogMessages(messages = @LogMessage(messageTemplate = KernelLogMessageConstant.UNABLE_TO_PARSE_COLOR_WITHIN_COLORSPACE)) public void patternColorParsingNotValidPdfTest() throws IOException { - String inputFile = sourceFolder + "patternColorParsingNotValidPdfTest.pdf"; + String inputFile = SOURCE_FOLDER + "patternColorParsingNotValidPdfTest.pdf"; PdfDocument pdfDocument = new PdfDocument(new PdfReader(inputFile)); for (int i = 1; i <= pdfDocument.getNumberOfPages(); ++i) { @@ -203,7 +203,7 @@ public void patternColorParsingNotValidPdfTest() throws IOException { @Test public void patternColorParsingValidPdfTest() throws IOException { - String inputFile = sourceFolder + "patternColorParsingValidPdfTest.pdf"; + String inputFile = SOURCE_FOLDER + "patternColorParsingValidPdfTest.pdf"; PdfDocument pdfDocument = new PdfDocument(new PdfReader(inputFile)); for (int i = 1; i <= pdfDocument.getNumberOfPages(); ++i) { diff --git a/kernel/src/test/java/com/itextpdf/kernel/pdf/canvas/parser/PdfContentExtractionTest.java b/kernel/src/test/java/com/itextpdf/kernel/pdf/canvas/parser/PdfContentExtractionTest.java index 3aa39ec548..2369006d18 100644 --- a/kernel/src/test/java/com/itextpdf/kernel/pdf/canvas/parser/PdfContentExtractionTest.java +++ b/kernel/src/test/java/com/itextpdf/kernel/pdf/canvas/parser/PdfContentExtractionTest.java @@ -31,25 +31,18 @@ This file is part of the iText (R) project. import com.itextpdf.test.annotations.type.IntegrationTest; import java.io.IOException; -import org.junit.Rule; +import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(IntegrationTest.class) public class PdfContentExtractionTest extends ExtendedITextTest { - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - private static final String sourceFolder = "./src/test/resources/com/itextpdf/kernel/parser/PdfContentExtractionTest/"; @Test //TODO: remove the expected exception construct once the issue is fixed (DEVSIX-1279) public void contentExtractionInDocWithBigCoordinatesTest() throws IOException { - junitExpectedException.expect(ClipperException.class); - junitExpectedException.expectMessage(ClipperExceptionConstant.COORDINATE_OUTSIDE_ALLOWED_RANGE); - String inputFileName = sourceFolder + "docWithBigCoordinates.pdf"; //In this document the CTM shrinks coordinates and this coordinates are large numbers. // At the moment creation of this test clipper has a problem with handling large numbers @@ -58,6 +51,10 @@ public void contentExtractionInDocWithBigCoordinatesTest() throws IOException { PdfDocument pdfDocument = new PdfDocument(new PdfReader(inputFileName)); PdfDocumentContentParser contentParser = new PdfDocumentContentParser(pdfDocument); - contentParser.processContent(1, new LocationTextExtractionStrategy()); + + Exception e = Assert.assertThrows(ClipperException.class, + () -> contentParser.processContent(1, new LocationTextExtractionStrategy()) + ); + Assert.assertEquals(ClipperExceptionConstant.COORDINATE_OUTSIDE_ALLOWED_RANGE, e.getMessage()); } } diff --git a/kernel/src/test/java/com/itextpdf/kernel/pdf/canvas/parser/clipper/PolyNodeTest.java b/kernel/src/test/java/com/itextpdf/kernel/pdf/canvas/parser/clipper/PolyNodeTest.java index e4b4a6888e..15ee4f5640 100644 --- a/kernel/src/test/java/com/itextpdf/kernel/pdf/canvas/parser/clipper/PolyNodeTest.java +++ b/kernel/src/test/java/com/itextpdf/kernel/pdf/canvas/parser/clipper/PolyNodeTest.java @@ -49,17 +49,12 @@ This file is part of the iText (R) project. import java.util.List; import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(UnitTest.class) public class PolyNodeTest extends ExtendedITextTest { - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void addAndGetChildTest() { PolyNode node = new PolyNode(); @@ -73,11 +68,11 @@ public void addAndGetChildTest() { @Test public void unmodifiableListOfChildsTest() { - junitExpectedException.expect(UnsupportedOperationException.class); PolyNode node = new PolyNode(); List childs = node.getChilds(); - childs.add(new PolyNode()); + + Assert.assertThrows(UnsupportedOperationException.class, () -> childs.add(new PolyNode())); } @Test diff --git a/kernel/src/test/java/com/itextpdf/kernel/pdf/canvas/parser/util/InlineImageParsingUtilsTest.java b/kernel/src/test/java/com/itextpdf/kernel/pdf/canvas/parser/util/InlineImageParsingUtilsTest.java new file mode 100644 index 0000000000..29d352b66c --- /dev/null +++ b/kernel/src/test/java/com/itextpdf/kernel/pdf/canvas/parser/util/InlineImageParsingUtilsTest.java @@ -0,0 +1,154 @@ +/* + This file is part of the iText (R) project. + Copyright (c) 1998-2021 iText Group NV + Authors: Bruno Lowagie, Paulo Soares, et al. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License version 3 + as published by the Free Software Foundation with the addition of the + following permission added to Section 15 as permitted in Section 7(a): + FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY + ITEXT GROUP. ITEXT GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT + OF THIRD PARTY RIGHTS + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Affero General Public License for more details. + You should have received a copy of the GNU Affero General Public License + along with this program; if not, see http://www.gnu.org/licenses or write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA, 02110-1301 USA, or download the license from the following URL: + http://itextpdf.com/terms-of-use/ + + The interactive user interfaces in modified source and object code versions + of this program must display Appropriate Legal Notices, as required under + Section 5 of the GNU Affero General Public License. + + In accordance with Section 7(b) of the GNU Affero General Public License, + a covered work must retain the producer line in every PDF that is created + or manipulated using iText. + + You can be released from the requirements of the license by purchasing + a commercial license. Buying such a license is mandatory as soon as you + develop commercial activities involving the iText software without + disclosing the source code of your own applications. + These activities include: offering paid services to customers as an ASP, + serving PDFs on the fly in a web application, shipping iText with a closed + source product. + + For more information, please contact iText Software Corp. at this + address: sales@itextpdf.com + */ +package com.itextpdf.kernel.pdf.canvas.parser.util; + +import com.itextpdf.io.util.MessageFormatUtil; +import com.itextpdf.kernel.PdfException; +import com.itextpdf.kernel.pdf.PdfArray; +import com.itextpdf.kernel.pdf.PdfDictionary; +import com.itextpdf.kernel.pdf.PdfName; +import com.itextpdf.kernel.pdf.PdfNumber; +import com.itextpdf.kernel.pdf.PdfStream; +import com.itextpdf.kernel.pdf.canvas.parser.util.InlineImageParsingUtils.InlineImageParseException; +import com.itextpdf.test.ExtendedITextTest; +import com.itextpdf.test.annotations.type.UnitTest; + +import org.junit.Assert; +import org.junit.Rule; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.junit.rules.ExpectedException; + +@Category(UnitTest.class) +public class InlineImageParsingUtilsTest extends ExtendedITextTest { + @Rule + public ExpectedException junitExpectedException = ExpectedException.none(); + + @Test + public void iccBasedCsTest() { + PdfName colorSpace = PdfName.ICCBased; + + PdfDictionary dictionary = new PdfDictionary(); + PdfArray array = new PdfArray(); + array.add(colorSpace); + PdfStream stream = new PdfStream(); + stream.put(PdfName.N, new PdfNumber(4)); + array.add(stream); + dictionary.put(colorSpace, array); + + Assert.assertEquals(4, InlineImageParsingUtils.getComponentsPerPixel(colorSpace, dictionary)); + } + + @Test + public void indexedCsTest() { + PdfName colorSpace = PdfName.Indexed; + + PdfDictionary dictionary = new PdfDictionary(); + PdfArray array = new PdfArray(); + array.add(colorSpace); + dictionary.put(colorSpace, array); + + Assert.assertEquals(1, InlineImageParsingUtils.getComponentsPerPixel(colorSpace, dictionary)); + } + + @Test + public void csInDictAsNameTest() { + PdfName colorSpace = PdfName.ICCBased; + + PdfDictionary dictionary = new PdfDictionary(); + dictionary.put(colorSpace, PdfName.DeviceCMYK); + + Assert.assertEquals(4, InlineImageParsingUtils.getComponentsPerPixel(colorSpace, dictionary)); + } + + @Test + public void csInDictAsNameNullTest() { + PdfName colorSpace = PdfName.ICCBased; + + PdfDictionary dictionary = new PdfDictionary(); + + junitExpectedException.expect(InlineImageParseException.class); + junitExpectedException.expectMessage(MessageFormatUtil.format(PdfException.UnexpectedColorSpace1, "/ICCBased")); + InlineImageParsingUtils.getComponentsPerPixel(colorSpace, dictionary); + } + + @Test + public void notSupportedCsWithCsDictionaryTest() { + PdfName colorSpace = PdfName.ICCBased; + + PdfDictionary dictionary = new PdfDictionary(); + PdfArray array = new PdfArray(); + array.add(PdfName.Pattern); + PdfStream stream = new PdfStream(); + stream.put(PdfName.N, new PdfNumber(4)); + array.add(stream); + dictionary.put(colorSpace, array); + + junitExpectedException.expect(InlineImageParseException.class); + junitExpectedException.expectMessage(MessageFormatUtil.format(PdfException.UnexpectedColorSpace1, "/ICCBased")); + InlineImageParsingUtils.getComponentsPerPixel(colorSpace, dictionary); + } + + @Test + public void nullCsTest() { + Assert.assertEquals(1, InlineImageParsingUtils.getComponentsPerPixel(null, null)); + } + + @Test + public void deviceGrayCsTest() { + PdfName colorSpace = PdfName.DeviceGray; + Assert.assertEquals(1, InlineImageParsingUtils.getComponentsPerPixel(colorSpace, null)); + } + + @Test + public void deviceRGBCsTest() { + PdfName colorSpace = PdfName.DeviceRGB; + Assert.assertEquals(3, InlineImageParsingUtils.getComponentsPerPixel(colorSpace, null)); + } + + @Test + public void deviceCMYKCsTest() { + PdfName colorSpace = PdfName.DeviceCMYK; + Assert.assertEquals(4, InlineImageParsingUtils.getComponentsPerPixel(colorSpace, null)); + } +} diff --git a/kernel/src/test/java/com/itextpdf/kernel/pdf/collection/PdfCollectionFieldTest.java b/kernel/src/test/java/com/itextpdf/kernel/pdf/collection/PdfCollectionFieldTest.java index adff107397..6e920e0f3b 100644 --- a/kernel/src/test/java/com/itextpdf/kernel/pdf/collection/PdfCollectionFieldTest.java +++ b/kernel/src/test/java/com/itextpdf/kernel/pdf/collection/PdfCollectionFieldTest.java @@ -49,21 +49,19 @@ This file is part of the iText (R) project. import com.itextpdf.kernel.pdf.PdfName; import com.itextpdf.kernel.pdf.PdfNumber; import com.itextpdf.kernel.pdf.PdfString; +import com.itextpdf.kernel.pdf.canvas.parser.clipper.ClipperException; +import com.itextpdf.kernel.pdf.canvas.parser.clipper.ClipperExceptionConstant; +import com.itextpdf.kernel.pdf.canvas.parser.listener.LocationTextExtractionStrategy; import com.itextpdf.test.ExtendedITextTest; import com.itextpdf.test.annotations.type.UnitTest; import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(UnitTest.class) public class PdfCollectionFieldTest extends ExtendedITextTest { - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - private static final PdfName[] ALLOWED_PDF_NAMES = { PdfName.D, PdfName.N, @@ -212,15 +210,13 @@ public void getUnsupportedTypeValueTest() { final String stringValue = "string value"; final String fieldName = "fieldName"; - junitExpectedException.expect(PdfException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(PdfException._1IsNotAnAcceptableValueForTheField2, - stringValue, fieldName)); - PdfCollectionField field = new PdfCollectionField(fieldName, PdfCollectionField.FILENAME); // this line will throw an exception as getValue() method is not // supported for subType which differs from S, N and D. - field.getValue(stringValue); + Exception e = Assert.assertThrows(PdfException.class, () -> field.getValue(stringValue)); + Assert.assertEquals(MessageFormatUtil.format(PdfException._1IsNotAnAcceptableValueForTheField2, + stringValue, fieldName), e.getMessage()); } @Test diff --git a/kernel/src/test/java/com/itextpdf/kernel/pdf/collection/PdfCollectionItemTest.java b/kernel/src/test/java/com/itextpdf/kernel/pdf/collection/PdfCollectionItemTest.java index ac0a9f72db..5fd90939ea 100644 --- a/kernel/src/test/java/com/itextpdf/kernel/pdf/collection/PdfCollectionItemTest.java +++ b/kernel/src/test/java/com/itextpdf/kernel/pdf/collection/PdfCollectionItemTest.java @@ -51,19 +51,13 @@ This file is part of the iText (R) project. import com.itextpdf.test.ExtendedITextTest; import com.itextpdf.test.annotations.type.UnitTest; -import java.util.TimeZone; import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(UnitTest.class) public class PdfCollectionItemTest extends ExtendedITextTest { - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void addItemTest() { final String fieldName = "fieldName"; @@ -188,8 +182,6 @@ public void addPrefixTest() { @Test public void addPrefixToEmptyFieldTest() { - junitExpectedException.expect(PdfException.class); - junitExpectedException.expectMessage(PdfException.YouMustSetAValueBeforeAddingAPrefix); final String fieldName = "fieldName"; final String fieldPrefix = "fieldPrefix"; @@ -205,7 +197,10 @@ public void addPrefixToEmptyFieldTest() { // this line will throw an exception as setPrefix() method may be called // only if value was set previously - item.setPrefix(fieldName, fieldPrefix); + Exception e = Assert.assertThrows(PdfException.class, + () -> item.setPrefix(fieldName, fieldPrefix) + ); + Assert.assertEquals(PdfException.YouMustSetAValueBeforeAddingAPrefix, e.getMessage()); } @Test diff --git a/kernel/src/test/java/com/itextpdf/kernel/pdf/collection/PdfCollectionSortTest.java b/kernel/src/test/java/com/itextpdf/kernel/pdf/collection/PdfCollectionSortTest.java index 5be32c10be..557fc0c5ce 100644 --- a/kernel/src/test/java/com/itextpdf/kernel/pdf/collection/PdfCollectionSortTest.java +++ b/kernel/src/test/java/com/itextpdf/kernel/pdf/collection/PdfCollectionSortTest.java @@ -48,15 +48,11 @@ This file is part of the iText (R) project. import com.itextpdf.test.annotations.type.UnitTest; import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(UnitTest.class) public class PdfCollectionSortTest extends ExtendedITextTest { - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); @Test public void oneKeyConstructorTest() { @@ -91,19 +87,17 @@ public void sortOrderForOneKeyTest() { @Test public void incorrectSortOrderForOneKeyTest() { - junitExpectedException.expect(PdfException.class); - junitExpectedException.expectMessage(PdfException.YouNeedASingleBooleanForThisCollectionSortDictionary); - final String key = "testKey"; final boolean[] testAscendings = {true, false}; PdfCollectionSort sort = new PdfCollectionSort(key); - sort.setSortOrder(testAscendings); - // this line will throw an exception as number of parameters of setSortOrder() // method should be exactly the same as number of keys of PdfCollectionSort // here we have one key but two params - Assert.assertTrue(sort.getPdfObject().getAsBool(PdfName.A)); + Exception e = Assert.assertThrows(PdfException.class, + () -> sort.setSortOrder(testAscendings) + ); + Assert.assertEquals(PdfException.YouNeedASingleBooleanForThisCollectionSortDictionary, e.getMessage()); } @Test @@ -122,9 +116,6 @@ public void sortOrderForMultipleKeysTest() { @Test public void singleSortOrderForMultipleKeysTest() { - junitExpectedException.expect(PdfException.class); - junitExpectedException.expectMessage(PdfException.YouHaveToDefineABooleanArrayForThisCollectionSortDictionary); - final String[] keys = { "testKey1", "testKey2", "testKey3"}; final boolean testAscending = true; @@ -133,14 +124,14 @@ public void singleSortOrderForMultipleKeysTest() { // this line will throw an exception as number of parameters of setSortOrder() // method should be exactly the same as number of keys of PdfCollectionSort // here we have three keys but one param - sort.setSortOrder(testAscending); + Exception e = Assert.assertThrows(PdfException.class, + () -> sort.setSortOrder(testAscending) + ); + Assert.assertEquals(PdfException.YouHaveToDefineABooleanArrayForThisCollectionSortDictionary, e.getMessage()); } @Test public void incorrectMultipleSortOrderForMultipleKeysTest() { - junitExpectedException.expect(PdfException.class); - junitExpectedException.expectMessage(PdfException.NumberOfBooleansInTheArrayDoesntCorrespondWithTheNumberOfFields); - final String[] keys = { "testKey1", "testKey2", "testKey3"}; final boolean[] testAscendings = {true, false}; @@ -150,7 +141,10 @@ public void incorrectMultipleSortOrderForMultipleKeysTest() { // this line will throw an exception as number of parameters of setSortOrder() // method should be exactly the same as number of keys of PdfCollectionSort // here we have three keys but two params - sort.setSortOrder(testAscendings); + Exception e = Assert.assertThrows(PdfException.class, + () -> sort.setSortOrder(testAscendings) + ); + Assert.assertEquals(PdfException.NumberOfBooleansInTheArrayDoesntCorrespondWithTheNumberOfFields, e.getMessage()); } @Test diff --git a/kernel/src/test/java/com/itextpdf/kernel/pdf/colorspace/PdfShadingTest.java b/kernel/src/test/java/com/itextpdf/kernel/pdf/colorspace/PdfShadingTest.java index 6e43a0df3a..a6e20ede2b 100644 --- a/kernel/src/test/java/com/itextpdf/kernel/pdf/colorspace/PdfShadingTest.java +++ b/kernel/src/test/java/com/itextpdf/kernel/pdf/colorspace/PdfShadingTest.java @@ -26,75 +26,70 @@ This file is part of the iText (R) project. import com.itextpdf.kernel.pdf.PdfDictionary; import com.itextpdf.kernel.pdf.PdfName; import com.itextpdf.kernel.pdf.PdfNumber; -import com.itextpdf.kernel.pdf.PdfNumberTest; import com.itextpdf.kernel.pdf.colorspace.PdfDeviceCs.Rgb; import com.itextpdf.kernel.pdf.colorspace.PdfShading.Axial; import com.itextpdf.kernel.pdf.colorspace.PdfShading.Radial; import com.itextpdf.kernel.pdf.colorspace.PdfShading.ShadingType; -import com.itextpdf.kernel.pdf.function.PdfFunction; import com.itextpdf.test.ExtendedITextTest; -import com.itextpdf.test.annotations.type.IntegrationTest; import com.itextpdf.test.annotations.type.UnitTest; import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(UnitTest.class) public class PdfShadingTest extends ExtendedITextTest { - @Rule - public ExpectedException expectedException = ExpectedException.none(); - @Test public void axialShadingConstructorNullExtendArgumentTest() { boolean[] extendArray = null; - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("extend"); - Axial axial = new Axial( - new Rgb(), 0f, 0f, new float[] {0f, 0f, 0f}, 0.5f, 0.5f, new float[]{0.5f, 0.5f, 0.5f}, - extendArray + Exception e = Assert.assertThrows(IllegalArgumentException.class, + () -> new Axial( + new Rgb(), 0f, 0f, new float[] {0f, 0f, 0f}, 0.5f, 0.5f, new float[]{0.5f, 0.5f, 0.5f}, + extendArray + ) ); + Assert.assertEquals("extend", e.getMessage()); } @Test public void axialShadingConstructorInvalidExtendArgumentTest() { boolean[] extendArray = new boolean[] {true}; - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("extend"); - Axial axial = new Axial( - new Rgb(), 0f, 0f, new float[] {0f, 0f, 0f}, 0.5f, 0.5f, new float[]{0.5f, 0.5f, 0.5f}, - extendArray + Exception e = Assert.assertThrows(IllegalArgumentException.class, + () -> new Axial( + new Rgb(), 0f, 0f, new float[] {0f, 0f, 0f}, 0.5f, 0.5f, new float[]{0.5f, 0.5f, 0.5f}, + extendArray + ) ); + Assert.assertEquals("extend", e.getMessage()); } @Test public void radialShadingConstructorNullExtendArgumentTest() { boolean[] extendArray = null; - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("extend"); - new Radial( - new Rgb(), 0f, 0f, 0f, new float[] {0f, 0f, 0f}, 0.5f, 0.5f, 10f, new float[]{0.5f, 0.5f, 0.5f}, - extendArray + Exception e = Assert.assertThrows(IllegalArgumentException.class, + () -> new Radial( + new Rgb(), 0f, 0f, 0f, new float[] {0f, 0f, 0f}, 0.5f, 0.5f, 10f, new float[]{0.5f, 0.5f, 0.5f}, + extendArray + ) ); + Assert.assertEquals("extend", e.getMessage()); } @Test public void radialShadingConstructorInvalidExtendArgumentTest() { boolean[] extendArray = new boolean[] {true, false, false}; - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("extend"); - new Radial( - new Rgb(), 0f, 0f, 0f, new float[] {0f, 0f, 0f}, 0.5f, 0.5f, 10f, new float[]{0.5f, 0.5f, 0.5f}, - extendArray + Exception e = Assert.assertThrows(IllegalArgumentException.class, + () -> new Radial( + new Rgb(), 0f, 0f, 0f, new float[] {0f, 0f, 0f}, 0.5f, 0.5f, 10f, new float[]{0.5f, 0.5f, 0.5f}, + extendArray + ) ); + Assert.assertEquals("extend", e.getMessage()); } @Test diff --git a/kernel/src/test/java/com/itextpdf/kernel/pdf/copy/PdfAnnotationCopyingTest.java b/kernel/src/test/java/com/itextpdf/kernel/pdf/copy/PdfAnnotationCopyingTest.java index 6b82074972..34d874a01c 100644 --- a/kernel/src/test/java/com/itextpdf/kernel/pdf/copy/PdfAnnotationCopyingTest.java +++ b/kernel/src/test/java/com/itextpdf/kernel/pdf/copy/PdfAnnotationCopyingTest.java @@ -46,10 +46,9 @@ This file is part of the iText (R) project. import java.io.IOException; import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Rule; +import org.junit.Ignore; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(IntegrationTest.class) public class PdfAnnotationCopyingTest extends ExtendedITextTest { @@ -57,19 +56,14 @@ public class PdfAnnotationCopyingTest extends ExtendedITextTest { public static final String destinationFolder = "./target/test/com/itextpdf/kernel/pdf/PdfAnnotationCopyingTest/"; public static final String sourceFolder = "./src/test/resources/com/itextpdf/kernel/pdf/PdfAnnotationCopyingTest/"; - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @BeforeClass public static void beforeClass() { createOrClearDestinationFolder(destinationFolder); } @Test - // TODO remove expected exception and thus enable assertions when DEVSIX-3585 is implemented + @Ignore("Unignore when DEVSIX-3585 would be implemented") public void testCopyingPageWithAnnotationContainingPopupKey() throws IOException { - junitExpectedException.expect(AssertionError.class); - String inFilePath = sourceFolder + "annotation-with-popup.pdf"; String outFilePath = destinationFolder + "copy-annotation-with-popup.pdf"; PdfDocument originalDocument = new PdfDocument(new PdfReader(inFilePath)); @@ -112,10 +106,8 @@ public void testCopyingPageWithAnnotationContainingPopupKey() throws IOException } @Test - // TODO remove expected exception and thus enable assertions when DEVSIX-3585 is implemented + @Ignore("Unignore when DEVSIX-3585 would be implemented") public void testCopyingPageWithAnnotationContainingIrtKey() throws IOException { - junitExpectedException.expect(AssertionError.class); - String inFilePath = sourceFolder + "annotation-with-irt.pdf"; String outFilePath = destinationFolder + "copy-annotation-with-irt.pdf"; PdfDocument originalDocument = new PdfDocument(new PdfReader(inFilePath)); diff --git a/kernel/src/test/java/com/itextpdf/kernel/pdf/filters/ASCIIHexDecodeFilterTest.java b/kernel/src/test/java/com/itextpdf/kernel/pdf/filters/ASCIIHexDecodeFilterTest.java index c5b178047f..2f015c6251 100644 --- a/kernel/src/test/java/com/itextpdf/kernel/pdf/filters/ASCIIHexDecodeFilterTest.java +++ b/kernel/src/test/java/com/itextpdf/kernel/pdf/filters/ASCIIHexDecodeFilterTest.java @@ -30,19 +30,14 @@ This file is part of the iText (R) project. import java.io.IOException; import java.nio.file.Files; import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(UnitTest.class) public class ASCIIHexDecodeFilterTest extends ExtendedITextTest { public static final String SOURCE_FILE = "./src/test/resources/com/itextpdf/kernel/pdf/filters/ASCIIHex.bin"; - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void decodingTest() throws IOException { File file = new File(SOURCE_FILE); @@ -63,9 +58,11 @@ public void decodingTest() throws IOException { @Test public void decodingIllegalaCharacterTest() { byte[] bytes = "4c6f72656d20697073756d2eg>".getBytes(); - junitExpectedException.expect(PdfException.class); - junitExpectedException.expectMessage(PdfException.IllegalCharacterInAsciihexdecode); - ASCIIHexDecodeFilter.ASCIIHexDecode(bytes); + + Exception e = Assert.assertThrows(PdfException.class, + () -> ASCIIHexDecodeFilter.ASCIIHexDecode(bytes) + ); + Assert.assertEquals(PdfException.IllegalCharacterInAsciihexdecode, e.getMessage()); } @Test diff --git a/kernel/src/test/java/com/itextpdf/kernel/pdf/xobject/GetImageBytesTest.java b/kernel/src/test/java/com/itextpdf/kernel/pdf/xobject/GetImageBytesTest.java index 4a4fe74f1c..0fbcc72717 100644 --- a/kernel/src/test/java/com/itextpdf/kernel/pdf/xobject/GetImageBytesTest.java +++ b/kernel/src/test/java/com/itextpdf/kernel/pdf/xobject/GetImageBytesTest.java @@ -77,10 +77,8 @@ This file is part of the iText (R) project. import java.util.Set; import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(IntegrationTest.class) public class GetImageBytesTest extends ExtendedITextTest { @@ -88,9 +86,6 @@ public class GetImageBytesTest extends ExtendedITextTest { private static final String sourceFolder = "./src/test/resources/com/itextpdf/kernel/pdf/xobject/GetImageBytesTest/"; private static final String destinationFolder = "./target/test/com/itextpdf/kernel/pdf/xobject/GetImageBytesTest/"; - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @BeforeClass public static void beforeClass() { createOrClearDestinationFolder(destinationFolder); @@ -199,17 +194,17 @@ public void extractByteAlignedG4TiffImageTest() throws IOException { @Test public void expectedByteAlignedTiffImageExtractionTest() throws IOException { //Byte-aligned image is expected in pdf file, but in fact it's not - junitExpectedException.expect(com.itextpdf.io.IOException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format - (com.itextpdf.io.IOException.ExpectedTrailingZeroBitsForByteAlignedLines)); - String inFileName = sourceFolder + "expectedByteAlignedTiffImageExtraction.pdf"; PdfDocument pdfDocument = new PdfDocument(new PdfReader(inFileName)); ImageExtractor listener = new ImageExtractor(); PdfCanvasProcessor processor = new PdfCanvasProcessor(listener); - processor.processPageContent(pdfDocument.getPage(1)); + + Exception e = Assert.assertThrows(com.itextpdf.io.IOException.class, + () -> processor.processPageContent(pdfDocument.getPage(1)) + ); + Assert.assertEquals(MessageFormatUtil.format(com.itextpdf.io.IOException.ExpectedTrailingZeroBitsForByteAlignedLines), e.getMessage()); } private class ImageExtractor implements IEventListener { diff --git a/kernel/src/test/java/com/itextpdf/kernel/utils/CompareToolTest.java b/kernel/src/test/java/com/itextpdf/kernel/utils/CompareToolTest.java index d5f88a7d15..6d270b4778 100644 --- a/kernel/src/test/java/com/itextpdf/kernel/utils/CompareToolTest.java +++ b/kernel/src/test/java/com/itextpdf/kernel/utils/CompareToolTest.java @@ -43,34 +43,38 @@ This file is part of the iText (R) project. package com.itextpdf.kernel.utils; import com.itextpdf.io.IoExceptionMessage; +import com.itextpdf.io.font.constants.StandardFonts; import com.itextpdf.io.util.GhostscriptHelper; import com.itextpdf.io.util.SystemUtil; +import com.itextpdf.kernel.font.PdfFontFactory; +import com.itextpdf.kernel.geom.Rectangle; +import com.itextpdf.kernel.pdf.PdfArray; +import com.itextpdf.kernel.pdf.PdfDocument; +import com.itextpdf.kernel.pdf.PdfPage; +import com.itextpdf.kernel.pdf.PdfWriter; +import com.itextpdf.kernel.pdf.annot.PdfLinkAnnotation; +import com.itextpdf.kernel.pdf.canvas.PdfCanvas; +import com.itextpdf.kernel.pdf.navigation.PdfExplicitDestination; import com.itextpdf.test.ExtendedITextTest; import com.itextpdf.test.annotations.LogMessage; import com.itextpdf.test.annotations.LogMessages; import com.itextpdf.test.annotations.type.IntegrationTest; import java.io.File; +import java.io.IOException; +import javax.xml.parsers.ParserConfigurationException; import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; import org.xml.sax.SAXException; -import javax.xml.parsers.ParserConfigurationException; -import java.io.IOException; - @Category(IntegrationTest.class) public class CompareToolTest extends ExtendedITextTest { public static final String sourceFolder = "./src/test/resources/com/itextpdf/kernel/utils/CompareToolTest/"; public static final String destinationFolder = "./target/test/com/itextpdf/kernel/utils/CompareToolTest/"; - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @BeforeClass public static void setUp() { createOrClearDestinationFolder(destinationFolder); @@ -172,11 +176,13 @@ public void gsEnvironmentVariableIsNotSpecifiedExceptionTest() throws IOExceptio @Test public void gsEnvironmentVariableSpecifiedIncorrectlyTest() throws IOException, InterruptedException { - junitExpectedException.expect(CompareTool.CompareToolExecutionException.class); - junitExpectedException.expectMessage(IoExceptionMessage.GS_ENVIRONMENT_VARIABLE_IS_NOT_SPECIFIED); String outPdf = sourceFolder + "simple_pdf.pdf"; String cmpPdf = sourceFolder + "cmp_simple_pdf.pdf"; - new CompareTool("unspecified", null).compareVisually(outPdf, cmpPdf, destinationFolder, "diff_"); + + Exception e = Assert.assertThrows(CompareTool.CompareToolExecutionException.class, + () -> new CompareTool("unspecified", null).compareVisually(outPdf, cmpPdf, destinationFolder, "diff_") + ); + Assert.assertEquals(IoExceptionMessage.GS_ENVIRONMENT_VARIABLE_IS_NOT_SPECIFIED, e.getMessage()); } @Test @@ -218,4 +224,66 @@ public void compareVisuallyDiffTestTest() throws IOException, InterruptedExcepti Assert.assertTrue(new File(destinationFolder + "diff_1.png").exists()); Assert.assertTrue(new File(destinationFolder + "diff_2.png").exists()); } + + @Test + public void compareDiffFilesWithSameLinkAnnotationTest() throws IOException { + String firstPdf = destinationFolder + "firstPdf.pdf"; + String secondPdf = destinationFolder + "secondPdf.pdf"; + PdfDocument firstDocument = new PdfDocument(new PdfWriter(firstPdf)); + + PdfPage page1FirstDocument = firstDocument.addNewPage(); + PdfCanvas canvas = new PdfCanvas(page1FirstDocument); + canvas.beginText(); + canvas.setFontAndSize(PdfFontFactory.createFont(StandardFonts.COURIER_BOLD), 14); + canvas.moveText(100, 600); + canvas.showText("Page 1"); + canvas.moveText(0, -30); + canvas.showText("Link to page 1. Click here!"); + canvas.endText(); + canvas.release(); + page1FirstDocument.addAnnotation(new PdfLinkAnnotation(new Rectangle(100, 560, 260, 25)).setDestination( + PdfExplicitDestination.createFit(page1FirstDocument)).setBorder(new PdfArray(new float[] {0, 0, 1}))); + page1FirstDocument.flush(); + firstDocument.close(); + + PdfDocument secondDocument = new PdfDocument(new PdfWriter(secondPdf)); + PdfPage page1secondDocument = secondDocument.addNewPage(); + canvas = new PdfCanvas(page1secondDocument); + canvas.beginText(); + canvas.setFontAndSize(PdfFontFactory.createFont(StandardFonts.COURIER_BOLD), 14); + canvas.moveText(100, 600); + canvas.showText("Page 1 wit different Text"); + canvas.moveText(0, -30); + canvas.showText("Link to page 1. Click here!"); + canvas.endText(); + canvas.release(); + page1secondDocument.addAnnotation(new PdfLinkAnnotation(new Rectangle(100, 560, 260, 25)).setDestination( + PdfExplicitDestination.createFit(page1secondDocument)).setBorder(new PdfArray(new float[] {0, 0, 1}))); + page1secondDocument.flush(); + secondDocument.close(); + + Assert.assertNull(new CompareTool().compareLinkAnnotations(firstPdf, secondPdf)); + } + + @Test + public void compareFilesWithDiffLinkAnnotationTest() throws IOException { + String firstPdf = destinationFolder + "outPdf.pdf"; + String secondPdf = destinationFolder + "secondPdf.pdf"; + PdfDocument firstDocument = new PdfDocument(new PdfWriter(firstPdf)); + PdfDocument secondDocument = new PdfDocument(new PdfWriter(secondPdf)); + + PdfPage page1FirstDocument = firstDocument.addNewPage(); + page1FirstDocument.addAnnotation(new PdfLinkAnnotation(new Rectangle(100, 560, 400, 50)).setDestination( + PdfExplicitDestination.createFit(page1FirstDocument)).setBorder(new PdfArray(new float[] {0, 0, 1}))); + page1FirstDocument.flush(); + firstDocument.close(); + + PdfPage page1SecondDocument = secondDocument.addNewPage(); + page1SecondDocument.addAnnotation(new PdfLinkAnnotation(new Rectangle(100, 560, 260, 25)).setDestination( + PdfExplicitDestination.createFit(page1SecondDocument)).setBorder(new PdfArray(new float[] {0, 0, 1}))); + page1SecondDocument.flush(); + secondDocument.close(); + + Assert.assertNotNull(new CompareTool().compareLinkAnnotations(firstPdf, secondPdf)); + } } diff --git a/kernel/src/test/java/com/itextpdf/kernel/utils/SecurityTestXmlParserFactory.java b/kernel/src/test/java/com/itextpdf/kernel/utils/SecurityTestXmlParserFactory.java new file mode 100644 index 0000000000..e2b00da7e1 --- /dev/null +++ b/kernel/src/test/java/com/itextpdf/kernel/utils/SecurityTestXmlParserFactory.java @@ -0,0 +1,72 @@ +/* + This file is part of the iText (R) project. + Copyright (c) 1998-2021 iText Group NV + Authors: iText Software. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License version 3 + as published by the Free Software Foundation with the addition of the + following permission added to Section 15 as permitted in Section 7(a): + FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY + ITEXT GROUP. ITEXT GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT + OF THIRD PARTY RIGHTS + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Affero General Public License for more details. + You should have received a copy of the GNU Affero General Public License + along with this program; if not, see http://www.gnu.org/licenses or write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA, 02110-1301 USA, or download the license from the following URL: + http://itextpdf.com/terms-of-use/ + + The interactive user interfaces in modified source and object code versions + of this program must display Appropriate Legal Notices, as required under + Section 5 of the GNU Affero General Public License. + + In accordance with Section 7(b) of the GNU Affero General Public License, + a covered work must retain the producer line in every PDF that is created + or manipulated using iText. + + You can be released from the requirements of the license by purchasing + a commercial license. Buying such a license is mandatory as soon as you + develop commercial activities involving the iText software without + disclosing the source code of your own applications. + These activities include: offering paid services to customers as an ASP, + serving PDFs on the fly in a web application, shipping iText with a closed + source product. + + For more information, please contact iText Software Corp. at this + address: sales@itextpdf.com + */ +package com.itextpdf.kernel.utils; + +import com.itextpdf.kernel.PdfException; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import org.xml.sax.EntityResolver; +import org.xml.sax.InputSource; + +public class SecurityTestXmlParserFactory extends DefaultSafeXmlParserFactory { + @Override + public DocumentBuilder createDocumentBuilderInstance(boolean namespaceAware, boolean ignoringComments) { + DocumentBuilder db; + try { + db = DocumentBuilderFactory.newInstance().newDocumentBuilder(); + } catch (ParserConfigurationException e) { + throw new PdfException(e.getMessage(), e); + } + + db.setEntityResolver(new TestEntityResolver()); + return db; + } + + private static class TestEntityResolver implements EntityResolver { + public InputSource resolveEntity(String publicId, String systemId) { + throw new PdfException("Test message"); + } + } +} \ No newline at end of file diff --git a/kernel/src/test/java/com/itextpdf/kernel/utils/XmlProcessorCreatorSecurityTest.java b/kernel/src/test/java/com/itextpdf/kernel/utils/XmlProcessorCreatorSecurityTest.java new file mode 100644 index 0000000000..a77097a3cc --- /dev/null +++ b/kernel/src/test/java/com/itextpdf/kernel/utils/XmlProcessorCreatorSecurityTest.java @@ -0,0 +1,227 @@ +/* + This file is part of the iText (R) project. + Copyright (c) 1998-2021 iText Group NV + Authors: iText Software. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License version 3 + as published by the Free Software Foundation with the addition of the + following permission added to Section 15 as permitted in Section 7(a): + FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY + ITEXT GROUP. ITEXT GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT + OF THIRD PARTY RIGHTS + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Affero General Public License for more details. + You should have received a copy of the GNU Affero General Public License + along with this program; if not, see http://www.gnu.org/licenses or write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA, 02110-1301 USA, or download the license from the following URL: + http://itextpdf.com/terms-of-use/ + + The interactive user interfaces in modified source and object code versions + of this program must display Appropriate Legal Notices, as required under + Section 5 of the GNU Affero General Public License. + + In accordance with Section 7(b) of the GNU Affero General Public License, + a covered work must retain the producer line in every PDF that is created + or manipulated using iText. + + You can be released from the requirements of the license by purchasing + a commercial license. Buying such a license is mandatory as soon as you + develop commercial activities involving the iText software without + disclosing the source code of your own applications. + These activities include: offering paid services to customers as an ASP, + serving PDFs on the fly in a web application, shipping iText with a closed + source product. + + For more information, please contact iText Software Corp. at this + address: sales@itextpdf.com + */ +package com.itextpdf.kernel.utils; + +import com.itextpdf.kernel.PdfException; +import com.itextpdf.test.ExceptionTestUtil; +import com.itextpdf.test.ExtendedITextTest; +import com.itextpdf.test.annotations.type.UnitTest; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.ParserConfigurationException; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.w3c.dom.Document; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; +import org.xml.sax.XMLReader; + +@Category(UnitTest.class) +public class XmlProcessorCreatorSecurityTest extends ExtendedITextTest { + + private static final String XML_WITHOUT_DTD = "\n" + + "\n" + + " Artem B\n" + + " Nikita K\n" + + ""; + + private static final String XML_WITH_DTD = "\n" + + "\n" + + " \n" + + "]>\n" + + "\n" + + " Artem B\n" + + " Nikita K\n" + + ""; + + private static final String XML_WITH_EMPTY_DTD = "\n" + + "\n" + + "\n" + + " Artem B\n" + + " Nikita K\n" + + ""; + + private static final String XML_WITH_INTERNAL_ENTITY = "\n" + + "\n" + + " \n" + + " \n" + + "]>\n" + + "\n" + + " Artem B &companyname;\n" + + " Nikita K &companyname;\n" + + ""; + + private static final String XML_WITH_XXE = "\n" + + "\n" + + " \n" + + " " + + "]>\n" + + "\n" + + " Artem B &xxe;\n" + + " Nikita K &xxe;\n" + + ""; + + private final static String DTD_EXCEPTION_MESSAGE = ExceptionTestUtil.getDoctypeIsDisallowedExceptionMessage(); + + @Before + public void resetXmlParserFactoryToDefault() { + XmlProcessorCreator.setXmlParserFactory(new DefaultSafeXmlParserFactory()); + } + + @Test + public void xmlWithoutDtd() throws ParserConfigurationException, IOException, SAXException { + Document document; + DocumentBuilder documentBuilder = XmlProcessorCreator.createSafeDocumentBuilder(false, false); + try (InputStream inputStream = new ByteArrayInputStream(XML_WITHOUT_DTD.getBytes(StandardCharsets.UTF_8))) { + document = documentBuilder.parse(inputStream); + } + Assert.assertNotNull(document); + } + + @Test + public void xmlWithXXECustomFactory() throws ParserConfigurationException, IOException, SAXException { + XmlProcessorCreator.setXmlParserFactory(new SecurityTestXmlParserFactory()); + DocumentBuilder documentBuilder = XmlProcessorCreator.createSafeDocumentBuilder(false, false); + try (InputStream inputStream = new ByteArrayInputStream(XML_WITH_XXE.getBytes(StandardCharsets.UTF_8))) { + Exception e = Assert.assertThrows(PdfException.class, + () -> documentBuilder.parse(inputStream) + ); + Assert.assertEquals("Test message", e.getMessage()); + } + } + + @Test + public void xmlWithDtd() throws ParserConfigurationException, IOException, SAXException { + createSafeDocumentBuilderTest(XML_WITH_DTD, false, false); + } + + @Test + public void xmlWithEmptyDtdDtd() throws ParserConfigurationException, IOException, SAXException { + createSafeDocumentBuilderTest(XML_WITH_EMPTY_DTD, false, false); + } + + @Test + public void xmlWithInternalEntity() throws ParserConfigurationException, IOException, SAXException { + createSafeDocumentBuilderTest(XML_WITH_INTERNAL_ENTITY, false, false); + } + + @Test + public void xmlWithXXE() throws ParserConfigurationException, IOException, SAXException { + createSafeDocumentBuilderTest(XML_WITH_XXE, false, false); + } + + @Test + public void xmlWithXXEFlags() throws ParserConfigurationException, IOException, SAXException { + createSafeDocumentBuilderTest(XML_WITH_XXE, true, true); + } + + @Test + public void xmlWithXXEFlags2() throws ParserConfigurationException, IOException, SAXException { + createSafeDocumentBuilderTest(XML_WITH_XXE, true, false); + } + + @Test + public void xmlWithXXEFlags3() throws ParserConfigurationException, IOException, SAXException { + createSafeDocumentBuilderTest(XML_WITH_XXE, false, true); + } + + @Test + public void xmlWithXxeXMLReader() throws ParserConfigurationException, IOException, SAXException { + createSafeXMLReaderTest(true, true); + } + + @Test + public void xmlWithXxeXMLReaderFlags() throws ParserConfigurationException, IOException, SAXException { + createSafeXMLReaderTest(false, false); + } + + @Test + public void xmlWithXxeXMLReaderFlags2() throws ParserConfigurationException, IOException, SAXException { + createSafeXMLReaderTest(true, false); + } + + @Test + public void xmlWithXxeXMLReaderFlags3() throws ParserConfigurationException, IOException, SAXException { + createSafeXMLReaderTest(false, true); + } + + @Test + public void setXmlParserFactoryNull() throws IOException, SAXException { + XmlProcessorCreator.setXmlParserFactory(null); + createSafeDocumentBuilderTest(XML_WITH_XXE, false, false); + } + + private void createSafeXMLReaderTest(boolean nameSpace, boolean validating) + throws IOException, SAXException { + XMLReader reader = XmlProcessorCreator.createSafeXMLReader(nameSpace, validating); + try (InputStream inputStream = new ByteArrayInputStream( + XmlProcessorCreatorSecurityTest.XML_WITH_XXE.getBytes(StandardCharsets.UTF_8))) { + InputSource inputSource = new InputSource(inputStream); + Exception e = Assert.assertThrows(SAXParseException.class, + () -> reader.parse(inputSource) + ); + Assert.assertEquals(XmlProcessorCreatorSecurityTest.DTD_EXCEPTION_MESSAGE, e.getMessage()); + } + } + + private void createSafeDocumentBuilderTest(String xml, boolean nameSpace, boolean comments) + throws IOException, SAXException { + DocumentBuilder documentBuilder = XmlProcessorCreator.createSafeDocumentBuilder(nameSpace, comments); + try (InputStream inputStream = new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8))) { + Exception e = Assert.assertThrows(SAXParseException.class, + () -> documentBuilder.parse(inputStream) + ); + Assert.assertEquals(XmlProcessorCreatorSecurityTest.DTD_EXCEPTION_MESSAGE, e.getMessage()); + } + } +} diff --git a/kernel/src/test/java/com/itextpdf/kernel/xmp/impl/SecurityTestXmlParserFactory.java b/kernel/src/test/java/com/itextpdf/kernel/xmp/impl/SecurityTestXmlParserFactory.java new file mode 100644 index 0000000000..aba960ff89 --- /dev/null +++ b/kernel/src/test/java/com/itextpdf/kernel/xmp/impl/SecurityTestXmlParserFactory.java @@ -0,0 +1,55 @@ +/* + This file is part of the iText (R) project. + Copyright (c) 1998-2021 iText Group NV + Authors: iText Software. + + This program is offered under a commercial and under the AGPL license. + For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below. + + AGPL licensing: + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + */ +package com.itextpdf.kernel.xmp.impl; + +import com.itextpdf.kernel.PdfException; +import com.itextpdf.kernel.utils.DefaultSafeXmlParserFactory; +import com.itextpdf.kernel.utils.IXmlParserFactory; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import org.xml.sax.EntityResolver; +import org.xml.sax.InputSource; + + +class SecurityTestXmlParserFactory extends DefaultSafeXmlParserFactory { + @Override + public DocumentBuilder createDocumentBuilderInstance(boolean namespaceAware, boolean ignoringComments) { + DocumentBuilder db; + try { + db = DocumentBuilderFactory.newInstance().newDocumentBuilder(); + } catch (ParserConfigurationException e) { + throw new PdfException(e.getMessage(), e); + } + + db.setEntityResolver(new TestEmptyEntityResolver()); + return db; + } + + private static class TestEmptyEntityResolver implements EntityResolver { + public InputSource resolveEntity(String publicId, String systemId) { + throw new PdfException("Test message"); + } + } +} \ No newline at end of file diff --git a/kernel/src/test/java/com/itextpdf/kernel/xmp/impl/XMPMetaParserSecurityTest.java b/kernel/src/test/java/com/itextpdf/kernel/xmp/impl/XMPMetaParserSecurityTest.java new file mode 100644 index 0000000000..6eac168210 --- /dev/null +++ b/kernel/src/test/java/com/itextpdf/kernel/xmp/impl/XMPMetaParserSecurityTest.java @@ -0,0 +1,96 @@ +/* + This file is part of the iText (R) project. + Copyright (c) 1998-2021 iText Group NV + Authors: iText Software. + + This program is offered under a commercial and under the AGPL license. + For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below. + + AGPL licensing: + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + */ +package com.itextpdf.kernel.xmp.impl; + +import com.itextpdf.kernel.PdfException; +import com.itextpdf.kernel.utils.DefaultSafeXmlParserFactory; +import com.itextpdf.kernel.utils.XmlProcessorCreator; +import com.itextpdf.kernel.xmp.XMPException; +import com.itextpdf.test.ExceptionTestUtil; +import com.itextpdf.test.ExtendedITextTest; +import com.itextpdf.test.annotations.type.UnitTest; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +@Category(UnitTest.class) +public class XMPMetaParserSecurityTest extends ExtendedITextTest { + + private static final String XMP_WITH_XXE = "\n" + + " ]>\n" + + "\n" + + " \n" + + " \n" + + " &xxe;1\n" + + " B\n" + + " \n" + + " \n" + + "\n" + + ""; + + private static final String DTD_EXCEPTION_MESSAGE = ExceptionTestUtil.getDoctypeIsDisallowedExceptionMessage(); + + @Before + public void resetXmlParserFactoryToDefault() { + XmlProcessorCreator.setXmlParserFactory(new DefaultSafeXmlParserFactory()); + } + + @Test + public void xxeTestFromString() throws XMPException { + Exception e = Assert.assertThrows(XMPException.class, () -> XMPMetaParser.parse(XMP_WITH_XXE, null)); + Assert.assertEquals(DTD_EXCEPTION_MESSAGE, e.getMessage()); + } + + @Test + public void xxeTestFromByteBuffer() throws XMPException { + Exception e = Assert.assertThrows(XMPException.class, + () -> XMPMetaParser.parse(XMP_WITH_XXE.getBytes(StandardCharsets.UTF_8), null) + ); + Assert.assertEquals(DTD_EXCEPTION_MESSAGE, e.getMessage()); + } + + @Test + public void xxeTestFromInputStream() throws XMPException, IOException { + try (InputStream inputStream = new ByteArrayInputStream(XMP_WITH_XXE.getBytes(StandardCharsets.UTF_8))) { + Exception e = Assert.assertThrows(XMPException.class, + () -> XMPMetaParser.parse(inputStream, null) + ); + Assert.assertEquals(DTD_EXCEPTION_MESSAGE, e.getMessage()); + } + } + + @Test + public void xxeTestFromStringCustomXmlParser() throws XMPException { + XmlProcessorCreator.setXmlParserFactory(new SecurityTestXmlParserFactory()); + Exception e = Assert.assertThrows(PdfException.class, + () -> XMPMetaParser.parse(XMP_WITH_XXE, null) + ); + Assert.assertEquals("Test message", e.getMessage()); + } +} diff --git a/kernel/src/test/java/com/itextpdf/kernel/xmp/impl/XMPMetaParserTest.java b/kernel/src/test/java/com/itextpdf/kernel/xmp/impl/XMPMetaParserTest.java deleted file mode 100644 index 2130b9a482..0000000000 --- a/kernel/src/test/java/com/itextpdf/kernel/xmp/impl/XMPMetaParserTest.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - This file is part of the iText (R) project. - Copyright (c) 1998-2021 iText Group NV - Authors: iText Software. - - This program is offered under a commercial and under the AGPL license. - For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below. - - AGPL licensing: - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . - */ -package com.itextpdf.kernel.xmp.impl; - -import com.itextpdf.io.util.MessageFormatUtil; -import com.itextpdf.kernel.xmp.XMPException; -import com.itextpdf.kernel.xmp.XMPMeta; -import com.itextpdf.kernel.xmp.XMPMetaFactory; -import com.itextpdf.test.ExtendedITextTest; -import com.itextpdf.test.annotations.type.UnitTest; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.nio.charset.StandardCharsets; -import org.junit.Assert; -import org.junit.Test; -import org.junit.experimental.categories.Category; - -@Category(UnitTest.class) -public class XMPMetaParserTest extends ExtendedITextTest { - - private static final String XXE_FILE_PATH = "./src/test/resources/com/itextpdf/kernel/xmp/impl/xxe-data.txt"; - - private static final String XMP_WITH_XXE = "\n" - + " ]>\n" - + "\n" - + " \n" - + " \n" - + " &xxe;1\n" - + " B\n" - + " \n" - + " \n" - + "\n" - + ""; - - private static final String EXPECTED_SERIALIZED_XMP = "\n" - + "\n" - + " \n" - + " \n" - + " \n" - + "\n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + ""; - - @Test - public void xxeTestFromString() throws XMPException { - String metadataToParse = MessageFormatUtil.format(XMP_WITH_XXE, XXE_FILE_PATH); - XMPMeta xmpMeta = XMPMetaParser.parse(metadataToParse, null); - String serializedResult = XMPMetaFactory.serializeToString(xmpMeta, null); - Assert.assertEquals(EXPECTED_SERIALIZED_XMP, serializedResult); - } - - @Test - public void xxeTestFromByteBuffer() throws XMPException { - String metadataToParse = MessageFormatUtil.format(XMP_WITH_XXE, XXE_FILE_PATH); - XMPMeta xmpMeta = XMPMetaParser.parse(metadataToParse.getBytes(StandardCharsets.UTF_8), null); - String serializedResult = XMPMetaFactory.serializeToString(xmpMeta, null); - Assert.assertEquals(EXPECTED_SERIALIZED_XMP, serializedResult); - } - - @Test - public void xxeTestFromInputStream() throws XMPException, IOException { - String metadataToParse = MessageFormatUtil.format(XMP_WITH_XXE, XXE_FILE_PATH); - try (InputStream inputStream = new ByteArrayInputStream(metadataToParse.getBytes(StandardCharsets.UTF_8))) { - XMPMeta xmpMeta = XMPMetaParser.parse(inputStream, null); - String serializedResult = XMPMetaFactory.serializeToString(xmpMeta, null); - Assert.assertEquals(EXPECTED_SERIALIZED_XMP, serializedResult); - } - } -} diff --git a/kernel/src/test/resources/com/itextpdf/kernel/pdf/EncryptedEmbeddedStreamsHandlerTest/cmp_noReaderAesEncryptionAddFileAttachment.pdf b/kernel/src/test/resources/com/itextpdf/kernel/pdf/EncryptedEmbeddedStreamsHandlerTest/cmp_noReaderAesEncryptionAddFileAttachment.pdf new file mode 100644 index 0000000000..cb8cd44e4a Binary files /dev/null and b/kernel/src/test/resources/com/itextpdf/kernel/pdf/EncryptedEmbeddedStreamsHandlerTest/cmp_noReaderAesEncryptionAddFileAttachment.pdf differ diff --git a/kernel/src/test/resources/com/itextpdf/kernel/pdf/EncryptedEmbeddedStreamsHandlerTest/cmp_noReaderStandardEncryptionAddAnnotation.pdf b/kernel/src/test/resources/com/itextpdf/kernel/pdf/EncryptedEmbeddedStreamsHandlerTest/cmp_noReaderStandardEncryptionAddAnnotation.pdf new file mode 100644 index 0000000000..585babf49d Binary files /dev/null and b/kernel/src/test/resources/com/itextpdf/kernel/pdf/EncryptedEmbeddedStreamsHandlerTest/cmp_noReaderStandardEncryptionAddAnnotation.pdf differ diff --git a/kernel/src/test/resources/com/itextpdf/kernel/pdf/EncryptedEmbeddedStreamsHandlerTest/cmp_noReaderStandardEncryptionAddFileAttachment.pdf b/kernel/src/test/resources/com/itextpdf/kernel/pdf/EncryptedEmbeddedStreamsHandlerTest/cmp_noReaderStandardEncryptionAddFileAttachment.pdf new file mode 100644 index 0000000000..a2c29f7647 Binary files /dev/null and b/kernel/src/test/resources/com/itextpdf/kernel/pdf/EncryptedEmbeddedStreamsHandlerTest/cmp_noReaderStandardEncryptionAddFileAttachment.pdf differ diff --git a/kernel/src/test/resources/com/itextpdf/kernel/pdf/EncryptedEmbeddedStreamsHandlerTest/cmp_readerWithoutEncryptionWriterStandardEncryption.pdf b/kernel/src/test/resources/com/itextpdf/kernel/pdf/EncryptedEmbeddedStreamsHandlerTest/cmp_readerWithoutEncryptionWriterStandardEncryption.pdf new file mode 100644 index 0000000000..20cb9763de Binary files /dev/null and b/kernel/src/test/resources/com/itextpdf/kernel/pdf/EncryptedEmbeddedStreamsHandlerTest/cmp_readerWithoutEncryptionWriterStandardEncryption.pdf differ diff --git a/kernel/src/test/resources/com/itextpdf/kernel/pdf/EncryptedEmbeddedStreamsHandlerTest/cmp_withReaderStandardEncryptionAddAnnotation.pdf b/kernel/src/test/resources/com/itextpdf/kernel/pdf/EncryptedEmbeddedStreamsHandlerTest/cmp_withReaderStandardEncryptionAddAnnotation.pdf new file mode 100644 index 0000000000..dbc6b6b878 Binary files /dev/null and b/kernel/src/test/resources/com/itextpdf/kernel/pdf/EncryptedEmbeddedStreamsHandlerTest/cmp_withReaderStandardEncryptionAddAnnotation.pdf differ diff --git a/kernel/src/test/resources/com/itextpdf/kernel/pdf/EncryptedEmbeddedStreamsHandlerTest/cmp_withReaderStandardEncryptionAddFileAttachment.pdf b/kernel/src/test/resources/com/itextpdf/kernel/pdf/EncryptedEmbeddedStreamsHandlerTest/cmp_withReaderStandardEncryptionAddFileAttachment.pdf new file mode 100644 index 0000000000..febe40e9a4 Binary files /dev/null and b/kernel/src/test/resources/com/itextpdf/kernel/pdf/EncryptedEmbeddedStreamsHandlerTest/cmp_withReaderStandardEncryptionAddFileAttachment.pdf differ diff --git a/kernel/src/test/resources/com/itextpdf/kernel/pdf/EncryptedEmbeddedStreamsHandlerTest/pdfWithFileAttachmentAnnotations.pdf b/kernel/src/test/resources/com/itextpdf/kernel/pdf/EncryptedEmbeddedStreamsHandlerTest/pdfWithFileAttachmentAnnotations.pdf new file mode 100644 index 0000000000..5faddbf408 Binary files /dev/null and b/kernel/src/test/resources/com/itextpdf/kernel/pdf/EncryptedEmbeddedStreamsHandlerTest/pdfWithFileAttachmentAnnotations.pdf differ diff --git a/kernel/src/test/resources/com/itextpdf/kernel/pdf/EncryptedEmbeddedStreamsHandlerTest/pdfWithFileAttachments.pdf b/kernel/src/test/resources/com/itextpdf/kernel/pdf/EncryptedEmbeddedStreamsHandlerTest/pdfWithFileAttachments.pdf new file mode 100644 index 0000000000..d4f38187d9 Binary files /dev/null and b/kernel/src/test/resources/com/itextpdf/kernel/pdf/EncryptedEmbeddedStreamsHandlerTest/pdfWithFileAttachments.pdf differ diff --git a/kernel/src/test/resources/com/itextpdf/kernel/pdf/EncryptedEmbeddedStreamsHandlerTest/pdfWithUnencryptedAttachmentAnnotations.pdf b/kernel/src/test/resources/com/itextpdf/kernel/pdf/EncryptedEmbeddedStreamsHandlerTest/pdfWithUnencryptedAttachmentAnnotations.pdf new file mode 100644 index 0000000000..c66138c0aa Binary files /dev/null and b/kernel/src/test/resources/com/itextpdf/kernel/pdf/EncryptedEmbeddedStreamsHandlerTest/pdfWithUnencryptedAttachmentAnnotations.pdf differ diff --git a/kernel/src/test/resources/com/itextpdf/kernel/pdf/PdfCopyTest/cmp_copyPagesLinkAnnotationTest.pdf b/kernel/src/test/resources/com/itextpdf/kernel/pdf/PdfCopyTest/cmp_copyPagesLinkAnnotationTest.pdf index 00fe82ff52..6311bc0120 100644 Binary files a/kernel/src/test/resources/com/itextpdf/kernel/pdf/PdfCopyTest/cmp_copyPagesLinkAnnotationTest.pdf and b/kernel/src/test/resources/com/itextpdf/kernel/pdf/PdfCopyTest/cmp_copyPagesLinkAnnotationTest.pdf differ diff --git a/kernel/src/test/resources/com/itextpdf/kernel/pdf/PdfDocumentUnitTest/pdfWithMetadata.pdf b/kernel/src/test/resources/com/itextpdf/kernel/pdf/PdfDocumentUnitTest/pdfWithMetadata.pdf new file mode 100644 index 0000000000..50886cb967 Binary files /dev/null and b/kernel/src/test/resources/com/itextpdf/kernel/pdf/PdfDocumentUnitTest/pdfWithMetadata.pdf differ diff --git a/kernel/src/test/resources/com/itextpdf/kernel/pdf/PdfEncryptorTest/initial.pdf b/kernel/src/test/resources/com/itextpdf/kernel/pdf/PdfEncryptorTest/initial.pdf new file mode 100644 index 0000000000..4879f13edf Binary files /dev/null and b/kernel/src/test/resources/com/itextpdf/kernel/pdf/PdfEncryptorTest/initial.pdf differ diff --git a/kernel/src/test/resources/com/itextpdf/kernel/pdf/canvas/PdfCanvasTest/cmp_canvasDrawArcsTest.pdf b/kernel/src/test/resources/com/itextpdf/kernel/pdf/canvas/PdfCanvasTest/cmp_canvasDrawArcsTest.pdf new file mode 100644 index 0000000000..e8374a47f4 Binary files /dev/null and b/kernel/src/test/resources/com/itextpdf/kernel/pdf/canvas/PdfCanvasTest/cmp_canvasDrawArcsTest.pdf differ diff --git a/kernel/src/test/resources/com/itextpdf/kernel/pdf/canvas/parser/GlyphBboxCalculationTest/type3FontCustomFontMatrixAndFontBBox.pdf b/kernel/src/test/resources/com/itextpdf/kernel/pdf/canvas/parser/GlyphBboxCalculationTest/type3FontCustomFontMatrixAndFontBBox.pdf new file mode 100644 index 0000000000..325381ce33 Binary files /dev/null and b/kernel/src/test/resources/com/itextpdf/kernel/pdf/canvas/parser/GlyphBboxCalculationTest/type3FontCustomFontMatrixAndFontBBox.pdf differ diff --git a/kernel/src/test/resources/com/itextpdf/kernel/xmp/impl/xxe-data.txt b/kernel/src/test/resources/com/itextpdf/kernel/xmp/impl/xxe-data.txt deleted file mode 100644 index 629b2d444e..0000000000 --- a/kernel/src/test/resources/com/itextpdf/kernel/xmp/impl/xxe-data.txt +++ /dev/null @@ -1 +0,0 @@ -XXE FILE DATA diff --git a/layout/pom.xml b/layout/pom.xml index 9589b01174..475c8df257 100644 --- a/layout/pom.xml +++ b/layout/pom.xml @@ -4,7 +4,7 @@ com.itextpdf root - 7.1.15 + 7.1.16 layout iText 7 - layout diff --git a/layout/src/main/java/com/itextpdf/layout/Document.java b/layout/src/main/java/com/itextpdf/layout/Document.java index 8fa6bec1b2..0a16d2b6f2 100644 --- a/layout/src/main/java/com/itextpdf/layout/Document.java +++ b/layout/src/main/java/com/itextpdf/layout/Document.java @@ -204,6 +204,10 @@ public void relayout() { throw new IllegalStateException("Operation not supported with immediate flush"); } + if (rootRenderer instanceof DocumentRenderer) { + ((DocumentRenderer) rootRenderer).getTargetCounterHandler().prepareHandlerToRelayout(); + } + IRenderer nextRelayoutRenderer = rootRenderer != null ? rootRenderer.getNextRenderer() : null; if (nextRelayoutRenderer == null || !(nextRelayoutRenderer instanceof RootRenderer)) { nextRelayoutRenderer = new DocumentRenderer(this, immediateFlush); diff --git a/layout/src/main/java/com/itextpdf/layout/borders/Border.java b/layout/src/main/java/com/itextpdf/layout/borders/Border.java index 1f3df8b4da..1ebcf40bc9 100644 --- a/layout/src/main/java/com/itextpdf/layout/borders/Border.java +++ b/layout/src/main/java/com/itextpdf/layout/borders/Border.java @@ -64,10 +64,6 @@ public abstract class Border { */ public static final Border NO_BORDER = null; - /** - * Value used by discontinuous borders during the drawing process - */ - private static final float CURV = 0.447f; /** * The solid border. * @@ -129,6 +125,13 @@ public abstract class Border { */ public static final int DASHED_FIXED = 9; + private static final int ARC_RIGHT_DEGREE = 0; + private static final int ARC_TOP_DEGREE = 90; + private static final int ARC_LEFT_DEGREE = 180; + private static final int ARC_BOTTOM_DEGREE = 270; + + private static final int ARC_QUARTER_CLOCKWISE_EXTENT = -90; + /** * The color of the border. * @@ -487,34 +490,34 @@ protected float getDotsGap(double distance, float initialGap) { * @param borderWidthAfter defines width of the border that is after the current one */ protected void drawDiscontinuousBorders(PdfCanvas canvas, Rectangle boundingRectangle, float[] horizontalRadii, float[] verticalRadii, Side defaultSide, float borderWidthBefore, float borderWidthAfter) { - float x1 = boundingRectangle.getX(); - float y1 = boundingRectangle.getY(); - float x2 = boundingRectangle.getRight(); - float y2 = boundingRectangle.getTop(); + double x1 = boundingRectangle.getX(); + double y1 = boundingRectangle.getY(); + double x2 = boundingRectangle.getRight(); + double y2 = boundingRectangle.getTop(); - float horizontalRadius1 = horizontalRadii[0]; - float horizontalRadius2 = horizontalRadii[1]; + final double horizontalRadius1 = horizontalRadii[0]; + final double horizontalRadius2 = horizontalRadii[1]; - float verticalRadius1 = verticalRadii[0]; - float verticalRadius2 = verticalRadii[1]; + final double verticalRadius1 = verticalRadii[0]; + final double verticalRadius2 = verticalRadii[1]; // Points (x0, y0) and (x3, y3) are used to produce Bezier curve - float x0 = boundingRectangle.getX(); - float y0 = boundingRectangle.getY(); - float x3 = boundingRectangle.getRight(); - float y3 = boundingRectangle.getTop(); + double x0 = boundingRectangle.getX(); + double y0 = boundingRectangle.getY(); + double x3 = boundingRectangle.getRight(); + double y3 = boundingRectangle.getTop(); - float innerRadiusBefore; - float innerRadiusFirst; - float innerRadiusSecond; - float innerRadiusAfter; + double innerRadiusBefore; + double innerRadiusFirst; + double innerRadiusSecond; + double innerRadiusAfter; - float widthHalf = width / 2; + final double widthHalf = width / 2.0; Point clipPoint1; Point clipPoint2; Point clipPoint; - Border.Side borderSide = getBorderSide(x1, y1, x2, y2, defaultSide); + final Border.Side borderSide = getBorderSide((float) x1, (float) y1, (float) x2, (float) y2, defaultSide); switch (borderSide) { case TOP: @@ -547,9 +550,12 @@ protected void drawDiscontinuousBorders(PdfCanvas canvas, Rectangle boundingRect y2 += widthHalf; canvas - .moveTo(x0, y0).curveTo(x0, y0 + innerRadiusFirst * CURV, x1 - innerRadiusBefore * CURV, y1, x1, y1) - .lineTo(x2, y2) - .curveTo(x2 + innerRadiusAfter * CURV, y2, x3, y3 + innerRadiusSecond * CURV, x3, y3); + .arc(x0, y0 - innerRadiusFirst, + x1 + innerRadiusBefore, y1, + ARC_LEFT_DEGREE, ARC_QUARTER_CLOCKWISE_EXTENT) + .arcContinuous(x2 - innerRadiusAfter, y2, + x3, y3 - innerRadiusSecond, + ARC_TOP_DEGREE, ARC_QUARTER_CLOCKWISE_EXTENT); break; case RIGHT: innerRadiusBefore = Math.max(0, verticalRadius1 - borderWidthBefore); @@ -580,10 +586,12 @@ protected void drawDiscontinuousBorders(PdfCanvas canvas, Rectangle boundingRect y2 += innerRadiusAfter; canvas - .moveTo(x0, y0).curveTo(x0 + innerRadiusFirst * CURV, y0, x1, y1 + innerRadiusBefore * CURV, x1, y1) - .lineTo(x2, y2) - .curveTo(x2, y2 - innerRadiusAfter * CURV, x3 + innerRadiusSecond * CURV, y3, x3, y3); - + .arc(x0 - innerRadiusFirst, y0, + x1, y1 - innerRadiusBefore, + ARC_TOP_DEGREE, ARC_QUARTER_CLOCKWISE_EXTENT) + .arcContinuous(x2, y2 + innerRadiusAfter, + x3 - innerRadiusSecond, y3, + ARC_RIGHT_DEGREE, ARC_QUARTER_CLOCKWISE_EXTENT); break; case BOTTOM: innerRadiusBefore = Math.max(0, horizontalRadius1 - borderWidthBefore); @@ -614,10 +622,12 @@ protected void drawDiscontinuousBorders(PdfCanvas canvas, Rectangle boundingRect y2 -= widthHalf; canvas - .moveTo(x0, y0).curveTo(x0, y0 - innerRadiusFirst * CURV, x1 + innerRadiusBefore * CURV, y1, x1, y1) - .lineTo(x2, y2) - .curveTo(x2 - innerRadiusAfter * CURV, y2, x3, y3 - innerRadiusSecond * CURV, x3, y3); - + .arc(x0, y0 + innerRadiusFirst, + x1 - innerRadiusBefore, y1, + ARC_RIGHT_DEGREE, ARC_QUARTER_CLOCKWISE_EXTENT) + .arcContinuous(x2 + innerRadiusAfter, y2, + x3, y3 + innerRadiusSecond, + ARC_BOTTOM_DEGREE, ARC_QUARTER_CLOCKWISE_EXTENT); break; case LEFT: innerRadiusBefore = Math.max(0, verticalRadius1 - borderWidthBefore); @@ -648,9 +658,12 @@ protected void drawDiscontinuousBorders(PdfCanvas canvas, Rectangle boundingRect y2 -= innerRadiusAfter; canvas - .moveTo(x0, y0).curveTo(x0 - innerRadiusFirst * CURV, y0, x1, y1 - innerRadiusBefore * CURV, x1, y1) - .lineTo(x2, y2) - .curveTo(x2, y2 + innerRadiusAfter * CURV, x3 - innerRadiusSecond * CURV, y3, x3, y3); + .arc(x0 + innerRadiusFirst, y0, + x1, y1 + innerRadiusBefore, + ARC_BOTTOM_DEGREE, ARC_QUARTER_CLOCKWISE_EXTENT) + .arcContinuous(x2, y2 - innerRadiusAfter, + x3 + innerRadiusSecond, y3, + ARC_LEFT_DEGREE, ARC_QUARTER_CLOCKWISE_EXTENT); break; default: break; diff --git a/layout/src/main/java/com/itextpdf/layout/element/AbstractElement.java b/layout/src/main/java/com/itextpdf/layout/element/AbstractElement.java index 909cd8dcba..5cfcfbe87c 100644 --- a/layout/src/main/java/com/itextpdf/layout/element/AbstractElement.java +++ b/layout/src/main/java/com/itextpdf/layout/element/AbstractElement.java @@ -132,6 +132,9 @@ public T1 getProperty(int property) { * @return this element */ public T addStyle(Style style) { + if (style == null) { + throw new IllegalArgumentException("Style can not be null."); + } if (styles == null) { styles = new LinkedHashSet<>(); } diff --git a/layout/src/main/java/com/itextpdf/layout/font/FontSelector.java b/layout/src/main/java/com/itextpdf/layout/font/FontSelector.java index 95c1caace6..64b721539c 100644 --- a/layout/src/main/java/com/itextpdf/layout/font/FontSelector.java +++ b/layout/src/main/java/com/itextpdf/layout/font/FontSelector.java @@ -42,6 +42,8 @@ This file is part of the iText (R) project. */ package com.itextpdf.layout.font; +import com.itextpdf.io.font.FontProgramDescriptor; + import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -57,6 +59,8 @@ public class FontSelector { private static final int EXPECTED_FONT_IS_BOLD_AWARD = 5; private static final int EXPECTED_FONT_IS_NOT_BOLD_AWARD = 3; + private static final int EXPECTED_FONT_WEIGHT_IS_EQUALS_AWARD = 1; + private static final int EXPECTED_FONT_WEIGHT_IS_FAR_AWARD = 1; private static final int EXPECTED_FONT_IS_ITALIC_AWARD = 5; private static final int EXPECTED_FONT_IS_NOT_ITALIC_AWARD = 3; private static final int EXPECTED_FONT_IS_MONOSPACED_AWARD = 5; @@ -171,9 +175,10 @@ private static FontCharacteristics parseFontStyle(String fontFamily, FontCharact */ // TODO DEVSIX-2120 Update javadoc if necessary private static int characteristicsSimilarity(String fontFamily, FontCharacteristics fc, FontInfo fontInfo, boolean isLastFontFamilyToBeProcessed) { - boolean isFontBold = fontInfo.getDescriptor().isBold() || fontInfo.getDescriptor().getFontWeight() > 500; - boolean isFontItalic = fontInfo.getDescriptor().isItalic() || fontInfo.getDescriptor().getItalicAngle() < 0; - boolean isFontMonospace = fontInfo.getDescriptor().isMonospace(); + FontProgramDescriptor fontDescriptor = fontInfo.getDescriptor(); + boolean isFontBold = fontDescriptor.isBold() || fontDescriptor.getFontWeight() > 500; + boolean isFontItalic = fontDescriptor.isItalic() || fontDescriptor.getItalicAngle() < 0; + boolean isFontMonospace = fontDescriptor.isMonospace(); int score = 0; // if font-family is monospace, serif or sans-serif, actual font's name shouldn't be checked @@ -197,9 +202,9 @@ private static int characteristicsSimilarity(String fontFamily, FontCharacterist // if alias is set, fontInfo's descriptor should not be checked if (!"".equals(fontFamily) && (null == fontInfo.getAlias() - && null != fontInfo.getDescriptor().getFamilyNameLowerCase() - && fontInfo.getDescriptor().getFamilyNameLowerCase().equals(fontFamily) - || (null != fontInfo.getAlias() && fontInfo.getAlias().toLowerCase().equals(fontFamily)))) { + && null != fontDescriptor.getFamilyNameLowerCase() + && fontDescriptor.getFamilyNameLowerCase().equals(fontFamily) + || (null != fontInfo.getAlias() && fontInfo.getAlias().toLowerCase().equals(fontFamily)))) { score += FONT_FAMILY_EQUALS_AWARD; } else { if (!isLastFontFamilyToBeProcessed) { @@ -209,6 +214,13 @@ private static int characteristicsSimilarity(String fontFamily, FontCharacterist } // calculate style characteristics + int maxWeight = Math.max(fontDescriptor.getFontWeight(), fc.getFontWeight()); + int minWeight = Math.min(fontDescriptor.getFontWeight(), fc.getFontWeight()); + if (maxWeight == minWeight) { + score += EXPECTED_FONT_WEIGHT_IS_EQUALS_AWARD; + } else if (maxWeight - minWeight >= 300) { + score -= EXPECTED_FONT_WEIGHT_IS_FAR_AWARD; + } if (fc.isBold()) { if (isFontBold) { score += EXPECTED_FONT_IS_BOLD_AWARD; diff --git a/layout/src/main/java/com/itextpdf/layout/hyphenation/PatternParser.java b/layout/src/main/java/com/itextpdf/layout/hyphenation/PatternParser.java index 99b3bf1ec3..b00d05c00d 100644 --- a/layout/src/main/java/com/itextpdf/layout/hyphenation/PatternParser.java +++ b/layout/src/main/java/com/itextpdf/layout/hyphenation/PatternParser.java @@ -18,24 +18,20 @@ package com.itextpdf.layout.hyphenation; import com.itextpdf.io.util.ResourceUtil; +import com.itextpdf.kernel.utils.XmlProcessorCreator; -import java.io.StringReader; -import javax.xml.parsers.SAXParser; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; import org.xml.sax.Attributes; -import org.xml.sax.EntityResolver; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; import org.xml.sax.XMLReader; import org.xml.sax.helpers.DefaultHandler; -import javax.xml.parsers.SAXParserFactory; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; - /** * A SAX document handler to read and parse hyphenation patterns * from a XML file. @@ -118,14 +114,7 @@ public void parse(InputStream stream, String name) throws HyphenationException { */ static XMLReader createParser() { try { - SAXParserFactory factory = SAXParserFactory.newInstance(); - factory.setNamespaceAware(true); - factory.setValidating(false); - factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); - SAXParser saxParser = factory.newSAXParser(); - XMLReader xmlReader = saxParser.getXMLReader(); - xmlReader.setEntityResolver(new SafeEmptyEntityResolver()); - return xmlReader; + return XmlProcessorCreator.createSafeXMLReader(true, false); } catch (Exception e) { // Converting checked exceptions to unchecked RuntimeException (java-specific comment). // @@ -436,12 +425,4 @@ private String getLocationString(SAXParseException ex) { // getLocationString(SAXParseException):String return str.toString(); } - - // Prevents XXE attacks - private static class SafeEmptyEntityResolver implements EntityResolver { - public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException { - return new InputSource(new StringReader("")); - } - } - } diff --git a/layout/src/main/java/com/itextpdf/layout/renderer/AbstractRenderer.java b/layout/src/main/java/com/itextpdf/layout/renderer/AbstractRenderer.java index 2266a79ec1..910aa8325a 100644 --- a/layout/src/main/java/com/itextpdf/layout/renderer/AbstractRenderer.java +++ b/layout/src/main/java/com/itextpdf/layout/renderer/AbstractRenderer.java @@ -149,6 +149,13 @@ public abstract class AbstractRenderer implements IRenderer { */ static final int LEFT_SIDE = 3; + private static final int ARC_RIGHT_DEGREE = 0; + private static final int ARC_TOP_DEGREE = 90; + private static final int ARC_LEFT_DEGREE = 180; + private static final int ARC_BOTTOM_DEGREE = 270; + + private static final int ARC_QUARTER_CLOCKWISE_EXTENT = -90; + // TODO linkedList? protected List childRenderers = new ArrayList<>(); protected List positionedRenderers = new ArrayList<>(); @@ -767,8 +774,6 @@ private boolean clipArea(DrawContext drawContext, Rectangle outerBorderBox, bool // border widths should be considered only once assert false == considerBordersBeforeOuterClipping || false == considerBordersBeforeInnerClipping; - final double curv = 0.4477f; - // border widths float[] borderWidths = {0, 0, 0, 0}; // outer box @@ -805,7 +810,7 @@ private boolean clipArea(DrawContext drawContext, Rectangle outerBorderBox, bool // clip border area outside if (clipOuter) { - clipOuterArea(canvas, curv, horizontalRadii, verticalRadii, outerBox, cornersX, cornersY); + clipOuterArea(canvas, horizontalRadii, verticalRadii, outerBox, cornersX, cornersY); } if (considerBordersBeforeInnerClipping) { @@ -814,28 +819,27 @@ private boolean clipArea(DrawContext drawContext, Rectangle outerBorderBox, bool // clip border area inside if (clipInner) { - clipInnerArea(canvas, curv, horizontalRadii, verticalRadii, outerBox, cornersX, cornersY, borderWidths); + clipInnerArea(canvas, horizontalRadii, verticalRadii, outerBox, cornersX, cornersY, borderWidths); } } return hasNotNullRadius; } - private void clipOuterArea(PdfCanvas canvas, double curv, float[] horizontalRadii, float[] verticalRadii, float[] outerBox, float[] cornersX, float[] cornersY) { - float top = outerBox[0], right = outerBox[1], - bottom = outerBox[2], - left = outerBox[3]; - - float x1 = cornersX[0], y1 = cornersY[0], - x2 = cornersX[1], y2 = cornersY[1], - x3 = cornersX[2], y3 = cornersY[2], - x4 = cornersX[3], y4 = cornersY[3]; + private void clipOuterArea(PdfCanvas canvas, float[] horizontalRadii, float[] verticalRadii, + float[] outerBox, float[] cornersX, float[] cornersY) { + final double top = outerBox[TOP_SIDE]; + final double right = outerBox[RIGHT_SIDE]; + final double bottom = outerBox[BOTTOM_SIDE]; + final double left = outerBox[LEFT_SIDE]; // left top corner if (0 != horizontalRadii[0] || 0 != verticalRadii[0]) { + double arcBottom = ((double) cornersY[TOP_SIDE]) - verticalRadii[TOP_SIDE]; + double arcRight = ((double) cornersX[TOP_SIDE]) + horizontalRadii[TOP_SIDE]; canvas .moveTo(left, bottom) - .lineTo(left, y1) - .curveTo(left, y1 + verticalRadii[0] * curv, x1 - horizontalRadii[0] * curv, top, x1, top) + .arcContinuous(left, arcBottom, arcRight, top, + ARC_LEFT_DEGREE, ARC_QUARTER_CLOCKWISE_EXTENT) .lineTo(right, top) .lineTo(right, bottom) .lineTo(left, bottom); @@ -843,10 +847,12 @@ private void clipOuterArea(PdfCanvas canvas, double curv, float[] horizontalRadi } // right top corner if (0 != horizontalRadii[1] || 0 != verticalRadii[1]) { + double arcLeft = ((double) cornersX[RIGHT_SIDE]) - horizontalRadii[RIGHT_SIDE]; + double arcBottom = ((double) cornersY[RIGHT_SIDE]) - verticalRadii[RIGHT_SIDE]; canvas .moveTo(left, top) - .lineTo(x2, top) - .curveTo(x2 + horizontalRadii[1] * curv, top, right, y2 + verticalRadii[1] * curv, right, y2) + .arcContinuous(arcLeft, top, right, arcBottom, + ARC_TOP_DEGREE, ARC_QUARTER_CLOCKWISE_EXTENT) .lineTo(right, bottom) .lineTo(left, bottom) .lineTo(left, top); @@ -854,10 +860,12 @@ private void clipOuterArea(PdfCanvas canvas, double curv, float[] horizontalRadi } // right bottom corner if (0 != horizontalRadii[2] || 0 != verticalRadii[2]) { + double arcTop = ((double) cornersY[BOTTOM_SIDE]) + verticalRadii[BOTTOM_SIDE]; + double arcLeft = ((double) cornersX[BOTTOM_SIDE]) - horizontalRadii[BOTTOM_SIDE]; canvas .moveTo(right, top) - .lineTo(right, y3) - .curveTo(right, y3 - verticalRadii[2] * curv, x3 + horizontalRadii[2] * curv, bottom, x3, bottom) + .arcContinuous(right, arcTop, arcLeft, bottom, + ARC_RIGHT_DEGREE, ARC_QUARTER_CLOCKWISE_EXTENT) .lineTo(left, bottom) .lineTo(left, top) .lineTo(right, top); @@ -865,10 +873,12 @@ private void clipOuterArea(PdfCanvas canvas, double curv, float[] horizontalRadi } // left bottom corner if (0 != horizontalRadii[3] || 0 != verticalRadii[3]) { + double arcRight = ((double) cornersX[LEFT_SIDE]) + horizontalRadii[LEFT_SIDE]; + double arcTop = ((double) cornersY[LEFT_SIDE]) + verticalRadii[LEFT_SIDE]; canvas .moveTo(right, bottom) - .lineTo(x4, bottom) - .curveTo(x4 - horizontalRadii[3] * curv, bottom, left, y4 - verticalRadii[3] * curv, left, y4) + .arcContinuous(arcRight, bottom, left, arcTop, + ARC_BOTTOM_DEGREE, ARC_QUARTER_CLOCKWISE_EXTENT) .lineTo(left, top) .lineTo(right, top) .lineTo(right, bottom); @@ -876,26 +886,32 @@ private void clipOuterArea(PdfCanvas canvas, double curv, float[] horizontalRadi } } - private void clipInnerArea(PdfCanvas canvas, double curv, float[] horizontalRadii, float[] verticalRadii, float[] outerBox, float[] cornersX, float[] cornersY, float[] borderWidths) { - float top = outerBox[0], - right = outerBox[1], - bottom = outerBox[2], - left = outerBox[3]; + private void clipInnerArea(PdfCanvas canvas, float[] horizontalRadii, float[] verticalRadii, + float[] outerBox, float[] cornersX, float[] cornersY, float[] borderWidths) { + final double top = outerBox[TOP_SIDE]; + final double right = outerBox[RIGHT_SIDE]; + final double bottom = outerBox[BOTTOM_SIDE]; + final double left = outerBox[LEFT_SIDE]; - float x1 = cornersX[0], y1 = cornersY[0], - x2 = cornersX[1], y2 = cornersY[1], - x3 = cornersX[2], y3 = cornersY[2], - x4 = cornersX[3], y4 = cornersY[3]; - float topBorderWidth = borderWidths[0], - rightBorderWidth = borderWidths[1], - bottomBorderWidth = borderWidths[2], - leftBorderWidth = borderWidths[3]; + final double x1 = cornersX[TOP_SIDE]; + final double y1 = cornersY[TOP_SIDE]; + final double x2 = cornersX[RIGHT_SIDE]; + final double y2 = cornersY[RIGHT_SIDE]; + final double x3 = cornersX[BOTTOM_SIDE]; + final double y3 = cornersY[BOTTOM_SIDE]; + final double x4 = cornersX[LEFT_SIDE]; + final double y4 = cornersY[LEFT_SIDE]; + final double topBorderWidth = borderWidths[TOP_SIDE]; + final double rightBorderWidth = borderWidths[RIGHT_SIDE]; + final double bottomBorderWidth = borderWidths[BOTTOM_SIDE]; + final double leftBorderWidth = borderWidths[LEFT_SIDE]; // left top corner if (0 != horizontalRadii[0] || 0 != verticalRadii[0]) { canvas - .moveTo(left, y1) - .curveTo(left, y1 + verticalRadii[0] * curv, x1 - horizontalRadii[0] * curv, top, x1, top) + .arc(left, y1 - verticalRadii[TOP_SIDE], + x1 + horizontalRadii[TOP_SIDE], top, + ARC_LEFT_DEGREE, ARC_QUARTER_CLOCKWISE_EXTENT) .lineTo(x2, top) .lineTo(right, y2) .lineTo(right, y3) @@ -914,8 +930,9 @@ private void clipInnerArea(PdfCanvas canvas, double curv, float[] horizontalRadi // right top corner if (0 != horizontalRadii[1] || 0 != verticalRadii[1]) { canvas - .moveTo(x2, top) - .curveTo(x2 + horizontalRadii[1] * curv, top, right, y2 + verticalRadii[1] * curv, right, y2) + .arc(x2 - horizontalRadii[RIGHT_SIDE], top, right, + y2 - verticalRadii[RIGHT_SIDE], + ARC_TOP_DEGREE, ARC_QUARTER_CLOCKWISE_EXTENT) .lineTo(right, y3) .lineTo(x3, bottom) .lineTo(x4, bottom) @@ -934,8 +951,9 @@ private void clipInnerArea(PdfCanvas canvas, double curv, float[] horizontalRadi // right bottom corner if (0 != horizontalRadii[2] || 0 != verticalRadii[2]) { canvas - .moveTo(right, y3) - .curveTo(right, y3 - verticalRadii[2] * curv, x3 + horizontalRadii[2] * curv, bottom, x3, bottom) + .arc(right, y3 + verticalRadii[BOTTOM_SIDE], + x3 - horizontalRadii[BOTTOM_SIDE], bottom, + ARC_RIGHT_DEGREE, ARC_QUARTER_CLOCKWISE_EXTENT) .lineTo(x4, bottom) .lineTo(left, y4) .lineTo(left, y1) @@ -954,8 +972,9 @@ private void clipInnerArea(PdfCanvas canvas, double curv, float[] horizontalRadi // left bottom corner if (0 != horizontalRadii[3] || 0 != verticalRadii[3]) { canvas - .moveTo(x4, bottom) - .curveTo(x4 - horizontalRadii[3] * curv, bottom, left, y4 - verticalRadii[3] * curv, left, y4) + .arc(x4 + horizontalRadii[LEFT_SIDE], bottom, + left, y4 + verticalRadii[LEFT_SIDE], + ARC_BOTTOM_DEGREE, ARC_QUARTER_CLOCKWISE_EXTENT) .lineTo(left, y1) .lineTo(x1, top) .lineTo(x2, top) @@ -1308,6 +1327,55 @@ protected static boolean isOverflowFit(OverflowPropertyValue rendererOverflowPro return rendererOverflowProperty == null || OverflowPropertyValue.FIT.equals(rendererOverflowProperty); } + /** + * Replaces given property own value with the given value. + * + * @param property the property to be replaced + * @param replacementValue the value with which property will be replaced + * @param the type associated with the property + * @return previous property value + */ + T replaceOwnProperty(int property, T replacementValue) { + T ownProperty = this.getOwnProperty(property); + setProperty(property, replacementValue); + return ownProperty; + } + + /** + * Returns back own value of the given property. + * + * @param property the property to be returned back + * @param prevValue the value which will be returned back + * @param the type associated with the property + */ + void returnBackOwnProperty(int property, T prevValue) { + if (prevValue == null) { + deleteOwnProperty(property); + } else { + setProperty(property, prevValue); + } + } + + /** + * Checks if this renderer has intrinsic aspect ratio. + * + * @return true, if aspect ratio is defined for this renderer, false otherwise + */ + boolean hasAspectRatio() { + // TODO DEVSIX-5255 This method should be changed after we support aspect-ratio property + return false; + } + + /** + * Gets intrinsic aspect ratio for this renderer. + * + * @return aspect ratio, if it is defined for this renderer, null otherwise + */ + Float getAspectRatio() { + // TODO DEVSIX-5255 This method should be changed after we support aspect-ratio property + return null; + } + static void processWaitingDrawing(IRenderer child, Transform transformProp, List waitingDrawing) { if (FloatingHelper.isRendererFloating(child) || transformProp != null) { waitingDrawing.add(child); @@ -2667,6 +2735,16 @@ void setThisAsParent(Collection children) { } } + boolean logWarningIfGetNextRendererNotOverridden(Class baseClass, Class rendererClass) { + if (baseClass != rendererClass) { + final Logger logger = LoggerFactory.getLogger(baseClass); + logger.warn(MessageFormatUtil.format(LogMessageConstant.GET_NEXT_RENDERER_SHOULD_BE_OVERRIDDEN)); + return false; + } else { + return true; + } + } + private void removeThisFromParent(IRenderer toRemove) { // we need to be sure that the removed element has no other entries in child renderers list if (toRemove != null && this == toRemove.getParent() && !this.childRenderers.contains(toRemove)) { diff --git a/layout/src/main/java/com/itextpdf/layout/renderer/BlockRenderer.java b/layout/src/main/java/com/itextpdf/layout/renderer/BlockRenderer.java index a4ad9bbe83..14b60534fa 100644 --- a/layout/src/main/java/com/itextpdf/layout/renderer/BlockRenderer.java +++ b/layout/src/main/java/com/itextpdf/layout/renderer/BlockRenderer.java @@ -977,6 +977,12 @@ void fixOccupiedAreaIfOverflowedY(OverflowPropertyValue overflowY, Rectangle lay } /** + * Decreases parentBBox to the size of borders, paddings and margins. + * + * @param parentBBox {@link Rectangle} to be decreased + * @param borders the border values to decrease parentBBox + * @param paddings the padding values to decrease parentBBox + * @return the difference between previous and current parentBBox's * @deprecated Need to be removed in next major release. */ @Deprecated diff --git a/layout/src/main/java/com/itextpdf/layout/renderer/CellRenderer.java b/layout/src/main/java/com/itextpdf/layout/renderer/CellRenderer.java index 7096a179a2..54e9a4fd6a 100644 --- a/layout/src/main/java/com/itextpdf/layout/renderer/CellRenderer.java +++ b/layout/src/main/java/com/itextpdf/layout/renderer/CellRenderer.java @@ -52,6 +52,7 @@ This file is part of the iText (R) project. import com.itextpdf.layout.IPropertyContainer; import com.itextpdf.layout.borders.Border; import com.itextpdf.layout.element.Cell; +import com.itextpdf.layout.layout.LayoutContext; import com.itextpdf.layout.property.BorderCollapsePropertyValue; import com.itextpdf.layout.property.Property; import com.itextpdf.layout.property.UnitValue; @@ -201,10 +202,19 @@ protected Rectangle applySpacings(Rectangle rect, float[] spacings, boolean reve } /** - * {@inheritDoc} + * Gets a new instance of this class to be used as a next renderer, after this renderer is used, if + * {@link #layout(LayoutContext)} is called more than once. + * + *

+ * If a renderer overflows to the next area, iText uses this method to create a renderer + * for the overflow part. So if one wants to extend {@link CellRenderer}, one should override + * this method: otherwise the default method will be used and thus the default rather than the custom + * renderer will be created. + * @return new renderer instance */ @Override public IRenderer getNextRenderer() { + logWarningIfGetNextRendererNotOverridden(CellRenderer.class, this.getClass()); return new CellRenderer((Cell) getModelElement()); } } diff --git a/layout/src/main/java/com/itextpdf/layout/renderer/DivRenderer.java b/layout/src/main/java/com/itextpdf/layout/renderer/DivRenderer.java index 05bf46efc5..d2f64171e8 100644 --- a/layout/src/main/java/com/itextpdf/layout/renderer/DivRenderer.java +++ b/layout/src/main/java/com/itextpdf/layout/renderer/DivRenderer.java @@ -44,6 +44,7 @@ This file is part of the iText (R) project. package com.itextpdf.layout.renderer; import com.itextpdf.layout.element.Div; +import com.itextpdf.layout.layout.LayoutContext; public class DivRenderer extends BlockRenderer { @@ -57,10 +58,19 @@ public DivRenderer(Div modelElement) { } /** - * {@inheritDoc} + * Gets a new instance of this class to be used as a next renderer, after this renderer is used, if + * {@link #layout(LayoutContext)} is called more than once. + * + *

+ * If a renderer overflows to the next area, iText uses this method to create a renderer + * for the overflow part. So if one wants to extend {@link DivRenderer}, one should override + * this method: otherwise the default method will be used and thus the default rather than the custom + * renderer will be created. + * @return new renderer instance */ @Override public IRenderer getNextRenderer() { + logWarningIfGetNextRendererNotOverridden(DivRenderer.class, this.getClass()); return new DivRenderer((Div) modelElement); } } diff --git a/layout/src/main/java/com/itextpdf/layout/renderer/DocumentRenderer.java b/layout/src/main/java/com/itextpdf/layout/renderer/DocumentRenderer.java index 52e88b659f..073d811b20 100644 --- a/layout/src/main/java/com/itextpdf/layout/renderer/DocumentRenderer.java +++ b/layout/src/main/java/com/itextpdf/layout/renderer/DocumentRenderer.java @@ -108,7 +108,9 @@ public LayoutArea getOccupiedArea() { */ @Override public IRenderer getNextRenderer() { - return new DocumentRenderer(document, immediateFlush); + DocumentRenderer renderer = new DocumentRenderer(document, immediateFlush); + renderer.targetCounterHandler = new TargetCounterHandler(targetCounterHandler); + return renderer; } protected LayoutArea updateCurrentArea(LayoutResult overflowResult) { @@ -117,7 +119,8 @@ protected LayoutArea updateCurrentArea(LayoutResult overflowResult) { if (taggingHelper != null) { taggingHelper.releaseFinishedHints(); } - AreaBreak areaBreak = overflowResult != null && overflowResult.getAreaBreak() != null ? overflowResult.getAreaBreak() : null; + AreaBreak areaBreak = overflowResult != null && overflowResult.getAreaBreak() != null ? + overflowResult.getAreaBreak() : null; if (areaBreak != null && areaBreak.getType() == AreaBreakType.LAST_PAGE) { while (currentPageNumber < document.getPdfDocument().getNumberOfPages()) { moveToNextPage(); @@ -126,7 +129,8 @@ protected LayoutArea updateCurrentArea(LayoutResult overflowResult) { moveToNextPage(); } PageSize customPageSize = areaBreak != null ? areaBreak.getPageSize() : null; - while (document.getPdfDocument().getNumberOfPages() >= currentPageNumber && document.getPdfDocument().getPage(currentPageNumber).isFlushed()) { + while (document.getPdfDocument().getNumberOfPages() >= currentPageNumber && + document.getPdfDocument().getPage(currentPageNumber).isFlushed()) { currentPageNumber++; } PageSize lastPageSize = ensureDocumentHasNPages(currentPageNumber, customPageSize); @@ -156,14 +160,16 @@ protected void flushSingleRenderer(IRenderer resultRenderer) { } boolean wrapOldContent = pdfDocument.getReader() != null && pdfDocument.getWriter() != null && - correspondingPage.getContentStreamCount() > 0 && correspondingPage.getLastContentStream().getLength() > 0 && + correspondingPage.getContentStreamCount() > 0 && + correspondingPage.getLastContentStream().getLength() > 0 && !wrappedContentPage.contains(pageNum) && pdfDocument.getNumberOfPages() >= pageNum; wrappedContentPage.add(pageNum); if (pdfDocument.isTagged()) { pdfDocument.getTagStructureContext().getAutoTaggingPointer().setPageForTagging(correspondingPage); } - resultRenderer.draw(new DrawContext(pdfDocument, new PdfCanvas(correspondingPage, wrapOldContent), pdfDocument.isTagged())); + resultRenderer.draw(new DrawContext(pdfDocument, + new PdfCanvas(correspondingPage, wrapOldContent), pdfDocument.isTagged())); } } @@ -178,7 +184,7 @@ protected PageSize addNewPage(PageSize customPageSize) { /** * Adds some pages so that the overall number is at least n. - * Returns the page size of the n'th page. + * Returns the page size of the page number {@code n}. */ private PageSize ensureDocumentHasNPages(int n, PageSize customPageSize) { PageSize lastPageSize = null; @@ -200,8 +206,8 @@ private Rectangle getCurrentPageEffectiveArea(PageSize pageSize) { } private void moveToNextPage() { - // We don't flush this page immediately, but only flush previous one because of manipulations with areas in case - // of keepTogether property. + // We don't flush this page immediately, but only flush previous one because of manipulations + // with areas in case of keepTogether property. if (immediateFlush && currentPageNumber > 1) { document.getPdfDocument().getPage(currentPageNumber - 1).flush(); } diff --git a/layout/src/main/java/com/itextpdf/layout/renderer/FlexContainerRenderer.java b/layout/src/main/java/com/itextpdf/layout/renderer/FlexContainerRenderer.java index c8030b5fa3..bcfd36cc4d 100644 --- a/layout/src/main/java/com/itextpdf/layout/renderer/FlexContainerRenderer.java +++ b/layout/src/main/java/com/itextpdf/layout/renderer/FlexContainerRenderer.java @@ -75,10 +75,19 @@ public FlexContainerRenderer(Div modelElement) { } /** - * {@inheritDoc} + * Gets a new instance of this class to be used as a next renderer, after this renderer is used, if + * {@link #layout(LayoutContext)} is called more than once. + * + *

+ * If a renderer overflows to the next area, iText uses this method to create a renderer + * for the overflow part. So if one wants to extend {@link FlexContainerRenderer}, one should override + * this method: otherwise the default method will be used and thus the default rather than the custom + * renderer will be created. + * @return new renderer instance */ @Override public IRenderer getNextRenderer() { + logWarningIfGetNextRendererNotOverridden(FlexContainerRenderer.class, this.getClass()); return new FlexContainerRenderer((Div) modelElement); } diff --git a/layout/src/main/java/com/itextpdf/layout/renderer/FlexUtil.java b/layout/src/main/java/com/itextpdf/layout/renderer/FlexUtil.java index 48306df177..f0b6cfd179 100644 --- a/layout/src/main/java/com/itextpdf/layout/renderer/FlexUtil.java +++ b/layout/src/main/java/com/itextpdf/layout/renderer/FlexUtil.java @@ -43,6 +43,7 @@ This file is part of the iText (R) project. */ package com.itextpdf.layout.renderer; +import com.itextpdf.io.LogMessageConstant; import com.itextpdf.kernel.geom.Rectangle; import com.itextpdf.layout.exceptions.LayoutExceptionMessageConstant; import com.itextpdf.layout.layout.LayoutArea; @@ -54,6 +55,8 @@ This file is part of the iText (R) project. import com.itextpdf.layout.property.JustifyContent; import com.itextpdf.layout.property.Property; import com.itextpdf.layout.property.UnitValue; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.List; @@ -66,6 +69,8 @@ final class FlexUtil { private static final float FLEX_SHRINK_INITIAL_VALUE = 1F; + private static Logger logger = LoggerFactory.getLogger(FlexUtil.class); + private FlexUtil() { // Do nothing } @@ -186,17 +191,24 @@ static void determineFlexBasisAndHypotheticalMainSizeForFlexItems( for (FlexItemCalculationInfo info : flexItemCalculationInfos) { // 3. Determine the flex base size and hypothetical main size of each item: - // A. If the item has a definite used flex basis, that’s the flex base size. - info.flexBaseSize = info.flexBasis; + AbstractRenderer renderer = info.renderer; // TODO DEVSIX-5001 content as width are not supported - // TODO DEVSIX-5004 Implement method to check whether an element has an intrinsic aspect ratio // B. If the flex item has ... // an intrinsic aspect ratio, // a used flex basis of content, and // a definite cross size, // then the flex base size is calculated from its inner cross size // and the flex item’s intrinsic aspect ratio. + Float rendererHeight = renderer.retrieveHeight(); + if (renderer.hasAspectRatio() && + info.flexBasisContent && rendererHeight != null) { + float aspectRatio = (float) renderer.getAspectRatio(); + info.flexBaseSize = (float) rendererHeight * aspectRatio; + } else { + // A. If the item has a definite used flex basis, that’s the flex base size. + info.flexBaseSize = info.flexBasis; + } // TODO DEVSIX-5001 content as width is not supported // C. If the used flex basis is content or depends on its available space, @@ -396,11 +408,20 @@ static void resolveFlexibleLengths(List> lines, fl static void determineHypotheticalCrossSizeForFlexItems(List> lines) { for (List line : lines) { for (FlexItemCalculationInfo info : line) { + UnitValue prevWidth = info.renderer.replaceOwnProperty(Property.WIDTH, + UnitValue.createPointValue(info.mainSize)); + UnitValue prevMinWidth = info.renderer.replaceOwnProperty(Property.MIN_WIDTH, null); LayoutResult result = info.renderer.layout(new LayoutContext( - new LayoutArea(0, new Rectangle(info.getOuterMainSize(info.mainSize), AbstractRenderer.INF)))); + new LayoutArea(0, new Rectangle(AbstractRenderer.INF, AbstractRenderer.INF)))); + info.renderer.returnBackOwnProperty(Property.MIN_WIDTH, prevMinWidth); + info.renderer.returnBackOwnProperty(Property.WIDTH, prevWidth); // Since main size is clamped with min-width, we do expect the result to be full - assert result.getStatus() == LayoutResult.FULL; - info.hypotheticalCrossSize = info.getInnerCrossSize(result.getOccupiedArea().getBBox().getHeight()); + if (result.getStatus() == LayoutResult.FULL) { + info.hypotheticalCrossSize = info.getInnerCrossSize(result.getOccupiedArea().getBBox().getHeight()); + } else { + logger.error(LogMessageConstant.FLEX_ITEM_LAYOUT_RESULT_IS_NOT_FULL); + info.hypotheticalCrossSize = 0; + } } } } @@ -481,12 +502,15 @@ static void determineUsedCrossSizeOfEachFlexItem(ListgetProperty( Property.ALIGN_SELF, alignItems); // TODO DEVSIX-5002 Stretch value shall be ignored if margin auto for cross axis is set - if (alignSelf == AlignmentPropertyValue.STRETCH || alignSelf == AlignmentPropertyValue.NORMAL) { + if ((alignSelf == AlignmentPropertyValue.STRETCH || alignSelf == AlignmentPropertyValue.NORMAL) && + info.renderer.getProperty(Property.HEIGHT) == null) { info.crossSize = info.getInnerCrossSize(lineCrossSizes.get(i)); Float maxHeight = infoRenderer.retrieveMaxHeight(); if (maxHeight != null) { @@ -612,8 +636,10 @@ private static List createFlexItemCalculationInfos( // TODO DEVSIX-5091 improve determining of the flex base size when flex-basis: content float maxWidth = calculateMaxWidth(abstractRenderer, flexContainerWidth); float flexBasis; + boolean flexBasisContent = false; if (renderer.getProperty(Property.FLEX_BASIS) == null) { flexBasis = maxWidth; + flexBasisContent = true; } else { flexBasis = (float) abstractRenderer.retrieveUnitValue(flexContainerWidth, Property.FLEX_BASIS); if (AbstractRenderer.isBorderBoxSizing(abstractRenderer)) { @@ -626,8 +652,8 @@ private static List createFlexItemCalculationInfos( float flexShrink = (float) renderer.getProperty(Property.FLEX_SHRINK, FLEX_SHRINK_INITIAL_VALUE); - final FlexItemCalculationInfo flexItemInfo = new FlexItemCalculationInfo( - (AbstractRenderer) renderer, flexBasis, flexGrow, flexShrink, flexContainerWidth); + final FlexItemCalculationInfo flexItemInfo = new FlexItemCalculationInfo((AbstractRenderer) renderer, + flexBasis, flexGrow, flexShrink, flexContainerWidth, flexBasisContent); flexItems.add(flexItemInfo); } @@ -649,9 +675,13 @@ private static float calculateMaxWidth(AbstractRenderer flexItemRenderer, float maxWidth = flexItemRenderer.retrieveMaxWidth(flexContainerWidth); } if (maxWidth == null) { - maxWidth = flexItemRenderer.getMinMaxWidth().getMaxWidth(); - maxWidth = flexItemRenderer.applyMarginsBordersPaddings( - new Rectangle((float) maxWidth, 0), false).getWidth(); + if (flexItemRenderer instanceof ImageRenderer) { + // TODO DEVSIX-5269 getMinMaxWidth doesn't always return the original image width + maxWidth = ((ImageRenderer) flexItemRenderer).getImageWidth(); + } else { + maxWidth = flexItemRenderer.applyMarginsBordersPaddings( + new Rectangle(flexItemRenderer.getMinMaxWidth().getMaxWidth(), 0), false).getWidth(); + } } } return (float) maxWidth; @@ -680,9 +710,11 @@ static class FlexItemCalculationInfo { float flexBaseSize; float hypotheticalMainSize; float hypotheticalCrossSize; + boolean flexBasisContent; public FlexItemCalculationInfo(AbstractRenderer renderer, float flexBasis, - float flexGrow, float flexShrink, float areaWidth) { + float flexGrow, float flexShrink, float areaWidth, boolean flexBasisContent) { + this.flexBasisContent = flexBasisContent; this.renderer = renderer; this.flexBasis = flexBasis; if (flexShrink < 0) { @@ -693,21 +725,13 @@ public FlexItemCalculationInfo(AbstractRenderer renderer, float flexBasis, throw new IllegalArgumentException(LayoutExceptionMessageConstant.FLEX_GROW_CANNOT_BE_NEGATIVE); } this.flexGrow = flexGrow; - // We always need to clamp flex item's sizes with min-width, so this calculation is necessary - // We also need to get min-width not based on Property.WIDTH - final UnitValue rendererWidth = renderer.getOwnProperty(Property.WIDTH); - final boolean hasOwnWidth = renderer.hasOwnProperty(Property.WIDTH); - renderer.setProperty(Property.WIDTH, null); - MinMaxWidth minMaxWidth = renderer.getMinMaxWidth(); - if (hasOwnWidth) { - renderer.setProperty(Property.WIDTH, rendererWidth); - } else { - renderer.deleteOwnProperty(Property.WIDTH); - } - this.minContent = getInnerMainSize(minMaxWidth.getMinWidth()); - boolean isMaxWidthApplied = null != this.renderer.retrieveMaxWidth(areaWidth); + Float definiteMinContent = renderer.retrieveMinWidth(areaWidth); + // null means that min-width property is not set or has auto value. In both cases we should calculate it + this.minContent = + definiteMinContent == null ? calculateMinContentAuto(areaWidth) : (float) definiteMinContent; + Float maxWidth = this.renderer.retrieveMaxWidth(areaWidth); // As for now we assume that max width should be calculated so - this.maxContent = isMaxWidthApplied ? minMaxWidth.getMaxWidth() : AbstractRenderer.INF; + this.maxContent = maxWidth == null ? AbstractRenderer.INF : (float) maxWidth; } public Rectangle toRectangle() { @@ -729,5 +753,107 @@ float getOuterCrossSize(float size) { float getInnerCrossSize(float size) { return renderer.applyMarginsBordersPaddings(new Rectangle(0, size), false).getHeight(); } + + private float calculateMinContentAuto(float flexContainerWidth) { + // Automatic Minimum Size of Flex Items https://www.w3.org/TR/css-flexbox-1/#content-based-minimum-size + Float specifiedSizeSuggestion = calculateSpecifiedSizeSuggestion(flexContainerWidth); + float contentSizeSuggestion = calculateContentSizeSuggestion(flexContainerWidth); + if (renderer.hasAspectRatio() && specifiedSizeSuggestion == null) { + // However, if the box has an aspect ratio and no specified size, + // its content-based minimum size is the smaller of its content size suggestion + // and its transferred size suggestion + Float transferredSizeSuggestion = calculateTransferredSizeSuggestion(); + if (transferredSizeSuggestion == null) { + return contentSizeSuggestion; + } else { + return Math.min(contentSizeSuggestion, (float) transferredSizeSuggestion); + } + } else if (specifiedSizeSuggestion == null) { + // If the box has neither a specified size suggestion nor an aspect ratio, + // its content-based minimum size is the content size suggestion. + return contentSizeSuggestion; + } else { + // In general, the content-based minimum size of a flex item is the smaller + // of its content size suggestion and its specified size suggestion + return Math.min(contentSizeSuggestion, (float) specifiedSizeSuggestion); + } + } + + /** + * If the item has an intrinsic aspect ratio and its computed cross size property is definite, + * then the transferred size suggestion is that size (clamped by its min and max cross size properties + * if they are definite), converted through the aspect ratio. It is otherwise undefined. + * + * @return transferred size suggestion if it can be calculated, null otherwise + */ + private Float calculateTransferredSizeSuggestion() { + Float transferredSizeSuggestion = null; + Float height = renderer.retrieveHeight(); + if (renderer.hasAspectRatio() && height != null) { + transferredSizeSuggestion = height * renderer.getAspectRatio(); + + transferredSizeSuggestion = + clampValueByCrossSizesConvertedThroughAspectRatio((float) transferredSizeSuggestion); + } + return transferredSizeSuggestion; + } + + /** + * If the item’s computed main size property is definite, + * then the specified size suggestion is that size (clamped by its max main size property if it’s definite). + * It is otherwise undefined. + * + * @param flexContainerWidth the width of the flex container + * @return specified size suggestion if it's definite, null otherwise + */ + private Float calculateSpecifiedSizeSuggestion(float flexContainerWidth) { + if (renderer.hasProperty(Property.WIDTH)) { + return renderer.retrieveWidth(flexContainerWidth); + } else { + return null; + } + } + + /** + * The content size suggestion is the min-content size in the main axis, clamped, if it has an aspect ratio, + * by any definite min and max cross size properties converted through the aspect ratio, + * and then further clamped by the max main size property if that is definite. + * + * @param flexContainerWidth the width of the flex container + * @return content size suggestion + */ + private float calculateContentSizeSuggestion(float flexContainerWidth) { + final UnitValue rendererWidth = renderer.replaceOwnProperty(Property.WIDTH, null); + final UnitValue rendererHeight = renderer.replaceOwnProperty(Property.HEIGHT, null); + MinMaxWidth minMaxWidth = renderer.getMinMaxWidth(); + float minContentSize = getInnerMainSize(minMaxWidth.getMinWidth()); + renderer.returnBackOwnProperty(Property.HEIGHT, rendererHeight); + renderer.returnBackOwnProperty(Property.WIDTH, rendererWidth); + + if (renderer.hasAspectRatio()) { + minContentSize = clampValueByCrossSizesConvertedThroughAspectRatio(minContentSize); + } + Float maxWidth = renderer.retrieveMaxWidth(flexContainerWidth); + if (maxWidth == null) { + maxWidth = AbstractRenderer.INF; + } + + return Math.min(minContentSize, (float) maxWidth); + } + + private float clampValueByCrossSizesConvertedThroughAspectRatio(float value) { + Float maxHeight = renderer.retrieveMaxHeight(); + if (maxHeight == null || !renderer.hasProperty(Property.MAX_HEIGHT)) { + maxHeight = AbstractRenderer.INF; + } + Float minHeight = renderer.retrieveMinHeight(); + if (minHeight == null || !renderer.hasProperty(Property.MIN_HEIGHT)) { + minHeight = 0F; + } + + return Math.min( + Math.max((float) (minHeight * renderer.getAspectRatio()), value), + (float) (maxHeight * renderer.getAspectRatio())); + } } } diff --git a/layout/src/main/java/com/itextpdf/layout/renderer/ImageRenderer.java b/layout/src/main/java/com/itextpdf/layout/renderer/ImageRenderer.java index f013b693b1..a07232c999 100644 --- a/layout/src/main/java/com/itextpdf/layout/renderer/ImageRenderer.java +++ b/layout/src/main/java/com/itextpdf/layout/renderer/ImageRenderer.java @@ -101,6 +101,8 @@ public class ImageRenderer extends AbstractRenderer implements ILeafElementRende */ public ImageRenderer(Image image) { super(image); + imageWidth = image.getImageWidth(); + imageHeight = image.getImageHeight(); } @Override @@ -111,8 +113,6 @@ public LayoutResult layout(LayoutContext layoutContext) { AffineTransform t = new AffineTransform(); Image modelElement = (Image) (getModelElement()); PdfXObject xObject = modelElement.getXObject(); - imageWidth = modelElement.getImageWidth(); - imageHeight = modelElement.getImageHeight(); calculateImageDimensions(layoutBox, t, xObject); @@ -390,6 +390,40 @@ public Rectangle getBorderAreaBBox() { return initialOccupiedAreaBBox; } + /** + * {@inheritDoc} + */ + @Override + boolean hasAspectRatio() { + return true; + } + + /** + * {@inheritDoc} + */ + @Override + Float getAspectRatio() { + return imageWidth / imageHeight; + } + + /** + * Gets original width of the image, not the width set by {@link Image#setWidth} method. + * + * @return original image width + */ + public float getImageWidth() { + return imageWidth; + } + + /** + * Gets original height of the image, not the height set by {@link Image#setHeight} method. + * + * @return original image height + */ + public float getImageHeight() { + return imageHeight; + } + @Override protected Rectangle applyPaddings(Rectangle rect, UnitValue[] paddings, boolean reverse) { return rect; diff --git a/layout/src/main/java/com/itextpdf/layout/renderer/LinkRenderer.java b/layout/src/main/java/com/itextpdf/layout/renderer/LinkRenderer.java index 111227cf0d..7650e51623 100644 --- a/layout/src/main/java/com/itextpdf/layout/renderer/LinkRenderer.java +++ b/layout/src/main/java/com/itextpdf/layout/renderer/LinkRenderer.java @@ -49,6 +49,7 @@ This file is part of the iText (R) project. import org.slf4j.LoggerFactory; import com.itextpdf.io.util.MessageFormatUtil; +import com.itextpdf.layout.layout.LayoutContext; public class LinkRenderer extends TextRenderer { @@ -88,8 +89,20 @@ public void draw(DrawContext drawContext) { } + /** + * Gets a new instance of this class to be used as a next renderer, after this renderer is used, if + * {@link #layout(LayoutContext)} is called more than once. + * + *

+ * If a renderer overflows to the next area, iText uses this method to create a renderer + * for the overflow part. So if one wants to extend {@link LinkRenderer}, one should override + * this method: otherwise the default method will be used and thus the default rather than the custom + * renderer will be created. + * @return new renderer instance + */ @Override public IRenderer getNextRenderer() { + logWarningIfGetNextRendererNotOverridden(LinkRenderer.class, this.getClass()); return new LinkRenderer((Link) modelElement); } } diff --git a/layout/src/main/java/com/itextpdf/layout/renderer/ListRenderer.java b/layout/src/main/java/com/itextpdf/layout/renderer/ListRenderer.java index 4eb069614d..b7c59adff5 100644 --- a/layout/src/main/java/com/itextpdf/layout/renderer/ListRenderer.java +++ b/layout/src/main/java/com/itextpdf/layout/renderer/ListRenderer.java @@ -103,8 +103,20 @@ public LayoutResult layout(LayoutContext layoutContext) { return result; } + /** + * Gets a new instance of this class to be used as a next renderer, after this renderer is used, if + * {@link #layout(LayoutContext)} is called more than once. + * + *

+ * If a renderer overflows to the next area, iText uses this method to create a renderer + * for the overflow part. So if one wants to extend {@link ListRenderer}, one should override + * this method: otherwise the default method will be used and thus the default rather than the custom + * renderer will be created. + * @return new renderer instance + */ @Override public IRenderer getNextRenderer() { + logWarningIfGetNextRendererNotOverridden(ListRenderer.class, this.getClass()); return new ListRenderer((com.itextpdf.layout.element.List) modelElement); } diff --git a/layout/src/main/java/com/itextpdf/layout/renderer/ParagraphRenderer.java b/layout/src/main/java/com/itextpdf/layout/renderer/ParagraphRenderer.java index 82bf6c524e..32ec0d3198 100644 --- a/layout/src/main/java/com/itextpdf/layout/renderer/ParagraphRenderer.java +++ b/layout/src/main/java/com/itextpdf/layout/renderer/ParagraphRenderer.java @@ -67,6 +67,7 @@ This file is part of the iText (R) project. import com.itextpdf.layout.property.RenderingMode; import com.itextpdf.layout.property.TextAlignment; import com.itextpdf.layout.property.UnitValue; + import org.slf4j.LoggerFactory; import java.util.ArrayList; @@ -501,10 +502,19 @@ protected LayoutResult directLayout(LayoutContext layoutContext) { } /** - * {@inheritDoc} + * Gets a new instance of this class to be used as a next renderer, after this renderer is used, if + * {@link #layout(LayoutContext)} is called more than once. + * + *

+ * If a renderer overflows to the next area, iText uses this method to create a renderer + * for the overflow part. So if one wants to extend {@link ParagraphRenderer}, one should override + * this method: otherwise the default method will be used and thus the default rather than the custom + * renderer will be created. + * @return new renderer instance */ @Override public IRenderer getNextRenderer() { + logWarningIfGetNextRendererNotOverridden(ParagraphRenderer.class, this.getClass()); return new ParagraphRenderer((Paragraph) modelElement); } diff --git a/layout/src/main/java/com/itextpdf/layout/renderer/TabRenderer.java b/layout/src/main/java/com/itextpdf/layout/renderer/TabRenderer.java index 68edde17a5..6fc9cfe704 100644 --- a/layout/src/main/java/com/itextpdf/layout/renderer/TabRenderer.java +++ b/layout/src/main/java/com/itextpdf/layout/renderer/TabRenderer.java @@ -106,8 +106,20 @@ public void draw(DrawContext drawContext) { } } + /** + * Gets a new instance of this class to be used as a next renderer, after this renderer is used, if + * {@link #layout(LayoutContext)} is called more than once. + * + *

+ * If a renderer overflows to the next area, iText uses this method to create a renderer + * for the overflow part. So if one wants to extend {@link TabRenderer}, one should override + * this method: otherwise the default method will be used and thus the default rather than the custom + * renderer will be created. + * @return new renderer instance + */ @Override public IRenderer getNextRenderer() { + logWarningIfGetNextRendererNotOverridden(TabRenderer.class, this.getClass()); return new TabRenderer((Tab) modelElement); } } diff --git a/layout/src/main/java/com/itextpdf/layout/renderer/TableRenderer.java b/layout/src/main/java/com/itextpdf/layout/renderer/TableRenderer.java index 302d889381..05c7e8eb06 100644 --- a/layout/src/main/java/com/itextpdf/layout/renderer/TableRenderer.java +++ b/layout/src/main/java/com/itextpdf/layout/renderer/TableRenderer.java @@ -1194,10 +1194,19 @@ public void drawBackground(DrawContext drawContext) { } /** - * {@inheritDoc} + * Gets a new instance of this class to be used as a next renderer, after this renderer is used, if + * {@link #layout(LayoutContext)} is called more than once. + * + *

+ * If a renderer overflows to the next area, iText uses this method to create a renderer + * for the overflow part. So if one wants to extend {@link TableRenderer}, one should override + * this method: otherwise the default method will be used and thus the default rather than the custom + * renderer will be created. + * @return new renderer instance */ @Override public IRenderer getNextRenderer() { + logWarningIfGetNextRendererNotOverridden(TableRenderer.class, this.getClass()); TableRenderer nextTable = new TableRenderer(); nextTable.modelElement = modelElement; return nextTable; diff --git a/layout/src/main/java/com/itextpdf/layout/renderer/TextRenderer.java b/layout/src/main/java/com/itextpdf/layout/renderer/TextRenderer.java index c35e893342..496c8fd3c2 100644 --- a/layout/src/main/java/com/itextpdf/layout/renderer/TextRenderer.java +++ b/layout/src/main/java/com/itextpdf/layout/renderer/TextRenderer.java @@ -196,6 +196,7 @@ public LayoutResult layout(LayoutContext layoutContext) { FloatingHelper.adjustFloatedBlockLayoutBox(this, layoutBox, null, floatRendererAreas, floatPropertyValue, overflowX); } + float preMarginBorderPaddingWidth = layoutBox.getWidth(); UnitValue[] margins = getMargins(); applyMargins(layoutBox, margins, false); Border[] borders = getBorders(); @@ -204,7 +205,7 @@ public LayoutResult layout(LayoutContext layoutContext) { UnitValue[] paddings = getPaddings(); applyPaddings(layoutBox, paddings, false); - MinMaxWidth countedMinMaxWidth = new MinMaxWidth(area.getBBox().getWidth() - layoutBox.getWidth()); + MinMaxWidth countedMinMaxWidth = new MinMaxWidth(preMarginBorderPaddingWidth - layoutBox.getWidth()); AbstractWidthHandler widthHandler; if (noSoftWrap) { widthHandler = new SumSumWidthHandler(countedMinMaxWidth); @@ -1204,8 +1205,22 @@ public float getTabAnchorCharacterPosition() { return tabAnchorCharacterPosition; } + /** + * Gets a new instance of this class to be used as a next renderer, after this renderer is used, if + * {@link #layout(LayoutContext)} is called more than once. + * + *

+ * If {@link TextRenderer} overflows to the next line, iText uses this method to create a renderer + * for the overflow part. So if one wants to extend {@link TextRenderer}, one should override + * this method: otherwise the default method will be used and thus the default rather than the custom + * renderer will be created. Another method that should be overridden in case of + * {@link TextRenderer}'s extension is {@link #createCopy(GlyphLine, PdfFont)}. This method is responsible + * for creation of {@link TextRenderer}'s copies, which represent its parts of specific font. + * @return new renderer instance + */ @Override public IRenderer getNextRenderer() { + logWarningIfGetNextRendererNotOverridden(TextRenderer.class, this.getClass()); return new TextRenderer((Text) modelElement); } @@ -1579,7 +1594,24 @@ protected void setProcessedGlyphLineAndFont(GlyphLine gl, PdfFont font) { setProperty(Property.FONT, font); } + /** + * Creates a copy of this {@link TextRenderer}, which corresponds to the passed {@link GlyphLine} + * with {@link PdfFont}. + *

+ * While processing {@link TextRenderer}, iText uses this method to create {@link GlyphLine glyph lines} + * of specific {@link PdfFont fonts}, which represent the {@link TextRenderer}'s parts. If one extends + * {@link TextRenderer}, one should override this method, otherwise if {@link com.itextpdf.layout.font.FontSelector} + * related logic is triggered, copies of this {@link TextRenderer} will have the default behavior rather than + * the custom one. + * @param gl a {@link GlyphLine} which represents some of this {@link TextRenderer}'s content + * @param font a {@link PdfFont} for this part of the {@link TextRenderer}'s content + * @return copy of this {@link TextRenderer}, which correspond to the passed {@link GlyphLine} with {@link PdfFont} + */ protected TextRenderer createCopy(GlyphLine gl, PdfFont font) { + if (TextRenderer.class != this.getClass()) { + Logger logger = LoggerFactory.getLogger(TextRenderer.class); + logger.error(MessageFormatUtil.format(LogMessageConstant.CREATE_COPY_SHOULD_BE_OVERRIDDEN)); + } TextRenderer copy = new TextRenderer(this); copy.setProcessedGlyphLineAndFont(gl, font); return copy; diff --git a/layout/src/test/java/com/itextpdf/layout/CanvasTest.java b/layout/src/test/java/com/itextpdf/layout/CanvasTest.java index 92d18796fc..6718dd0a1c 100644 --- a/layout/src/test/java/com/itextpdf/layout/CanvasTest.java +++ b/layout/src/test/java/com/itextpdf/layout/CanvasTest.java @@ -62,10 +62,8 @@ This file is part of the iText (R) project. import java.io.IOException; import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(IntegrationTest.class) public class CanvasTest extends ExtendedITextTest { @@ -78,9 +76,6 @@ public static void beforeClass() { createOrClearDestinationFolder(destinationFolder); } - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test @LogMessages(messages = @LogMessage(messageTemplate = LogMessageConstant.UNABLE_TO_APPLY_PAGE_DEPENDENT_PROP_UNKNOWN_PAGE_ON_WHICH_ELEMENT_IS_DRAWN)) public void canvasNoPageLinkTest() throws IOException, InterruptedException { @@ -254,8 +249,6 @@ public void parentElemWithAbsolPositionKidNotSuitCanvasTest() throws IOException @Test //TODO: DEVSIX-4820 (NullPointerException on processing absolutely positioned elements in small canvas area) public void nestedElementWithAbsolutePositioningInCanvasTest() throws IOException, InterruptedException { - junitExpectedException.expect(NullPointerException.class); - String testName = "nestedElementWithAbsolutePositioningInCanvas"; String out = destinationFolder + testName + ".pdf"; String cmp = sourceFolder + "cmp_" + testName + ".pdf"; @@ -272,8 +265,8 @@ public void nestedElementWithAbsolutePositioningInCanvasTest() throws IOExceptio divWithPosition.add(new Paragraph("Paragraph in Div with set position")); notFittingDiv.add(divWithPosition); - canvas.add(notFittingDiv); - + + Assert.assertThrows(NullPointerException.class, () -> canvas.add(notFittingDiv)); canvas.close(); } diff --git a/layout/src/test/java/com/itextpdf/layout/CollapsingMarginsTest.java b/layout/src/test/java/com/itextpdf/layout/CollapsingMarginsTest.java index f3591f0192..74bbf651f5 100644 --- a/layout/src/test/java/com/itextpdf/layout/CollapsingMarginsTest.java +++ b/layout/src/test/java/com/itextpdf/layout/CollapsingMarginsTest.java @@ -63,11 +63,8 @@ This file is part of the iText (R) project. import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; - import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -92,9 +89,6 @@ public static void beforeClass() { createOrClearDestinationFolder(destinationFolder); } - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void collapsingMarginsTest01() throws IOException, InterruptedException { String outFileName = destinationFolder + "collapsingMarginsTest01.pdf"; @@ -343,29 +337,27 @@ private void drawPageBorders(PdfDocument pdfDocument, int pageNum) { change the type of the expected exception to a more specific one to make the test stricter. */ public void columnRendererTest() throws IOException, InterruptedException { - junitExpectedException.expect(Exception.class); String outFileName = destinationFolder + "columnRendererTest.pdf"; String cmpFileName = sourceFolder + "cmp_columnRendererTest.pdf"; PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outFileName)); - Document doc = new Document(pdfDocument); - doc.setProperty(Property.COLLAPSING_MARGINS, true); + try (Document doc = new Document(pdfDocument)) { + doc.setProperty(Property.COLLAPSING_MARGINS, true); - Paragraph p = new Paragraph(); - for (int i = 0; i < 10; i++) { - p.add(TEXT_BYRON); - } - - Div div = new Div().add(p); - List areas = new ArrayList<>(); - areas.add(new Rectangle(30, 30, 150, 600)); - areas.add(new Rectangle(200, 30, 150, 600)); - areas.add(new Rectangle(370, 30, 150, 600)); - div.setNextRenderer(new CustomColumnDocumentRenderer(div, areas)); + Paragraph p = new Paragraph(); + for (int i = 0; i < 10; i++) { + p.add(TEXT_BYRON); + } - doc.add(div); + Div div = new Div().add(p); + List areas = new ArrayList<>(); + areas.add(new Rectangle(30, 30, 150, 600)); + areas.add(new Rectangle(200, 30, 150, 600)); + areas.add(new Rectangle(370, 30, 150, 600)); + div.setNextRenderer(new CustomColumnDocumentRenderer(div, areas)); - doc.close(); + Assert.assertThrows(Exception.class, () -> doc.add(div)); + } Assert.assertNull(new CompareTool().compareByContent(outFileName, cmpFileName, destinationFolder, "diff")); } diff --git a/layout/src/test/java/com/itextpdf/layout/FontProviderTest.java b/layout/src/test/java/com/itextpdf/layout/FontProviderTest.java index b0e5eed52e..589ba9dfb3 100644 --- a/layout/src/test/java/com/itextpdf/layout/FontProviderTest.java +++ b/layout/src/test/java/com/itextpdf/layout/FontProviderTest.java @@ -64,10 +64,8 @@ This file is part of the iText (R) project. import com.itextpdf.test.annotations.type.IntegrationTest; import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; import java.io.FileInputStream; import java.io.FileOutputStream; @@ -78,9 +76,6 @@ This file is part of the iText (R) project. @Category(IntegrationTest.class) public class FontProviderTest extends ExtendedITextTest { - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - private static class PdfFontProvider extends FontProvider { private List pdfFontInfos = new ArrayList<>(); @@ -202,20 +197,17 @@ public void customFontProvider2() throws Exception { @Test public void fontProviderNotSetExceptionTest() throws Exception { - junitExpectedException.expect(IllegalStateException.class); - junitExpectedException.expectMessage(PdfException.FontProviderNotSetFontFamilyNotResolved); - String fileName = "fontProviderNotSetExceptionTest.pdf"; String outFileName = destinationFolder + fileName + ".pdf"; - PdfDocument pdfDoc = new PdfDocument(new PdfWriter(new FileOutputStream(outFileName))); - Document doc = new Document(pdfDoc); + try (PdfDocument pdfDoc = new PdfDocument(new PdfWriter(new FileOutputStream(outFileName)))) { + Document doc = new Document(pdfDoc); - Paragraph paragraph = new Paragraph("Hello world!") - .setFontFamily("ABRACADABRA_NO_FONT_PROVIDER_ANYWAY"); - doc.add(paragraph); + Paragraph paragraph = new Paragraph("Hello world!") + .setFontFamily("ABRACADABRA_NO_FONT_PROVIDER_ANYWAY"); - doc.close(); + Exception e = Assert.assertThrows(IllegalStateException.class, () -> doc.add(paragraph)); + Assert.assertEquals(PdfException.FontProviderNotSetFontFamilyNotResolved, e.getMessage()); + } } - } diff --git a/layout/src/test/java/com/itextpdf/layout/FontSelectorTest.java b/layout/src/test/java/com/itextpdf/layout/FontSelectorTest.java index b81b28b7cf..304a32f7f1 100644 --- a/layout/src/test/java/com/itextpdf/layout/FontSelectorTest.java +++ b/layout/src/test/java/com/itextpdf/layout/FontSelectorTest.java @@ -563,7 +563,95 @@ public void standardFontSetCourierTest01() { public void openSansFontSetIncorrectNameTest01() { FontSet set = getOpenSansFontSet(); addTimesFonts(set); - checkSelector(set.getFonts(), "OpenSans", "OpenSans-Light", "OpenSans-Bold", "OpenSans-LightItalic", "OpenSans-BoldItalic"); + Collection fontInfoCollection = set.getFonts(); + List fontFamilies = new ArrayList<>(); + fontFamilies.add("Open Sans"); + + // Normal + + FontCharacteristics fc = new FontCharacteristics(); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-Regular"); + + fc = new FontCharacteristics(); + fc.setFontWeight((short) 300); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-Light"); + + fc = new FontCharacteristics(); + fc.setFontWeight((short) 100); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-Light"); + + fc = new FontCharacteristics(); + fc.setFontWeight("normal"); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-Regular"); + + fc = new FontCharacteristics(); + fc.setFontStyle("normal"); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-Regular"); + + // Bold + + fc = new FontCharacteristics(); + fc.setBoldFlag(true); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-SemiBold"); + + fc = new FontCharacteristics(); + fc.setFontWeight("bold"); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-Bold"); + + fc = new FontCharacteristics(); + fc.setFontWeight((short) 700); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-Bold"); + + fc = new FontCharacteristics(); + fc.setFontWeight((short) 800); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-ExtraBold"); + + // Italic + + fc = new FontCharacteristics(); + fc.setFontStyle("italic"); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-Italic"); + + fc = new FontCharacteristics(); + fc.setFontStyle("italic"); + fc.setFontWeight("normal"); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-Italic"); + + fc = new FontCharacteristics(); + fc.setFontStyle("italic"); + fc.setFontWeight((short) 300); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-LightItalic"); + + fc = new FontCharacteristics(); + fc.setFontStyle("italic"); + fc.setFontWeight((short) 500); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-LightItalic"); + + fc = new FontCharacteristics(); + fc.setFontStyle("oblique"); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-Italic"); + + // BoldItalic + + fc = new FontCharacteristics(); + fc.setFontStyle("italic"); + fc.setFontWeight("bold"); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-BoldItalic"); + + fc = new FontCharacteristics(); + fc.setFontStyle("oblique"); + fc.setFontWeight("bold"); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-BoldItalic"); + + fc = new FontCharacteristics(); + fc.setFontStyle("italic"); + fc.setFontWeight((short) 700); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-BoldItalic"); + + fc = new FontCharacteristics(); + fc.setFontStyle("italic"); + fc.setFontWeight((short) 800); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-ExtraBoldItalic"); } @Test @@ -572,7 +660,95 @@ public void openSansFontSetIncorrectNameTest01() { public void openSansFontSetRegularTest01() { FontSet set = getOpenSansFontSet(); addTimesFonts(set); - checkSelector(set.getFonts(), "Open Sans", "OpenSans-Light", "OpenSans-Bold", "OpenSans-LightItalic", "OpenSans-BoldItalic"); + Collection fontInfoCollection = set.getFonts(); + List fontFamilies = new ArrayList<>(); + fontFamilies.add("Open Sans"); + + // Normal + + FontCharacteristics fc = new FontCharacteristics(); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-Regular"); + + fc = new FontCharacteristics(); + fc.setFontWeight((short) 300); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-Light"); + + fc = new FontCharacteristics(); + fc.setFontWeight((short) 100); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-Light"); + + fc = new FontCharacteristics(); + fc.setFontWeight("normal"); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-Regular"); + + fc = new FontCharacteristics(); + fc.setFontStyle("normal"); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-Regular"); + + // Bold + + fc = new FontCharacteristics(); + fc.setBoldFlag(true); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-SemiBold"); + + fc = new FontCharacteristics(); + fc.setFontWeight("bold"); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-Bold"); + + fc = new FontCharacteristics(); + fc.setFontWeight((short) 700); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-Bold"); + + fc = new FontCharacteristics(); + fc.setFontWeight((short) 800); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-ExtraBold"); + + // Italic + + fc = new FontCharacteristics(); + fc.setFontStyle("italic"); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-Italic"); + + fc = new FontCharacteristics(); + fc.setFontStyle("italic"); + fc.setFontWeight("normal"); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-Italic"); + + fc = new FontCharacteristics(); + fc.setFontStyle("italic"); + fc.setFontWeight((short) 300); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-LightItalic"); + + fc = new FontCharacteristics(); + fc.setFontStyle("italic"); + fc.setFontWeight((short) 500); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-LightItalic"); + + fc = new FontCharacteristics(); + fc.setFontStyle("oblique"); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-Italic"); + + // BoldItalic + + fc = new FontCharacteristics(); + fc.setFontStyle("italic"); + fc.setFontWeight("bold"); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-BoldItalic"); + + fc = new FontCharacteristics(); + fc.setFontStyle("oblique"); + fc.setFontWeight("bold"); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-BoldItalic"); + + fc = new FontCharacteristics(); + fc.setFontStyle("italic"); + fc.setFontWeight((short) 700); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-BoldItalic"); + + fc = new FontCharacteristics(); + fc.setFontStyle("italic"); + fc.setFontWeight((short) 800); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-ExtraBoldItalic"); } @Test @@ -582,7 +758,95 @@ public void openSansFontSetRegularTest01() { public void openSansFontSetLightTest01() { FontSet set = getOpenSansFontSet(); addTimesFonts(set); - checkSelector(set.getFonts(), "Open Sans Light", "OpenSans-Light", "OpenSans-Bold", "OpenSans-LightItalic", "OpenSans-BoldItalic"); + Collection fontInfoCollection = set.getFonts(); + List fontFamilies = new ArrayList<>(); + fontFamilies.add("Open Sans"); + + // Normal + + FontCharacteristics fc = new FontCharacteristics(); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-Regular"); + + fc = new FontCharacteristics(); + fc.setFontWeight((short) 300); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-Light"); + + fc = new FontCharacteristics(); + fc.setFontWeight((short) 100); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-Light"); + + fc = new FontCharacteristics(); + fc.setFontWeight("normal"); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-Regular"); + + fc = new FontCharacteristics(); + fc.setFontStyle("normal"); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-Regular"); + + // Bold + + fc = new FontCharacteristics(); + fc.setBoldFlag(true); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-SemiBold"); + + fc = new FontCharacteristics(); + fc.setFontWeight("bold"); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-Bold"); + + fc = new FontCharacteristics(); + fc.setFontWeight((short) 700); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-Bold"); + + fc = new FontCharacteristics(); + fc.setFontWeight((short) 800); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-ExtraBold"); + + // Italic + + fc = new FontCharacteristics(); + fc.setFontStyle("italic"); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-Italic"); + + fc = new FontCharacteristics(); + fc.setFontStyle("italic"); + fc.setFontWeight("normal"); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-Italic"); + + fc = new FontCharacteristics(); + fc.setFontStyle("italic"); + fc.setFontWeight((short) 300); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-LightItalic"); + + fc = new FontCharacteristics(); + fc.setFontStyle("italic"); + fc.setFontWeight((short) 500); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-LightItalic"); + + fc = new FontCharacteristics(); + fc.setFontStyle("oblique"); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-Italic"); + + // BoldItalic + + fc = new FontCharacteristics(); + fc.setFontStyle("italic"); + fc.setFontWeight("bold"); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-BoldItalic"); + + fc = new FontCharacteristics(); + fc.setFontStyle("oblique"); + fc.setFontWeight("bold"); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-BoldItalic"); + + fc = new FontCharacteristics(); + fc.setFontStyle("italic"); + fc.setFontWeight((short) 700); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-BoldItalic"); + + fc = new FontCharacteristics(); + fc.setFontStyle("italic"); + fc.setFontWeight((short) 800); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-ExtraBoldItalic"); } @Test @@ -592,11 +856,98 @@ public void openSansFontSetLightTest01() { public void openSansFontSetExtraBoldTest01() { FontSet set = getOpenSansFontSet(); addTimesFonts(set); - checkSelector(set.getFonts(), "Open Sans ExtraBold", "Times-Bold", "Times-Bold", "Times-BoldItalic", "Times-BoldItalic"); + Collection fontInfoCollection = set.getFonts(); + List fontFamilies = new ArrayList<>(); + fontFamilies.add("Open Sans"); + + // Normal + + FontCharacteristics fc = new FontCharacteristics(); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-Regular"); + + fc = new FontCharacteristics(); + fc.setFontWeight((short) 300); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-Light"); + + fc = new FontCharacteristics(); + fc.setFontWeight((short) 100); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-Light"); + + fc = new FontCharacteristics(); + fc.setFontWeight("normal"); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-Regular"); + + fc = new FontCharacteristics(); + fc.setFontStyle("normal"); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-Regular"); + + // Bold + + fc = new FontCharacteristics(); + fc.setBoldFlag(true); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-SemiBold"); + + fc = new FontCharacteristics(); + fc.setFontWeight("bold"); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-Bold"); + + fc = new FontCharacteristics(); + fc.setFontWeight((short) 700); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-Bold"); + + fc = new FontCharacteristics(); + fc.setFontWeight((short) 800); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-ExtraBold"); + + // Italic + + fc = new FontCharacteristics(); + fc.setFontStyle("italic"); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-Italic"); + + fc = new FontCharacteristics(); + fc.setFontStyle("italic"); + fc.setFontWeight("normal"); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-Italic"); + + fc = new FontCharacteristics(); + fc.setFontStyle("italic"); + fc.setFontWeight((short) 300); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-LightItalic"); + + fc = new FontCharacteristics(); + fc.setFontStyle("italic"); + fc.setFontWeight((short) 500); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-LightItalic"); + + fc = new FontCharacteristics(); + fc.setFontStyle("oblique"); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-Italic"); + + // BoldItalic + + fc = new FontCharacteristics(); + fc.setFontStyle("italic"); + fc.setFontWeight("bold"); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-BoldItalic"); + + fc = new FontCharacteristics(); + fc.setFontStyle("oblique"); + fc.setFontWeight("bold"); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-BoldItalic"); + + fc = new FontCharacteristics(); + fc.setFontStyle("italic"); + fc.setFontWeight((short) 700); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-BoldItalic"); + + fc = new FontCharacteristics(); + fc.setFontStyle("italic"); + fc.setFontWeight((short) 800); + assertSelectedFont(fontInfoCollection, fontFamilies, fc, "OpenSans-ExtraBoldItalic"); } @Test - //TODO: DEVSIX-4147 (update cmp-file after the issue will be resolved) public void openSansFontWeightBoldRenderingTest() throws Exception { String outFileName = destinationFolder + "openSansFontWeightBoldRendering.pdf"; String cmpFileName = sourceFolder + "cmp_openSansFontWeightBoldRendering.pdf"; @@ -633,7 +984,6 @@ public void openSansFontWeightBoldRenderingTest() throws Exception { } @Test - //TODO: DEVSIX-4147 (update cmp-file after the issue will be resolved) public void openSansFontWeightNotBoldRenderingTest() throws Exception { String outFileName = destinationFolder + "openSansFontWeightNotBoldRendering.pdf"; String cmpFileName = sourceFolder + "cmp_openSansFontWeightNotBoldRendering.pdf"; diff --git a/layout/src/test/java/com/itextpdf/layout/LayoutTaggingPdf2Test.java b/layout/src/test/java/com/itextpdf/layout/LayoutTaggingPdf2Test.java index 1b5825a579..7d2d763aaa 100644 --- a/layout/src/test/java/com/itextpdf/layout/LayoutTaggingPdf2Test.java +++ b/layout/src/test/java/com/itextpdf/layout/LayoutTaggingPdf2Test.java @@ -71,12 +71,11 @@ This file is part of the iText (R) project. import com.itextpdf.test.annotations.LogMessage; import com.itextpdf.test.annotations.LogMessages; import com.itextpdf.test.annotations.type.IntegrationTest; + import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; import org.xml.sax.SAXException; import javax.xml.parsers.ParserConfigurationException; @@ -91,9 +90,6 @@ public class LayoutTaggingPdf2Test extends ExtendedITextTest { public static final String imageName = "Desert.jpg"; public static final String sourceFolder = "./src/test/resources/com/itextpdf/layout/LayoutTaggingPdf2Test/"; - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @BeforeClass public static void beforeClass() { createOrClearDestinationFolder(destinationFolder); @@ -327,9 +323,6 @@ public void docWithExplicitAndImplicitDefaultNsAtTheSameTime() throws IOExceptio @Test public void docWithInvalidMapping01() throws IOException { - junitExpectedException.expect(PdfException.class); - junitExpectedException.expectMessage(MessageFormat.format(PdfException.RoleInNamespaceIsNotMappedToAnyStandardRole, "p", "http://iso.org/pdf/ssn")); - PdfDocument pdfDocument = new PdfDocument(new PdfWriter(destinationFolder + "docWithInvalidMapping01.pdf", new WriterProperties().setPdfVersion(PdfVersion.PDF_2_0))); pdfDocument.setTagged(); @@ -337,25 +330,24 @@ public void docWithInvalidMapping01() throws IOException { tagsContext.setDocumentDefaultNamespace(null); PdfNamespace explicitDefaultNs = tagsContext.fetchNamespace(StandardNamespaces.PDF_1_7); - Document document = new Document(pdfDocument); + try (Document document = new Document(pdfDocument)) { - pdfDocument.getStructTreeRoot().addRoleMapping(HtmlRoles.p, StandardRoles.P); - - Paragraph customRolePara = new Paragraph("Hello world text."); - customRolePara.getAccessibilityProperties().setRole(HtmlRoles.p); - customRolePara.getAccessibilityProperties().setNamespace(explicitDefaultNs); - document.add(customRolePara); + pdfDocument.getStructTreeRoot().addRoleMapping(HtmlRoles.p, StandardRoles.P); - document.close(); + Paragraph customRolePara = new Paragraph("Hello world text."); + customRolePara.getAccessibilityProperties().setRole(HtmlRoles.p); + customRolePara.getAccessibilityProperties().setNamespace(explicitDefaultNs); - // compareResult("docWithInvalidMapping01"); + Exception e = Assert.assertThrows(PdfException.class, + () -> document.add(customRolePara) + ); + Assert.assertEquals(MessageFormat.format(PdfException.RoleInNamespaceIsNotMappedToAnyStandardRole, + "p", "http://iso.org/pdf/ssn"), e.getMessage()); + } } @Test public void docWithInvalidMapping02() throws IOException { - junitExpectedException.expect(PdfException.class); - junitExpectedException.expectMessage(MessageFormat.format(PdfException.RoleIsNotMappedToAnyStandardRole, "p")); - PdfDocument pdfDocument = new PdfDocument(new PdfWriter(destinationFolder + "docWithInvalidMapping02.pdf", new WriterProperties().setPdfVersion(PdfVersion.PDF_2_0))); pdfDocument.setTagged(); @@ -363,37 +355,36 @@ public void docWithInvalidMapping02() throws IOException { tagsContext.setDocumentDefaultNamespace(null); PdfNamespace explicitDefaultNs = tagsContext.fetchNamespace(StandardNamespaces.PDF_1_7); - Document document = new Document(pdfDocument); - - explicitDefaultNs.addNamespaceRoleMapping(HtmlRoles.p, StandardRoles.P); + try (Document document = new Document(pdfDocument)) { - Paragraph customRolePara = new Paragraph("Hello world text."); - customRolePara.getAccessibilityProperties().setRole(HtmlRoles.p); - document.add(customRolePara); + explicitDefaultNs.addNamespaceRoleMapping(HtmlRoles.p, StandardRoles.P); - document.close(); + Paragraph customRolePara = new Paragraph("Hello world text."); + customRolePara.getAccessibilityProperties().setRole(HtmlRoles.p); - // compareResult("docWithInvalidMapping02"); + Exception e = Assert.assertThrows(PdfException.class, + () -> document.add(customRolePara) + ); + Assert.assertEquals(MessageFormat.format(PdfException.RoleIsNotMappedToAnyStandardRole, "p"), + e.getMessage()); + } } @Test public void docWithInvalidMapping03() throws IOException { - junitExpectedException.expect(PdfException.class); - junitExpectedException.expectMessage(MessageFormat.format(PdfException.RoleInNamespaceIsNotMappedToAnyStandardRole, "p", "http://iso.org/pdf2/ssn")); - PdfDocument pdfDocument = new PdfDocument(new PdfWriter(destinationFolder + "docWithInvalidMapping03.pdf", new WriterProperties().setPdfVersion(PdfVersion.PDF_2_0))); pdfDocument.setTagged(); - Document document = new Document(pdfDocument); - - Paragraph customRolePara = new Paragraph("Hello world text."); - customRolePara.getAccessibilityProperties().setRole(HtmlRoles.p); - document.add(customRolePara); + try (Document document = new Document(pdfDocument)) { - document.close(); + Paragraph customRolePara = new Paragraph("Hello world text."); + customRolePara.getAccessibilityProperties().setRole(HtmlRoles.p); - // compareResult("docWithInvalidMapping03"); + Exception e = Assert.assertThrows(PdfException.class, () -> document.add(customRolePara)); + Assert.assertEquals(MessageFormat.format(PdfException.RoleInNamespaceIsNotMappedToAnyStandardRole, + "p", "http://iso.org/pdf2/ssn"), e.getMessage()); + } } @Test @@ -422,33 +413,29 @@ public void docWithInvalidMapping04() throws IOException, InterruptedException, @Test public void docWithInvalidMapping05() throws IOException { - junitExpectedException.expect(PdfException.class); - junitExpectedException.expectMessage(MessageFormat.format(PdfException.RoleInNamespaceIsNotMappedToAnyStandardRole, "p", "http://iso.org/pdf2/ssn")); - PdfDocument pdfDocument = new PdfDocument(new PdfWriter(destinationFolder + "docWithInvalidMapping05.pdf", new WriterProperties().setPdfVersion(PdfVersion.PDF_2_0))); pdfDocument.setTagged(); - Document document = new Document(pdfDocument); + try (Document document = new Document(pdfDocument)) { - // deliberately creating namespace via constructor instead of using TagStructureContext#fetchNamespace - PdfNamespace stdNs2 = new PdfNamespace(StandardNamespaces.PDF_2_0); - stdNs2.addNamespaceRoleMapping(HtmlRoles.p, StandardRoles.P, stdNs2); - - Paragraph customRolePara = new Paragraph("Hello world text."); - customRolePara.getAccessibilityProperties().setRole(HtmlRoles.p); - customRolePara.getAccessibilityProperties().setNamespace(stdNs2); - document.add(customRolePara); - - Paragraph customRolePara2 = new Paragraph("Hello world text."); - customRolePara2.getAccessibilityProperties().setRole(HtmlRoles.p); - // not explicitly setting namespace that we've manually created. This will lead to the situation, when - // /Namespaces entry in StructTreeRoot would have two different namespace dictionaries with the same name. - document.add(customRolePara2); + // deliberately creating namespace via constructor instead of using TagStructureContext#fetchNamespace + PdfNamespace stdNs2 = new PdfNamespace(StandardNamespaces.PDF_2_0); + stdNs2.addNamespaceRoleMapping(HtmlRoles.p, StandardRoles.P, stdNs2); - document.close(); + Paragraph customRolePara = new Paragraph("Hello world text."); + customRolePara.getAccessibilityProperties().setRole(HtmlRoles.p); + customRolePara.getAccessibilityProperties().setNamespace(stdNs2); + document.add(customRolePara); -// compareResult("docWithInvalidMapping05"); + Paragraph customRolePara2 = new Paragraph("Hello world text."); + customRolePara2.getAccessibilityProperties().setRole(HtmlRoles.p); + // not explicitly setting namespace that we've manually created. This will lead to the situation, when + // /Namespaces entry in StructTreeRoot would have two different namespace dictionaries with the same name. + Exception e = Assert.assertThrows(PdfException.class, () -> document.add(customRolePara2)); + Assert.assertEquals(MessageFormat.format(PdfException.RoleInNamespaceIsNotMappedToAnyStandardRole, + "p", "http://iso.org/pdf2/ssn"), e.getMessage()); + } } @Test @@ -488,54 +475,46 @@ public void docWithInvalidMapping06() throws IOException, InterruptedException, @Test @LogMessages(messages = @LogMessage(messageTemplate = LogMessageConstant.CANNOT_RESOLVE_ROLE_IN_NAMESPACE_TOO_MUCH_TRANSITIVE_MAPPINGS, count = 1)) public void docWithInvalidMapping07() throws IOException { - junitExpectedException.expect(PdfException.class); - junitExpectedException.expectMessage(MessageFormat.format(PdfException.RoleInNamespaceIsNotMappedToAnyStandardRole, "span", "http://iso.org/pdf2/ssn")); - PdfDocument pdfDocument = new PdfDocument(new PdfWriter(destinationFolder + "docWithInvalidMapping07.pdf", new WriterProperties().setPdfVersion(PdfVersion.PDF_2_0))); pdfDocument.setTagged(); - Document document = new Document(pdfDocument); + try (Document document = new Document(pdfDocument)) { - PdfNamespace stdNs2 = pdfDocument.getTagStructureContext().fetchNamespace(StandardNamespaces.PDF_2_0); - int numOfTransitiveMappings = 120; - String prevRole = HtmlRoles.span; - for (int i = 0; i < numOfTransitiveMappings; ++i) { - String nextRole = "span" + i; - stdNs2.addNamespaceRoleMapping(prevRole, nextRole, stdNs2); - prevRole = nextRole; - } - stdNs2.addNamespaceRoleMapping(prevRole, StandardRoles.SPAN, stdNs2); - - - Text customRolePText1 = new Text("Hello world text."); - customRolePText1.getAccessibilityProperties().setRole(HtmlRoles.span); - customRolePText1.getAccessibilityProperties().setNamespace(stdNs2); - document.add(new Paragraph(customRolePText1)); + PdfNamespace stdNs2 = pdfDocument.getTagStructureContext().fetchNamespace(StandardNamespaces.PDF_2_0); + int numOfTransitiveMappings = 120; + String prevRole = HtmlRoles.span; + for (int i = 0; i < numOfTransitiveMappings; ++i) { + String nextRole = "span" + i; + stdNs2.addNamespaceRoleMapping(prevRole, nextRole, stdNs2); + prevRole = nextRole; + } + stdNs2.addNamespaceRoleMapping(prevRole, StandardRoles.SPAN, stdNs2); - document.close(); + Text customRolePText1 = new Text("Hello world text."); + customRolePText1.getAccessibilityProperties().setRole(HtmlRoles.span); + customRolePText1.getAccessibilityProperties().setNamespace(stdNs2); -// compareResult("docWithInvalidMapping07"); + Exception e = Assert.assertThrows(PdfException.class, () -> document.add(new Paragraph(customRolePText1))); + Assert.assertEquals(MessageFormat.format(PdfException.RoleInNamespaceIsNotMappedToAnyStandardRole, + "span", "http://iso.org/pdf2/ssn"), e.getMessage()); + } } @Test public void docWithInvalidMapping08() throws IOException { - junitExpectedException.expect(PdfException.class); - junitExpectedException.expectMessage(MessageFormat.format(PdfException.RoleIsNotMappedToAnyStandardRole, "H9")); - PdfDocument pdfDocument = new PdfDocument(new PdfWriter(destinationFolder + "docWithInvalidMapping08.pdf", new WriterProperties().setPdfVersion(PdfVersion.PDF_1_7))); pdfDocument.setTagged(); - Document document = new Document(pdfDocument); - - Paragraph h9Para = new Paragraph("Header level 9"); - h9Para.getAccessibilityProperties().setRole("H9"); - document.add(h9Para); + try (Document document = new Document(pdfDocument)) { - document.close(); + Paragraph h9Para = new Paragraph("Header level 9"); + h9Para.getAccessibilityProperties().setRole("H9"); -// compareResult("docWithInvalidMapping08"); + Exception e = Assert.assertThrows(PdfException.class, () -> document.add(h9Para)); + Assert.assertEquals(MessageFormat.format(PdfException.RoleIsNotMappedToAnyStandardRole, "H9"), e.getMessage()); + } } @Test diff --git a/layout/src/test/java/com/itextpdf/layout/LinkTest.java b/layout/src/test/java/com/itextpdf/layout/LinkTest.java index f9d38a1db7..31f9a4449e 100644 --- a/layout/src/test/java/com/itextpdf/layout/LinkTest.java +++ b/layout/src/test/java/com/itextpdf/layout/LinkTest.java @@ -70,13 +70,11 @@ This file is part of the iText (R) project. import com.itextpdf.test.annotations.type.IntegrationTest; import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; import java.io.FileOutputStream; import java.io.IOException; -import org.junit.rules.ExpectedException; @Category(IntegrationTest.class) public class LinkTest extends ExtendedITextTest { @@ -91,9 +89,6 @@ public class LinkTest extends ExtendedITextTest { + "Donec fringilla sapien sed neque finibus, non luctus justo lobortis. Praesent commodo pellentesque ligula, vel fringilla odio commodo id. Nam ultrices justo a dignissim congue. Nullam imperdiet sem eget placerat aliquam. Suspendisse non faucibus libero. Aenean purus arcu, auctor vitae tincidunt in, tincidunt at ante. Pellentesque euismod, velit vel vulputate faucibus, dolor erat consectetur sapien, ut elementum dui turpis nec lacus. In hac habitasse platea dictumst. Aenean vel elit ultrices, varius mi quis, congue erat." + "Curabitur sit amet nunc porttitor, congue elit vestibulum, vestibulum sapien. Fusce ut arcu consequat, scelerisque sapien vitae, dignissim ligula. Duis gravida mollis volutpat. Maecenas condimentum pulvinar urna in cursus. Nulla ornare est non tellus elementum auctor. Mauris ornare, elit non ornare lobortis, risus augue consectetur orci, ac efficitur ex nunc nec leo. Aenean dictum mattis magna vitae bibendum."; - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @BeforeClass public static void beforeClass() { createDestinationFolder(destinationFolder); diff --git a/layout/src/test/java/com/itextpdf/layout/OrphansWidowsTest.java b/layout/src/test/java/com/itextpdf/layout/OrphansWidowsTest.java index 4dcd11c336..729d5fd05f 100644 --- a/layout/src/test/java/com/itextpdf/layout/OrphansWidowsTest.java +++ b/layout/src/test/java/com/itextpdf/layout/OrphansWidowsTest.java @@ -559,6 +559,11 @@ private static class CustomParagraphRenderer extends ParagraphRenderer { public CustomParagraphRenderer(CustomParagraph modelElement) { super(modelElement); } + + @Override + public IRenderer getNextRenderer() { + return new CustomParagraphRenderer((CustomParagraph) this.modelElement); + } } private static class CustomParagraph extends Paragraph { diff --git a/layout/src/test/java/com/itextpdf/layout/PositioningTest.java b/layout/src/test/java/com/itextpdf/layout/PositioningTest.java index 8fd88722c6..03df1c6d72 100644 --- a/layout/src/test/java/com/itextpdf/layout/PositioningTest.java +++ b/layout/src/test/java/com/itextpdf/layout/PositioningTest.java @@ -69,12 +69,11 @@ This file is part of the iText (R) project. import com.itextpdf.test.annotations.LogMessage; import com.itextpdf.test.annotations.LogMessages; import com.itextpdf.test.annotations.type.IntegrationTest; + import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; import java.io.IOException; @@ -89,9 +88,6 @@ public static void beforeClass() { createOrClearDestinationFolder(destinationFolder); } - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void relativePositioningTest01() throws IOException, InterruptedException { String outFileName = destinationFolder + "relativePositioningTest01.pdf"; @@ -367,25 +363,26 @@ public void showTextAlignedTest03() throws IOException, InterruptedException { @Test public void showTextAlignedOnFlushedPageTest01() throws IOException { - junitExpectedException.expect(PdfException.class); - junitExpectedException.expectMessage(PdfException.CannotDrawElementsOnAlreadyFlushedPages); - String outFileName = destinationFolder + "showTextAlignedOnFlushedPageTest01.pdf"; - PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName)); - Document doc = new Document(pdfDoc); + try (PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName)); + Document doc = new Document(pdfDoc)) { - Paragraph p = new Paragraph(); - for (int i = 0; i < 1000; ++i) { - p.add("abcdefghijklkmnopqrstuvwxyz"); - } + Paragraph p = new Paragraph(); + for (int i = 0; i < 1000; ++i) { + p.add("abcdefghijklkmnopqrstuvwxyz"); + } - doc.add(p); - // First page will be flushed by now, because immediateFlush is set to false by default. - int pageNumberToDrawTextOn = 1; - doc.showTextAligned(new Paragraph("Hello Bruno on page 1!"), 36, 36, pageNumberToDrawTextOn, TextAlignment.LEFT, VerticalAlignment.TOP, 0); + doc.add(p); + // First page will be flushed by now, because immediateFlush is set to false by default. + int pageNumberToDrawTextOn = 1; - doc.close(); + Exception e = Assert.assertThrows(PdfException.class, + () -> doc.showTextAligned(new Paragraph("Hello Bruno on page 1!"), 36, 36, pageNumberToDrawTextOn, + TextAlignment.LEFT, VerticalAlignment.TOP, 0) + ); + Assert.assertEquals(PdfException.CannotDrawElementsOnAlreadyFlushedPages, e.getMessage()); + } } diff --git a/layout/src/test/java/com/itextpdf/layout/StylesTest.java b/layout/src/test/java/com/itextpdf/layout/StylesTest.java index fd1b821290..37baa21e1c 100644 --- a/layout/src/test/java/com/itextpdf/layout/StylesTest.java +++ b/layout/src/test/java/com/itextpdf/layout/StylesTest.java @@ -52,19 +52,14 @@ This file is part of the iText (R) project. import com.itextpdf.test.annotations.type.IntegrationTest; import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(IntegrationTest.class) public class StylesTest extends ExtendedITextTest { public static float EPS = 0.0001f; - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void copyConstructorTest() { Style myStyle = new Style(); @@ -133,18 +128,9 @@ public void addingSeveralStyleTest() { @Test public void addNullAsStyleTest() { - // Sharpen mappings map NPE to NullReferenceException, however in .NET in this situation - // ArgumentNullException is thrown. In order not to introduce any porting issues, - // which unfortunately couldn't be handled in a convenient way, the most basic Exception - // is set to be expected. - junitExpectedException.expect(Exception.class); - - Style myStyle = null; - - Paragraph p = new Paragraph("text").addStyle(myStyle); + Paragraph p = new Paragraph("text"); - // the following line should produce a NPE - p.getRenderer().getProperty(Property.FONT_COLOR); + Assert.assertThrows(IllegalArgumentException.class, () -> p.addStyle(null)); } @Test diff --git a/layout/src/test/java/com/itextpdf/layout/TableBorderTest.java b/layout/src/test/java/com/itextpdf/layout/TableBorderTest.java index e50a5418bb..e596482121 100644 --- a/layout/src/test/java/com/itextpdf/layout/TableBorderTest.java +++ b/layout/src/test/java/com/itextpdf/layout/TableBorderTest.java @@ -67,13 +67,11 @@ This file is part of the iText (R) project. import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Ignore; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; import java.io.FileNotFoundException; import java.io.IOException; -import org.junit.rules.ExpectedException; @Category(IntegrationTest.class) public class TableBorderTest extends ExtendedITextTest { @@ -81,9 +79,6 @@ public class TableBorderTest extends ExtendedITextTest { public static final String destinationFolder = "./target/test/com/itextpdf/layout/TableBorderTest/"; public static final String cmpPrefix = "cmp_"; - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - String fileName; String outFileName; String cmpFileName; diff --git a/layout/src/test/java/com/itextpdf/layout/TableTest.java b/layout/src/test/java/com/itextpdf/layout/TableTest.java index fbbdf34f9c..6e0ca81f42 100644 --- a/layout/src/test/java/com/itextpdf/layout/TableTest.java +++ b/layout/src/test/java/com/itextpdf/layout/TableTest.java @@ -80,13 +80,12 @@ This file is part of the iText (R) project. import com.itextpdf.test.annotations.LogMessage; import com.itextpdf.test.annotations.LogMessages; import com.itextpdf.test.annotations.type.IntegrationTest; + import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Ignore; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -103,9 +102,6 @@ public class TableTest extends ExtendedITextTest { private static final String MIDDLE_TEXT_CONTENT = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas porttitor congue massa. Fusce posuere, magna sed pulvinar ultricies, purus lectus malesuada libero, sit amet commodo magna eros quis urna.\n" + "Nunc viverra imperdiet enim. Fusce est. Vivamus a tellus."; - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @BeforeClass public static void beforeClass() { createDestinationFolder(destinationFolder); @@ -1825,7 +1821,9 @@ public void tableWithIncompleteFooter() throws IOException, InterruptedException } @Test - @LogMessages(messages = {@LogMessage(messageTemplate = LogMessageConstant.LAST_ROW_IS_NOT_COMPLETE, count = 1)}) + @LogMessages(messages = { + @LogMessage(messageTemplate = LogMessageConstant.LAST_ROW_IS_NOT_COMPLETE), + @LogMessage(messageTemplate = LogMessageConstant.GET_NEXT_RENDERER_SHOULD_BE_OVERRIDDEN)}) public void tableWithCustomRendererTest01() throws IOException, InterruptedException { String testName = "tableWithCustomRendererTest01.pdf"; String outFileName = destinationFolder + testName; @@ -3046,6 +3044,117 @@ public void inheritHeaderPropsWhileMinMaxWidthCalculationsTest() throws IOExcept sourceFolder + "cmp_" + filename, destinationFolder, "diff")); } + @Test + // TODO DEVSIX-5250 The first column should be fully red + public void bigRowSpanTooFarFullTest() throws IOException, InterruptedException { + String filename = "bigRowSpanTooFarFullTest.pdf"; + + PdfDocument pdf = new PdfDocument(new PdfWriter(destinationFolder + filename)); + Document document = new Document(pdf); + + Table table = new Table(2); + + int bigRowSpan = 5; + table.addCell( + new Cell(bigRowSpan, 1) + .add(new Paragraph("row span " + bigRowSpan)) + .setBackgroundColor(ColorConstants.RED)); + for (int i = 0; i < bigRowSpan; i++) { + table.addCell( + new Cell() + .add(new Paragraph(Integer.toString(i))) + .setHeight(375) + .setBackgroundColor(ColorConstants.BLUE)); + } + + document.add(table); + document.add(new AreaBreak()); + + table.setBorderCollapse(BorderCollapsePropertyValue.SEPARATE); + document.add(table); + + document.close(); + + Assert.assertNull(new CompareTool().compareByContent(destinationFolder + filename, + sourceFolder + "cmp_" + filename, destinationFolder)); + } + + @Test + // TODO DEVSIX-5250 The first column should be fully red, but on page 2 it is not + public void bigRowSpanTooFarPartialTest() throws IOException, InterruptedException { + String filename = "bigRowSpanTooFarPartialTest.pdf"; + + PdfDocument pdf = new PdfDocument(new PdfWriter(destinationFolder + filename)); + Document document = new Document(pdf); + + Table table = new Table(2); + + int bigRowSpan = 5; + table.addCell( + new Cell(bigRowSpan, 1) + .add(new Paragraph("row span " + bigRowSpan)) + .setHeight(800) + .setBackgroundColor(ColorConstants.RED)); + for (int i = 0; i < bigRowSpan; i++) { + table.addCell( + new Cell() + .add(new Paragraph(Integer.toString(i))) + .setHeight(375) + .setBackgroundColor(ColorConstants.BLUE)); + } + + document.add(table); + document.add(new AreaBreak()); + + table.setBorderCollapse(BorderCollapsePropertyValue.SEPARATE); + document.add(table); + + document.close(); + + Assert.assertNull(new CompareTool().compareByContent(destinationFolder + filename, + sourceFolder + "cmp_" + filename, destinationFolder)); + } + + @Test + @LogMessages(messages = { + @LogMessage(messageTemplate = LogMessageConstant.ELEMENT_DOES_NOT_FIT_AREA, count = 1) + }) + // TODO DEVSIX-5250 The first column should be fully red + public void bigRowSpanTooFarNothingTest() throws IOException, InterruptedException { + String filename = "bigRowSpanTooFarNothingTest.pdf"; + + PdfDocument pdf = new PdfDocument(new PdfWriter(destinationFolder + filename)); + Document document = new Document(pdf); + + Table table = new Table(2); + + int bigRowSpan = 5; + table.addCell( + new Cell(bigRowSpan, 1) + .add(new Paragraph("row span " + bigRowSpan)) + .setHeight(800) + .setKeepTogether(true) + .setBackgroundColor(ColorConstants.RED)); + for (int i = 0; i < bigRowSpan; i++) { + table.addCell( + new Cell() + .add(new Paragraph(Integer.toString(i))) + .setHeight(375) + .setBackgroundColor(ColorConstants.BLUE)); + } + + document.add(table); + document.add(new AreaBreak()); + + table.setBorderCollapse(BorderCollapsePropertyValue.SEPARATE); + document.add(table); + + document.close(); + + Assert.assertNull(new CompareTool().compareByContent(destinationFolder + filename, + sourceFolder + "cmp_" + filename, destinationFolder)); + } + private static class RotatedDocumentRenderer extends DocumentRenderer { private final PdfDocument pdfDoc; diff --git a/layout/src/test/java/com/itextpdf/layout/element/FlexContainerTest.java b/layout/src/test/java/com/itextpdf/layout/element/FlexContainerTest.java index 4de1b231f8..cdce458a9e 100644 --- a/layout/src/test/java/com/itextpdf/layout/element/FlexContainerTest.java +++ b/layout/src/test/java/com/itextpdf/layout/element/FlexContainerTest.java @@ -80,14 +80,9 @@ public FlexContainerTest(Object alignItemsValue, Object justifyContentValue, Obj public static Iterable alignItemsAndJustifyContentProperties() { return Arrays.asList(new Object[][]{ {AlignmentPropertyValue.FLEX_START, JustifyContent.FLEX_START, 1}, - {AlignmentPropertyValue.START, JustifyContent.START, 2}, - {AlignmentPropertyValue.SELF_START, JustifyContent.SELF_START, 3}, - {AlignmentPropertyValue.BASELINE, JustifyContent.LEFT, 4}, - {AlignmentPropertyValue.FLEX_END, JustifyContent.FLEX_END, 5}, - {AlignmentPropertyValue.END, JustifyContent.END, 6}, - {AlignmentPropertyValue.SELF_END, JustifyContent.RIGHT, 7}, - {AlignmentPropertyValue.CENTER, JustifyContent.CENTER, 8}, - {AlignmentPropertyValue.STRETCH, JustifyContent.CENTER, 9} + {AlignmentPropertyValue.FLEX_END, JustifyContent.FLEX_END, 2}, + {AlignmentPropertyValue.CENTER, JustifyContent.CENTER, 3}, + {AlignmentPropertyValue.STRETCH, JustifyContent.CENTER, 4} }); } diff --git a/layout/src/test/java/com/itextpdf/layout/font/RangeTest.java b/layout/src/test/java/com/itextpdf/layout/font/RangeTest.java index dee1f14b62..3e37fad73f 100644 --- a/layout/src/test/java/com/itextpdf/layout/font/RangeTest.java +++ b/layout/src/test/java/com/itextpdf/layout/font/RangeTest.java @@ -44,31 +44,23 @@ This file is part of the iText (R) project. import com.itextpdf.test.ExtendedITextTest; import com.itextpdf.test.annotations.type.UnitTest; + import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; - import java.util.Random; @Category(UnitTest.class) public class RangeTest extends ExtendedITextTest { - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - - @Test public void testWrongRange() { - junitExpectedException.expect(IllegalArgumentException.class); - new RangeBuilder().addRange(11, 10); + Assert.assertThrows(IllegalArgumentException.class, () -> new RangeBuilder().addRange(11, 10)); } @Test public void testWrongRangeSize() { - junitExpectedException.expect(IllegalArgumentException.class); - new RangeBuilder().create(); + Assert.assertThrows(IllegalArgumentException.class, () -> new RangeBuilder().create()); } @Test diff --git a/layout/src/test/java/com/itextpdf/layout/renderer/AreaBreakRendererUnitTest.java b/layout/src/test/java/com/itextpdf/layout/renderer/AreaBreakRendererUnitTest.java index f950942f5e..81e3e379f8 100644 --- a/layout/src/test/java/com/itextpdf/layout/renderer/AreaBreakRendererUnitTest.java +++ b/layout/src/test/java/com/itextpdf/layout/renderer/AreaBreakRendererUnitTest.java @@ -23,7 +23,6 @@ This file is part of the iText (R) project. package com.itextpdf.layout.renderer; import com.itextpdf.io.source.ByteArrayOutputStream; -import com.itextpdf.kernel.PdfException; import com.itextpdf.kernel.pdf.PdfDocument; import com.itextpdf.kernel.pdf.PdfWriter; import com.itextpdf.layout.element.AreaBreak; @@ -34,42 +33,36 @@ This file is part of the iText (R) project. import com.itextpdf.test.AssertUtil; import com.itextpdf.test.ExtendedITextTest; import com.itextpdf.test.annotations.type.UnitTest; + import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(UnitTest.class) public class AreaBreakRendererUnitTest extends ExtendedITextTest { - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void addChildTestUnsupported() { - junitExpectedException.expect(RuntimeException.class); - AreaBreakRenderer areaBreakRenderer = new AreaBreakRenderer(new AreaBreak()); - Assert.assertNull(areaBreakRenderer.getChildRenderers()); - areaBreakRenderer.addChild(new TextRenderer(new Text("Test"))); + Assert.assertNull(areaBreakRenderer.getChildRenderers()); + Assert.assertThrows(Exception.class, () -> areaBreakRenderer.addChild(new TextRenderer(new Text("Test")))); } @Test public void drawTestUnsupported() { - junitExpectedException.expect(UnsupportedOperationException.class); - AreaBreakRenderer areaBreakRenderer = new AreaBreakRenderer(new AreaBreak()); - areaBreakRenderer.draw(new DrawContext(new PdfDocument(new PdfWriter(new ByteArrayOutputStream())), null)); + + Assert.assertThrows(UnsupportedOperationException.class, + () -> areaBreakRenderer.draw(new DrawContext(new PdfDocument(new PdfWriter(new ByteArrayOutputStream())), null)) + ); } @Test public void getOccupiedAreaTestUnsupported() { - junitExpectedException.expect(UnsupportedOperationException.class); - AreaBreakRenderer areaBreakRenderer = new AreaBreakRenderer(new AreaBreak()); - areaBreakRenderer.getOccupiedArea(); + + Assert.assertThrows(UnsupportedOperationException.class, () -> areaBreakRenderer.getOccupiedArea()); } @Test @@ -115,19 +108,17 @@ public void getDefaultPropertyTest() { @Test //The BORDER_RADIUS property is chosen without any specific intention. It could be replaced with any other property. public void getPropertyWithDefaultValueTestUnsupported() { - junitExpectedException.expect(UnsupportedOperationException.class); - AreaBreakRenderer areaBreakRenderer = new AreaBreakRenderer(new AreaBreak()); - areaBreakRenderer.getProperty(Property.BORDER_RADIUS, 3); + + Assert.assertThrows(UnsupportedOperationException.class, () -> areaBreakRenderer.getProperty(Property.BORDER_RADIUS, 3)); } @Test //The BORDER_RADIUS property is chosen without any specific intention. It could be replaced with any other property. public void setPropertyTestUnsupported() { - junitExpectedException.expect(UnsupportedOperationException.class); - AreaBreakRenderer areaBreakRenderer = new AreaBreakRenderer(new AreaBreak()); - areaBreakRenderer.setProperty(Property.BORDER_RADIUS, 5); + + Assert.assertThrows(UnsupportedOperationException.class, () -> areaBreakRenderer.setProperty(Property.BORDER_RADIUS, 5)); } @Test @@ -164,10 +155,9 @@ public void isFlushedTest() { @Test public void moveTestUnsupported() { - junitExpectedException.expect(UnsupportedOperationException.class); - AreaBreakRenderer areaBreakRenderer = new AreaBreakRenderer(new AreaBreak()); - areaBreakRenderer.move(2.0f, 2.0f); + + Assert.assertThrows(UnsupportedOperationException.class, () -> areaBreakRenderer.move(2.0f, 2.0f)); } @Test diff --git a/layout/src/test/java/com/itextpdf/layout/renderer/CellRendererUnitTest.java b/layout/src/test/java/com/itextpdf/layout/renderer/CellRendererUnitTest.java new file mode 100644 index 0000000000..f3dcccb768 --- /dev/null +++ b/layout/src/test/java/com/itextpdf/layout/renderer/CellRendererUnitTest.java @@ -0,0 +1,50 @@ +/* + This file is part of the iText (R) project. + Copyright (c) 1998-2021 iText Group NV + Authors: iText Software. + + This program is offered under a commercial and under the AGPL license. + For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below. + + AGPL licensing: + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + */ +package com.itextpdf.layout.renderer; + +import com.itextpdf.io.LogMessageConstant; +import com.itextpdf.layout.element.Cell; +import com.itextpdf.test.ExtendedITextTest; +import com.itextpdf.test.annotations.LogMessage; +import com.itextpdf.test.annotations.LogMessages; +import com.itextpdf.test.annotations.type.UnitTest; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +@Category(UnitTest.class) +public class CellRendererUnitTest extends ExtendedITextTest { + + @Test + @LogMessages(messages = { + @LogMessage(messageTemplate = LogMessageConstant.GET_NEXT_RENDERER_SHOULD_BE_OVERRIDDEN) + }) + public void getNextRendererShouldBeOverriddenTest() { + CellRenderer cellRenderer = new CellRenderer(new Cell()) { + // Nothing is overridden + }; + + Assert.assertEquals(CellRenderer.class, cellRenderer.getNextRenderer().getClass()); + } +} diff --git a/layout/src/test/java/com/itextpdf/layout/renderer/DivRendererUnitTest.java b/layout/src/test/java/com/itextpdf/layout/renderer/DivRendererUnitTest.java new file mode 100644 index 0000000000..9376d2d249 --- /dev/null +++ b/layout/src/test/java/com/itextpdf/layout/renderer/DivRendererUnitTest.java @@ -0,0 +1,50 @@ +/* + This file is part of the iText (R) project. + Copyright (c) 1998-2021 iText Group NV + Authors: iText Software. + + This program is offered under a commercial and under the AGPL license. + For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below. + + AGPL licensing: + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + */ +package com.itextpdf.layout.renderer; + +import com.itextpdf.io.LogMessageConstant; +import com.itextpdf.layout.element.Div; +import com.itextpdf.test.ExtendedITextTest; +import com.itextpdf.test.annotations.LogMessage; +import com.itextpdf.test.annotations.LogMessages; +import com.itextpdf.test.annotations.type.UnitTest; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +@Category(UnitTest.class) +public class DivRendererUnitTest extends ExtendedITextTest { + + @Test + @LogMessages(messages = { + @LogMessage(messageTemplate = LogMessageConstant.GET_NEXT_RENDERER_SHOULD_BE_OVERRIDDEN) + }) + public void getNextRendererShouldBeOverriddenTest() { + DivRenderer divRenderer = new DivRenderer(new Div()) { + // Nothing is overridden + }; + + Assert.assertEquals(DivRenderer.class, divRenderer.getNextRenderer().getClass()); + } +} diff --git a/layout/src/test/java/com/itextpdf/layout/renderer/FlexContainerRendererTest.java b/layout/src/test/java/com/itextpdf/layout/renderer/FlexContainerRendererTest.java index e8697cc2f2..eb5ca1d13c 100644 --- a/layout/src/test/java/com/itextpdf/layout/renderer/FlexContainerRendererTest.java +++ b/layout/src/test/java/com/itextpdf/layout/renderer/FlexContainerRendererTest.java @@ -22,6 +22,7 @@ This file is part of the iText (R) project. */ package com.itextpdf.layout.renderer; +import com.itextpdf.io.LogMessageConstant; import com.itextpdf.kernel.geom.Rectangle; import com.itextpdf.layout.borders.SolidBorder; import com.itextpdf.layout.element.Div; @@ -31,6 +32,8 @@ This file is part of the iText (R) project. import com.itextpdf.layout.property.Property; import com.itextpdf.layout.property.UnitValue; import com.itextpdf.test.ExtendedITextTest; +import com.itextpdf.test.annotations.LogMessage; +import com.itextpdf.test.annotations.LogMessages; import com.itextpdf.test.annotations.type.UnitTest; import org.junit.Assert; @@ -260,4 +263,16 @@ public void widthSetToChildManyChildrenFlexRendererWithMaxWidthLowerThanMinWidth Assert.assertEquals(100F, flexRenderer.getMinMaxWidth().getMinWidth(), EPS); Assert.assertEquals(100F, flexRenderer.getMinMaxWidth().getMaxWidth(), EPS); } + + @Test + @LogMessages(messages = { + @LogMessage(messageTemplate = LogMessageConstant.GET_NEXT_RENDERER_SHOULD_BE_OVERRIDDEN) + }) + public void getNextRendererShouldBeOverriddenTest() { + FlexContainerRenderer flexContainerRenderer = new FlexContainerRenderer(new Div()) { + // Nothing is overridden + }; + + Assert.assertEquals(FlexContainerRenderer.class, flexContainerRenderer.getNextRenderer().getClass()); + } } diff --git a/layout/src/test/java/com/itextpdf/layout/renderer/FlexUtilTest.java b/layout/src/test/java/com/itextpdf/layout/renderer/FlexUtilTest.java index effb91af6a..2a152237cc 100644 --- a/layout/src/test/java/com/itextpdf/layout/renderer/FlexUtilTest.java +++ b/layout/src/test/java/com/itextpdf/layout/renderer/FlexUtilTest.java @@ -29,6 +29,7 @@ This file is part of the iText (R) project. import com.itextpdf.kernel.geom.Rectangle; import com.itextpdf.kernel.pdf.PdfDocument; import com.itextpdf.kernel.pdf.PdfWriter; +import com.itextpdf.kernel.pdf.xobject.PdfFormXObject; import com.itextpdf.layout.Document; import com.itextpdf.layout.Style; import com.itextpdf.layout.borders.SolidBorder; @@ -58,6 +59,10 @@ This file is part of the iText (R) project. @Category(UnitTest.class) public class FlexUtilTest extends ExtendedITextTest { + /* To see integration tests for flex algorithm go to FlexAlgoTest in html2pdf module. + The names are preserved: one can go to FlexAlgoTest and see the corresponding tests, but be aware that with + time they might change and we will not maintain such correspondence */ + private static final float EPS = 0.001f; private static final Style DEFAULT_STYLE; @@ -65,8 +70,6 @@ public class FlexUtilTest extends ExtendedITextTest { private static final List NULL_FLEX_BASIS_LIST; - // Here one can find an html version for all of the tests - // TODO DEVSIX-5049 Make html2pdf+layout tests from these htmls private static final String SOURCE_FOLDER = "./src/test/resources/com/itextpdf/layout/FlexUtilTest/"; static { @@ -2266,6 +2269,150 @@ public void differentBasisPercentSumGtWidthGrow1Shrink0Test01() { Assert.assertEquals(200f, rectangleTable.get(0).get(2).getRectangle().getWidth(), EPS); } + @Test + public void calculateMinContentWithMinWidthTest() { + DivRenderer divRenderer = new DivRenderer(new Div()); + divRenderer.setProperty(Property.WIDTH, UnitValue.createPointValue(100)); + divRenderer.setProperty(Property.MIN_WIDTH, UnitValue.createPointValue(30)); + + FlexUtil.FlexItemCalculationInfo info = createFlexItemCalculationInfo(divRenderer); + Assert.assertEquals(30f, info.minContent, EPS); + + divRenderer.setProperty(Property.WIDTH, UnitValue.createPointValue(30)); + divRenderer.setProperty(Property.MIN_WIDTH, UnitValue.createPointValue(100)); + + info = createFlexItemCalculationInfo(divRenderer); + Assert.assertEquals(100f, info.minContent, EPS); + } + + @Test + public void calculateMinContentForDivWithContentTest() { + Div div = new Div(); + div.add(new Div().setWidth(50)); + IRenderer divRenderer = div.createRendererSubTree(); + + FlexUtil.FlexItemCalculationInfo info = createFlexItemCalculationInfo((AbstractRenderer) divRenderer); + Assert.assertEquals(50.0f, info.minContent, EPS); + } + + @Test + public void calculateMinContentForDivWithWidthTest() { + DivRenderer divRenderer = new DivRenderer(new Div()); + divRenderer.setProperty(Property.WIDTH, UnitValue.createPointValue(100)); + + FlexUtil.FlexItemCalculationInfo info = createFlexItemCalculationInfo(divRenderer); + Assert.assertEquals(0.0f, info.minContent, EPS); + } + + @Test + public void calculateMinContentForDivWithWidthAndContentTest() { + Div div = new Div(); + div.add(new Div().setWidth(50)); + IRenderer divRenderer = div.createRendererSubTree(); + divRenderer.setProperty(Property.WIDTH, UnitValue.createPointValue(100)); + + FlexUtil.FlexItemCalculationInfo info = createFlexItemCalculationInfo((AbstractRenderer) divRenderer); + Assert.assertEquals(50.0f, info.minContent, EPS); + + div = new Div(); + div.add(new Div().setWidth(150)); + divRenderer = div.createRendererSubTree(); + divRenderer.setProperty(Property.WIDTH, UnitValue.createPointValue(100)); + + info = createFlexItemCalculationInfo((AbstractRenderer) divRenderer); + Assert.assertEquals(100.0f, info.minContent, EPS); + } + + @Test + public void calculateMinContentForDivWithWidthMaxWidthAndContentTest() { + Div div = new Div(); + div.add(new Div().setWidth(50)); + div.setProperty(Property.MAX_WIDTH, UnitValue.createPointValue(45)); + IRenderer divRenderer = div.createRendererSubTree(); + divRenderer.setProperty(Property.WIDTH, UnitValue.createPointValue(100)); + + FlexUtil.FlexItemCalculationInfo info = createFlexItemCalculationInfo((AbstractRenderer) divRenderer); + Assert.assertEquals(45.0f, info.minContent, EPS); + + div = new Div(); + div.add(new Div().setWidth(150)); + div.setProperty(Property.MAX_WIDTH, UnitValue.createPointValue(120)); + divRenderer = div.createRendererSubTree(); + divRenderer.setProperty(Property.WIDTH, UnitValue.createPointValue(100)); + + info = createFlexItemCalculationInfo((AbstractRenderer) divRenderer); + Assert.assertEquals(100.0f, info.minContent, EPS); + } + + @Test + public void calculateMinContentForImageTest() { + Image image = new Image(new PdfFormXObject(new Rectangle(60, 150))); + IRenderer imageRenderer = image.createRendererSubTree(); + + FlexUtil.FlexItemCalculationInfo info = createFlexItemCalculationInfo((AbstractRenderer) imageRenderer); + Assert.assertEquals(60.0f, info.minContent, EPS); + } + + @Test + public void calculateMinContentForImageWithHeightTest() { + Image image = new Image(new PdfFormXObject(new Rectangle(60, 150))); + image.setHeight(300); + IRenderer imageRenderer = image.createRendererSubTree(); + + FlexUtil.FlexItemCalculationInfo info = createFlexItemCalculationInfo((AbstractRenderer) imageRenderer); + Assert.assertEquals(60.0f, info.minContent, EPS); + + image = new Image(new PdfFormXObject(new Rectangle(60, 150))); + image.setHeight(100); + imageRenderer = image.createRendererSubTree(); + + info = createFlexItemCalculationInfo((AbstractRenderer) imageRenderer); + Assert.assertEquals(40.0f, info.minContent, EPS); + } + + @Test + public void calculateMinContentForImageWithHeightAndMinMaxHeightsTest() { + Image image = new Image(new PdfFormXObject(new Rectangle(60, 150))); + image.setHeight(300); + image.setMinHeight(20); + image.setMaxHeight(100); + IRenderer imageRenderer = image.createRendererSubTree(); + + FlexUtil.FlexItemCalculationInfo info = createFlexItemCalculationInfo((AbstractRenderer) imageRenderer); + Assert.assertEquals(40.0f, info.minContent, EPS); + + image = new Image(new PdfFormXObject(new Rectangle(60, 150))); + image.setHeight(100); + image.setMinHeight(20); + image.setMaxHeight(75); + imageRenderer = image.createRendererSubTree(); + + info = createFlexItemCalculationInfo((AbstractRenderer) imageRenderer); + Assert.assertEquals(30.0f, info.minContent, EPS); + } + + @Test + public void calculateMinContentForImageWithHeightAndWidthTest() { + Image image = new Image(new PdfFormXObject(new Rectangle(60, 150))); + image.setHeight(50); + image.setWidth(100); + IRenderer imageRenderer = image.createRendererSubTree(); + + FlexUtil.FlexItemCalculationInfo info = createFlexItemCalculationInfo((AbstractRenderer) imageRenderer); + Assert.assertEquals(60.0f, info.minContent, EPS); + + image = new Image(new PdfFormXObject(new Rectangle(60, 150))); + image.setHeight(50); + image.setWidth(50); + imageRenderer = image.createRendererSubTree(); + + info = createFlexItemCalculationInfo((AbstractRenderer) imageRenderer); + Assert.assertEquals(50.0f, info.minContent, EPS); + } + + private static FlexUtil.FlexItemCalculationInfo createFlexItemCalculationInfo(AbstractRenderer renderer) { + return new FlexUtil.FlexItemCalculationInfo(renderer, 0, 0, 0, 0, false); + } private static List> testFlex(List flexBasisValues, List flexGrowValues, List flexShrinkValues) { diff --git a/layout/src/test/java/com/itextpdf/layout/renderer/LineRendererUnitTest.java b/layout/src/test/java/com/itextpdf/layout/renderer/LineRendererUnitTest.java index ef206f9b54..064c911be0 100644 --- a/layout/src/test/java/com/itextpdf/layout/renderer/LineRendererUnitTest.java +++ b/layout/src/test/java/com/itextpdf/layout/renderer/LineRendererUnitTest.java @@ -84,7 +84,7 @@ public class LineRendererUnitTest extends RendererUnitTest { @Test public void adjustChildPositionsAfterReorderingSimpleTest01() { - Document dummyDocument = createDocument(); + Document dummyDocument = createDummyDocument(); IRenderer dummy1 = createLayoutedTextRenderer("Hello", dummyDocument); IRenderer dummy2 = createLayoutedTextRenderer("world", dummyDocument); IRenderer dummyImage = createLayoutedImageRenderer(100, 100, dummyDocument); @@ -101,7 +101,7 @@ public void adjustChildPositionsAfterReorderingSimpleTest01() { @LogMessages(messages = { @LogMessage(messageTemplate = LogMessageConstant.PROPERTY_IN_PERCENTS_NOT_SUPPORTED, count = 4)}) public void adjustChildPositionsAfterReorderingTestWithPercentMargins01() { - Document dummyDocument = createDocument(); + Document dummyDocument = createDummyDocument(); IRenderer dummy1 = createLayoutedTextRenderer("Hello", dummyDocument); dummy1.setProperty(Property.MARGIN_LEFT, UnitValue.createPercentValue(10)); dummy1.setProperty(Property.MARGIN_RIGHT, UnitValue.createPercentValue(10)); @@ -118,7 +118,7 @@ public void adjustChildPositionsAfterReorderingTestWithPercentMargins01() { @Test public void adjustChildPositionsAfterReorderingTestWithFloats01() { - Document dummyDocument = createDocument(); + Document dummyDocument = createDummyDocument(); IRenderer dummy1 = createLayoutedTextRenderer("Hello", dummyDocument); IRenderer dummy2 = createLayoutedTextRenderer("world", dummyDocument); IRenderer dummyImage = createLayoutedImageRenderer(100, 100, dummyDocument); @@ -136,7 +136,7 @@ public void adjustChildPositionsAfterReorderingTestWithFloats01() { @Test @LogMessages(messages = {@LogMessage(messageTemplate = LogMessageConstant.INLINE_BLOCK_ELEMENT_WILL_BE_CLIPPED)}) public void inlineBlockWithBigMinWidth01() { - Document dummyDocument = createDocument(); + Document dummyDocument = createDummyDocument(); LineRenderer lineRenderer = (LineRenderer) new LineRenderer().setParent(dummyDocument.getRenderer()); Div div = new Div().setMinWidth(2000).setHeight(100); DivRenderer inlineBlockRenderer = (DivRenderer) div.createRendererSubTree(); @@ -150,7 +150,7 @@ public void inlineBlockWithBigMinWidth01() { @Test public void adjustChildrenYLineTextChildHtmlModeTest() { - Document document = createDocument(); + Document document = createDummyDocument(); LineRenderer lineRenderer = new LineRenderer(); lineRenderer.setParent(document.getRenderer()); @@ -172,7 +172,7 @@ public void adjustChildrenYLineTextChildHtmlModeTest() { @Test public void adjustChildrenYLineImageChildHtmlModeTest() { - Document document = createDocument(); + Document document = createDummyDocument(); LineRenderer lineRenderer = new LineRenderer(); lineRenderer.setParent(document.getRenderer()); @@ -231,7 +231,7 @@ public void hasChildRendererInHtmlModeNoChildrenTest() { @Test public void lineRendererLayoutInHtmlModeWithLineHeightAndNoChildrenTest() { - Document document = createDocument(); + Document document = createDummyDocument(); LineRenderer lineRenderer = new LineRenderer(); lineRenderer.setParent(document.getRenderer()); @@ -246,7 +246,7 @@ public void lineRendererLayoutInHtmlModeWithLineHeightAndNoChildrenTest() { @Test public void lineRendererLayoutInHtmlModeWithLineHeightAndChildrenInDefaultModeTest() { - Document document = createDocument(); + Document document = createDummyDocument(); LineRenderer lineRenderer = new LineRenderer(); lineRenderer.setParent(document.getRenderer()); @@ -270,7 +270,7 @@ public void lineRendererLayoutInHtmlModeWithLineHeightAndChildrenInDefaultModeTe @Test public void lineRendererLayoutInHtmlModeWithLineHeightAndChildInHtmlModeTest() { - Document document = createDocument(); + Document document = createDummyDocument(); LineRenderer lineRenderer = new LineRenderer(); lineRenderer.setParent(document.getRenderer()); @@ -294,7 +294,7 @@ public void lineRendererLayoutInHtmlModeWithLineHeightAndChildInHtmlModeTest() { @Test public void lineRendererLayoutInHtmlModeWithLineHeightPropertyNotSet() throws IOException { LineRenderer lineRenderer = new LineRenderer(); - lineRenderer.setParent(createDocument().getRenderer()); + lineRenderer.setParent(createDummyDocument().getRenderer()); lineRenderer.setProperty(Property.RENDERING_MODE, RenderingMode.HTML_MODE); // Set fonts with different ascent/descent to line and text @@ -316,9 +316,6 @@ public void lineRendererLayoutInHtmlModeWithLineHeightPropertyNotSet() throws IO @Test public void minMaxWidthEqualsActualMarginsBordersPaddings() { - PdfDocument pdfDocument = new PdfDocument(new PdfWriter(new ByteArrayOutputStream())); - Document document = new Document(pdfDocument); - Text ranText = new Text("ran"); ranText.setProperty(Property.MARGIN_LEFT, new UnitValue(UnitValue.POINT, 8f)); @@ -341,7 +338,7 @@ public void minMaxWidthEqualsActualMarginsBordersPaddings() { new Rectangle(AbstractRenderer.INF, AbstractRenderer.INF)); LineRenderer lineRenderer = new LineRenderer(); - lineRenderer.setParent(document.getRenderer()); + lineRenderer.setParent(createDummyDocument().getRenderer()); lineRenderer.addChild(ran); lineRenderer.addChild(dom); @@ -353,7 +350,7 @@ public void minMaxWidthEqualsActualMarginsBordersPaddings() { @Test public void splitLineIntoGlyphsSimpleTest() { - Document dummyDocument = createDocument(); + Document dummyDocument = createDummyDocument(); TextRenderer dummy1 = createLayoutedTextRenderer("hello", dummyDocument); TextRenderer dummy2 = createLayoutedTextRenderer("world", dummyDocument); TextRenderer dummy3 = createLayoutedTextRenderer("!!!", dummyDocument); @@ -386,7 +383,7 @@ public void splitLineIntoGlyphsSimpleTest() { @Test public void splitLineIntoGlyphsWithLineBreakTest() { - Document dummyDocument = createDocument(); + Document dummyDocument = createDummyDocument(); TextRenderer dummy1 = createLayoutedTextRenderer("hello", dummyDocument); TextRenderer dummy2 = createLayoutedTextRenderer("world", dummyDocument); dummy2.line.set(2, new Glyph('\n', 0, '\n')); @@ -419,7 +416,7 @@ public void splitLineIntoGlyphsWithLineBreakTest() { @Test public void reorderSimpleTest() { - Document dummyDocument = createDocument(); + Document dummyDocument = createDummyDocument(); IRenderer dummy1 = createLayoutedTextRenderer("hello", dummyDocument); IRenderer dummy2 = createLayoutedTextRenderer("world", dummyDocument); IRenderer dummy3 = createLayoutedTextRenderer("!!!", dummyDocument); diff --git a/layout/src/test/java/com/itextpdf/layout/renderer/LinkRendererUnitTest.java b/layout/src/test/java/com/itextpdf/layout/renderer/LinkRendererUnitTest.java new file mode 100644 index 0000000000..5153e05fe5 --- /dev/null +++ b/layout/src/test/java/com/itextpdf/layout/renderer/LinkRendererUnitTest.java @@ -0,0 +1,54 @@ +/* + This file is part of the iText (R) project. + Copyright (c) 1998-2021 iText Group NV + Authors: iText Software. + + This program is offered under a commercial and under the AGPL license. + For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below. + + AGPL licensing: + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + */ +package com.itextpdf.layout.renderer; + +import com.itextpdf.io.LogMessageConstant; +import com.itextpdf.kernel.geom.Rectangle; +import com.itextpdf.kernel.pdf.action.PdfAction; +import com.itextpdf.kernel.pdf.annot.PdfLinkAnnotation; +import com.itextpdf.layout.element.Link; +import com.itextpdf.test.ExtendedITextTest; +import com.itextpdf.test.annotations.LogMessage; +import com.itextpdf.test.annotations.LogMessages; +import com.itextpdf.test.annotations.type.UnitTest; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +@Category(UnitTest.class) +public class LinkRendererUnitTest extends ExtendedITextTest { + + @Test + @LogMessages(messages = { + @LogMessage(messageTemplate = LogMessageConstant.GET_NEXT_RENDERER_SHOULD_BE_OVERRIDDEN) + }) + public void getNextRendererShouldBeOverriddenTest() { + LinkRenderer linkRenderer = + new LinkRenderer(new Link("test", new PdfLinkAnnotation(new Rectangle(0 ,0)))) { + // Nothing is overridden + }; + + Assert.assertEquals(LinkRenderer.class, linkRenderer.getNextRenderer().getClass()); + } +} diff --git a/layout/src/test/java/com/itextpdf/layout/renderer/ListRendererUnitTest.java b/layout/src/test/java/com/itextpdf/layout/renderer/ListRendererUnitTest.java new file mode 100644 index 0000000000..42b8555590 --- /dev/null +++ b/layout/src/test/java/com/itextpdf/layout/renderer/ListRendererUnitTest.java @@ -0,0 +1,50 @@ +/* + This file is part of the iText (R) project. + Copyright (c) 1998-2021 iText Group NV + Authors: iText Software. + + This program is offered under a commercial and under the AGPL license. + For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below. + + AGPL licensing: + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + */ +package com.itextpdf.layout.renderer; + +import com.itextpdf.io.LogMessageConstant; +import com.itextpdf.layout.element.List; +import com.itextpdf.test.ExtendedITextTest; +import com.itextpdf.test.annotations.LogMessage; +import com.itextpdf.test.annotations.LogMessages; +import com.itextpdf.test.annotations.type.UnitTest; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +@Category(UnitTest.class) +public class ListRendererUnitTest extends ExtendedITextTest { + + @Test + @LogMessages(messages = { + @LogMessage(messageTemplate = LogMessageConstant.GET_NEXT_RENDERER_SHOULD_BE_OVERRIDDEN) + }) + public void getNextRendererShouldBeOverriddenTest() { + ListRenderer listRenderer = new ListRenderer(new List()) { + // Nothing is overridden + }; + + Assert.assertEquals(ListRenderer.class, listRenderer.getNextRenderer().getClass()); + } +} diff --git a/layout/src/test/java/com/itextpdf/layout/renderer/ParagraphRendererUnitTest.java b/layout/src/test/java/com/itextpdf/layout/renderer/ParagraphRendererUnitTest.java new file mode 100644 index 0000000000..66e1d8987c --- /dev/null +++ b/layout/src/test/java/com/itextpdf/layout/renderer/ParagraphRendererUnitTest.java @@ -0,0 +1,50 @@ +/* + This file is part of the iText (R) project. + Copyright (c) 1998-2021 iText Group NV + Authors: iText Software. + + This program is offered under a commercial and under the AGPL license. + For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below. + + AGPL licensing: + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + */ +package com.itextpdf.layout.renderer; + +import com.itextpdf.io.LogMessageConstant; +import com.itextpdf.layout.element.Paragraph; +import com.itextpdf.test.ExtendedITextTest; +import com.itextpdf.test.annotations.LogMessage; +import com.itextpdf.test.annotations.LogMessages; +import com.itextpdf.test.annotations.type.UnitTest; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +@Category(UnitTest.class) +public class ParagraphRendererUnitTest extends ExtendedITextTest { + + @Test + @LogMessages(messages = { + @LogMessage(messageTemplate = LogMessageConstant.GET_NEXT_RENDERER_SHOULD_BE_OVERRIDDEN) + }) + public void getNextRendererShouldBeOverriddenTest() { + ParagraphRenderer paragraphRenderer = new ParagraphRenderer(new Paragraph()) { + // Nothing is overridden + }; + + Assert.assertEquals(ParagraphRenderer.class, paragraphRenderer.getNextRenderer().getClass()); + } +} diff --git a/layout/src/test/java/com/itextpdf/layout/renderer/RendererUnitTest.java b/layout/src/test/java/com/itextpdf/layout/renderer/RendererUnitTest.java index 3f6acb7697..4b70831e67 100644 --- a/layout/src/test/java/com/itextpdf/layout/renderer/RendererUnitTest.java +++ b/layout/src/test/java/com/itextpdf/layout/renderer/RendererUnitTest.java @@ -57,7 +57,7 @@ This file is part of the iText (R) project. public abstract class RendererUnitTest extends ExtendedITextTest { // This also can be converted to a @Rule to have it all at hand in the future - protected static Document createDocument() { + protected static Document createDummyDocument() { return new Document(new PdfDocument(new PdfWriter(new ByteArrayOutputStream()))); } diff --git a/layout/src/test/java/com/itextpdf/layout/renderer/TabRendererUnitTest.java b/layout/src/test/java/com/itextpdf/layout/renderer/TabRendererUnitTest.java new file mode 100644 index 0000000000..8e581c7153 --- /dev/null +++ b/layout/src/test/java/com/itextpdf/layout/renderer/TabRendererUnitTest.java @@ -0,0 +1,50 @@ +/* + This file is part of the iText (R) project. + Copyright (c) 1998-2021 iText Group NV + Authors: iText Software. + + This program is offered under a commercial and under the AGPL license. + For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below. + + AGPL licensing: + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + */ +package com.itextpdf.layout.renderer; + +import com.itextpdf.io.LogMessageConstant; +import com.itextpdf.layout.element.Tab; +import com.itextpdf.test.ExtendedITextTest; +import com.itextpdf.test.annotations.LogMessage; +import com.itextpdf.test.annotations.LogMessages; +import com.itextpdf.test.annotations.type.UnitTest; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +@Category(UnitTest.class) +public class TabRendererUnitTest extends ExtendedITextTest { + + @Test + @LogMessages(messages = { + @LogMessage(messageTemplate = LogMessageConstant.GET_NEXT_RENDERER_SHOULD_BE_OVERRIDDEN) + }) + public void getNextRendererShouldBeOverriddenTest() { + TabRenderer tabRenderer = new TabRenderer(new Tab()) { + // Nothing is overridden + }; + + Assert.assertEquals(TabRenderer.class, tabRenderer.getNextRenderer().getClass()); + } +} diff --git a/layout/src/test/java/com/itextpdf/layout/renderer/TableRendererUnitTest.java b/layout/src/test/java/com/itextpdf/layout/renderer/TableRendererUnitTest.java new file mode 100644 index 0000000000..3c6d74b717 --- /dev/null +++ b/layout/src/test/java/com/itextpdf/layout/renderer/TableRendererUnitTest.java @@ -0,0 +1,50 @@ +/* + This file is part of the iText (R) project. + Copyright (c) 1998-2021 iText Group NV + Authors: iText Software. + + This program is offered under a commercial and under the AGPL license. + For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below. + + AGPL licensing: + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + */ +package com.itextpdf.layout.renderer; + +import com.itextpdf.io.LogMessageConstant; +import com.itextpdf.layout.element.Table; +import com.itextpdf.test.ExtendedITextTest; +import com.itextpdf.test.annotations.LogMessage; +import com.itextpdf.test.annotations.LogMessages; +import com.itextpdf.test.annotations.type.UnitTest; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +@Category(UnitTest.class) +public class TableRendererUnitTest extends ExtendedITextTest { + + @Test + @LogMessages(messages = { + @LogMessage(messageTemplate = LogMessageConstant.GET_NEXT_RENDERER_SHOULD_BE_OVERRIDDEN) + }) + public void getNextRendererShouldBeOverriddenTest() { + TableRenderer tableRenderer = new TableRenderer(new Table(1)) { + // Nothing is overridden + }; + + Assert.assertEquals(TableRenderer.class, tableRenderer.getNextRenderer().getClass()); + } +} diff --git a/layout/src/test/java/com/itextpdf/layout/renderer/TargetCounterHandlerTest.java b/layout/src/test/java/com/itextpdf/layout/renderer/TargetCounterHandlerTest.java index d4ae3b1c8d..5332197a64 100644 --- a/layout/src/test/java/com/itextpdf/layout/renderer/TargetCounterHandlerTest.java +++ b/layout/src/test/java/com/itextpdf/layout/renderer/TargetCounterHandlerTest.java @@ -25,7 +25,13 @@ This file is part of the iText (R) project. import com.itextpdf.io.font.constants.StandardFonts; import com.itextpdf.io.image.ImageDataFactory; import com.itextpdf.kernel.font.PdfFontFactory; +import com.itextpdf.kernel.geom.PageSize; import com.itextpdf.kernel.geom.Rectangle; +import com.itextpdf.kernel.pdf.PdfDocument; +import com.itextpdf.kernel.pdf.PdfWriter; +import com.itextpdf.kernel.utils.CompareTool; +import com.itextpdf.layout.Document; +import com.itextpdf.layout.element.AreaBreak; import com.itextpdf.layout.element.Div; import com.itextpdf.layout.element.Image; import com.itextpdf.layout.element.Paragraph; @@ -33,22 +39,32 @@ This file is part of the iText (R) project. import com.itextpdf.layout.element.Text; import com.itextpdf.layout.layout.LayoutArea; import com.itextpdf.layout.layout.LayoutContext; +import com.itextpdf.layout.layout.LayoutResult; import com.itextpdf.layout.property.Property; import com.itextpdf.layout.property.UnitValue; import com.itextpdf.layout.splitting.DefaultSplitCharacters; import com.itextpdf.test.ExtendedITextTest; import com.itextpdf.test.annotations.type.IntegrationTest; + +import java.io.IOException; import org.junit.Assert; +import org.junit.BeforeClass; import org.junit.Test; import org.junit.experimental.categories.Category; -import java.io.IOException; - @Category(IntegrationTest.class) public class TargetCounterHandlerTest extends ExtendedITextTest { + public static final String SOURCE_FOLDER = "./src/test/resources/com/itextpdf/layout/renderer/TargetCounterHandlerTest/"; + public static final String DESTINATION_FOLDER = "./target/test/com/itextpdf/layout/renderer/TargetCounterHandlerTest/"; + + @BeforeClass + public static void beforeClass() { + createDestinationFolder(DESTINATION_FOLDER); + } + @Test - public void BlockRendererAddByIDTest() { + public void blockRendererAddByIDTest() { DocumentRenderer documentRenderer = new DocumentRenderer(null); DivRenderer divRenderer = new DivRenderer(new Div()); divRenderer.setParent(documentRenderer); @@ -62,7 +78,7 @@ public void BlockRendererAddByIDTest() { } @Test - public void TextRendererAddByIDTest() throws IOException { + public void textRendererAddByIDTest() throws IOException { DocumentRenderer documentRenderer = new DocumentRenderer(null); TextRenderer textRenderer = new TextRenderer(new Text("a")); @@ -84,7 +100,7 @@ public void TextRendererAddByIDTest() throws IOException { } @Test - public void TableRendererAddByIDTest() { + public void tableRendererAddByIDTest() { DocumentRenderer documentRenderer = new DocumentRenderer(null); TableRenderer tableRenderer = new TableRenderer(new Table(5)); tableRenderer.setParent(documentRenderer); @@ -98,7 +114,7 @@ public void TableRendererAddByIDTest() { } @Test - public void ParagraphRendererAddByIDTest() { + public void paragraphRendererAddByIDTest() { DocumentRenderer documentRenderer = new DocumentRenderer(null); ParagraphRenderer paragraphRenderer = new ParagraphRenderer(new Paragraph()); paragraphRenderer.setParent(documentRenderer); @@ -112,7 +128,7 @@ public void ParagraphRendererAddByIDTest() { } @Test - public void ImageRendererAddByIDTest() { + public void imageRendererAddByIDTest() { DocumentRenderer documentRenderer = new DocumentRenderer(null); ImageRenderer imageRenderer = new ImageRenderer(new Image(ImageDataFactory.createRawImage(new byte[]{50, 21}))); imageRenderer.setParent(documentRenderer); @@ -126,7 +142,7 @@ public void ImageRendererAddByIDTest() { } @Test - public void LineRendererAddByIDTest() { + public void lineRendererAddByIDTest() { DocumentRenderer documentRenderer = new DocumentRenderer(null); LineRenderer lineRenderer = new LineRenderer(); lineRenderer.setParent(documentRenderer); @@ -138,4 +154,69 @@ public void LineRendererAddByIDTest() { documentRenderer.getTargetCounterHandler().prepareHandlerToRelayout(); Assert.assertEquals((Integer) 4, TargetCounterHandler.getPageByID(lineRenderer, id)); } + + @Test + public void targetCounterHandlerEndToEndLayoutTest() throws IOException, InterruptedException { + String targetPdf = DESTINATION_FOLDER + "targetCounterHandlerEndToEndLayoutTest.pdf"; + String cmpPdf = SOURCE_FOLDER + "cmp_targetCounterHandlerEndToEndLayoutTest.pdf"; + Document document = new Document(new PdfDocument(new PdfWriter(targetPdf)), + PageSize.A4, false); + + Text pageNumPlaceholder = new Text("x"); + String id = "1"; + pageNumPlaceholder.setProperty(Property.ID, id); + pageNumPlaceholder.setNextRenderer(new TargetCounterAwareTextRenderer(pageNumPlaceholder)); + Paragraph intro = new Paragraph("The paragraph is on page ").add(pageNumPlaceholder); + document.add(intro); + + document.add(new AreaBreak()); + Paragraph text = new Paragraph("This is main text"); + text.setProperty(Property.ID, id); + text.setNextRenderer(new TargetCounterAwareParagraphRenderer(text)); + document.add(text); + + document.relayout(); + + document.close(); + + Assert.assertNull(new CompareTool().compareByContent(targetPdf, cmpPdf, DESTINATION_FOLDER, "diff")); + } + + private static class TargetCounterAwareTextRenderer extends TextRenderer { + public TargetCounterAwareTextRenderer(Text link) { + super(link); + } + + @Override + public LayoutResult layout(LayoutContext layoutContext) { + Integer targetPageNumber = TargetCounterHandler.getPageByID(this, this.getProperty(Property.ID)); + if (targetPageNumber != null) { + setText(String.valueOf(targetPageNumber)); + } + return super.layout(layoutContext); + } + + @Override + public IRenderer getNextRenderer() { + return new TargetCounterAwareTextRenderer((Text) getModelElement()); + } + } + + private static class TargetCounterAwareParagraphRenderer extends ParagraphRenderer { + public TargetCounterAwareParagraphRenderer(Paragraph modelElement) { + super(modelElement); + } + + @Override + public IRenderer getNextRenderer() { + return new TargetCounterAwareParagraphRenderer((Paragraph) modelElement); + } + + @Override + public LayoutResult layout(LayoutContext layoutContext) { + LayoutResult result = super.layout(layoutContext); + TargetCounterHandler.addPageByID(this); + return result; + } + } } diff --git a/layout/src/test/java/com/itextpdf/layout/renderer/TextRendererIntegrationTest.java b/layout/src/test/java/com/itextpdf/layout/renderer/TextRendererIntegrationTest.java index e05a5709d9..63871a9748 100644 --- a/layout/src/test/java/com/itextpdf/layout/renderer/TextRendererIntegrationTest.java +++ b/layout/src/test/java/com/itextpdf/layout/renderer/TextRendererIntegrationTest.java @@ -24,6 +24,7 @@ This file is part of the iText (R) project. import com.itextpdf.io.LogMessageConstant; import com.itextpdf.io.font.PdfEncodings; +import com.itextpdf.io.font.otf.GlyphLine; import com.itextpdf.io.image.ImageDataFactory; import com.itextpdf.kernel.colors.ColorConstants; import com.itextpdf.kernel.font.PdfFont; @@ -42,6 +43,7 @@ This file is part of the iText (R) project. import com.itextpdf.layout.element.Paragraph; import com.itextpdf.layout.element.Table; import com.itextpdf.layout.element.Text; +import com.itextpdf.layout.font.FontProvider; import com.itextpdf.layout.property.FloatPropertyValue; import com.itextpdf.layout.property.OverflowPropertyValue; import com.itextpdf.layout.property.OverflowWrapPropertyValue; @@ -54,6 +56,7 @@ This file is part of the iText (R) project. import com.itextpdf.test.annotations.LogMessages; import com.itextpdf.test.annotations.type.IntegrationTest; +import java.io.FileNotFoundException; import java.io.IOException; import org.junit.Assert; import org.junit.BeforeClass; @@ -718,4 +721,139 @@ public void overflowWrapBreakWordWithOverflowXTest() throws IOException, Interru doc.close(); Assert.assertNull(new CompareTool().compareByContent(outFileName, cmpFileName, destinationFolder)); } + + @Test + @LogMessages(messages = { + @LogMessage(messageTemplate = LogMessageConstant.GET_NEXT_RENDERER_SHOULD_BE_OVERRIDDEN, count = 3) + }) + public void customTextRendererShouldOverrideGetNextRendererTest() throws IOException, InterruptedException { + String outFileName = destinationFolder + "customTextRendererShouldOverrideGetNextRendererTest.pdf"; + String cmpFileName = sourceFolder + "cmp_customTextRendererShouldOverrideGetNextRendererTest.pdf"; + + PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName)); + Document doc = new Document(pdfDoc); + + Text text = new Text("If getNextRenderer() is not overridden and text overflows to the next line," + + " then customizations are not applied. "); + text.setNextRenderer(new TextRenderer(text) { + @Override + public void draw(DrawContext drawContext) { + drawContext.getCanvas() + .saveState() + .setFillColor(ColorConstants.RED) + .rectangle(occupiedArea.getBBox()) + .fill() + .restoreState(); + super.draw(drawContext); + } + }); + doc.add(new Paragraph(text)); + + text = new Text("If getNextRenderer() is overridden and text overflows to the next line, " + + "then customizations are applied. "); + text.setNextRenderer(new TextRenderer(text) { + @Override + public void draw(DrawContext drawContext) { + drawContext.getCanvas() + .saveState() + .setFillColor(ColorConstants.RED) + .rectangle(occupiedArea.getBBox()) + .fill() + .restoreState(); + super.draw(drawContext); + } + + @Override + public IRenderer getNextRenderer() { + return new TextRendererWithOverriddenGetNextRenderer((Text) modelElement); + } + }); + doc.add(new Paragraph(text)); + + doc.close(); + Assert.assertNull(new CompareTool().compareByContent(outFileName, cmpFileName, destinationFolder)); + } + + @Test + @LogMessages(messages = { + @LogMessage(messageTemplate = LogMessageConstant.CREATE_COPY_SHOULD_BE_OVERRIDDEN, count = 8) + }) + public void customTextRendererShouldOverrideCreateCopyTest() throws IOException, InterruptedException { + String outFileName = destinationFolder + "customTextRendererShouldOverrideCreateCopyTest.pdf"; + String cmpFileName = sourceFolder + "cmp_customTextRendererShouldOverrideCreateCopyTest.pdf"; + + PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName)); + Document doc = new Document(pdfDoc); + + FontProvider fontProvider = new FontProvider(); + Assert.assertTrue(fontProvider.addFont(fontsFolder + "NotoSans-Regular.ttf")); + + doc.setFontProvider(fontProvider); + // To trigger font selector related logic one need to apply some font on a document + doc.setProperty(Property.FONT, new String[] {"SomeFont"}); + + StringBuilder longTextBuilder = new StringBuilder(); + for (int i = 0; i < 4; i++) { + longTextBuilder.append("Дзень добры, Ñвет! Hallo Welt! "); + } + + Text text = new Text(longTextBuilder.toString()); + text.setNextRenderer(new TextRenderer(text) { + @Override + public void draw(DrawContext drawContext) { + drawContext.getCanvas() + .saveState() + .setFillColor(ColorConstants.RED) + .rectangle(occupiedArea.getBBox()) + .fill() + .restoreState(); + super.draw(drawContext); + } + + @Override + public IRenderer getNextRenderer() { + return new TextRendererWithOverriddenGetNextRenderer((Text) modelElement); + } + }); + doc.add(new Paragraph(text)); + + text.setNextRenderer(new TextRendererWithOverriddenGetNextRenderer(text)); + doc.add(new Paragraph(text)); + + doc.close(); + Assert.assertNull(new CompareTool().compareByContent(outFileName, cmpFileName, destinationFolder)); + } + + private static class TextRendererWithOverriddenGetNextRenderer extends TextRenderer { + public TextRendererWithOverriddenGetNextRenderer(Text textElement) { + super(textElement); + } + + protected TextRendererWithOverriddenGetNextRenderer(TextRenderer other) { + super(other); + } + + @Override + public void draw(DrawContext drawContext) { + drawContext.getCanvas() + .saveState() + .setFillColor(ColorConstants.RED) + .rectangle(occupiedArea.getBBox()) + .fill() + .restoreState(); + super.draw(drawContext); + } + + @Override + public IRenderer getNextRenderer() { + return new TextRendererWithOverriddenGetNextRenderer((Text) modelElement); + } + + @Override + protected TextRenderer createCopy(GlyphLine gl, PdfFont font) { + TextRenderer copy = new TextRendererWithOverriddenGetNextRenderer(this); + copy.setProcessedGlyphLineAndFont(gl, font); + return copy; + } + } } diff --git a/layout/src/test/java/com/itextpdf/layout/renderer/TextRendererTest.java b/layout/src/test/java/com/itextpdf/layout/renderer/TextRendererTest.java index a35d9ab5fc..627a90cc4a 100644 --- a/layout/src/test/java/com/itextpdf/layout/renderer/TextRendererTest.java +++ b/layout/src/test/java/com/itextpdf/layout/renderer/TextRendererTest.java @@ -61,6 +61,7 @@ This file is part of the iText (R) project. import com.itextpdf.layout.layout.LayoutResult; import com.itextpdf.layout.layout.TextLayoutResult; import com.itextpdf.layout.minmaxwidth.MinMaxWidth; +import com.itextpdf.layout.property.FloatPropertyValue; import com.itextpdf.layout.property.OverflowPropertyValue; import com.itextpdf.layout.property.OverflowWrapPropertyValue; import com.itextpdf.layout.property.Property; @@ -203,7 +204,7 @@ public void setFontAsText() { @Test public void getDescentTest() { - Document doc = createDocument(); + Document doc = createDummyDocument(); TextRenderer textRenderer = createLayoutedTextRenderer("hello", doc); textRenderer.setProperty(Property.PADDING_TOP, UnitValue.createPointValue(20f)); textRenderer.setProperty(Property.MARGIN_TOP, UnitValue.createPointValue(20f)); @@ -212,7 +213,7 @@ public void getDescentTest() { @Test public void getOccupiedAreaBBoxTest() { - Document doc = createDocument(); + Document doc = createDummyDocument(); TextRenderer textRenderer = createLayoutedTextRenderer("hello", doc); textRenderer.setProperty(Property.PADDING_TOP, UnitValue.createPointValue(20f)); textRenderer.setProperty(Property.MARGIN_TOP, UnitValue.createPointValue(20f)); @@ -224,7 +225,7 @@ public void getOccupiedAreaBBoxTest() { @Test public void getInnerAreaBBoxTest() { - Document doc = createDocument(); + Document doc = createDummyDocument(); TextRenderer textRenderer = createLayoutedTextRenderer("hello", doc); textRenderer.setProperty(Property.PADDING_TOP, UnitValue.createPointValue(20f)); textRenderer.setProperty(Property.MARGIN_TOP, UnitValue.createPointValue(20f)); @@ -284,19 +285,14 @@ public void cyrillicCharacterDoesntBelongToSpecificScripts() { // u0433 Cyrillic Small Letter U Assert.assertFalse(TextRenderer.codePointIsOfSpecialScript(1091)); } - + @Test public void overflowWrapAnywhereProperty() { - PdfDocument pdfDoc = new PdfDocument(new PdfWriter(new ByteArrayOutputStream())); - pdfDoc.addNewPage(); - Document doc = new Document(pdfDoc); - RootRenderer documentRenderer = doc.getRenderer(); - Text text = new Text("wow"); text.setProperty(Property.OVERFLOW_WRAP, OverflowWrapPropertyValue.ANYWHERE); TextRenderer textRenderer = (TextRenderer) text.getRenderer(); - textRenderer.setParent(documentRenderer); + textRenderer.setParent(createDummyDocument().getRenderer()); MinMaxWidth minMaxWidth = textRenderer.getMinMaxWidth(); @@ -305,17 +301,13 @@ public void overflowWrapAnywhereProperty() { @Test public void overflowWrapBreakWordProperty() { - PdfDocument pdfDoc = new PdfDocument(new PdfWriter(new ByteArrayOutputStream())); - pdfDoc.addNewPage(); - Document doc = new Document(pdfDoc); - RootRenderer documentRenderer = doc.getRenderer(); - Text text = new Text("wooow"); TextRenderer textRenderer = (TextRenderer) text.getRenderer(); - textRenderer.setParent(documentRenderer); + RootRenderer parentRenderer = createDummyDocument().getRenderer(); + textRenderer.setParent(parentRenderer); // overflow is set here to mock LineRenderer#layout behavior - documentRenderer.setProperty(Property.OVERFLOW_X, OverflowPropertyValue.VISIBLE); + parentRenderer.setProperty(Property.OVERFLOW_X, OverflowPropertyValue.VISIBLE); float fullWordWidth = textRenderer.getMinMaxWidth().getMaxWidth(); @@ -332,16 +324,11 @@ public void overflowWrapBreakWordProperty() { @Test public void overflowWrapAnywhereBoldSimulationMaxWidth() { - PdfDocument pdfDoc = new PdfDocument(new PdfWriter(new ByteArrayOutputStream())); - pdfDoc.addNewPage(); - Document doc = new Document(pdfDoc); - RootRenderer documentRenderer = doc.getRenderer(); - Text text = new Text("wow"); text.setBold(); TextRenderer textRenderer = (TextRenderer) text.getRenderer(); - textRenderer.setParent(documentRenderer); + textRenderer.setParent(createDummyDocument().getRenderer()); float maxWidthNoOverflowWrap = textRenderer.getMinMaxWidth().getMaxWidth(); @@ -353,16 +340,11 @@ public void overflowWrapAnywhereBoldSimulationMaxWidth() { @Test public void overflowWrapAnywhereItalicSimulationMaxWidth() { - PdfDocument pdfDoc = new PdfDocument(new PdfWriter(new ByteArrayOutputStream())); - pdfDoc.addNewPage(); - Document doc = new Document(pdfDoc); - RootRenderer documentRenderer = doc.getRenderer(); - Text text = new Text("wow"); text.setItalic(); TextRenderer textRenderer = (TextRenderer) text.getRenderer(); - textRenderer.setParent(documentRenderer); + textRenderer.setParent(createDummyDocument().getRenderer()); float maxWidthNoOverflowWrap = textRenderer.getMinMaxWidth().getMaxWidth(); @@ -374,16 +356,11 @@ public void overflowWrapAnywhereItalicSimulationMaxWidth() { @Test public void overflowWrapAnywhereBoldSimulationMinWidth() { - PdfDocument pdfDoc = new PdfDocument(new PdfWriter(new ByteArrayOutputStream())); - pdfDoc.addNewPage(); - Document doc = new Document(pdfDoc); - RootRenderer documentRenderer = doc.getRenderer(); - Text text = new Text("wow"); text.setProperty(Property.OVERFLOW_WRAP, OverflowWrapPropertyValue.ANYWHERE); TextRenderer textRenderer = (TextRenderer) text.getRenderer(); - textRenderer.setParent(documentRenderer); + textRenderer.setParent(createDummyDocument().getRenderer()); float minWidthNoBoldSimulation = textRenderer.getMinMaxWidth().getMinWidth(); @@ -395,16 +372,11 @@ public void overflowWrapAnywhereBoldSimulationMinWidth() { @Test public void overflowWrapAnywhereItalicSimulationMinWidth() { - PdfDocument pdfDoc = new PdfDocument(new PdfWriter(new ByteArrayOutputStream())); - pdfDoc.addNewPage(); - Document doc = new Document(pdfDoc); - RootRenderer documentRenderer = doc.getRenderer(); - Text text = new Text("wow"); text.setProperty(Property.OVERFLOW_WRAP, OverflowWrapPropertyValue.ANYWHERE); TextRenderer textRenderer = (TextRenderer) text.getRenderer(); - textRenderer.setParent(documentRenderer); + textRenderer.setParent(createDummyDocument().getRenderer()); float minWidthNoItalicSimulation = textRenderer.getMinMaxWidth().getMinWidth(); @@ -413,4 +385,26 @@ public void overflowWrapAnywhereItalicSimulationMinWidth() { Assert.assertTrue(minWidthAndItalicSimulation > minWidthNoItalicSimulation); } + + @Test + public void floatingRightMinMaxWidth() throws IOException { + String longestWord = "float:right"; + String wholeText = "text with " + longestWord; + TextRenderer textRenderer = new TextRenderer(new Text(wholeText)); + textRenderer.setProperty(Property.FLOAT, FloatPropertyValue.RIGHT); + + textRenderer.setParent(createDummyDocument().getRenderer()); + + PdfFont font = PdfFontFactory.createFont(); + int fontSize = 12; + textRenderer.setProperty(Property.FONT, font); + textRenderer.setProperty(Property.FONT_SIZE, UnitValue.createPointValue(fontSize)); + + float expectedMaxWidth = font.getWidth(wholeText, fontSize); + float expectedMinWidth = font.getWidth(longestWord, fontSize); + + MinMaxWidth minMaxWidth = textRenderer.getMinMaxWidth(); + Assert.assertEquals(expectedMinWidth, minMaxWidth.getMinWidth(), 0.01f); + Assert.assertEquals(expectedMaxWidth, minMaxWidth.getMaxWidth(), 0.01f); + } } diff --git a/layout/src/test/java/com/itextpdf/layout/renderer/TextRendererUnitTest.java b/layout/src/test/java/com/itextpdf/layout/renderer/TextRendererUnitTest.java new file mode 100644 index 0000000000..f64b61bec7 --- /dev/null +++ b/layout/src/test/java/com/itextpdf/layout/renderer/TextRendererUnitTest.java @@ -0,0 +1,50 @@ +/* + This file is part of the iText (R) project. + Copyright (c) 1998-2021 iText Group NV + Authors: iText Software. + + This program is offered under a commercial and under the AGPL license. + For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below. + + AGPL licensing: + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + */ +package com.itextpdf.layout.renderer; + +import com.itextpdf.io.LogMessageConstant; +import com.itextpdf.layout.element.Text; +import com.itextpdf.test.ExtendedITextTest; +import com.itextpdf.test.annotations.LogMessage; +import com.itextpdf.test.annotations.LogMessages; +import com.itextpdf.test.annotations.type.UnitTest; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +@Category(UnitTest.class) +public class TextRendererUnitTest extends ExtendedITextTest { + + @Test + @LogMessages(messages = { + @LogMessage(messageTemplate = LogMessageConstant.GET_NEXT_RENDERER_SHOULD_BE_OVERRIDDEN) + }) + public void getNextRendererShouldBeOverriddenTest() { + TextRenderer textRenderer = new TextRenderer(new Text("tet")) { + // Nothing is overridden + }; + + Assert.assertEquals(TextRenderer.class, textRenderer.getNextRenderer().getClass()); + } +} diff --git a/layout/src/test/resources/com/itextpdf/layout/BlockTest/cmp_borderRadiusTest01.pdf b/layout/src/test/resources/com/itextpdf/layout/BlockTest/cmp_borderRadiusTest01.pdf index 59bb7794b7..3046afc8fc 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/BlockTest/cmp_borderRadiusTest01.pdf and b/layout/src/test/resources/com/itextpdf/layout/BlockTest/cmp_borderRadiusTest01.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/BlockTest/cmp_borderRadiusTest02.pdf b/layout/src/test/resources/com/itextpdf/layout/BlockTest/cmp_borderRadiusTest02.pdf index b3ee538a97..cd4262f782 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/BlockTest/cmp_borderRadiusTest02.pdf and b/layout/src/test/resources/com/itextpdf/layout/BlockTest/cmp_borderRadiusTest02.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/BlockTest/cmp_borderRadiusTest03.pdf b/layout/src/test/resources/com/itextpdf/layout/BlockTest/cmp_borderRadiusTest03.pdf index 33bd4345a5..2804068e6d 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/BlockTest/cmp_borderRadiusTest03.pdf and b/layout/src/test/resources/com/itextpdf/layout/BlockTest/cmp_borderRadiusTest03.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/BlockTest/cmp_borderRadiusTest04.pdf b/layout/src/test/resources/com/itextpdf/layout/BlockTest/cmp_borderRadiusTest04.pdf index 6068d0cd81..358bff690a 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/BlockTest/cmp_borderRadiusTest04.pdf and b/layout/src/test/resources/com/itextpdf/layout/BlockTest/cmp_borderRadiusTest04.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/BlockTest/cmp_borderRadiusTest05.pdf b/layout/src/test/resources/com/itextpdf/layout/BlockTest/cmp_borderRadiusTest05.pdf index 4f13624f33..8fbab6b3df 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/BlockTest/cmp_borderRadiusTest05.pdf and b/layout/src/test/resources/com/itextpdf/layout/BlockTest/cmp_borderRadiusTest05.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/BlockTest/cmp_borderRadiusTest06.pdf b/layout/src/test/resources/com/itextpdf/layout/BlockTest/cmp_borderRadiusTest06.pdf index 8e75a5bbf8..2bde301d9d 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/BlockTest/cmp_borderRadiusTest06.pdf and b/layout/src/test/resources/com/itextpdf/layout/BlockTest/cmp_borderRadiusTest06.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/CanvasTest/cmp_nestedElementWithAbsolutePositioningInCanvas.pdf b/layout/src/test/resources/com/itextpdf/layout/CanvasTest/cmp_nestedElementWithAbsolutePositioningInCanvas.pdf new file mode 100644 index 0000000000..99a955d52b Binary files /dev/null and b/layout/src/test/resources/com/itextpdf/layout/CanvasTest/cmp_nestedElementWithAbsolutePositioningInCanvas.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/CollapsingMarginsTest/cmp_columnRendererTest.pdf b/layout/src/test/resources/com/itextpdf/layout/CollapsingMarginsTest/cmp_columnRendererTest.pdf new file mode 100644 index 0000000000..9e069d3e7e Binary files /dev/null and b/layout/src/test/resources/com/itextpdf/layout/CollapsingMarginsTest/cmp_columnRendererTest.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_collapsingMarginsFlexContainerTest1.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_collapsingMarginsFlexContainerTest1.pdf index 05e0f7d5d9..b91ea2ce8b 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_collapsingMarginsFlexContainerTest1.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_collapsingMarginsFlexContainerTest1.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_collapsingMarginsFlexContainerTest2.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_collapsingMarginsFlexContainerTest2.pdf index ce15d684c6..3046d80856 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_collapsingMarginsFlexContainerTest2.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_collapsingMarginsFlexContainerTest2.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_collapsingMarginsFlexContainerTest3.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_collapsingMarginsFlexContainerTest3.pdf index 33f2f22a38..09b03953aa 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_collapsingMarginsFlexContainerTest3.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_collapsingMarginsFlexContainerTest3.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_collapsingMarginsFlexContainerTest4.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_collapsingMarginsFlexContainerTest4.pdf index 8287337f77..a6207928fa 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_collapsingMarginsFlexContainerTest4.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_collapsingMarginsFlexContainerTest4.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_collapsingMarginsFlexContainerTest5.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_collapsingMarginsFlexContainerTest5.pdf deleted file mode 100644 index bbfbcd6f48..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_collapsingMarginsFlexContainerTest5.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_collapsingMarginsFlexContainerTest6.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_collapsingMarginsFlexContainerTest6.pdf deleted file mode 100644 index faf51a7f38..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_collapsingMarginsFlexContainerTest6.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_collapsingMarginsFlexContainerTest7.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_collapsingMarginsFlexContainerTest7.pdf deleted file mode 100644 index 423fafe21c..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_collapsingMarginsFlexContainerTest7.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_collapsingMarginsFlexContainerTest8.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_collapsingMarginsFlexContainerTest8.pdf deleted file mode 100644 index a2a6b4a8f3..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_collapsingMarginsFlexContainerTest8.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_collapsingMarginsFlexContainerTest9.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_collapsingMarginsFlexContainerTest9.pdf deleted file mode 100644 index 892883011e..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_collapsingMarginsFlexContainerTest9.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_defaultFlexContainerTest1.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_defaultFlexContainerTest1.pdf index f7e1e70191..90ac0b4188 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_defaultFlexContainerTest1.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_defaultFlexContainerTest1.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_defaultFlexContainerTest2.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_defaultFlexContainerTest2.pdf index 2d5ba61d0c..4c8e9f07f2 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_defaultFlexContainerTest2.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_defaultFlexContainerTest2.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_defaultFlexContainerTest3.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_defaultFlexContainerTest3.pdf index 61b9bc57ff..1a0fb2099c 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_defaultFlexContainerTest3.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_defaultFlexContainerTest3.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_defaultFlexContainerTest4.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_defaultFlexContainerTest4.pdf index 69cc664e12..1b367b231a 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_defaultFlexContainerTest4.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_defaultFlexContainerTest4.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_defaultFlexContainerTest5.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_defaultFlexContainerTest5.pdf deleted file mode 100644 index d7b13bb7d9..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_defaultFlexContainerTest5.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_defaultFlexContainerTest6.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_defaultFlexContainerTest6.pdf deleted file mode 100644 index c82a238ff4..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_defaultFlexContainerTest6.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_defaultFlexContainerTest7.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_defaultFlexContainerTest7.pdf deleted file mode 100644 index 6201322485..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_defaultFlexContainerTest7.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_defaultFlexContainerTest8.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_defaultFlexContainerTest8.pdf deleted file mode 100644 index 0ecf2c5443..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_defaultFlexContainerTest8.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_defaultFlexContainerTest9.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_defaultFlexContainerTest9.pdf deleted file mode 100644 index 48bc85aea7..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_defaultFlexContainerTest9.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerBoxSizingTest1.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerBoxSizingTest1.pdf index 7a1358331e..858635b832 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerBoxSizingTest1.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerBoxSizingTest1.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerBoxSizingTest2.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerBoxSizingTest2.pdf index 1535f75298..ff5bbe49e7 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerBoxSizingTest2.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerBoxSizingTest2.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerBoxSizingTest3.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerBoxSizingTest3.pdf index d18747e3ca..76eb0d6ef9 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerBoxSizingTest3.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerBoxSizingTest3.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerBoxSizingTest4.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerBoxSizingTest4.pdf index c0f484a0e8..7060db8794 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerBoxSizingTest4.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerBoxSizingTest4.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerBoxSizingTest5.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerBoxSizingTest5.pdf deleted file mode 100644 index 9fcdd1329e..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerBoxSizingTest5.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerBoxSizingTest6.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerBoxSizingTest6.pdf deleted file mode 100644 index d42e1fdd89..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerBoxSizingTest6.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerBoxSizingTest7.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerBoxSizingTest7.pdf deleted file mode 100644 index 8808796d03..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerBoxSizingTest7.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerBoxSizingTest8.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerBoxSizingTest8.pdf deleted file mode 100644 index d5fd7795f4..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerBoxSizingTest8.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerBoxSizingTest9.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerBoxSizingTest9.pdf deleted file mode 100644 index 4c0bfe4e2c..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerBoxSizingTest9.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyForcedPlacementTest1.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyForcedPlacementTest1.pdf index d0e6a55baa..6433e4b0db 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyForcedPlacementTest1.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyForcedPlacementTest1.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyForcedPlacementTest2.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyForcedPlacementTest2.pdf index 0da6232fac..de7b2be2f9 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyForcedPlacementTest2.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyForcedPlacementTest2.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyForcedPlacementTest3.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyForcedPlacementTest3.pdf index b0dff4aefa..34af172817 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyForcedPlacementTest3.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyForcedPlacementTest3.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyForcedPlacementTest4.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyForcedPlacementTest4.pdf index a7aea359c4..ed87943b7b 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyForcedPlacementTest4.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyForcedPlacementTest4.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyForcedPlacementTest5.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyForcedPlacementTest5.pdf deleted file mode 100644 index e5ea7a724e..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyForcedPlacementTest5.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyForcedPlacementTest6.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyForcedPlacementTest6.pdf deleted file mode 100644 index 3b089a13f6..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyForcedPlacementTest6.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyForcedPlacementTest7.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyForcedPlacementTest7.pdf deleted file mode 100644 index a8fd72a84e..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyForcedPlacementTest7.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyForcedPlacementTest8.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyForcedPlacementTest8.pdf deleted file mode 100644 index 209ade5549..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyForcedPlacementTest8.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyForcedPlacementTest9.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyForcedPlacementTest9.pdf deleted file mode 100644 index a7f0fbf06a..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyForcedPlacementTest9.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyTest1.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyTest1.pdf index 154c47025d..442f93aa95 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyTest1.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyTest1.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyTest2.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyTest2.pdf index ef78717be5..92cd0227ea 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyTest2.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyTest2.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyTest3.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyTest3.pdf index 7db8b6c7f3..c39b787d29 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyTest3.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyTest3.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyTest4.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyTest4.pdf index 08e8da0fa6..30f613f4e4 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyTest4.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyTest4.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyTest5.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyTest5.pdf deleted file mode 100644 index dd6d5e427a..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyTest5.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyTest6.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyTest6.pdf deleted file mode 100644 index 1c30655f71..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyTest6.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyTest7.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyTest7.pdf deleted file mode 100644 index 9505885bf8..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyTest7.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyTest8.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyTest8.pdf deleted file mode 100644 index bf80fc533c..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyTest8.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyTest9.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyTest9.pdf deleted file mode 100644 index 177a383eed..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitHorizontallyTest9.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitVerticallyTest1.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitVerticallyTest1.pdf index 62c0bae35b..71b7f3801c 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitVerticallyTest1.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitVerticallyTest1.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitVerticallyTest2.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitVerticallyTest2.pdf index 2d7a7e5152..29247c254b 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitVerticallyTest2.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitVerticallyTest2.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitVerticallyTest3.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitVerticallyTest3.pdf index f458631c55..054876c91b 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitVerticallyTest3.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitVerticallyTest3.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitVerticallyTest4.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitVerticallyTest4.pdf index 15d4fc5c8f..e1d47f1d66 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitVerticallyTest4.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitVerticallyTest4.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitVerticallyTest5.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitVerticallyTest5.pdf deleted file mode 100644 index 8032fc904e..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitVerticallyTest5.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitVerticallyTest6.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitVerticallyTest6.pdf deleted file mode 100644 index da77d329d9..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitVerticallyTest6.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitVerticallyTest7.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitVerticallyTest7.pdf deleted file mode 100644 index 76ae146ab2..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitVerticallyTest7.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitVerticallyTest8.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitVerticallyTest8.pdf deleted file mode 100644 index 5c642b09bf..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitVerticallyTest8.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitVerticallyTest9.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitVerticallyTest9.pdf deleted file mode 100644 index 61af84aa7d..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenDontFitVerticallyTest9.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenFitContainerDoesNotFitVerticallyTest1.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenFitContainerDoesNotFitVerticallyTest1.pdf index 322ee29ac9..aa9731177c 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenFitContainerDoesNotFitVerticallyTest1.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenFitContainerDoesNotFitVerticallyTest1.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenFitContainerDoesNotFitVerticallyTest2.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenFitContainerDoesNotFitVerticallyTest2.pdf index 20948a680d..c3895484b0 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenFitContainerDoesNotFitVerticallyTest2.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenFitContainerDoesNotFitVerticallyTest2.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenFitContainerDoesNotFitVerticallyTest3.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenFitContainerDoesNotFitVerticallyTest3.pdf index d6d26348ca..f5f7dd41bf 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenFitContainerDoesNotFitVerticallyTest3.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenFitContainerDoesNotFitVerticallyTest3.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenFitContainerDoesNotFitVerticallyTest4.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenFitContainerDoesNotFitVerticallyTest4.pdf index 94efa20c05..adcad83c4a 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenFitContainerDoesNotFitVerticallyTest4.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenFitContainerDoesNotFitVerticallyTest4.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenFitContainerDoesNotFitVerticallyTest5.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenFitContainerDoesNotFitVerticallyTest5.pdf deleted file mode 100644 index f23866d5e8..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenFitContainerDoesNotFitVerticallyTest5.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenFitContainerDoesNotFitVerticallyTest6.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenFitContainerDoesNotFitVerticallyTest6.pdf deleted file mode 100644 index fa90eb85af..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenFitContainerDoesNotFitVerticallyTest6.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenFitContainerDoesNotFitVerticallyTest7.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenFitContainerDoesNotFitVerticallyTest7.pdf deleted file mode 100644 index be9ef012e0..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenFitContainerDoesNotFitVerticallyTest7.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenFitContainerDoesNotFitVerticallyTest8.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenFitContainerDoesNotFitVerticallyTest8.pdf deleted file mode 100644 index bb183b847b..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenFitContainerDoesNotFitVerticallyTest8.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenFitContainerDoesNotFitVerticallyTest9.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenFitContainerDoesNotFitVerticallyTest9.pdf deleted file mode 100644 index 87efd92492..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenFitContainerDoesNotFitVerticallyTest9.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenTest1.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenTest1.pdf index f21bdc937b..9246d4d542 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenTest1.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenTest1.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenTest2.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenTest2.pdf index 69b99d570c..fa02204b6d 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenTest2.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenTest2.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenTest3.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenTest3.pdf index a77e5773c6..ab5d595127 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenTest3.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenTest3.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenTest4.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenTest4.pdf index ba6e76a1d9..4e990260e5 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenTest4.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenTest4.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenTest5.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenTest5.pdf deleted file mode 100644 index 26abd0651c..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenTest5.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenTest6.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenTest6.pdf deleted file mode 100644 index 412c4773ae..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenTest6.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenTest7.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenTest7.pdf deleted file mode 100644 index e19fa79345..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenTest7.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenTest8.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenTest8.pdf deleted file mode 100644 index 9b986193a7..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenTest8.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenTest9.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenTest9.pdf deleted file mode 100644 index 054e1e2c0e..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenTest9.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexBasisTest1.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexBasisTest1.pdf index ed42acd013..cdab23c984 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexBasisTest1.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexBasisTest1.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexBasisTest2.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexBasisTest2.pdf index f0a5aa2940..769ccfaddf 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexBasisTest2.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexBasisTest2.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexBasisTest3.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexBasisTest3.pdf index 8148f2777b..8da940fb87 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexBasisTest3.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexBasisTest3.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexBasisTest4.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexBasisTest4.pdf index 170e570e8b..2bc993a7f4 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexBasisTest4.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexBasisTest4.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexBasisTest5.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexBasisTest5.pdf deleted file mode 100644 index 2260f7214a..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexBasisTest5.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexBasisTest6.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexBasisTest6.pdf deleted file mode 100644 index 0ad6686884..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexBasisTest6.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexBasisTest7.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexBasisTest7.pdf deleted file mode 100644 index f95d0bf0d7..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexBasisTest7.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexBasisTest8.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexBasisTest8.pdf deleted file mode 100644 index 10330e7759..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexBasisTest8.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexBasisTest9.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexBasisTest9.pdf deleted file mode 100644 index f6b7ca5553..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexBasisTest9.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexShrinkTest1.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexShrinkTest1.pdf index 9d54558ab0..465e26726b 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexShrinkTest1.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexShrinkTest1.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexShrinkTest2.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexShrinkTest2.pdf index eadf0ab4fd..71319b2856 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexShrinkTest2.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexShrinkTest2.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexShrinkTest3.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexShrinkTest3.pdf index 66617212e1..1bd11f9750 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexShrinkTest3.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexShrinkTest3.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexShrinkTest4.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexShrinkTest4.pdf index 08a4093f74..9ed462637f 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexShrinkTest4.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexShrinkTest4.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexShrinkTest5.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexShrinkTest5.pdf deleted file mode 100644 index 20c481319c..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexShrinkTest5.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexShrinkTest6.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexShrinkTest6.pdf deleted file mode 100644 index a8bba1953a..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexShrinkTest6.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexShrinkTest7.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexShrinkTest7.pdf deleted file mode 100644 index 91b83927c8..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexShrinkTest7.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexShrinkTest8.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexShrinkTest8.pdf deleted file mode 100644 index 19a2429adb..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexShrinkTest8.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexShrinkTest9.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexShrinkTest9.pdf deleted file mode 100644 index 41bcc7b3fa..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithFlexShrinkTest9.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithGrowTest1.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithGrowTest1.pdf index 7ff8aab92d..bbad35002d 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithGrowTest1.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithGrowTest1.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithGrowTest2.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithGrowTest2.pdf index 13a6121a84..8b605caef8 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithGrowTest2.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithGrowTest2.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithGrowTest3.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithGrowTest3.pdf index 6fbba61bcf..c1acf33f57 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithGrowTest3.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithGrowTest3.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithGrowTest4.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithGrowTest4.pdf index d4285c8c13..924e6dbd8d 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithGrowTest4.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithGrowTest4.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithGrowTest5.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithGrowTest5.pdf deleted file mode 100644 index e7a8df0da0..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithGrowTest5.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithGrowTest6.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithGrowTest6.pdf deleted file mode 100644 index 16cdd394a7..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithGrowTest6.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithGrowTest7.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithGrowTest7.pdf deleted file mode 100644 index 1aa9cad5b5..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithGrowTest7.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithGrowTest8.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithGrowTest8.pdf deleted file mode 100644 index d090c2669b..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithGrowTest8.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithGrowTest9.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithGrowTest9.pdf deleted file mode 100644 index b32fc1e02a..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerDifferentChildrenWithGrowTest9.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFillAvailableAreaTest1.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFillAvailableAreaTest1.pdf index 27bb8741f7..91d15efd48 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFillAvailableAreaTest1.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFillAvailableAreaTest1.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFillAvailableAreaTest2.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFillAvailableAreaTest2.pdf index d468ce659f..c795158290 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFillAvailableAreaTest2.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFillAvailableAreaTest2.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFillAvailableAreaTest3.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFillAvailableAreaTest3.pdf index 9ab5f1fbc1..cf476b2cbb 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFillAvailableAreaTest3.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFillAvailableAreaTest3.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFillAvailableAreaTest4.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFillAvailableAreaTest4.pdf index f33ec599ce..a17093196c 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFillAvailableAreaTest4.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFillAvailableAreaTest4.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFillAvailableAreaTest5.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFillAvailableAreaTest5.pdf deleted file mode 100644 index 8147923637..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFillAvailableAreaTest5.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFillAvailableAreaTest6.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFillAvailableAreaTest6.pdf deleted file mode 100644 index 00f4688f15..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFillAvailableAreaTest6.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFillAvailableAreaTest7.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFillAvailableAreaTest7.pdf deleted file mode 100644 index 598d75f493..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFillAvailableAreaTest7.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFillAvailableAreaTest8.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFillAvailableAreaTest8.pdf deleted file mode 100644 index 1a78370149..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFillAvailableAreaTest8.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFillAvailableAreaTest9.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFillAvailableAreaTest9.pdf deleted file mode 100644 index 14ec56c198..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFillAvailableAreaTest9.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFixedHeightWidthTest1.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFixedHeightWidthTest1.pdf index 4043672ebd..c0b8a37520 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFixedHeightWidthTest1.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFixedHeightWidthTest1.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFixedHeightWidthTest2.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFixedHeightWidthTest2.pdf index 3a64a0ec8a..47aa472d5e 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFixedHeightWidthTest2.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFixedHeightWidthTest2.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFixedHeightWidthTest3.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFixedHeightWidthTest3.pdf index 49fa8ddaad..01bb840bd3 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFixedHeightWidthTest3.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFixedHeightWidthTest3.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFixedHeightWidthTest4.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFixedHeightWidthTest4.pdf index 9f94d10224..61febe4638 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFixedHeightWidthTest4.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFixedHeightWidthTest4.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFixedHeightWidthTest5.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFixedHeightWidthTest5.pdf deleted file mode 100644 index 13fc162f6a..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFixedHeightWidthTest5.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFixedHeightWidthTest6.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFixedHeightWidthTest6.pdf deleted file mode 100644 index 2ba0da7565..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFixedHeightWidthTest6.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFixedHeightWidthTest7.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFixedHeightWidthTest7.pdf deleted file mode 100644 index 181fd80e81..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFixedHeightWidthTest7.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFixedHeightWidthTest8.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFixedHeightWidthTest8.pdf deleted file mode 100644 index 988023e5ff..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFixedHeightWidthTest8.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFixedHeightWidthTest9.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFixedHeightWidthTest9.pdf deleted file mode 100644 index 5bccc5328c..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerFixedHeightWidthTest9.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerHeightClippedTest1.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerHeightClippedTest1.pdf index 90c26a408c..aed7d967f2 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerHeightClippedTest1.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerHeightClippedTest1.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerHeightClippedTest2.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerHeightClippedTest2.pdf index 44f76bb86e..2358c5dd1b 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerHeightClippedTest2.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerHeightClippedTest2.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerHeightClippedTest3.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerHeightClippedTest3.pdf index 8e93cd52be..ae07dea7d0 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerHeightClippedTest3.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerHeightClippedTest3.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerHeightClippedTest4.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerHeightClippedTest4.pdf index b4e5f7a16a..84cd397ff0 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerHeightClippedTest4.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerHeightClippedTest4.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerHeightClippedTest5.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerHeightClippedTest5.pdf deleted file mode 100644 index 22cb2c8554..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerHeightClippedTest5.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerHeightClippedTest6.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerHeightClippedTest6.pdf deleted file mode 100644 index 68eaa37e7e..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerHeightClippedTest6.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerHeightClippedTest7.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerHeightClippedTest7.pdf deleted file mode 100644 index 1e660ccde3..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerHeightClippedTest7.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerHeightClippedTest8.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerHeightClippedTest8.pdf deleted file mode 100644 index 8adae0e32a..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerHeightClippedTest8.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerHeightClippedTest9.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerHeightClippedTest9.pdf deleted file mode 100644 index 382d2f2bde..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerHeightClippedTest9.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerTest1.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerTest1.pdf index 5e9fb95dcd..dc16eba6ca 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerTest1.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerTest1.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerTest2.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerTest2.pdf index 84f00f19f7..4df9a2171c 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerTest2.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerTest2.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerTest3.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerTest3.pdf index df3a97982d..8237904f41 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerTest3.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerTest3.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerTest4.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerTest4.pdf index 63350206ae..eedb851a9a 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerTest4.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerTest4.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerTest5.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerTest5.pdf deleted file mode 100644 index 6ce3990f65..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerTest5.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerTest6.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerTest6.pdf deleted file mode 100644 index 4583b38e05..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerTest6.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerTest7.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerTest7.pdf deleted file mode 100644 index 36b0e976dd..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerTest7.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerTest8.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerTest8.pdf deleted file mode 100644 index dae73a4a49..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerTest8.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerTest9.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerTest9.pdf deleted file mode 100644 index 5e9459d6e4..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerTest9.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerWithHugeBordersTest1.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerWithHugeBordersTest1.pdf index 79455d0399..8a9ea5990e 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerWithHugeBordersTest1.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerWithHugeBordersTest1.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerWithHugeBordersTest2.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerWithHugeBordersTest2.pdf index 2d336a22a5..f773beee83 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerWithHugeBordersTest2.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerWithHugeBordersTest2.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerWithHugeBordersTest3.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerWithHugeBordersTest3.pdf index 27e6261aa1..f50888f60d 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerWithHugeBordersTest3.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerWithHugeBordersTest3.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerWithHugeBordersTest4.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerWithHugeBordersTest4.pdf index b2dfedf642..650bf72000 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerWithHugeBordersTest4.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerWithHugeBordersTest4.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerWithHugeBordersTest5.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerWithHugeBordersTest5.pdf deleted file mode 100644 index 34b7c386be..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerWithHugeBordersTest5.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerWithHugeBordersTest6.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerWithHugeBordersTest6.pdf deleted file mode 100644 index a342d44d68..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerWithHugeBordersTest6.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerWithHugeBordersTest7.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerWithHugeBordersTest7.pdf deleted file mode 100644 index e5dce80c80..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerWithHugeBordersTest7.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerWithHugeBordersTest8.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerWithHugeBordersTest8.pdf deleted file mode 100644 index a1d860ecc1..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerWithHugeBordersTest8.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerWithHugeBordersTest9.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerWithHugeBordersTest9.pdf deleted file mode 100644 index b1428595f1..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerInsideFlexContainerWithHugeBordersTest9.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerRotationAngleTest1.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerRotationAngleTest1.pdf index 2ca3da420d..d3c39d840e 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerRotationAngleTest1.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerRotationAngleTest1.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerRotationAngleTest2.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerRotationAngleTest2.pdf index c4570e4866..7ab236ba29 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerRotationAngleTest2.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerRotationAngleTest2.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerRotationAngleTest3.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerRotationAngleTest3.pdf index f9ff30ba3f..f2d4c5a8fc 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerRotationAngleTest3.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerRotationAngleTest3.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerRotationAngleTest4.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerRotationAngleTest4.pdf index d6f8fb242b..f206ec8d9b 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerRotationAngleTest4.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerRotationAngleTest4.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerRotationAngleTest5.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerRotationAngleTest5.pdf deleted file mode 100644 index 997cf68f44..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerRotationAngleTest5.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerRotationAngleTest6.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerRotationAngleTest6.pdf deleted file mode 100644 index 6fe8b56019..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerRotationAngleTest6.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerRotationAngleTest7.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerRotationAngleTest7.pdf deleted file mode 100644 index f54e60a559..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerRotationAngleTest7.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerRotationAngleTest8.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerRotationAngleTest8.pdf deleted file mode 100644 index d4bb082fc7..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerRotationAngleTest8.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerRotationAngleTest9.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerRotationAngleTest9.pdf deleted file mode 100644 index 4bb1e8baa2..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexContainerRotationAngleTest9.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemBoxSizingTest1.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemBoxSizingTest1.pdf index e26a76bf0c..a21e58053b 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemBoxSizingTest1.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemBoxSizingTest1.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemBoxSizingTest2.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemBoxSizingTest2.pdf index 61a25fdae6..0a0b96c775 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemBoxSizingTest2.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemBoxSizingTest2.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemBoxSizingTest3.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemBoxSizingTest3.pdf index f56eafe7e8..27fd7ed77e 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemBoxSizingTest3.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemBoxSizingTest3.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemBoxSizingTest4.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemBoxSizingTest4.pdf index 0d17d9a19d..ee234d542a 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemBoxSizingTest4.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemBoxSizingTest4.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemBoxSizingTest5.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemBoxSizingTest5.pdf deleted file mode 100644 index 4ab97acbc5..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemBoxSizingTest5.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemBoxSizingTest6.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemBoxSizingTest6.pdf deleted file mode 100644 index fa9fc72e18..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemBoxSizingTest6.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemBoxSizingTest7.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemBoxSizingTest7.pdf deleted file mode 100644 index 9ec365ffcf..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemBoxSizingTest7.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemBoxSizingTest8.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemBoxSizingTest8.pdf deleted file mode 100644 index 5bdd28f259..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemBoxSizingTest8.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemBoxSizingTest9.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemBoxSizingTest9.pdf deleted file mode 100644 index 15ef6251d5..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemBoxSizingTest9.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemsMinHeightShouldBeOverriddenTest1.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemsMinHeightShouldBeOverriddenTest1.pdf index 5e793d8e31..657e45fd28 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemsMinHeightShouldBeOverriddenTest1.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemsMinHeightShouldBeOverriddenTest1.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemsMinHeightShouldBeOverriddenTest2.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemsMinHeightShouldBeOverriddenTest2.pdf index 4a58b78295..3672ff89ef 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemsMinHeightShouldBeOverriddenTest2.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemsMinHeightShouldBeOverriddenTest2.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemsMinHeightShouldBeOverriddenTest3.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemsMinHeightShouldBeOverriddenTest3.pdf index abbb62bf6e..92b8993d79 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemsMinHeightShouldBeOverriddenTest3.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemsMinHeightShouldBeOverriddenTest3.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemsMinHeightShouldBeOverriddenTest4.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemsMinHeightShouldBeOverriddenTest4.pdf index 8e85a31d3d..a4dc6e1efa 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemsMinHeightShouldBeOverriddenTest4.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemsMinHeightShouldBeOverriddenTest4.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemsMinHeightShouldBeOverriddenTest5.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemsMinHeightShouldBeOverriddenTest5.pdf deleted file mode 100644 index d6b9be5807..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemsMinHeightShouldBeOverriddenTest5.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemsMinHeightShouldBeOverriddenTest6.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemsMinHeightShouldBeOverriddenTest6.pdf deleted file mode 100644 index e5177e36cc..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemsMinHeightShouldBeOverriddenTest6.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemsMinHeightShouldBeOverriddenTest7.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemsMinHeightShouldBeOverriddenTest7.pdf deleted file mode 100644 index 6f6c4f96c9..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemsMinHeightShouldBeOverriddenTest7.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemsMinHeightShouldBeOverriddenTest8.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemsMinHeightShouldBeOverriddenTest8.pdf deleted file mode 100644 index 5256ba026a..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemsMinHeightShouldBeOverriddenTest8.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemsMinHeightShouldBeOverriddenTest9.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemsMinHeightShouldBeOverriddenTest9.pdf deleted file mode 100644 index fdaf6d428c..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_flexItemsMinHeightShouldBeOverriddenTest9.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMaxHeightShouldBeRespectedTest1.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMaxHeightShouldBeRespectedTest1.pdf index 21143afec6..e746f3f983 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMaxHeightShouldBeRespectedTest1.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMaxHeightShouldBeRespectedTest1.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMaxHeightShouldBeRespectedTest2.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMaxHeightShouldBeRespectedTest2.pdf index 8fe4f2e704..2f751dd59d 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMaxHeightShouldBeRespectedTest2.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMaxHeightShouldBeRespectedTest2.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMaxHeightShouldBeRespectedTest3.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMaxHeightShouldBeRespectedTest3.pdf index 8777dd878b..cb97a4051c 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMaxHeightShouldBeRespectedTest3.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMaxHeightShouldBeRespectedTest3.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMaxHeightShouldBeRespectedTest4.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMaxHeightShouldBeRespectedTest4.pdf index f455929d75..d1620fdc1d 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMaxHeightShouldBeRespectedTest4.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMaxHeightShouldBeRespectedTest4.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMaxHeightShouldBeRespectedTest5.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMaxHeightShouldBeRespectedTest5.pdf deleted file mode 100644 index 5d6b3ea073..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMaxHeightShouldBeRespectedTest5.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMaxHeightShouldBeRespectedTest6.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMaxHeightShouldBeRespectedTest6.pdf deleted file mode 100644 index 54112ec91f..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMaxHeightShouldBeRespectedTest6.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMaxHeightShouldBeRespectedTest7.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMaxHeightShouldBeRespectedTest7.pdf deleted file mode 100644 index 87fbdd2a36..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMaxHeightShouldBeRespectedTest7.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMaxHeightShouldBeRespectedTest8.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMaxHeightShouldBeRespectedTest8.pdf deleted file mode 100644 index 045467316d..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMaxHeightShouldBeRespectedTest8.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMaxHeightShouldBeRespectedTest9.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMaxHeightShouldBeRespectedTest9.pdf deleted file mode 100644 index b0cee911ee..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMaxHeightShouldBeRespectedTest9.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMinHeightShouldBeRespectedTest1.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMinHeightShouldBeRespectedTest1.pdf index dc1642f9e9..e2c58b897c 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMinHeightShouldBeRespectedTest1.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMinHeightShouldBeRespectedTest1.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMinHeightShouldBeRespectedTest2.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMinHeightShouldBeRespectedTest2.pdf index 2e7331bc26..31d1105356 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMinHeightShouldBeRespectedTest2.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMinHeightShouldBeRespectedTest2.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMinHeightShouldBeRespectedTest3.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMinHeightShouldBeRespectedTest3.pdf index f7f7008daf..86b4015424 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMinHeightShouldBeRespectedTest3.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMinHeightShouldBeRespectedTest3.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMinHeightShouldBeRespectedTest4.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMinHeightShouldBeRespectedTest4.pdf index 6c8447d93b..c729c99196 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMinHeightShouldBeRespectedTest4.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMinHeightShouldBeRespectedTest4.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMinHeightShouldBeRespectedTest5.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMinHeightShouldBeRespectedTest5.pdf deleted file mode 100644 index f03ece2b08..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMinHeightShouldBeRespectedTest5.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMinHeightShouldBeRespectedTest6.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMinHeightShouldBeRespectedTest6.pdf deleted file mode 100644 index f635dcce46..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMinHeightShouldBeRespectedTest6.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMinHeightShouldBeRespectedTest7.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMinHeightShouldBeRespectedTest7.pdf deleted file mode 100644 index 6421e8ef61..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMinHeightShouldBeRespectedTest7.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMinHeightShouldBeRespectedTest8.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMinHeightShouldBeRespectedTest8.pdf deleted file mode 100644 index dfe69d1076..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMinHeightShouldBeRespectedTest8.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMinHeightShouldBeRespectedTest9.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMinHeightShouldBeRespectedTest9.pdf deleted file mode 100644 index d8d77daa35..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_linesMinHeightShouldBeRespectedTest9.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersInsideFlexContainerTest1.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersInsideFlexContainerTest1.pdf index c56b675c90..d58bf11ac9 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersInsideFlexContainerTest1.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersInsideFlexContainerTest1.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersInsideFlexContainerTest2.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersInsideFlexContainerTest2.pdf index 4e15d071b9..c713a29d1f 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersInsideFlexContainerTest2.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersInsideFlexContainerTest2.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersInsideFlexContainerTest3.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersInsideFlexContainerTest3.pdf index 980408dc07..4ce7cdd106 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersInsideFlexContainerTest3.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersInsideFlexContainerTest3.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersInsideFlexContainerTest4.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersInsideFlexContainerTest4.pdf index 40acbe22b0..5b442717ef 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersInsideFlexContainerTest4.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersInsideFlexContainerTest4.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersInsideFlexContainerTest5.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersInsideFlexContainerTest5.pdf deleted file mode 100644 index 244c28a9bf..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersInsideFlexContainerTest5.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersInsideFlexContainerTest6.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersInsideFlexContainerTest6.pdf deleted file mode 100644 index ca51209255..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersInsideFlexContainerTest6.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersInsideFlexContainerTest7.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersInsideFlexContainerTest7.pdf deleted file mode 100644 index 676a138b02..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersInsideFlexContainerTest7.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersInsideFlexContainerTest8.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersInsideFlexContainerTest8.pdf deleted file mode 100644 index 54c0f80b37..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersInsideFlexContainerTest8.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersInsideFlexContainerTest9.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersInsideFlexContainerTest9.pdf deleted file mode 100644 index e39d44417d..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersInsideFlexContainerTest9.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMaxWidthsInsideFlexContainerTest1.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMaxWidthsInsideFlexContainerTest1.pdf index 3eb2ab4cf6..c7801077ee 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMaxWidthsInsideFlexContainerTest1.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMaxWidthsInsideFlexContainerTest1.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMaxWidthsInsideFlexContainerTest2.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMaxWidthsInsideFlexContainerTest2.pdf index c3359f594f..bbc6ebdf05 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMaxWidthsInsideFlexContainerTest2.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMaxWidthsInsideFlexContainerTest2.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMaxWidthsInsideFlexContainerTest3.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMaxWidthsInsideFlexContainerTest3.pdf index 0a5a91b6d2..c738a05443 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMaxWidthsInsideFlexContainerTest3.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMaxWidthsInsideFlexContainerTest3.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMaxWidthsInsideFlexContainerTest4.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMaxWidthsInsideFlexContainerTest4.pdf index 7c5a7916d1..f82e846716 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMaxWidthsInsideFlexContainerTest4.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMaxWidthsInsideFlexContainerTest4.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMaxWidthsInsideFlexContainerTest5.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMaxWidthsInsideFlexContainerTest5.pdf deleted file mode 100644 index bab8ad4c74..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMaxWidthsInsideFlexContainerTest5.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMaxWidthsInsideFlexContainerTest6.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMaxWidthsInsideFlexContainerTest6.pdf deleted file mode 100644 index fb2c0820a9..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMaxWidthsInsideFlexContainerTest6.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMaxWidthsInsideFlexContainerTest7.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMaxWidthsInsideFlexContainerTest7.pdf deleted file mode 100644 index 65583e9a38..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMaxWidthsInsideFlexContainerTest7.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMaxWidthsInsideFlexContainerTest8.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMaxWidthsInsideFlexContainerTest8.pdf deleted file mode 100644 index 915583cad9..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMaxWidthsInsideFlexContainerTest8.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMaxWidthsInsideFlexContainerTest9.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMaxWidthsInsideFlexContainerTest9.pdf deleted file mode 100644 index 1a8e188304..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMaxWidthsInsideFlexContainerTest9.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMinWidthsInsideFlexContainerTest1.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMinWidthsInsideFlexContainerTest1.pdf index 6fd02f2f85..3c10a48b40 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMinWidthsInsideFlexContainerTest1.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMinWidthsInsideFlexContainerTest1.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMinWidthsInsideFlexContainerTest2.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMinWidthsInsideFlexContainerTest2.pdf index 94c8f92d7e..8288621259 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMinWidthsInsideFlexContainerTest2.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMinWidthsInsideFlexContainerTest2.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMinWidthsInsideFlexContainerTest3.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMinWidthsInsideFlexContainerTest3.pdf index a232db1fc1..da0bb83115 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMinWidthsInsideFlexContainerTest3.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMinWidthsInsideFlexContainerTest3.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMinWidthsInsideFlexContainerTest4.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMinWidthsInsideFlexContainerTest4.pdf index 084666c37f..9e9f46cc9d 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMinWidthsInsideFlexContainerTest4.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMinWidthsInsideFlexContainerTest4.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMinWidthsInsideFlexContainerTest5.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMinWidthsInsideFlexContainerTest5.pdf deleted file mode 100644 index 6ac81b71b8..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMinWidthsInsideFlexContainerTest5.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMinWidthsInsideFlexContainerTest6.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMinWidthsInsideFlexContainerTest6.pdf deleted file mode 100644 index 2022a422d4..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMinWidthsInsideFlexContainerTest6.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMinWidthsInsideFlexContainerTest7.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMinWidthsInsideFlexContainerTest7.pdf deleted file mode 100644 index 134db33e61..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMinWidthsInsideFlexContainerTest7.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMinWidthsInsideFlexContainerTest8.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMinWidthsInsideFlexContainerTest8.pdf deleted file mode 100644 index 123c5d9bf0..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMinWidthsInsideFlexContainerTest8.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMinWidthsInsideFlexContainerTest9.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMinWidthsInsideFlexContainerTest9.pdf deleted file mode 100644 index 571acfdd85..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedMinWidthsInsideFlexContainerTest9.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPercentWidthsInsideFlexContainerTest1.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPercentWidthsInsideFlexContainerTest1.pdf index f35ccd247d..c7d12f65ed 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPercentWidthsInsideFlexContainerTest1.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPercentWidthsInsideFlexContainerTest1.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPercentWidthsInsideFlexContainerTest2.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPercentWidthsInsideFlexContainerTest2.pdf index 914ea51138..aec9c215d7 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPercentWidthsInsideFlexContainerTest2.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPercentWidthsInsideFlexContainerTest2.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPercentWidthsInsideFlexContainerTest3.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPercentWidthsInsideFlexContainerTest3.pdf index a97412850d..07e5f2a224 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPercentWidthsInsideFlexContainerTest3.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPercentWidthsInsideFlexContainerTest3.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPercentWidthsInsideFlexContainerTest4.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPercentWidthsInsideFlexContainerTest4.pdf index f9245a5c32..56ea250adc 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPercentWidthsInsideFlexContainerTest4.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPercentWidthsInsideFlexContainerTest4.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPercentWidthsInsideFlexContainerTest5.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPercentWidthsInsideFlexContainerTest5.pdf deleted file mode 100644 index 82e0b494e5..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPercentWidthsInsideFlexContainerTest5.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPercentWidthsInsideFlexContainerTest6.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPercentWidthsInsideFlexContainerTest6.pdf deleted file mode 100644 index f7df3f23a5..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPercentWidthsInsideFlexContainerTest6.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPercentWidthsInsideFlexContainerTest7.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPercentWidthsInsideFlexContainerTest7.pdf deleted file mode 100644 index 77119f5fa4..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPercentWidthsInsideFlexContainerTest7.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPercentWidthsInsideFlexContainerTest8.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPercentWidthsInsideFlexContainerTest8.pdf deleted file mode 100644 index a73ce4f54d..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPercentWidthsInsideFlexContainerTest8.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPercentWidthsInsideFlexContainerTest9.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPercentWidthsInsideFlexContainerTest9.pdf deleted file mode 100644 index 359549d4cd..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPercentWidthsInsideFlexContainerTest9.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPointWidthsInsideFlexContainerTest1.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPointWidthsInsideFlexContainerTest1.pdf index 33bf1ee625..0eb3323919 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPointWidthsInsideFlexContainerTest1.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPointWidthsInsideFlexContainerTest1.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPointWidthsInsideFlexContainerTest2.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPointWidthsInsideFlexContainerTest2.pdf index 42bf311994..5a921c5f9d 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPointWidthsInsideFlexContainerTest2.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPointWidthsInsideFlexContainerTest2.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPointWidthsInsideFlexContainerTest3.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPointWidthsInsideFlexContainerTest3.pdf index 2a8051b401..a70e0090ba 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPointWidthsInsideFlexContainerTest3.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPointWidthsInsideFlexContainerTest3.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPointWidthsInsideFlexContainerTest4.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPointWidthsInsideFlexContainerTest4.pdf index 7bced3a3c1..142aaf1a56 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPointWidthsInsideFlexContainerTest4.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPointWidthsInsideFlexContainerTest4.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPointWidthsInsideFlexContainerTest5.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPointWidthsInsideFlexContainerTest5.pdf deleted file mode 100644 index ac5d402e69..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPointWidthsInsideFlexContainerTest5.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPointWidthsInsideFlexContainerTest6.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPointWidthsInsideFlexContainerTest6.pdf deleted file mode 100644 index 9fe99b3a15..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPointWidthsInsideFlexContainerTest6.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPointWidthsInsideFlexContainerTest7.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPointWidthsInsideFlexContainerTest7.pdf deleted file mode 100644 index cf970fb3e1..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPointWidthsInsideFlexContainerTest7.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPointWidthsInsideFlexContainerTest8.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPointWidthsInsideFlexContainerTest8.pdf deleted file mode 100644 index 43357a348d..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPointWidthsInsideFlexContainerTest8.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPointWidthsInsideFlexContainerTest9.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPointWidthsInsideFlexContainerTest9.pdf deleted file mode 100644 index b6b57f6e80..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_multipleFlexContainersWithPredefinedPointWidthsInsideFlexContainerTest9.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersHeightTest1.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersHeightTest1.pdf index b39e41b6e3..f7da24270b 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersHeightTest1.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersHeightTest1.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersHeightTest2.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersHeightTest2.pdf index 762fa31150..3512776676 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersHeightTest2.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersHeightTest2.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersHeightTest3.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersHeightTest3.pdf index 01f996be87..2c95140653 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersHeightTest3.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersHeightTest3.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersHeightTest4.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersHeightTest4.pdf index 6c2fc86176..53a592f662 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersHeightTest4.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersHeightTest4.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersHeightTest5.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersHeightTest5.pdf deleted file mode 100644 index 5acf4ea693..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersHeightTest5.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersHeightTest6.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersHeightTest6.pdf deleted file mode 100644 index 9112873fa0..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersHeightTest6.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersHeightTest7.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersHeightTest7.pdf deleted file mode 100644 index 3ab9cab7c8..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersHeightTest7.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersHeightTest8.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersHeightTest8.pdf deleted file mode 100644 index 80d03694f7..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersHeightTest8.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersHeightTest9.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersHeightTest9.pdf deleted file mode 100644 index 8f4138e434..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersHeightTest9.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersWidthTest1.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersWidthTest1.pdf index 2fbb669f5f..59d2ae130d 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersWidthTest1.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersWidthTest1.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersWidthTest2.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersWidthTest2.pdf index 6cbeff77c8..0298db958d 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersWidthTest2.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersWidthTest2.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersWidthTest3.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersWidthTest3.pdf index 236e57e3a3..0ee44c8f66 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersWidthTest3.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersWidthTest3.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersWidthTest4.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersWidthTest4.pdf index c9351d8c33..48587d547a 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersWidthTest4.pdf and b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersWidthTest4.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersWidthTest5.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersWidthTest5.pdf deleted file mode 100644 index c7afb0edbd..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersWidthTest5.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersWidthTest6.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersWidthTest6.pdf deleted file mode 100644 index 869e7b8d96..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersWidthTest6.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersWidthTest7.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersWidthTest7.pdf deleted file mode 100644 index 737a6bfadd..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersWidthTest7.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersWidthTest8.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersWidthTest8.pdf deleted file mode 100644 index b7b8a97908..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersWidthTest8.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersWidthTest9.pdf b/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersWidthTest9.pdf deleted file mode 100644 index ad404ac375..0000000000 Binary files a/layout/src/test/resources/com/itextpdf/layout/FlexContainerTest/cmp_respectFlexContainersWidthTest9.pdf and /dev/null differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FontProviderTest/cmp_taggedDocumentWithType3Font.pdf b/layout/src/test/resources/com/itextpdf/layout/FontProviderTest/cmp_taggedDocumentWithType3Font.pdf index a72f1a220a..7ce4e06421 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FontProviderTest/cmp_taggedDocumentWithType3Font.pdf and b/layout/src/test/resources/com/itextpdf/layout/FontProviderTest/cmp_taggedDocumentWithType3Font.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FontSelectorTest/cmp_openSansFontWeightBoldRendering.pdf b/layout/src/test/resources/com/itextpdf/layout/FontSelectorTest/cmp_openSansFontWeightBoldRendering.pdf index e946f000a9..ffbef8bffe 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FontSelectorTest/cmp_openSansFontWeightBoldRendering.pdf and b/layout/src/test/resources/com/itextpdf/layout/FontSelectorTest/cmp_openSansFontWeightBoldRendering.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/FontSelectorTest/cmp_openSansFontWeightNotBoldRendering.pdf b/layout/src/test/resources/com/itextpdf/layout/FontSelectorTest/cmp_openSansFontWeightNotBoldRendering.pdf index 7bb8949c15..74def15c5a 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/FontSelectorTest/cmp_openSansFontWeightNotBoldRendering.pdf and b/layout/src/test/resources/com/itextpdf/layout/FontSelectorTest/cmp_openSansFontWeightNotBoldRendering.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/ImageTest/cmp_imageBorderRadiusTest01.pdf b/layout/src/test/resources/com/itextpdf/layout/ImageTest/cmp_imageBorderRadiusTest01.pdf index 835ed5aa73..edced4691c 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/ImageTest/cmp_imageBorderRadiusTest01.pdf and b/layout/src/test/resources/com/itextpdf/layout/ImageTest/cmp_imageBorderRadiusTest01.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/ObjectFitTest/cmp_objectFit_test_with_effects.pdf b/layout/src/test/resources/com/itextpdf/layout/ObjectFitTest/cmp_objectFit_test_with_effects.pdf index 94405f2246..bb0f8c6d6e 100644 Binary files a/layout/src/test/resources/com/itextpdf/layout/ObjectFitTest/cmp_objectFit_test_with_effects.pdf and b/layout/src/test/resources/com/itextpdf/layout/ObjectFitTest/cmp_objectFit_test_with_effects.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/TableTest/cmp_bigRowSpanTooFarFullTest.pdf b/layout/src/test/resources/com/itextpdf/layout/TableTest/cmp_bigRowSpanTooFarFullTest.pdf new file mode 100644 index 0000000000..f54e8ecce5 Binary files /dev/null and b/layout/src/test/resources/com/itextpdf/layout/TableTest/cmp_bigRowSpanTooFarFullTest.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/TableTest/cmp_bigRowSpanTooFarNothingTest.pdf b/layout/src/test/resources/com/itextpdf/layout/TableTest/cmp_bigRowSpanTooFarNothingTest.pdf new file mode 100644 index 0000000000..36ad213afa Binary files /dev/null and b/layout/src/test/resources/com/itextpdf/layout/TableTest/cmp_bigRowSpanTooFarNothingTest.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/TableTest/cmp_bigRowSpanTooFarPartialTest.pdf b/layout/src/test/resources/com/itextpdf/layout/TableTest/cmp_bigRowSpanTooFarPartialTest.pdf new file mode 100644 index 0000000000..f3f689b39b Binary files /dev/null and b/layout/src/test/resources/com/itextpdf/layout/TableTest/cmp_bigRowSpanTooFarPartialTest.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/TextRendererIntegrationTest/cmp_customTextRendererShouldOverrideCreateCopyTest.pdf b/layout/src/test/resources/com/itextpdf/layout/TextRendererIntegrationTest/cmp_customTextRendererShouldOverrideCreateCopyTest.pdf new file mode 100644 index 0000000000..b85729e734 Binary files /dev/null and b/layout/src/test/resources/com/itextpdf/layout/TextRendererIntegrationTest/cmp_customTextRendererShouldOverrideCreateCopyTest.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/TextRendererIntegrationTest/cmp_customTextRendererShouldOverrideGetNextRendererTest.pdf b/layout/src/test/resources/com/itextpdf/layout/TextRendererIntegrationTest/cmp_customTextRendererShouldOverrideGetNextRendererTest.pdf new file mode 100644 index 0000000000..a51414e038 Binary files /dev/null and b/layout/src/test/resources/com/itextpdf/layout/TextRendererIntegrationTest/cmp_customTextRendererShouldOverrideGetNextRendererTest.pdf differ diff --git a/layout/src/test/resources/com/itextpdf/layout/renderer/TargetCounterHandlerTest/cmp_targetCounterHandlerEndToEndLayoutTest.pdf b/layout/src/test/resources/com/itextpdf/layout/renderer/TargetCounterHandlerTest/cmp_targetCounterHandlerEndToEndLayoutTest.pdf new file mode 100644 index 0000000000..c183d6b64d Binary files /dev/null and b/layout/src/test/resources/com/itextpdf/layout/renderer/TargetCounterHandlerTest/cmp_targetCounterHandlerEndToEndLayoutTest.pdf differ diff --git a/pdfa/pom.xml b/pdfa/pom.xml index 3be45da5d5..595ce41fcb 100644 --- a/pdfa/pom.xml +++ b/pdfa/pom.xml @@ -4,7 +4,7 @@ com.itextpdf root - 7.1.15 + 7.1.16 pdfa iText 7 - pdfa diff --git a/pdfa/src/main/java/com/itextpdf/pdfa/PdfADocument.java b/pdfa/src/main/java/com/itextpdf/pdfa/PdfADocument.java index e98a94075f..b9934d6062 100644 --- a/pdfa/src/main/java/com/itextpdf/pdfa/PdfADocument.java +++ b/pdfa/src/main/java/com/itextpdf/pdfa/PdfADocument.java @@ -153,17 +153,7 @@ public PdfADocument(PdfReader reader, PdfWriter writer) { public PdfADocument(PdfReader reader, PdfWriter writer, StampingProperties properties) { super(reader, writer, properties); - byte[] existingXmpMetadata = getXmpMetadata(); - if (existingXmpMetadata == null) { - throw new PdfAConformanceException(PdfAConformanceException.DOCUMENT_TO_READ_FROM_SHALL_BE_A_PDFA_CONFORMANT_FILE_WITH_VALID_XMP_METADATA); - } - XMPMeta meta; - try { - meta = XMPMetaFactory.parseFromBuffer(existingXmpMetadata); - } catch (XMPException exc) { - throw new PdfAConformanceException(PdfAConformanceException.DOCUMENT_TO_READ_FROM_SHALL_BE_A_PDFA_CONFORMANT_FILE_WITH_VALID_XMP_METADATA); - } - PdfAConformanceLevel conformanceLevel = PdfAConformanceLevel.getConformanceLevel(meta); + PdfAConformanceLevel conformanceLevel = reader.getPdfAConformanceLevel(); if (conformanceLevel == null) { throw new PdfAConformanceException(PdfAConformanceException.DOCUMENT_TO_READ_FROM_SHALL_BE_A_PDFA_CONFORMANT_FILE_WITH_VALID_XMP_METADATA); } diff --git a/pdfa/src/test/java/com/itextpdf/pdfa/PdfA1AcroFormCheckTest.java b/pdfa/src/test/java/com/itextpdf/pdfa/PdfA1AcroFormCheckTest.java index f60ecd5b04..a252aa98be 100644 --- a/pdfa/src/test/java/com/itextpdf/pdfa/PdfA1AcroFormCheckTest.java +++ b/pdfa/src/test/java/com/itextpdf/pdfa/PdfA1AcroFormCheckTest.java @@ -52,11 +52,11 @@ This file is part of the iText (R) project. import com.itextpdf.kernel.utils.CompareTool; import com.itextpdf.test.ExtendedITextTest; import com.itextpdf.test.annotations.type.IntegrationTest; + +import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; import java.io.FileInputStream; import java.io.FileNotFoundException; @@ -76,13 +76,8 @@ public static void beforeClass() { createOrClearDestinationFolder(destinationFolder); } - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void acroFormCheck01() throws FileNotFoundException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.NEEDAPPEARANCES_FLAG_OF_THE_INTERACTIVE_FORM_DICTIONARY_SHALL_EITHER_NOT_BE_PRESENTED_OR_SHALL_BE_FALSE); PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_1B, new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is)); @@ -91,7 +86,9 @@ public void acroFormCheck01() throws FileNotFoundException { acroForm.put(PdfName.NeedAppearances, new PdfBoolean(true)); doc.getCatalog().put(PdfName.AcroForm, acroForm); - doc.close(); + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> doc.close()); + Assert.assertEquals(PdfAConformanceException.NEEDAPPEARANCES_FLAG_OF_THE_INTERACTIVE_FORM_DICTIONARY_SHALL_EITHER_NOT_BE_PRESENTED_OR_SHALL_BE_FALSE, + e.getMessage()); } @Test diff --git a/pdfa/src/test/java/com/itextpdf/pdfa/PdfA1ActionCheckTest.java b/pdfa/src/test/java/com/itextpdf/pdfa/PdfA1ActionCheckTest.java index 2771d2cea8..ba5c813fc2 100644 --- a/pdfa/src/test/java/com/itextpdf/pdfa/PdfA1ActionCheckTest.java +++ b/pdfa/src/test/java/com/itextpdf/pdfa/PdfA1ActionCheckTest.java @@ -53,10 +53,10 @@ This file is part of the iText (R) project. import com.itextpdf.kernel.pdf.action.PdfAction; import com.itextpdf.test.ExtendedITextTest; import com.itextpdf.test.annotations.type.IntegrationTest; -import org.junit.Rule; + +import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; import java.io.FileInputStream; import java.io.FileNotFoundException; @@ -66,14 +66,8 @@ This file is part of the iText (R) project. public class PdfA1ActionCheckTest extends ExtendedITextTest { public static final String sourceFolder = "./src/test/resources/com/itextpdf/pdfa/"; - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void actionCheck01() throws FileNotFoundException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(PdfAConformanceException._0_ACTIONS_ARE_NOT_ALLOWED, PdfName.Launch.getValue())); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_1B, new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is)); @@ -82,14 +76,12 @@ public void actionCheck01() throws FileNotFoundException { openActions.put(PdfName.S, PdfName.Launch); doc.getCatalog().put(PdfName.OpenAction, openActions); - doc.close(); + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> doc.close()); + Assert.assertEquals(MessageFormatUtil.format(PdfAConformanceException._0_ACTIONS_ARE_NOT_ALLOWED, PdfName.Launch.getValue()), e.getMessage()); } @Test public void actionCheck02() throws FileNotFoundException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(PdfAConformanceException._0_ACTIONS_ARE_NOT_ALLOWED, PdfName.Hide.getValue())); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_1B, new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is)); @@ -98,14 +90,13 @@ public void actionCheck02() throws FileNotFoundException { openActions.put(PdfName.S, PdfName.Hide); doc.getCatalog().put(PdfName.OpenAction, openActions); - doc.close(); + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> doc.close()); + Assert.assertEquals(MessageFormatUtil.format(PdfAConformanceException._0_ACTIONS_ARE_NOT_ALLOWED, PdfName.Hide.getValue()), + e.getMessage()); } @Test public void actionCheck03() throws FileNotFoundException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(PdfAConformanceException._0_ACTIONS_ARE_NOT_ALLOWED, PdfName.Sound.getValue())); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_1B, new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is)); @@ -114,14 +105,12 @@ public void actionCheck03() throws FileNotFoundException { openActions.put(PdfName.S, PdfName.Sound); doc.getCatalog().put(PdfName.OpenAction, openActions); - doc.close(); + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> doc.close()); + Assert.assertEquals(MessageFormatUtil.format(PdfAConformanceException._0_ACTIONS_ARE_NOT_ALLOWED, PdfName.Sound.getValue()), e.getMessage()); } @Test public void actionCheck04() throws FileNotFoundException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(PdfAConformanceException._0_ACTIONS_ARE_NOT_ALLOWED, PdfName.Movie.getValue())); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_1B, new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is)); @@ -130,14 +119,13 @@ public void actionCheck04() throws FileNotFoundException { openActions.put(PdfName.S, PdfName.Movie); doc.getCatalog().put(PdfName.OpenAction, openActions); - doc.close(); + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> doc.close()); + Assert.assertEquals(MessageFormatUtil.format(PdfAConformanceException._0_ACTIONS_ARE_NOT_ALLOWED, PdfName.Movie.getValue()), + e.getMessage()); } @Test public void actionCheck05() throws FileNotFoundException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(PdfAConformanceException._0_ACTIONS_ARE_NOT_ALLOWED, PdfName.ResetForm.getValue())); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_1B, new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is)); @@ -146,14 +134,13 @@ public void actionCheck05() throws FileNotFoundException { openActions.put(PdfName.S, PdfName.ResetForm); doc.getCatalog().put(PdfName.OpenAction, openActions); - doc.close(); + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> doc.close()); + Assert.assertEquals(MessageFormatUtil.format(PdfAConformanceException._0_ACTIONS_ARE_NOT_ALLOWED, PdfName.ResetForm.getValue()), + e.getMessage()); } @Test public void actionCheck06() throws FileNotFoundException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(PdfAConformanceException._0_ACTIONS_ARE_NOT_ALLOWED, PdfName.ImportData.getValue())); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_1B, new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is)); @@ -162,14 +149,13 @@ public void actionCheck06() throws FileNotFoundException { openActions.put(PdfName.S, PdfName.ImportData); doc.getCatalog().put(PdfName.OpenAction, openActions); - doc.close(); + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> doc.close()); + Assert.assertEquals(MessageFormatUtil.format(PdfAConformanceException._0_ACTIONS_ARE_NOT_ALLOWED, PdfName.ImportData.getValue()), + e.getMessage()); } @Test public void actionCheck07() throws FileNotFoundException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(PdfAConformanceException._0_ACTIONS_ARE_NOT_ALLOWED, PdfName.JavaScript.getValue())); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_1B, new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is)); @@ -178,14 +164,13 @@ public void actionCheck07() throws FileNotFoundException { openActions.put(PdfName.S, PdfName.JavaScript); doc.getCatalog().put(PdfName.OpenAction, openActions); - doc.close(); + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> doc.close()); + Assert.assertEquals(MessageFormatUtil.format(PdfAConformanceException._0_ACTIONS_ARE_NOT_ALLOWED, PdfName.JavaScript.getValue()), + e.getMessage()); } @Test public void actionCheck08() throws FileNotFoundException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(PdfAConformanceException.NAMED_ACTION_TYPE_0_IS_NOT_ALLOWED, "CustomName")); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_1B, new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is)); @@ -195,28 +180,26 @@ public void actionCheck08() throws FileNotFoundException { openActions.put(PdfName.N, new PdfName("CustomName")); doc.getCatalog().put(PdfName.OpenAction, openActions); - doc.close(); + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> doc.close()); + Assert.assertEquals(MessageFormatUtil.format(PdfAConformanceException.NAMED_ACTION_TYPE_0_IS_NOT_ALLOWED, "CustomName"), + e.getMessage()); } @Test public void actionCheck09() throws FileNotFoundException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(PdfAConformanceException._0_ACTIONS_ARE_NOT_ALLOWED, PdfName.JavaScript.getValue())); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_1B, new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is)); PdfPage page = doc.addNewPage(); page.setAdditionalAction(PdfName.C, PdfAction.createJavaScript("js")); - doc.close(); + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> doc.close()); + Assert.assertEquals(MessageFormatUtil.format(PdfAConformanceException._0_ACTIONS_ARE_NOT_ALLOWED, PdfName.JavaScript.getValue()), + e.getMessage()); } @Test public void actionCheck10() throws FileNotFoundException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.DEPRECATED_SETSTATE_AND_NOOP_ACTIONS_ARE_NOT_ALLOWED); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_1B, new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is)); @@ -225,19 +208,18 @@ public void actionCheck10() throws FileNotFoundException { action.put(PdfName.S, PdfName.SetState); page.setAdditionalAction(PdfName.C, new PdfAction(action)); - doc.close(); + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> doc.close()); + Assert.assertEquals(PdfAConformanceException.DEPRECATED_SETSTATE_AND_NOOP_ACTIONS_ARE_NOT_ALLOWED, e.getMessage()); } @Test public void actionCheck11() throws FileNotFoundException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.A_CATALOG_DICTIONARY_SHALL_NOT_CONTAIN_AA_ENTRY); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_1B, new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is)); doc.getCatalog().setAdditionalAction(PdfName.C, PdfAction.createJavaScript("js")); - doc.close(); + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> doc.close()); + Assert.assertEquals(PdfAConformanceException.A_CATALOG_DICTIONARY_SHALL_NOT_CONTAIN_AA_ENTRY, e.getMessage()); } } diff --git a/pdfa/src/test/java/com/itextpdf/pdfa/PdfA1AnnotationCheckTest.java b/pdfa/src/test/java/com/itextpdf/pdfa/PdfA1AnnotationCheckTest.java index 82c0531651..93b8b293a2 100644 --- a/pdfa/src/test/java/com/itextpdf/pdfa/PdfA1AnnotationCheckTest.java +++ b/pdfa/src/test/java/com/itextpdf/pdfa/PdfA1AnnotationCheckTest.java @@ -63,11 +63,11 @@ This file is part of the iText (R) project. import com.itextpdf.kernel.utils.CompareTool; import com.itextpdf.test.ExtendedITextTest; import com.itextpdf.test.annotations.type.IntegrationTest; + +import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; import java.io.FileInputStream; import java.io.FileNotFoundException; @@ -88,14 +88,8 @@ public static void beforeClass() { createOrClearDestinationFolder(destinationFolder); } - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void annotationCheckTest01() throws FileNotFoundException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(PdfAConformanceException.ANNOTATION_TYPE_0_IS_NOT_PERMITTED, PdfName.FileAttachment.getValue())); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_1B, new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is)); @@ -104,14 +98,14 @@ public void annotationCheckTest01() throws FileNotFoundException { Rectangle rect = new Rectangle(100, 100, 100, 100); PdfAnnotation annot = new PdfFileAttachmentAnnotation(rect); page.addAnnotation(annot); - doc.close(); + + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> doc.close()); + Assert.assertEquals(MessageFormatUtil.format(PdfAConformanceException.ANNOTATION_TYPE_0_IS_NOT_PERMITTED, + PdfName.FileAttachment.getValue()), e.getMessage()); } @Test public void annotationCheckTest02() throws FileNotFoundException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.AN_ANNOTATION_DICTIONARY_SHALL_NOT_CONTAIN_THE_CA_KEY_WITH_A_VALUE_OTHER_THAN_1); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_1B, new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is)); @@ -123,14 +117,14 @@ public void annotationCheckTest02() throws FileNotFoundException { annot.setOpacity(new PdfNumber(0.5)); page.addAnnotation(annot); - doc.close(); + + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> doc.close()); + Assert.assertEquals(PdfAConformanceException.AN_ANNOTATION_DICTIONARY_SHALL_NOT_CONTAIN_THE_CA_KEY_WITH_A_VALUE_OTHER_THAN_1, + e.getMessage()); } @Test public void annotationCheckTest03() throws FileNotFoundException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.THE_F_KEYS_PRINT_FLAG_BIT_SHALL_BE_SET_TO_1_AND_ITS_HIDDEN_INVISIBLE_AND_NOVIEW_FLAG_BITS_SHALL_BE_SET_TO_0); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_1B, new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is)); @@ -141,14 +135,16 @@ public void annotationCheckTest03() throws FileNotFoundException { annot.setFlag(0); page.addAnnotation(annot); - doc.close(); + + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> doc.close() + ); + Assert.assertEquals(PdfAConformanceException.THE_F_KEYS_PRINT_FLAG_BIT_SHALL_BE_SET_TO_1_AND_ITS_HIDDEN_INVISIBLE_AND_NOVIEW_FLAG_BITS_SHALL_BE_SET_TO_0, + e.getMessage()); } @Test public void annotationCheckTest04() throws FileNotFoundException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.THE_F_KEYS_PRINT_FLAG_BIT_SHALL_BE_SET_TO_1_AND_ITS_HIDDEN_INVISIBLE_AND_NOVIEW_FLAG_BITS_SHALL_BE_SET_TO_0); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_1B, new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is)); @@ -160,14 +156,14 @@ public void annotationCheckTest04() throws FileNotFoundException { annot.setFlag(PdfAnnotation.INVISIBLE); page.addAnnotation(annot); - doc.close(); + + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> doc.close()); + Assert.assertEquals(PdfAConformanceException.THE_F_KEYS_PRINT_FLAG_BIT_SHALL_BE_SET_TO_1_AND_ITS_HIDDEN_INVISIBLE_AND_NOVIEW_FLAG_BITS_SHALL_BE_SET_TO_0, + e.getMessage()); } @Test public void annotationCheckTest05() throws FileNotFoundException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.APPEARANCE_DICTIONARY_SHALL_CONTAIN_ONLY_THE_N_KEY_WITH_STREAM_VALUE); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_1B, new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is)); @@ -182,14 +178,14 @@ public void annotationCheckTest05() throws FileNotFoundException { annot.setNormalAppearance(s); page.addAnnotation(annot); - doc.close(); + + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> doc.close()); + Assert.assertEquals(PdfAConformanceException.APPEARANCE_DICTIONARY_SHALL_CONTAIN_ONLY_THE_N_KEY_WITH_STREAM_VALUE, + e.getMessage()); } @Test public void annotationCheckTest06() throws FileNotFoundException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.APPEARANCE_DICTIONARY_SHALL_CONTAIN_ONLY_THE_N_KEY_WITH_STREAM_VALUE); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_1B, new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is)); @@ -202,7 +198,10 @@ public void annotationCheckTest06() throws FileNotFoundException { annot.setNormalAppearance(new PdfDictionary()); page.addAnnotation(annot); - doc.close(); + + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> doc.close()); + Assert.assertEquals(PdfAConformanceException.APPEARANCE_DICTIONARY_SHALL_CONTAIN_ONLY_THE_N_KEY_WITH_STREAM_VALUE, + e.getMessage()); } @Test @@ -225,9 +224,6 @@ public void annotationCheckTest07() throws IOException, InterruptedException { @Test public void annotationCheckTest08() throws FileNotFoundException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(PdfAConformanceException.ANNOTATION_OF_TYPE_0_SHOULD_HAVE_CONTENTS_KEY, PdfName.Stamp.getValue())); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_1A, new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is)); @@ -240,7 +236,10 @@ public void annotationCheckTest08() throws FileNotFoundException { annot.setFlag(PdfAnnotation.PRINT); page.addAnnotation(annot); - doc.close(); + + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> doc.close()); + Assert.assertEquals(MessageFormatUtil.format(PdfAConformanceException.ANNOTATION_OF_TYPE_0_SHOULD_HAVE_CONTENTS_KEY, + PdfName.Stamp.getValue()), e.getMessage()); } @Test diff --git a/pdfa/src/test/java/com/itextpdf/pdfa/PdfA1CanvasCheckTest.java b/pdfa/src/test/java/com/itextpdf/pdfa/PdfA1CanvasCheckTest.java index 7b9f5a137e..385c22d4e1 100644 --- a/pdfa/src/test/java/com/itextpdf/pdfa/PdfA1CanvasCheckTest.java +++ b/pdfa/src/test/java/com/itextpdf/pdfa/PdfA1CanvasCheckTest.java @@ -50,11 +50,11 @@ This file is part of the iText (R) project. import com.itextpdf.kernel.utils.CompareTool; import com.itextpdf.test.ExtendedITextTest; import com.itextpdf.test.annotations.type.IntegrationTest; + +import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; import java.io.ByteArrayOutputStream; import java.io.FileInputStream; @@ -74,30 +74,22 @@ public static void beforeClass() { createOrClearDestinationFolder(destinationFolder); } - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void canvasCheckTest1() throws IOException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.GRAPHICS_STATE_STACK_DEPTH_IS_GREATER_THAN_28); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfOutputIntent outputIntent = new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is); - PdfADocument pdfDocument = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_1B, outputIntent); - pdfDocument.addNewPage(); - PdfCanvas canvas = new PdfCanvas(pdfDocument.getLastPage()); - for (int i = 0; i < 29; i++) { - canvas.saveState(); - } + try (PdfADocument pdfDocument = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_1B, outputIntent)) { + pdfDocument.addNewPage(); + PdfCanvas canvas = new PdfCanvas(pdfDocument.getLastPage()); + for (int i = 0; i < 28; i++) { + canvas.saveState(); + } - for (int i = 0; i < 28; i++) { - canvas.restoreState(); + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> canvas.saveState()); + Assert.assertEquals(PdfAConformanceException.GRAPHICS_STATE_STACK_DEPTH_IS_GREATER_THAN_28, e.getMessage()); } - - pdfDocument.close(); } @Test @@ -130,18 +122,20 @@ public void canvasCheckTest2() throws IOException, InterruptedException { @Test public void canvasCheckTest3() throws IOException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.IF_SPECIFIED_RENDERING_SHALL_BE_ONE_OF_THE_FOLLOWING_RELATIVECOLORIMETRIC_ABSOLUTECOLORIMETRIC_PERCEPTUAL_OR_SATURATION); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfOutputIntent outputIntent = new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is); - PdfADocument pdfDocument = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_1B, outputIntent); - pdfDocument.addNewPage(); - PdfCanvas canvas = new PdfCanvas(pdfDocument.getLastPage()); - canvas.setRenderingIntent(new PdfName("Test")); + try (PdfADocument pdfDocument = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_1B, outputIntent)) { + pdfDocument.addNewPage(); + PdfCanvas canvas = new PdfCanvas(pdfDocument.getLastPage()); - pdfDocument.close(); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> canvas.setRenderingIntent(new PdfName("Test")) + ); + Assert.assertEquals( + PdfAConformanceException.IF_SPECIFIED_RENDERING_SHALL_BE_ONE_OF_THE_FOLLOWING_RELATIVECOLORIMETRIC_ABSOLUTECOLORIMETRIC_PERCEPTUAL_OR_SATURATION, + e.getMessage()); + } } } diff --git a/pdfa/src/test/java/com/itextpdf/pdfa/PdfA1EmbeddedFilesCheckTest.java b/pdfa/src/test/java/com/itextpdf/pdfa/PdfA1EmbeddedFilesCheckTest.java index 5cb04a5043..e795a74fb2 100644 --- a/pdfa/src/test/java/com/itextpdf/pdfa/PdfA1EmbeddedFilesCheckTest.java +++ b/pdfa/src/test/java/com/itextpdf/pdfa/PdfA1EmbeddedFilesCheckTest.java @@ -53,10 +53,10 @@ This file is part of the iText (R) project. import com.itextpdf.kernel.pdf.filespec.PdfFileSpec; import com.itextpdf.test.ExtendedITextTest; import com.itextpdf.test.annotations.type.IntegrationTest; -import org.junit.Rule; + +import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; import java.io.ByteArrayOutputStream; import java.io.FileInputStream; @@ -67,14 +67,8 @@ This file is part of the iText (R) project. public class PdfA1EmbeddedFilesCheckTest extends ExtendedITextTest { public static final String sourceFolder = "./src/test/resources/com/itextpdf/pdfa/"; - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void fileSpecCheckTest01() throws IOException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.A_NAME_DICTIONARY_SHALL_NOT_CONTAIN_THE_EMBEDDED_FILES_KEY); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfOutputIntent outputIntent = new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is); @@ -95,14 +89,12 @@ public void fileSpecCheckTest01() throws IOException { pdfDocument.addNewPage(); - pdfDocument.close(); + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> pdfDocument.close()); + Assert.assertEquals(PdfAConformanceException.A_NAME_DICTIONARY_SHALL_NOT_CONTAIN_THE_EMBEDDED_FILES_KEY, e.getMessage()); } @Test public void fileSpecCheckTest02() throws IOException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.STREAM_OBJECT_DICTIONARY_SHALL_NOT_CONTAIN_THE_F_FFILTER_OR_FDECODEPARAMS_KEYS); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfOutputIntent outputIntent = new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is); @@ -116,14 +108,13 @@ public void fileSpecCheckTest02() throws IOException { pdfDocument.addNewPage(); - pdfDocument.close(); + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> pdfDocument.close()); + Assert.assertEquals(PdfAConformanceException.STREAM_OBJECT_DICTIONARY_SHALL_NOT_CONTAIN_THE_F_FFILTER_OR_FDECODEPARAMS_KEYS, + e.getMessage()); } @Test public void fileSpecCheckTest03() throws IOException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.FILE_SPECIFICATION_DICTIONARY_SHALL_NOT_CONTAIN_THE_EF_KEY); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfOutputIntent outputIntent = new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is); @@ -137,6 +128,7 @@ public void fileSpecCheckTest03() throws IOException { pdfDocument.addNewPage(); - pdfDocument.close(); + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> pdfDocument.close()); + Assert.assertEquals(PdfAConformanceException.FILE_SPECIFICATION_DICTIONARY_SHALL_NOT_CONTAIN_THE_EF_KEY, e.getMessage()); } } diff --git a/pdfa/src/test/java/com/itextpdf/pdfa/PdfA1GraphicsTest.java b/pdfa/src/test/java/com/itextpdf/pdfa/PdfA1GraphicsTest.java index 6314fe23eb..3b470d3bb9 100644 --- a/pdfa/src/test/java/com/itextpdf/pdfa/PdfA1GraphicsTest.java +++ b/pdfa/src/test/java/com/itextpdf/pdfa/PdfA1GraphicsTest.java @@ -46,7 +46,6 @@ This file is part of the iText (R) project. import com.itextpdf.kernel.colors.DeviceCmyk; import com.itextpdf.kernel.geom.Rectangle; import com.itextpdf.kernel.pdf.PdfAConformanceLevel; -import com.itextpdf.kernel.pdf.PdfDictionary; import com.itextpdf.kernel.pdf.PdfName; import com.itextpdf.kernel.pdf.PdfOutputIntent; import com.itextpdf.kernel.pdf.PdfWriter; @@ -57,11 +56,11 @@ This file is part of the iText (R) project. import com.itextpdf.kernel.utils.CompareTool; import com.itextpdf.test.ExtendedITextTest; import com.itextpdf.test.annotations.type.IntegrationTest; + +import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; import java.io.ByteArrayOutputStream; import java.io.FileInputStream; @@ -81,14 +80,8 @@ public static void beforeClass() { createOrClearDestinationFolder(destinationFolder); } - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void colorCheckTest1() throws IOException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.DEVICERGB_AND_DEVICECMYK_COLORSPACES_CANNOT_BE_USED_BOTH_IN_ONE_FILE); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfOutputIntent outputIntent = new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is); @@ -101,20 +94,24 @@ public void colorCheckTest1() throws IOException { canvas.lineTo(doc.getDefaultPageSize().getRight(), doc.getDefaultPageSize().getBottom()); canvas.lineTo(doc.getDefaultPageSize().getRight(), doc.getDefaultPageSize().getTop()); canvas.fill(); - canvas.setFillColor(ColorConstants.RED); + + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> canvas.setFillColor(ColorConstants.RED) + ); + Assert.assertEquals(PdfAConformanceException.DEVICERGB_AND_DEVICECMYK_COLORSPACES_CANNOT_BE_USED_BOTH_IN_ONE_FILE, e.getMessage()); canvas.moveTo(doc.getDefaultPageSize().getRight(), doc.getDefaultPageSize().getTop()); canvas.lineTo(doc.getDefaultPageSize().getRight(), doc.getDefaultPageSize().getBottom()); canvas.lineTo(doc.getDefaultPageSize().getLeft(), doc.getDefaultPageSize().getBottom()); canvas.fill(); - doc.close(); + Exception e2 = Assert.assertThrows(PdfAConformanceException.class, + () -> doc.close() + ); + Assert.assertEquals(PdfAConformanceException.DEVICERGB_AND_DEVICECMYK_COLORSPACES_CANNOT_BE_USED_BOTH_IN_ONE_FILE, e.getMessage()); } @Test public void colorCheckTest2() throws IOException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.DEVICECMYK_MAY_BE_USED_ONLY_IF_THE_FILE_HAS_A_CMYK_PDFA_OUTPUT_INTENT); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfOutputIntent outputIntent = new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is); @@ -128,14 +125,14 @@ public void colorCheckTest2() throws IOException { canvas.lineTo(doc.getDefaultPageSize().getRight(), doc.getDefaultPageSize().getTop()); canvas.fill(); - doc.close(); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> doc.close() + ); + Assert.assertEquals(PdfAConformanceException.DEVICECMYK_MAY_BE_USED_ONLY_IF_THE_FILE_HAS_A_CMYK_PDFA_OUTPUT_INTENT, e.getMessage()); } @Test public void colorCheckTest3() { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.IF_DEVICE_RGB_CMYK_GRAY_USED_IN_FILE_THAT_FILE_SHALL_CONTAIN_PDFA_OUTPUTINTENT); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_1B, null); doc.addNewPage(); @@ -147,7 +144,11 @@ public void colorCheckTest3() { canvas.lineTo(doc.getDefaultPageSize().getRight(), doc.getDefaultPageSize().getTop()); canvas.fill(); - doc.close(); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> doc.close() + ); + Assert.assertEquals(PdfAConformanceException.IF_DEVICE_RGB_CMYK_GRAY_USED_IN_FILE_THAT_FILE_SHALL_CONTAIN_PDFA_OUTPUTINTENT + , e.getMessage()); } @Test @@ -174,20 +175,20 @@ public void colorCheckTest4() throws IOException, InterruptedException { @Test public void egsCheckTest1() throws IOException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.AN_EXTGSTATE_DICTIONARY_SHALL_NOT_CONTAIN_THE_TR_KEY); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfOutputIntent outputIntent = new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is); - PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_1B, outputIntent); - doc.addNewPage(); - PdfCanvas canvas = new PdfCanvas(doc.getLastPage()); - canvas.setExtGState(new PdfExtGState().setTransferFunction(new PdfName("Test"))); - canvas.rectangle(30, 30, 100, 100).fill(); + try (PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_1B, outputIntent)) { + doc.addNewPage(); + PdfCanvas canvas = new PdfCanvas(doc.getLastPage()); - doc.close(); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> canvas.setExtGState(new PdfExtGState().setTransferFunction(new PdfName("Test"))) + ); + Assert.assertEquals(PdfAConformanceException.AN_EXTGSTATE_DICTIONARY_SHALL_NOT_CONTAIN_THE_TR_KEY, + e.getMessage()); + } } @Test @@ -211,45 +212,44 @@ public void egsCheckTest2() throws IOException, InterruptedException { @Test public void egsCheckTest3() throws IOException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.AN_EXTGSTATE_DICTIONARY_SHALL_NOT_CONTAIN_THE_TR_2_KEY_WITH_A_VALUE_OTHER_THAN_DEFAULT); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfOutputIntent outputIntent = new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is); - PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_1B, outputIntent); - doc.addNewPage(); - PdfCanvas canvas = new PdfCanvas(doc.getLastPage()); - canvas.setExtGState(new PdfExtGState().setTransferFunction2(new PdfName("Test"))); - canvas.rectangle(30, 30, 100, 100).fill(); + try (PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_1B, outputIntent)) { + doc.addNewPage(); + PdfCanvas canvas = new PdfCanvas(doc.getLastPage()); - doc.close(); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> canvas.setExtGState(new PdfExtGState().setTransferFunction2(new PdfName("Test"))) + ); + Assert.assertEquals( + PdfAConformanceException.AN_EXTGSTATE_DICTIONARY_SHALL_NOT_CONTAIN_THE_TR_2_KEY_WITH_A_VALUE_OTHER_THAN_DEFAULT, + e.getMessage()); + } } @Test public void egsCheckTest4() throws IOException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.IF_SPECIFIED_RENDERING_SHALL_BE_ONE_OF_THE_FOLLOWING_RELATIVECOLORIMETRIC_ABSOLUTECOLORIMETRIC_PERCEPTUAL_OR_SATURATION); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfOutputIntent outputIntent = new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is); - PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_1B, outputIntent); - doc.addNewPage(); - PdfCanvas canvas = new PdfCanvas(doc.getLastPage()); - canvas.setExtGState(new PdfExtGState().setRenderingIntent(new PdfName("Test"))); - canvas.rectangle(30, 30, 100, 100).fill(); + try (PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_1B, outputIntent)) { + doc.addNewPage(); + PdfCanvas canvas = new PdfCanvas(doc.getLastPage()); - doc.close(); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> canvas.setExtGState(new PdfExtGState().setRenderingIntent(new PdfName("Test"))) + ); + Assert.assertEquals( + PdfAConformanceException.IF_SPECIFIED_RENDERING_SHALL_BE_ONE_OF_THE_FOLLOWING_RELATIVECOLORIMETRIC_ABSOLUTECOLORIMETRIC_PERCEPTUAL_OR_SATURATION, + e.getMessage()); + } } @Test public void transparencyCheckTest1() throws IOException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.A_GROUP_OBJECT_WITH_AN_S_KEY_WITH_A_VALUE_OF_TRANSPARENCY_SHALL_NOT_BE_INCLUDED_IN_A_FORM_XOBJECT); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfOutputIntent outputIntent = new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is); @@ -265,25 +265,26 @@ public void transparencyCheckTest1() throws IOException { xObject.setGroup(group); canvas.addXObject(xObject, new Rectangle(300, 300)); - doc.close(); + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> doc.close()); + Assert.assertEquals(PdfAConformanceException.A_GROUP_OBJECT_WITH_AN_S_KEY_WITH_A_VALUE_OF_TRANSPARENCY_SHALL_NOT_BE_INCLUDED_IN_A_FORM_XOBJECT, + e.getMessage()); } @Test public void transparencyCheckTest2() throws IOException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.THE_SMASK_KEY_IS_NOT_ALLOWED_IN_EXTGSTATE); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfOutputIntent outputIntent = new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is); - PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_1B, outputIntent); - doc.addNewPage(); - PdfCanvas canvas = new PdfCanvas(doc.getLastPage()); - canvas.setExtGState(new PdfExtGState().setSoftMask(new PdfName("Test"))); - canvas.rectangle(30, 30, 100, 100).fill(); + try (PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_1B, outputIntent)) { + doc.addNewPage(); + PdfCanvas canvas = new PdfCanvas(doc.getLastPage()); - doc.close(); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> canvas.setExtGState(new PdfExtGState().setSoftMask(new PdfName("Test"))) + ); + Assert.assertEquals(PdfAConformanceException.THE_SMASK_KEY_IS_NOT_ALLOWED_IN_EXTGSTATE, e.getMessage()); + } } @Test diff --git a/pdfa/src/test/java/com/itextpdf/pdfa/PdfA2AcroFormCheckTest.java b/pdfa/src/test/java/com/itextpdf/pdfa/PdfA2AcroFormCheckTest.java index 21cd30839b..acbadfa10a 100644 --- a/pdfa/src/test/java/com/itextpdf/pdfa/PdfA2AcroFormCheckTest.java +++ b/pdfa/src/test/java/com/itextpdf/pdfa/PdfA2AcroFormCheckTest.java @@ -53,12 +53,11 @@ This file is part of the iText (R) project. import com.itextpdf.kernel.utils.CompareTool; import com.itextpdf.test.ExtendedITextTest; import com.itextpdf.test.annotations.type.IntegrationTest; + import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; import java.io.FileInputStream; import java.io.FileNotFoundException; @@ -78,9 +77,6 @@ public static void beforeClass() { createOrClearDestinationFolder(destinationFolder); } - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void acroFormCheck01() throws FileNotFoundException { PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); @@ -131,9 +127,6 @@ public void acroFormCheck03() throws IOException, InterruptedException { @Test public void acroFormCheck04() throws FileNotFoundException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.THE_INTERACTIVE_FORM_DICTIONARY_SHALL_NOT_CONTAIN_THE_XFA_KEY); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_2B, new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is)); @@ -142,7 +135,8 @@ public void acroFormCheck04() throws FileNotFoundException { acroForm.put(PdfName.XFA, new PdfArray()); doc.getCatalog().put(PdfName.AcroForm, acroForm); - doc.close(); + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> doc.close()); + Assert.assertEquals(PdfAConformanceException.THE_INTERACTIVE_FORM_DICTIONARY_SHALL_NOT_CONTAIN_THE_XFA_KEY, e.getMessage()); } private void compareResult(String outPdf, String cmpPdf) throws IOException, InterruptedException { diff --git a/pdfa/src/test/java/com/itextpdf/pdfa/PdfA2ActionCheckTest.java b/pdfa/src/test/java/com/itextpdf/pdfa/PdfA2ActionCheckTest.java index 6010455dc0..f0cf1369f0 100644 --- a/pdfa/src/test/java/com/itextpdf/pdfa/PdfA2ActionCheckTest.java +++ b/pdfa/src/test/java/com/itextpdf/pdfa/PdfA2ActionCheckTest.java @@ -55,11 +55,11 @@ This file is part of the iText (R) project. import com.itextpdf.kernel.utils.CompareTool; import com.itextpdf.test.ExtendedITextTest; import com.itextpdf.test.annotations.type.IntegrationTest; + +import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; import java.io.FileInputStream; import java.io.FileNotFoundException; @@ -78,14 +78,8 @@ public static void beforeClass() { createOrClearDestinationFolder(destinationFolder); } - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void actionCheck01() throws FileNotFoundException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(PdfAConformanceException._0_ACTIONS_ARE_NOT_ALLOWED, PdfName.Launch.getValue())); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_2B, new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is)); @@ -94,14 +88,13 @@ public void actionCheck01() throws FileNotFoundException { openActions.put(PdfName.S, PdfName.Launch); doc.getCatalog().put(PdfName.OpenAction, openActions); - doc.close(); + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> doc.close()); + Assert.assertEquals(MessageFormatUtil.format(PdfAConformanceException._0_ACTIONS_ARE_NOT_ALLOWED, PdfName.Launch.getValue()), + e.getMessage()); } @Test public void actionCheck02() throws FileNotFoundException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(PdfAConformanceException._0_ACTIONS_ARE_NOT_ALLOWED, PdfName.Hide.getValue())); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_2B, new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is)); @@ -110,14 +103,13 @@ public void actionCheck02() throws FileNotFoundException { openActions.put(PdfName.S, PdfName.Hide); doc.getCatalog().put(PdfName.OpenAction, openActions); - doc.close(); + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> doc.close()); + Assert.assertEquals(MessageFormatUtil.format(PdfAConformanceException._0_ACTIONS_ARE_NOT_ALLOWED, PdfName.Hide.getValue()), + e.getMessage()); } @Test public void actionCheck03() throws FileNotFoundException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(PdfAConformanceException._0_ACTIONS_ARE_NOT_ALLOWED, PdfName.Sound.getValue())); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_2B, new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is)); @@ -126,14 +118,13 @@ public void actionCheck03() throws FileNotFoundException { openActions.put(PdfName.S, PdfName.Sound); doc.getCatalog().put(PdfName.OpenAction, openActions); - doc.close(); + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> doc.close()); + Assert.assertEquals(MessageFormatUtil.format(PdfAConformanceException._0_ACTIONS_ARE_NOT_ALLOWED, PdfName.Sound.getValue()), + e.getMessage()); } @Test public void actionCheck04() throws FileNotFoundException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(PdfAConformanceException._0_ACTIONS_ARE_NOT_ALLOWED, PdfName.Movie.getValue())); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_2B, new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is)); @@ -142,14 +133,13 @@ public void actionCheck04() throws FileNotFoundException { openActions.put(PdfName.S, PdfName.Movie); doc.getCatalog().put(PdfName.OpenAction, openActions); - doc.close(); + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> doc.close()); + Assert.assertEquals(MessageFormatUtil.format(PdfAConformanceException._0_ACTIONS_ARE_NOT_ALLOWED, PdfName.Movie.getValue()), + e.getMessage()); } @Test public void actionCheck05() throws FileNotFoundException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(PdfAConformanceException._0_ACTIONS_ARE_NOT_ALLOWED, PdfName.ResetForm.getValue())); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_2B, new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is)); @@ -158,14 +148,13 @@ public void actionCheck05() throws FileNotFoundException { openActions.put(PdfName.S, PdfName.ResetForm); doc.getCatalog().put(PdfName.OpenAction, openActions); - doc.close(); + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> doc.close()); + Assert.assertEquals(MessageFormatUtil.format(PdfAConformanceException._0_ACTIONS_ARE_NOT_ALLOWED, PdfName.ResetForm.getValue()), + e.getMessage()); } @Test public void actionCheck06() throws FileNotFoundException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(PdfAConformanceException._0_ACTIONS_ARE_NOT_ALLOWED, PdfName.ImportData.getValue())); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_2B, new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is)); @@ -174,14 +163,13 @@ public void actionCheck06() throws FileNotFoundException { openActions.put(PdfName.S, PdfName.ImportData); doc.getCatalog().put(PdfName.OpenAction, openActions); - doc.close(); + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> doc.close()); + Assert.assertEquals(MessageFormatUtil.format(PdfAConformanceException._0_ACTIONS_ARE_NOT_ALLOWED, PdfName.ImportData.getValue()), + e.getMessage()); } @Test public void actionCheck07() throws FileNotFoundException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(PdfAConformanceException._0_ACTIONS_ARE_NOT_ALLOWED, PdfName.JavaScript.getValue())); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_2B, new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is)); @@ -190,14 +178,12 @@ public void actionCheck07() throws FileNotFoundException { openActions.put(PdfName.S, PdfName.JavaScript); doc.getCatalog().put(PdfName.OpenAction, openActions); - doc.close(); + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> doc.close()); + Assert.assertEquals(MessageFormatUtil.format(PdfAConformanceException._0_ACTIONS_ARE_NOT_ALLOWED, PdfName.JavaScript.getValue()), e.getMessage()); } @Test public void actionCheck08() throws FileNotFoundException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(PdfAConformanceException.NAMED_ACTION_TYPE_0_IS_NOT_ALLOWED, "CustomName")); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_2B, new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is)); @@ -207,14 +193,13 @@ public void actionCheck08() throws FileNotFoundException { openActions.put(PdfName.N, new PdfName("CustomName")); doc.getCatalog().put(PdfName.OpenAction, openActions); - doc.close(); + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> doc.close()); + Assert.assertEquals(MessageFormatUtil.format(PdfAConformanceException.NAMED_ACTION_TYPE_0_IS_NOT_ALLOWED, "CustomName"), + e.getMessage()); } @Test public void actionCheck09() throws FileNotFoundException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(PdfAConformanceException._0_ACTIONS_ARE_NOT_ALLOWED, PdfName.SetOCGState.getValue())); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_2B, new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is)); @@ -223,14 +208,13 @@ public void actionCheck09() throws FileNotFoundException { openActions.put(PdfName.S, PdfName.SetOCGState); doc.getCatalog().put(PdfName.OpenAction, openActions); - doc.close(); + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> doc.close()); + Assert.assertEquals(MessageFormatUtil.format(PdfAConformanceException._0_ACTIONS_ARE_NOT_ALLOWED, PdfName.SetOCGState.getValue()), + e.getMessage()); } @Test public void actionCheck10() throws FileNotFoundException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(PdfAConformanceException._0_ACTIONS_ARE_NOT_ALLOWED, PdfName.Rendition.getValue())); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_2B, new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is)); @@ -239,14 +223,15 @@ public void actionCheck10() throws FileNotFoundException { openActions.put(PdfName.S, PdfName.Rendition); doc.getCatalog().put(PdfName.OpenAction, openActions); - doc.close(); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> doc.close() + ); + Assert.assertEquals(MessageFormatUtil.format(PdfAConformanceException._0_ACTIONS_ARE_NOT_ALLOWED, PdfName.Rendition.getValue()), + e.getMessage()); } @Test public void actionCheck11() throws FileNotFoundException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(PdfAConformanceException._0_ACTIONS_ARE_NOT_ALLOWED, PdfName.Trans.getValue())); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_2B, new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is)); @@ -255,14 +240,12 @@ public void actionCheck11() throws FileNotFoundException { openActions.put(PdfName.S, PdfName.Trans); doc.getCatalog().put(PdfName.OpenAction, openActions); - doc.close(); + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> doc.close()); + Assert.assertEquals(MessageFormatUtil.format(PdfAConformanceException._0_ACTIONS_ARE_NOT_ALLOWED, PdfName.Trans.getValue()), e.getMessage()); } @Test public void actionCheck12() throws FileNotFoundException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(PdfAConformanceException._0_ACTIONS_ARE_NOT_ALLOWED, PdfName.GoTo3DView.getValue())); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_2B, new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is)); @@ -271,35 +254,33 @@ public void actionCheck12() throws FileNotFoundException { openActions.put(PdfName.S, PdfName.GoTo3DView); doc.getCatalog().put(PdfName.OpenAction, openActions); - doc.close(); + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> doc.close()); + Assert.assertEquals(MessageFormatUtil.format(PdfAConformanceException._0_ACTIONS_ARE_NOT_ALLOWED, PdfName.GoTo3DView.getValue()), + e.getMessage()); } @Test public void actionCheck13() throws FileNotFoundException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.THE_PAGE_DICTIONARY_SHALL_NOT_CONTAIN_AA_ENTRY); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_2B, new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is)); PdfPage page = doc.addNewPage(); page.setAdditionalAction(PdfName.C, PdfAction.createJavaScript("js")); - doc.close(); + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> doc.close()); + Assert.assertEquals(PdfAConformanceException.THE_PAGE_DICTIONARY_SHALL_NOT_CONTAIN_AA_ENTRY, e.getMessage()); } @Test public void actionCheck14() throws FileNotFoundException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.A_CATALOG_DICTIONARY_SHALL_NOT_CONTAIN_AA_ENTRY); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_2B, new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is)); doc.addNewPage(); doc.getCatalog().setAdditionalAction(PdfName.C, PdfAction.createJavaScript("js")); - doc.close(); + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> doc.close()); + Assert.assertEquals(PdfAConformanceException.A_CATALOG_DICTIONARY_SHALL_NOT_CONTAIN_AA_ENTRY, e.getMessage()); } @Test diff --git a/pdfa/src/test/java/com/itextpdf/pdfa/PdfA2AnnotationCheckTest.java b/pdfa/src/test/java/com/itextpdf/pdfa/PdfA2AnnotationCheckTest.java index 4f0c512801..cacb64e118 100644 --- a/pdfa/src/test/java/com/itextpdf/pdfa/PdfA2AnnotationCheckTest.java +++ b/pdfa/src/test/java/com/itextpdf/pdfa/PdfA2AnnotationCheckTest.java @@ -67,11 +67,11 @@ This file is part of the iText (R) project. import com.itextpdf.kernel.utils.CompareTool; import com.itextpdf.test.ExtendedITextTest; import com.itextpdf.test.annotations.type.IntegrationTest; + +import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; import java.io.FileInputStream; import java.io.FileNotFoundException; @@ -91,14 +91,8 @@ public static void beforeClass() { createOrClearDestinationFolder(destinationFolder); } - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void annotationCheckTest01() throws FileNotFoundException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.AN_ANNOTATION_DICTIONARY_SHALL_CONTAIN_THE_F_KEY); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_2B, new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is)); @@ -107,7 +101,9 @@ public void annotationCheckTest01() throws FileNotFoundException { Rectangle rect = new Rectangle(100, 650, 400, 100); PdfAnnotation annot = new PdfFileAttachmentAnnotation(rect); page.addAnnotation(annot); - doc.close(); + + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> doc.close()); + Assert.assertEquals(PdfAConformanceException.AN_ANNOTATION_DICTIONARY_SHALL_CONTAIN_THE_F_KEY, e.getMessage()); } @Test @@ -148,9 +144,6 @@ public void annotationCheckTest03() throws IOException, InterruptedException { @Test public void annotationCheckTest04() throws FileNotFoundException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.EVERY_ANNOTATION_SHALL_HAVE_AT_LEAST_ONE_APPEARANCE_DICTIONARY); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_2B, new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is)); @@ -162,14 +155,13 @@ public void annotationCheckTest04() throws FileNotFoundException { annot.setFlag(PdfAnnotation.PRINT); page.addAnnotation(annot); - doc.close(); + + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> doc.close()); + Assert.assertEquals(PdfAConformanceException.EVERY_ANNOTATION_SHALL_HAVE_AT_LEAST_ONE_APPEARANCE_DICTIONARY, e.getMessage()); } @Test public void annotationCheckTest05() throws FileNotFoundException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.THE_F_KEYS_PRINT_FLAG_BIT_SHALL_BE_SET_TO_1_AND_ITS_HIDDEN_INVISIBLE_NOVIEW_AND_TOGGLENOVIEW_FLAG_BITS_SHALL_BE_SET_TO_0); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_2B, new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is)); @@ -180,14 +172,14 @@ public void annotationCheckTest05() throws FileNotFoundException { annot.setFlag(0); page.addAnnotation(annot); - doc.close(); + + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> doc.close()); + Assert.assertEquals(PdfAConformanceException.THE_F_KEYS_PRINT_FLAG_BIT_SHALL_BE_SET_TO_1_AND_ITS_HIDDEN_INVISIBLE_NOVIEW_AND_TOGGLENOVIEW_FLAG_BITS_SHALL_BE_SET_TO_0, + e.getMessage()); } @Test public void annotationCheckTest06() throws FileNotFoundException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.THE_F_KEYS_PRINT_FLAG_BIT_SHALL_BE_SET_TO_1_AND_ITS_HIDDEN_INVISIBLE_NOVIEW_AND_TOGGLENOVIEW_FLAG_BITS_SHALL_BE_SET_TO_0); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_2B, new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is)); @@ -198,14 +190,14 @@ public void annotationCheckTest06() throws FileNotFoundException { annot.setFlags(PdfAnnotation.PRINT | PdfAnnotation.INVISIBLE); page.addAnnotation(annot); - doc.close(); + + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> doc.close()); + Assert.assertEquals(PdfAConformanceException.THE_F_KEYS_PRINT_FLAG_BIT_SHALL_BE_SET_TO_1_AND_ITS_HIDDEN_INVISIBLE_NOVIEW_AND_TOGGLENOVIEW_FLAG_BITS_SHALL_BE_SET_TO_0, + e.getMessage()); } @Test public void annotationCheckTest07() throws IOException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.APPEARANCE_DICTIONARY_SHALL_CONTAIN_ONLY_THE_N_KEY_WITH_STREAM_VALUE); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_2B, new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is)); @@ -221,14 +213,14 @@ public void annotationCheckTest07() throws IOException { annot.setNormalAppearance(createAppearance(doc, formRect)); page.addAnnotation(annot); - doc.close(); + + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> doc.close()); + Assert.assertEquals(PdfAConformanceException.APPEARANCE_DICTIONARY_SHALL_CONTAIN_ONLY_THE_N_KEY_WITH_STREAM_VALUE, + e.getMessage()); } @Test public void annotationCheckTest08() throws IOException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.APPEARANCE_DICTIONARY_OF_WIDGET_SUBTYPE_AND_BTN_FIELD_TYPE_SHALL_CONTAIN_ONLY_THE_N_KEY_WITH_DICTIONARY_VALUE); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_2B, new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is)); @@ -244,14 +236,14 @@ public void annotationCheckTest08() throws IOException { annot.setNormalAppearance(createAppearance(doc, formRect)); page.addAnnotation(annot); - doc.close(); + + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> doc.close()); + Assert.assertEquals(PdfAConformanceException.APPEARANCE_DICTIONARY_OF_WIDGET_SUBTYPE_AND_BTN_FIELD_TYPE_SHALL_CONTAIN_ONLY_THE_N_KEY_WITH_DICTIONARY_VALUE, + e.getMessage()); } @Test public void annotationCheckTest09() throws FileNotFoundException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.APPEARANCE_DICTIONARY_SHALL_CONTAIN_ONLY_THE_N_KEY_WITH_STREAM_VALUE); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_2B, new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is)); @@ -265,7 +257,10 @@ public void annotationCheckTest09() throws FileNotFoundException { annot.setNormalAppearance(new PdfDictionary()); page.addAnnotation(annot); - doc.close(); + + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> doc.close()); + Assert.assertEquals(PdfAConformanceException.APPEARANCE_DICTIONARY_SHALL_CONTAIN_ONLY_THE_N_KEY_WITH_STREAM_VALUE, + e.getMessage()); } @Test @@ -315,9 +310,6 @@ public void annotationCheckTest11() throws IOException, InterruptedException { @Test public void annotationCheckTest12() throws FileNotFoundException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(PdfAConformanceException.ANNOTATION_OF_TYPE_0_SHOULD_HAVE_CONTENTS_KEY, PdfName.Stamp.getValue())); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_2A, new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is)); @@ -330,14 +322,14 @@ public void annotationCheckTest12() throws FileNotFoundException { annot.setFlags(PdfAnnotation.PRINT); page.addAnnotation(annot); - doc.close(); + + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> doc.close()); + Assert.assertEquals(MessageFormatUtil.format(PdfAConformanceException.ANNOTATION_OF_TYPE_0_SHOULD_HAVE_CONTENTS_KEY, PdfName.Stamp.getValue()), + e.getMessage()); } @Test public void annotationCheckTest13() throws FileNotFoundException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.EVERY_ANNOTATION_SHALL_HAVE_AT_LEAST_ONE_APPEARANCE_DICTIONARY); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_2A, new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is)); @@ -351,7 +343,10 @@ public void annotationCheckTest13() throws FileNotFoundException { annot.setContents("Hello world"); page.addAnnotation(annot); - doc.close(); + + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> doc.close()); + Assert.assertEquals(PdfAConformanceException.EVERY_ANNOTATION_SHALL_HAVE_AT_LEAST_ONE_APPEARANCE_DICTIONARY, + e.getMessage()); } @Test diff --git a/pdfa/src/test/java/com/itextpdf/pdfa/PdfA2CanvasCheckTest.java b/pdfa/src/test/java/com/itextpdf/pdfa/PdfA2CanvasCheckTest.java index 861b1ef7cc..b8b92184e7 100644 --- a/pdfa/src/test/java/com/itextpdf/pdfa/PdfA2CanvasCheckTest.java +++ b/pdfa/src/test/java/com/itextpdf/pdfa/PdfA2CanvasCheckTest.java @@ -51,11 +51,11 @@ This file is part of the iText (R) project. import com.itextpdf.kernel.utils.CompareTool; import com.itextpdf.test.ExtendedITextTest; import com.itextpdf.test.annotations.type.IntegrationTest; + +import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; import java.io.FileInputStream; import java.io.IOException; @@ -73,31 +73,25 @@ public static void beforeClass() { createOrClearDestinationFolder(destinationFolder); } - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void canvasCheckTest1() throws IOException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.GRAPHICS_STATE_STACK_DEPTH_IS_GREATER_THAN_28); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfOutputIntent outputIntent = new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is); - PdfADocument pdfDocument = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_2B, outputIntent); - - pdfDocument.addNewPage(); - PdfCanvas canvas = new PdfCanvas(pdfDocument.getLastPage()); - for (int i = 0; i < 29; i++) { - canvas.saveState(); + try (PdfADocument pdfDocument = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_2B, outputIntent)) { + pdfDocument.addNewPage(); + PdfCanvas canvas = new PdfCanvas(pdfDocument.getLastPage()); + + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> { + for (int i = 0; i < 29; i++) { + canvas.saveState(); + } + } + ); + Assert.assertEquals(PdfAConformanceException.GRAPHICS_STATE_STACK_DEPTH_IS_GREATER_THAN_28, e.getMessage()); } - - for (int i = 0; i < 28; i++) { - canvas.restoreState(); - } - - pdfDocument.close(); } @Test @@ -108,20 +102,20 @@ public void canvasCheckTest2() throws IOException, InterruptedException { PdfWriter writer = new PdfWriter(outPdf); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfOutputIntent outputIntent = new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is); - PdfADocument pdfDocument = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_2B, outputIntent); - pdfDocument.addNewPage(); - PdfCanvas canvas = new PdfCanvas(pdfDocument.getLastPage()); + try (PdfADocument pdfDocument = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_2B, outputIntent)) { - for (int i = 0; i < 28; i++) { - canvas.saveState(); - } + pdfDocument.addNewPage(); + PdfCanvas canvas = new PdfCanvas(pdfDocument.getLastPage()); - for (int i = 0; i < 28; i++) { - canvas.restoreState(); - } + for (int i = 0; i < 28; i++) { + canvas.saveState(); + } - pdfDocument.close(); + for (int i = 0; i < 28; i++) { + canvas.restoreState(); + } + } String result = new CompareTool().compareByContent(outPdf, cmpPdf, destinationFolder, "diff_"); if (result != null) { @@ -131,20 +125,20 @@ public void canvasCheckTest2() throws IOException, InterruptedException { @Test public void canvasCheckTest3() throws IOException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.IF_SPECIFIED_RENDERING_SHALL_BE_ONE_OF_THE_FOLLOWING_RELATIVECOLORIMETRIC_ABSOLUTECOLORIMETRIC_PERCEPTUAL_OR_SATURATION); - PdfWriter writer = new PdfWriter(new java.io.ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfOutputIntent outputIntent = new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is); - PdfADocument pdfDocument = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_2B, outputIntent); - pdfDocument.addNewPage(); - PdfCanvas canvas = new PdfCanvas(pdfDocument.getLastPage()); + try (PdfADocument pdfDocument = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_2B, outputIntent)) { + pdfDocument.addNewPage(); + PdfCanvas canvas = new PdfCanvas(pdfDocument.getLastPage()); - canvas.setRenderingIntent(new PdfName("Test")); - - pdfDocument.close(); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> canvas.setRenderingIntent(new PdfName("Test")) + ); + Assert.assertEquals( + PdfAConformanceException.IF_SPECIFIED_RENDERING_SHALL_BE_ONE_OF_THE_FOLLOWING_RELATIVECOLORIMETRIC_ABSOLUTECOLORIMETRIC_PERCEPTUAL_OR_SATURATION, + e.getMessage()); + } } } - diff --git a/pdfa/src/test/java/com/itextpdf/pdfa/PdfA2CatalogCheckTest.java b/pdfa/src/test/java/com/itextpdf/pdfa/PdfA2CatalogCheckTest.java index 898b5a1967..bfd9be5131 100644 --- a/pdfa/src/test/java/com/itextpdf/pdfa/PdfA2CatalogCheckTest.java +++ b/pdfa/src/test/java/com/itextpdf/pdfa/PdfA2CatalogCheckTest.java @@ -57,10 +57,8 @@ This file is part of the iText (R) project. import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; import java.io.FileInputStream; import java.io.FileNotFoundException; @@ -80,9 +78,6 @@ public static void beforeClass() { createOrClearDestinationFolder(destinationFolder); } - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void catalogCheck03() throws IOException, InterruptedException { String outPdf = destinationFolder + "pdfA2b_catalogCheck03.pdf"; @@ -114,9 +109,6 @@ public void catalogCheck03() throws IOException, InterruptedException { @Test public void catalogCheck04() throws FileNotFoundException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.OPTIONAL_CONTENT_CONFIGURATION_DICTIONARY_SHALL_CONTAIN_NAME_ENTRY); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_2B, new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is)); @@ -135,7 +127,8 @@ public void catalogCheck04() throws FileNotFoundException { doc.getCatalog().put(PdfName.OCProperties, ocProperties); - doc.close(); + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> doc.close()); + Assert.assertEquals(PdfAConformanceException.OPTIONAL_CONTENT_CONFIGURATION_DICTIONARY_SHALL_CONTAIN_NAME_ENTRY, e.getMessage()); } @Test diff --git a/pdfa/src/test/java/com/itextpdf/pdfa/PdfA2EmbeddedFilesCheckTest.java b/pdfa/src/test/java/com/itextpdf/pdfa/PdfA2EmbeddedFilesCheckTest.java index 9bc22aaaa3..e1690e03c5 100644 --- a/pdfa/src/test/java/com/itextpdf/pdfa/PdfA2EmbeddedFilesCheckTest.java +++ b/pdfa/src/test/java/com/itextpdf/pdfa/PdfA2EmbeddedFilesCheckTest.java @@ -57,11 +57,10 @@ This file is part of the iText (R) project. import com.itextpdf.test.annotations.LogMessage; import com.itextpdf.test.annotations.LogMessages; import com.itextpdf.test.annotations.type.IntegrationTest; + import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; import java.io.ByteArrayOutputStream; import java.io.FileInputStream; @@ -82,9 +81,6 @@ public static void beforeClass() { createOrClearDestinationFolder(destinationFolder); } - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test @LogMessages(messages = { @LogMessage(messageTemplate = PdfAConformanceLogMessageConstant.EMBEDDED_FILE_SHALL_BE_COMPLIANT_WITH_SPEC, count = 1) diff --git a/pdfa/src/test/java/com/itextpdf/pdfa/PdfA2GraphicsCheckTest.java b/pdfa/src/test/java/com/itextpdf/pdfa/PdfA2GraphicsCheckTest.java index 2a749c3bd7..c9b1aeb52d 100644 --- a/pdfa/src/test/java/com/itextpdf/pdfa/PdfA2GraphicsCheckTest.java +++ b/pdfa/src/test/java/com/itextpdf/pdfa/PdfA2GraphicsCheckTest.java @@ -71,11 +71,11 @@ This file is part of the iText (R) project. import com.itextpdf.kernel.utils.CompareTool; import com.itextpdf.test.ExtendedITextTest; import com.itextpdf.test.annotations.type.IntegrationTest; + +import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; import java.io.ByteArrayOutputStream; import java.io.FileInputStream; @@ -98,35 +98,29 @@ public static void beforeClass() { createOrClearDestinationFolder(destinationFolder); } - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void colorCheckTest1() throws IOException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(PdfAConformanceException.COLOR_SPACE_0_SHALL_HAVE_1_COMPONENTS, PdfName.DefaultCMYK.getValue(), 4)); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfOutputIntent outputIntent = new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is); - PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_2B, outputIntent); - float[] whitePoint = {0.9505f, 1f, 1.089f}; - float[] gamma = {2.2f, 2.2f, 2.2f}; - float[] matrix = {0.4124f, 0.2126f, 0.0193f, 0.3576f, 0.7152f, 0.1192f, 0.1805f, 0.0722f, 0.9505f}; - PdfCieBasedCs.CalRgb calRgb = new PdfCieBasedCs.CalRgb(whitePoint, null, gamma, matrix); + try (PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_2B, outputIntent)) { - PdfCanvas canvas = new PdfCanvas(doc.addNewPage()); + float[] whitePoint = {0.9505f, 1f, 1.089f}; + float[] gamma = {2.2f, 2.2f, 2.2f}; + float[] matrix = {0.4124f, 0.2126f, 0.0193f, 0.3576f, 0.7152f, 0.1192f, 0.1805f, 0.0722f, 0.9505f}; + PdfCieBasedCs.CalRgb calRgb = new PdfCieBasedCs.CalRgb(whitePoint, null, gamma, matrix); - canvas.getResources().setDefaultCmyk(calRgb); + PdfCanvas canvas = new PdfCanvas(doc.addNewPage()); - canvas.setFillColor(new DeviceCmyk(0.1f, 0.1f, 0.1f, 0.1f)); - canvas.moveTo(doc.getDefaultPageSize().getLeft(), doc.getDefaultPageSize().getBottom()); - canvas.lineTo(doc.getDefaultPageSize().getRight(), doc.getDefaultPageSize().getBottom()); - canvas.lineTo(doc.getDefaultPageSize().getRight(), doc.getDefaultPageSize().getTop()); - canvas.fill(); + canvas.getResources().setDefaultCmyk(calRgb); - doc.close(); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> canvas.setFillColor(new DeviceCmyk(0.1f, 0.1f, 0.1f, 0.1f)) + ); + Assert.assertEquals(MessageFormatUtil.format(PdfAConformanceException.COLOR_SPACE_0_SHALL_HAVE_1_COMPONENTS, + PdfName.DefaultCMYK.getValue(), 4), e.getMessage()); + } } @Test @@ -134,37 +128,35 @@ public void colorCheckTest2() throws IOException, InterruptedException { String outPdf = destinationFolder + "pdfA2b_colorCheckTest2.pdf"; String cmpPdf = cmpFolder + "cmp_pdfA2b_colorCheckTest2.pdf"; PdfWriter writer = new PdfWriter(outPdf); - PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_2B, null); - float[] whitePoint = {0.9505f, 1f, 1.089f}; - float[] gamma = {2.2f, 2.2f, 2.2f}; - float[] matrix = {0.4124f, 0.2126f, 0.0193f, 0.3576f, 0.7152f, 0.1192f, 0.1805f, 0.0722f, 0.9505f}; - PdfCieBasedCs.CalRgb calRgb = new PdfCieBasedCs.CalRgb(whitePoint, null, gamma, matrix); + try (PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_2B, null)) { - PdfCieBasedCs.CalGray calGray = new PdfCieBasedCs.CalGray(whitePoint, null, 2.2f); + float[] whitePoint = {0.9505f, 1f, 1.089f}; + float[] gamma = {2.2f, 2.2f, 2.2f}; + float[] matrix = {0.4124f, 0.2126f, 0.0193f, 0.3576f, 0.7152f, 0.1192f, 0.1805f, 0.0722f, 0.9505f}; + PdfCieBasedCs.CalRgb calRgb = new PdfCieBasedCs.CalRgb(whitePoint, null, gamma, matrix); - PdfCanvas canvas = new PdfCanvas(doc.addNewPage()); + PdfCieBasedCs.CalGray calGray = new PdfCieBasedCs.CalGray(whitePoint, null, 2.2f); - canvas.getResources().setDefaultRgb(calRgb); - canvas.getResources().setDefaultGray(calGray); + PdfCanvas canvas = new PdfCanvas(doc.addNewPage()); - String shortText = "text"; + canvas.getResources().setDefaultRgb(calRgb); + canvas.getResources().setDefaultGray(calGray); - PdfFont font = PdfFontFactory.createFont( - sourceFolder + "FreeSans.ttf", EmbeddingStrategy.PREFER_EMBEDDED); - canvas.setFontAndSize(font, 12); - canvas.setFillColor(ColorConstants.RED).beginText().showText(shortText).endText(); - canvas.setFillColor(DeviceGray.GRAY).beginText().showText(shortText).endText(); + String shortText = "text"; + + PdfFont font = PdfFontFactory.createFont( + sourceFolder + "FreeSans.ttf", EmbeddingStrategy.PREFER_EMBEDDED); + canvas.setFontAndSize(font, 12); + canvas.setFillColor(ColorConstants.RED).beginText().showText(shortText).endText(); + canvas.setFillColor(DeviceGray.GRAY).beginText().showText(shortText).endText(); + } - doc.close(); compareResult(outPdf, cmpPdf); } @Test public void colorCheckTest3() throws IOException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.DEVICECMYK_MAY_BE_USED_ONLY_IF_THE_FILE_HAS_A_CMYK_PDFA_OUTPUT_INTENT_OR_DEFAULTCMYK_IN_USAGE_CONTEXT); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfOutputIntent outputIntent = new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is); @@ -178,14 +170,15 @@ public void colorCheckTest3() throws IOException { canvas.lineTo(doc.getDefaultPageSize().getRight(), doc.getDefaultPageSize().getTop()); canvas.fill(); - doc.close(); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> doc.close() + ); + Assert.assertEquals(PdfAConformanceException.DEVICECMYK_MAY_BE_USED_ONLY_IF_THE_FILE_HAS_A_CMYK_PDFA_OUTPUT_INTENT_OR_DEFAULTCMYK_IN_USAGE_CONTEXT, + e.getMessage()); } @Test public void colorCheckTest4() throws IOException, InterruptedException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.DEVICECMYK_MAY_BE_USED_ONLY_IF_THE_FILE_HAS_A_CMYK_PDFA_OUTPUT_INTENT_OR_DEFAULTCMYK_IN_USAGE_CONTEXT); - String outPdf = destinationFolder + "pdfA2b_colorCheckTest4.pdf"; String cmpPdf = cmpFolder + "cmp_pdfA2b_colorCheckTest4.pdf"; PdfWriter writer = new PdfWriter(outPdf); @@ -208,15 +201,13 @@ public void colorCheckTest4() throws IOException, InterruptedException { canvas.lineTo(doc.getDefaultPageSize().getRight(), doc.getDefaultPageSize().getTop()); canvas.fill(); - doc.close(); - compareResult(outPdf, cmpPdf); + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> doc.close()); + Assert.assertEquals(PdfAConformanceException.DEVICECMYK_MAY_BE_USED_ONLY_IF_THE_FILE_HAS_A_CMYK_PDFA_OUTPUT_INTENT_OR_DEFAULTCMYK_IN_USAGE_CONTEXT, + e.getMessage()); } @Test public void colorCheckTest5() throws IOException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.DEVICECMYK_MAY_BE_USED_ONLY_IF_THE_FILE_HAS_A_CMYK_PDFA_OUTPUT_INTENT_OR_DEFAULTCMYK_IN_USAGE_CONTEXT); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfOutputIntent outputIntent = new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is); @@ -238,14 +229,13 @@ public void colorCheckTest5() throws IOException { canvas.setTextRenderingMode(PdfCanvasConstants.TextRenderingMode.FILL); canvas.setFillColor(DeviceGray.GRAY).beginText().showText(shortText).endText(); - doc.close(); + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> doc.close()); + Assert.assertEquals(PdfAConformanceException.DEVICECMYK_MAY_BE_USED_ONLY_IF_THE_FILE_HAS_A_CMYK_PDFA_OUTPUT_INTENT_OR_DEFAULTCMYK_IN_USAGE_CONTEXT, + e.getMessage()); } @Test public void colorCheckTest6() throws IOException, InterruptedException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.DEVICECMYK_MAY_BE_USED_ONLY_IF_THE_FILE_HAS_A_CMYK_PDFA_OUTPUT_INTENT_OR_DEFAULTCMYK_IN_USAGE_CONTEXT); - String outPdf = destinationFolder + "pdfA2b_colorCheckTest6.pdf"; String cmpPdf = cmpFolder + "cmp_pdfA2b_colorCheckTest6.pdf"; PdfWriter writer = new PdfWriter(outPdf); @@ -266,15 +256,13 @@ public void colorCheckTest6() throws IOException, InterruptedException { canvas.setFillColor(DeviceGray.GRAY).beginText().showText(shortText).endText(); - doc.close(); - compareResult(outPdf, cmpPdf); + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> doc.close()); + Assert.assertEquals(PdfAConformanceException.DEVICECMYK_MAY_BE_USED_ONLY_IF_THE_FILE_HAS_A_CMYK_PDFA_OUTPUT_INTENT_OR_DEFAULTCMYK_IN_USAGE_CONTEXT, + e.getMessage()); } @Test public void colorCheckTest7() throws IOException, InterruptedException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.DEVICECMYK_MAY_BE_USED_ONLY_IF_THE_FILE_HAS_A_CMYK_PDFA_OUTPUT_INTENT_OR_DEFAULTCMYK_IN_USAGE_CONTEXT); - String outPdf = destinationFolder + "pdfA2b_colorCheckTest7.pdf"; String cmpPdf = cmpFolder + "cmp_pdfA2b_colorCheckTest7.pdf"; PdfWriter writer = new PdfWriter(outPdf); @@ -298,15 +286,13 @@ public void colorCheckTest7() throws IOException, InterruptedException { canvas.setTextRenderingMode(PdfCanvasConstants.TextRenderingMode.INVISIBLE); canvas.setFillColor(new DeviceCmyk(0.1f, 0.1f, 0.1f, 0.1f)).beginText().showText(shortText).endText(); - doc.close(); - compareResult(outPdf, cmpPdf); + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> doc.close()); + Assert.assertEquals(PdfAConformanceException.DEVICECMYK_MAY_BE_USED_ONLY_IF_THE_FILE_HAS_A_CMYK_PDFA_OUTPUT_INTENT_OR_DEFAULTCMYK_IN_USAGE_CONTEXT, + e.getMessage()); } @Test public void egsCheckTest1() throws IOException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.AN_EXTGSTATE_DICTIONARY_SHALL_NOT_CONTAIN_THE_HTP_KEY); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfOutputIntent outputIntent = new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is); @@ -315,7 +301,10 @@ public void egsCheckTest1() throws IOException { doc.addNewPage(); PdfCanvas canvas = new PdfCanvas(doc.getLastPage()); - canvas.setExtGState(new PdfExtGState().put(PdfName.HTP, new PdfName("Test"))); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> canvas.setExtGState(new PdfExtGState().put(PdfName.HTP, new PdfName("Test"))) + ); + Assert.assertEquals(PdfAConformanceException.AN_EXTGSTATE_DICTIONARY_SHALL_NOT_CONTAIN_THE_HTP_KEY, e.getMessage()); canvas.rectangle(30, 30, 100, 100).fill(); doc.close(); @@ -323,34 +312,28 @@ public void egsCheckTest1() throws IOException { @Test public void egsCheckTest2() throws IOException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.HALFTONES_SHALL_NOT_CONTAIN_HALFTONENAME); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfOutputIntent outputIntent = new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is); - PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_2B, outputIntent); - doc.addNewPage(); - PdfCanvas canvas = new PdfCanvas(doc.getLastPage()); + try (PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_2B, outputIntent)) { - PdfDictionary dict = new PdfDictionary(); - dict.put(PdfName.HalftoneType, new PdfNumber(5)); - dict.put(PdfName.HalftoneName, new PdfName("Test")); + doc.addNewPage(); + PdfCanvas canvas = new PdfCanvas(doc.getLastPage()); + PdfDictionary dict = new PdfDictionary(); + dict.put(PdfName.HalftoneType, new PdfNumber(5)); + dict.put(PdfName.HalftoneName, new PdfName("Test")); - - canvas.setExtGState(new PdfExtGState().setHalftone(dict)); - canvas.rectangle(30, 30, 100, 100).fill(); - - doc.close(); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> canvas.setExtGState(new PdfExtGState().setHalftone(dict)) + ); + Assert.assertEquals(PdfAConformanceException.HALFTONES_SHALL_NOT_CONTAIN_HALFTONENAME, e.getMessage()); + } } @Test public void imageCheckTest1() throws FileNotFoundException, MalformedURLException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.ONLY_JPX_BASELINE_SET_OF_FEATURES_SHALL_BE_USED); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfOutputIntent outputIntent = new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is); @@ -361,14 +344,12 @@ public void imageCheckTest1() throws FileNotFoundException, MalformedURLExceptio canvas.addImage(ImageDataFactory.create(sourceFolder + "jpeg2000/p0_01.j2k"), 300, 300, false); - doc.close(); + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> doc.close()); + Assert.assertEquals(PdfAConformanceException.ONLY_JPX_BASELINE_SET_OF_FEATURES_SHALL_BE_USED, e.getMessage()); } @Test public void imageCheckTest2() throws FileNotFoundException, MalformedURLException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.EXACTLY_ONE_COLOUR_SPACE_SPECIFICATION_SHALL_HAVE_THE_VALUE_0X01_IN_THE_APPROX_FIELD); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfOutputIntent outputIntent = new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is); @@ -379,13 +360,13 @@ public void imageCheckTest2() throws FileNotFoundException, MalformedURLExceptio canvas.addImage(ImageDataFactory.create(sourceFolder + "jpeg2000/file5.jp2"), 300, 300, false); - doc.close(); + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> doc.close()); + Assert.assertEquals(PdfAConformanceException.EXACTLY_ONE_COLOUR_SPACE_SPECIFICATION_SHALL_HAVE_THE_VALUE_0X01_IN_THE_APPROX_FIELD, + e.getMessage()); } + @Test public void imageCheckTest3() throws FileNotFoundException, MalformedURLException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.EXACTLY_ONE_COLOUR_SPACE_SPECIFICATION_SHALL_HAVE_THE_VALUE_0X01_IN_THE_APPROX_FIELD); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfOutputIntent outputIntent = new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is); @@ -396,8 +377,9 @@ public void imageCheckTest3() throws FileNotFoundException, MalformedURLExceptio canvas.addImage(ImageDataFactory.create(sourceFolder + "jpeg2000/file7.jp2"), 300, 300, false); - - doc.close(); + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> doc.close()); + Assert.assertEquals(PdfAConformanceException.EXACTLY_ONE_COLOUR_SPACE_SPECIFICATION_SHALL_HAVE_THE_VALUE_0X01_IN_THE_APPROX_FIELD, + e.getMessage()); } @@ -436,9 +418,6 @@ public void imageCheckTest4() throws IOException, InterruptedException { @Test public void transparencyCheckTest1() { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.THE_DOCUMENT_DOES_NOT_CONTAIN_A_PDFA_OUTPUTINTENT_BUT_PAGE_CONTAINS_TRANSPARENCY_AND_DOES_NOT_CONTAIN_BLENDING_COLOR_SPACE); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_2B, null); @@ -456,7 +435,9 @@ public void transparencyCheckTest1() { canvas.fill(); canvas.restoreState(); - doc.close(); + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> doc.close()); + Assert.assertEquals(PdfAConformanceException.THE_DOCUMENT_DOES_NOT_CONTAIN_A_PDFA_OUTPUTINTENT_BUT_PAGE_CONTAINS_TRANSPARENCY_AND_DOES_NOT_CONTAIN_BLENDING_COLOR_SPACE, + e.getMessage()); } @Test @@ -488,29 +469,29 @@ public void transparencyCheckTest2() throws IOException, InterruptedException { @Test public void transparencyCheckTest3() throws FileNotFoundException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.ONLY_STANDARD_BLEND_MODES_SHALL_BE_USED_FOR_THE_VALUE_OF_THE_BM_KEY_IN_AN_EXTENDED_GRAPHIC_STATE_DICTIONARY); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfOutputIntent outputIntent = new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is); - PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_2B, outputIntent); - PdfCanvas canvas = new PdfCanvas(doc.addNewPage()); + try (PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_2B, outputIntent)) { - canvas.saveState(); - canvas.setExtGState(new PdfExtGState().setBlendMode(PdfName.Darken)); - canvas.rectangle(100, 100, 100, 100); - canvas.fill(); - canvas.restoreState(); + PdfCanvas canvas = new PdfCanvas(doc.addNewPage()); - canvas.saveState(); - canvas.setExtGState(new PdfExtGState().setBlendMode(new PdfName("UnknownBlendMode"))); - canvas.rectangle(200, 200, 100, 100); - canvas.fill(); - canvas.restoreState(); + canvas.saveState(); + canvas.setExtGState(new PdfExtGState().setBlendMode(PdfName.Darken)); + canvas.rectangle(100, 100, 100, 100); + canvas.fill(); + canvas.restoreState(); + + canvas.saveState(); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> canvas.setExtGState(new PdfExtGState().setBlendMode(new PdfName("UnknownBlendMode"))) + ); + Assert.assertEquals( + PdfAConformanceException.ONLY_STANDARD_BLEND_MODES_SHALL_BE_USED_FOR_THE_VALUE_OF_THE_BM_KEY_IN_AN_EXTENDED_GRAPHIC_STATE_DICTIONARY, + e.getMessage()); + } - doc.close(); } @Test diff --git a/pdfa/src/test/java/com/itextpdf/pdfa/PdfA2PageCheckTest.java b/pdfa/src/test/java/com/itextpdf/pdfa/PdfA2PageCheckTest.java index 53242bdb51..c62b4fb0dc 100644 --- a/pdfa/src/test/java/com/itextpdf/pdfa/PdfA2PageCheckTest.java +++ b/pdfa/src/test/java/com/itextpdf/pdfa/PdfA2PageCheckTest.java @@ -51,10 +51,10 @@ This file is part of the iText (R) project. import com.itextpdf.kernel.pdf.PdfWriter; import com.itextpdf.test.ExtendedITextTest; import com.itextpdf.test.annotations.type.IntegrationTest; -import org.junit.Rule; + +import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; import java.io.FileInputStream; import java.io.FileNotFoundException; @@ -64,21 +64,15 @@ This file is part of the iText (R) project. public class PdfA2PageCheckTest extends ExtendedITextTest { public static final String sourceFolder = "./src/test/resources/com/itextpdf/pdfa/"; - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void catalogCheck01() throws FileNotFoundException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.THE_PAGE_DICTIONARY_SHALL_NOT_CONTAIN_PRESSTEPS_ENTRY); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_2B, new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is)); PdfPage page = doc.addNewPage(); page.getPdfObject().put(PdfName.PresSteps, new PdfDictionary()); - doc.close(); + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> doc.close()); + Assert.assertEquals(PdfAConformanceException.THE_PAGE_DICTIONARY_SHALL_NOT_CONTAIN_PRESSTEPS_ENTRY, e.getMessage()); } - } diff --git a/pdfa/src/test/java/com/itextpdf/pdfa/PdfA3CatalogCheckTest.java b/pdfa/src/test/java/com/itextpdf/pdfa/PdfA3CatalogCheckTest.java index 1efd781f68..599472c8b6 100644 --- a/pdfa/src/test/java/com/itextpdf/pdfa/PdfA3CatalogCheckTest.java +++ b/pdfa/src/test/java/com/itextpdf/pdfa/PdfA3CatalogCheckTest.java @@ -42,7 +42,6 @@ This file is part of the iText (R) project. */ package com.itextpdf.pdfa; -import com.itextpdf.io.source.ByteArrayOutputStream; import com.itextpdf.kernel.pdf.PdfAConformanceLevel; import com.itextpdf.kernel.pdf.PdfArray; import com.itextpdf.kernel.pdf.PdfDictionary; @@ -56,15 +55,12 @@ This file is part of the iText (R) project. import com.itextpdf.test.pdfa.VeraPdfValidator; import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(IntegrationTest.class) public class PdfA3CatalogCheckTest extends ExtendedITextTest { @@ -72,9 +68,6 @@ public class PdfA3CatalogCheckTest extends ExtendedITextTest { public static final String cmpFolder = sourceFolder + "cmp/PdfA3CatalogCheckTest/"; public static final String destinationFolder = "./target/test/com/itextpdf/pdfa/PdfA3CatalogCheckTest/"; - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @BeforeClass public static void beforeClass() { createOrClearDestinationFolder(destinationFolder); diff --git a/pdfa/src/test/java/com/itextpdf/pdfa/PdfA3EmbeddedFilesCheckTest.java b/pdfa/src/test/java/com/itextpdf/pdfa/PdfA3EmbeddedFilesCheckTest.java index c7d8f9d218..278f6254c0 100644 --- a/pdfa/src/test/java/com/itextpdf/pdfa/PdfA3EmbeddedFilesCheckTest.java +++ b/pdfa/src/test/java/com/itextpdf/pdfa/PdfA3EmbeddedFilesCheckTest.java @@ -55,11 +55,10 @@ This file is part of the iText (R) project. import com.itextpdf.kernel.utils.CompareTool; import com.itextpdf.test.ExtendedITextTest; import com.itextpdf.test.annotations.type.IntegrationTest; + import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; import java.io.ByteArrayOutputStream; import java.io.FileInputStream; @@ -80,9 +79,6 @@ public static void beforeClass() { createOrClearDestinationFolder(destinationFolder); } - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void fileSpecCheckTest01() throws IOException, InterruptedException { String outPdf = destinationFolder + "pdfA3b_fileSpecCheckTest01.pdf"; diff --git a/pdfa/src/test/java/com/itextpdf/pdfa/PdfAFontTest.java b/pdfa/src/test/java/com/itextpdf/pdfa/PdfAFontTest.java index c04ca3f226..6fc7e6a93a 100644 --- a/pdfa/src/test/java/com/itextpdf/pdfa/PdfAFontTest.java +++ b/pdfa/src/test/java/com/itextpdf/pdfa/PdfAFontTest.java @@ -57,11 +57,11 @@ This file is part of the iText (R) project. import com.itextpdf.kernel.utils.CompareTool; import com.itextpdf.test.ExtendedITextTest; import com.itextpdf.test.annotations.type.IntegrationTest; + +import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; import java.io.ByteArrayOutputStream; import java.io.FileInputStream; @@ -81,9 +81,6 @@ public static void beforeClass() { createOrClearDestinationFolder(outputDir); } - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void fontCheckPdfA1_01() throws IOException, InterruptedException { String outPdf = outputDir + "pdfA1b_fontCheckPdfA1_01.pdf"; @@ -109,9 +106,6 @@ public void fontCheckPdfA1_01() throws IOException, InterruptedException { @Test public void fontCheckPdfA1_02() throws IOException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(PdfAConformanceException.ALL_THE_FONTS_MUST_BE_EMBEDDED_THIS_ONE_IS_NOT_0, "FreeSans")); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfDocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_1B, new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is)); @@ -126,7 +120,10 @@ public void fontCheckPdfA1_02() throws IOException { .showText("Hello World! Pdf/A-1B") .endText() .restoreState(); - doc.close(); + + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> doc.close()); + Assert.assertEquals(MessageFormatUtil.format(PdfAConformanceException.ALL_THE_FONTS_MUST_BE_EMBEDDED_THIS_ONE_IS_NOT_0, "FreeSans"), + e.getMessage()); } @Test @@ -155,9 +152,6 @@ public void fontCheckPdfA1_03() throws IOException, InterruptedException { @Test public void fontCheckPdfA1_04() throws IOException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(PdfAConformanceException.ALL_THE_FONTS_MUST_BE_EMBEDDED_THIS_ONE_IS_NOT_0, "Helvetica")); - PdfWriter writer = new PdfWriter(new ByteArrayOutputStream()); InputStream is = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); PdfDocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_1B, new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is)); @@ -173,7 +167,10 @@ public void fontCheckPdfA1_04() throws IOException { .showText("Hello World! Pdf/A-1B") .endText() .restoreState(); - doc.close(); + + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> doc.close()); + Assert.assertEquals(MessageFormatUtil.format(PdfAConformanceException.ALL_THE_FONTS_MUST_BE_EMBEDDED_THIS_ONE_IS_NOT_0, "Helvetica"), + e.getMessage()); } @Test @@ -342,10 +339,12 @@ public void symbolicTtfCharEncodingsPdfA1Test02() throws IOException, Interrupte @Test public void symbolicTtfCharEncodingsPdfA1Test03() throws IOException, InterruptedException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.ALL_NON_SYMBOLIC_TRUE_TYPE_FONT_SHALL_SPECIFY_MAC_ROMAN_OR_WIN_ANSI_ENCODING_AS_THE_ENCODING_ENTRY); // if you specify encoding, symbolic font is treated as non-symbolic - createDocumentWithFont("symbolicTtfCharEncodingsPdfA1Test03.pdf", "Symbols1.ttf", "ISO-8859-1", PdfAConformanceLevel.PDF_A_1B); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> createDocumentWithFont("symbolicTtfCharEncodingsPdfA1Test03.pdf", "Symbols1.ttf", "ISO-8859-1", PdfAConformanceLevel.PDF_A_1B) + ); + Assert.assertEquals(PdfAConformanceException.ALL_NON_SYMBOLIC_TRUE_TYPE_FONT_SHALL_SPECIFY_MAC_ROMAN_OR_WIN_ANSI_ENCODING_AS_THE_ENCODING_ENTRY, + e.getMessage()); } @Test @@ -357,10 +356,12 @@ public void nonSymbolicTtfCharEncodingsPdfA1Test01() throws IOException, Interru @Test public void nonSymbolicTtfCharEncodingsPdfA1Test02() throws IOException, InterruptedException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.ALL_NON_SYMBOLIC_TRUE_TYPE_FONT_SHALL_SPECIFY_MAC_ROMAN_ENCODING_OR_WIN_ANSI_ENCODING); // encoding must be either winansi or macroman, by default winansi is used - createDocumentWithFont("nonSymbolicTtfCharEncodingsPdfA1Test02.pdf", "FreeSans.ttf", "ISO-8859-1", PdfAConformanceLevel.PDF_A_2B); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> createDocumentWithFont("nonSymbolicTtfCharEncodingsPdfA1Test02.pdf", "FreeSans.ttf", "ISO-8859-1", PdfAConformanceLevel.PDF_A_2B) + ); + Assert.assertEquals(PdfAConformanceException.ALL_NON_SYMBOLIC_TRUE_TYPE_FONT_SHALL_SPECIFY_MAC_ROMAN_ENCODING_OR_WIN_ANSI_ENCODING, + e.getMessage()); } private void createDocumentWithFont(String outFileName, String fontFileName, String encoding, PdfAConformanceLevel conformanceLevel) throws IOException, InterruptedException { diff --git a/pdfa/src/test/java/com/itextpdf/pdfa/PdfAFormFieldTest.java b/pdfa/src/test/java/com/itextpdf/pdfa/PdfAFormFieldTest.java index 98952001c0..23c7576b49 100644 --- a/pdfa/src/test/java/com/itextpdf/pdfa/PdfAFormFieldTest.java +++ b/pdfa/src/test/java/com/itextpdf/pdfa/PdfAFormFieldTest.java @@ -70,6 +70,7 @@ This file is part of the iText (R) project. import com.itextpdf.layout.element.Paragraph; import com.itextpdf.layout.element.Text; import com.itextpdf.layout.renderer.DrawContext; +import com.itextpdf.layout.renderer.IRenderer; import com.itextpdf.layout.renderer.ParagraphRenderer; import com.itextpdf.test.ExtendedITextTest; import com.itextpdf.test.annotations.LogMessage; @@ -195,6 +196,11 @@ public void draw(DrawContext context) { //appearance stream was set, while AS has kept as is, i.e. in Off state. chk.setAppearance(PdfName.N, "v1".equals(_value) ? _value : "Off", appearance.getPdfObject()); } + + @Override + public IRenderer getNextRenderer() { + return new PdfAButtonFieldTestRenderer((Paragraph) modelElement, _group, _value); + } } @Test diff --git a/pdfa/src/test/java/com/itextpdf/pdfa/PdfAIndirectObjectsCountLimitTest.java b/pdfa/src/test/java/com/itextpdf/pdfa/PdfAIndirectObjectsCountLimitTest.java index cef4344a8a..3f37dada25 100644 --- a/pdfa/src/test/java/com/itextpdf/pdfa/PdfAIndirectObjectsCountLimitTest.java +++ b/pdfa/src/test/java/com/itextpdf/pdfa/PdfAIndirectObjectsCountLimitTest.java @@ -62,18 +62,14 @@ This file is part of the iText (R) project. import java.io.InputStream; import java.io.OutputStream; import java.util.UUID; -import org.junit.Rule; +import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(IntegrationTest.class) public class PdfAIndirectObjectsCountLimitTest extends ExtendedITextTest { public static final String sourceFolder = "./src/test/resources/com/itextpdf/pdfa/"; - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void validAmountOfIndirectObjectsTest() throws IOException { PdfA1Checker testChecker = new PdfA1Checker(PdfAConformanceLevel.PDF_A_1B) { @@ -101,10 +97,6 @@ protected long getMaxNumberOfIndirectObjects() { @Test public void invalidAmountOfIndirectObjectsTest() throws IOException { - - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.MAXIMUM_NUMBER_OF_INDIRECT_OBJECTS_EXCEEDED); - PdfA1Checker testChecker = new PdfA1Checker(PdfAConformanceLevel.PDF_A_1B) { @Override protected long getMaxNumberOfIndirectObjects() { @@ -115,10 +107,10 @@ protected long getMaxNumberOfIndirectObjects() { try ( InputStream icm = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); OutputStream fos = new ByteArrayOutputStream(); - Document document = new Document(new PdfADocument(new PdfWriter(fos), - PdfAConformanceLevel.PDF_A_1B, - getOutputIntent(icm))); ) { + Document document = new Document(new PdfADocument(new PdfWriter(fos), + PdfAConformanceLevel.PDF_A_1B, + getOutputIntent(icm))); PdfADocument pdfa = (PdfADocument) document.getPdfDocument(); pdfa.checker = testChecker; document.add(buildContent()); @@ -126,15 +118,13 @@ protected long getMaxNumberOfIndirectObjects() { // generated document contains exactly 10 indirect objects. Given 9 is the allowed // limit per "mock specification" conformance exception should be thrown as the limit // is exceeded + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> document.close()); + Assert.assertEquals(PdfAConformanceException.MAXIMUM_NUMBER_OF_INDIRECT_OBJECTS_EXCEEDED, e.getMessage()); } } @Test public void invalidAmountOfIndirectObjectsAppendModeTest() throws IOException { - - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.MAXIMUM_NUMBER_OF_INDIRECT_OBJECTS_EXCEEDED); - PdfA1Checker testChecker = new PdfA1Checker(PdfAConformanceLevel.PDF_A_1B) { @Override protected long getMaxNumberOfIndirectObjects() { @@ -145,13 +135,15 @@ protected long getMaxNumberOfIndirectObjects() { try ( InputStream fis = new FileInputStream(sourceFolder + "pdfs/pdfa10IndirectObjects.pdf"); OutputStream fos = new ByteArrayOutputStream(); - PdfADocument pdfa = new PdfADocument(new PdfReader(fis), new PdfWriter(fos), new StampingProperties().useAppendMode()) - ) { + PdfADocument pdfa = new PdfADocument(new PdfReader(fis), new PdfWriter(fos), new StampingProperties().useAppendMode()); pdfa.checker = testChecker; pdfa.addNewPage(); + // during closing of pdfa object exception will be thrown as new document will contain // 12 indirect objects and limit per "mock specification" conformance will be exceeded + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> pdfa.close()); + Assert.assertEquals(PdfAConformanceException.MAXIMUM_NUMBER_OF_INDIRECT_OBJECTS_EXCEEDED, e.getMessage()); } } diff --git a/pdfa/src/test/java/com/itextpdf/pdfa/PdfALongStringTest.java b/pdfa/src/test/java/com/itextpdf/pdfa/PdfALongStringTest.java index b70a4ecbdd..ce1314c2e2 100644 --- a/pdfa/src/test/java/com/itextpdf/pdfa/PdfALongStringTest.java +++ b/pdfa/src/test/java/com/itextpdf/pdfa/PdfALongStringTest.java @@ -56,11 +56,11 @@ This file is part of the iText (R) project. import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; +import java.io.OutputStream; +import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(IntegrationTest.class) public class PdfALongStringTest extends ExtendedITextTest { @@ -69,9 +69,6 @@ public class PdfALongStringTest extends ExtendedITextTest { private static final String LOREM_IPSUM = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis condimentum, tortor sit amet fermentum pharetra, sem felis finibus enim, vel consectetur nunc justo at nisi. In hac habitasse platea dictumst. Donec quis suscipit eros. Nam urna purus, scelerisque in placerat in, convallis vel sapien. Suspendisse sed lacus sit amet orci ornare vulputate. In hac habitasse platea dictumst. Ut eu aliquet felis, at consectetur neque."; private static final int STRING_LENGTH_LIMIT = 32767; - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @BeforeClass public static void beforeClass() { createDestinationFolder(destinationFolder); @@ -79,22 +76,18 @@ public static void beforeClass() { @Test public void runTest() throws Exception { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.PDF_STRING_IS_TOO_LONG); String file = "pdfALongString.pdf"; String filename = destinationFolder + file; try (InputStream icm = new FileInputStream(sourceFolder + "sRGB Color Space Profile.icm"); - Document document = new Document( - new PdfADocument(new PdfWriter(new FileOutputStream(filename)), - PdfAConformanceLevel.PDF_A_3U, - new PdfOutputIntent("Custom", "", - "http://www.color.org", "sRGB ICC preference", icm)) - )) { + FileOutputStream fos = new FileOutputStream(filename)) { + Document document = new Document(new PdfADocument(new PdfWriter(fos), PdfAConformanceLevel.PDF_A_3U, + new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB ICC preference", icm)) + ); StringBuilder stringBuilder = new StringBuilder(LOREM_IPSUM); while (stringBuilder.length() < STRING_LENGTH_LIMIT) { stringBuilder.append(stringBuilder.toString()); } - PdfFontFactory.register(sourceFolder + "FreeSans.ttf",sourceFolder + "FreeSans.ttf"); + PdfFontFactory.register(sourceFolder + "FreeSans.ttf", sourceFolder + "FreeSans.ttf"); PdfFont font = PdfFontFactory.createFont( sourceFolder + "FreeSans.ttf", EmbeddingStrategy.PREFER_EMBEDDED); Paragraph p = new Paragraph(stringBuilder.toString()); @@ -102,9 +95,11 @@ public void runTest() throws Exception { p.setFont(font); document.add(p); - // when document is auto-closing, ISO conformance check is performed + // when document is closing, ISO conformance check is performed // this document contain a string which is longer than it is allowed // per specification. That is why conformance exception should be thrown + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> document.close()); + Assert.assertEquals(PdfAConformanceException.PDF_STRING_IS_TOO_LONG, e.getMessage()); } } } diff --git a/pdfa/src/test/java/com/itextpdf/pdfa/PdfATransparencyCheckTest.java b/pdfa/src/test/java/com/itextpdf/pdfa/PdfATransparencyCheckTest.java index 71eec46a28..d071636efb 100644 --- a/pdfa/src/test/java/com/itextpdf/pdfa/PdfATransparencyCheckTest.java +++ b/pdfa/src/test/java/com/itextpdf/pdfa/PdfATransparencyCheckTest.java @@ -63,11 +63,11 @@ This file is part of the iText (R) project. import com.itextpdf.kernel.utils.CompareTool; import com.itextpdf.test.ExtendedITextTest; import com.itextpdf.test.annotations.type.IntegrationTest; + +import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; import java.io.IOException; @@ -84,14 +84,8 @@ public static void beforeClass() { createOrClearDestinationFolder(destinationFolder); } - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void textTransparencyNoOutputIntentTest() throws IOException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(PdfAConformanceException.THE_DOCUMENT_DOES_NOT_CONTAIN_A_PDFA_OUTPUTINTENT_BUT_PAGE_CONTAINS_TRANSPARENCY_AND_DOES_NOT_CONTAIN_BLENDING_COLOR_SPACE)); - PdfWriter writer = new PdfWriter(new java.io.ByteArrayOutputStream()); PdfDocument pdfDocument = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_3B, null); @@ -123,7 +117,9 @@ public void textTransparencyNoOutputIntentTest() throws IOException { .endText() .restoreState(); - pdfDocument.close(); + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> pdfDocument.close()); + Assert.assertEquals(MessageFormatUtil.format(PdfAConformanceException.THE_DOCUMENT_DOES_NOT_CONTAIN_A_PDFA_OUTPUTINTENT_BUT_PAGE_CONTAINS_TRANSPARENCY_AND_DOES_NOT_CONTAIN_BLENDING_COLOR_SPACE), + e.getMessage()); } @Test @@ -171,9 +167,6 @@ public void transparentTextWithGroupColorSpaceTest() throws IOException, Interru @Test public void imageTransparencyTest() throws IOException { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(PdfAConformanceException.THE_DOCUMENT_DOES_NOT_CONTAIN_A_PDFA_OUTPUTINTENT_BUT_PAGE_CONTAINS_TRANSPARENCY_AND_DOES_NOT_CONTAIN_BLENDING_COLOR_SPACE)); - PdfDocument pdfDoc = new PdfADocument(new PdfWriter(new java.io.ByteArrayOutputStream()), PdfAConformanceLevel.PDF_A_3B, null); PdfPage page = pdfDoc.addNewPage(); @@ -184,14 +177,14 @@ public void imageTransparencyTest() throws IOException { canvas.saveState(); canvas.addImage(ImageDataFactory.create(sourceFolder + "itext.png"), 0, 0, page.getPageSize().getWidth() / 2, false); canvas.restoreState(); - pdfDoc.close(); + + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> pdfDoc.close()); + Assert.assertEquals(MessageFormatUtil.format(PdfAConformanceException.THE_DOCUMENT_DOES_NOT_CONTAIN_A_PDFA_OUTPUTINTENT_BUT_PAGE_CONTAINS_TRANSPARENCY_AND_DOES_NOT_CONTAIN_BLENDING_COLOR_SPACE), + e.getMessage()); } @Test public void nestedXObjectWithTransparencyTest() { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(PdfAConformanceException.THE_DOCUMENT_DOES_NOT_CONTAIN_A_PDFA_OUTPUTINTENT_BUT_PAGE_CONTAINS_TRANSPARENCY_AND_DOES_NOT_CONTAIN_BLENDING_COLOR_SPACE)); - PdfWriter writer = new PdfWriter(new java.io.ByteArrayOutputStream()); PdfDocument pdfDocument = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_3B, null); PdfFormXObject form1 = new PdfFormXObject(new Rectangle(0, 0, 50, 50)); @@ -221,7 +214,9 @@ public void nestedXObjectWithTransparencyTest() { canvas.addXObject(form, 0, 0); canvas.release(); - pdfDocument.close(); + Exception e = Assert.assertThrows(PdfAConformanceException.class, () -> pdfDocument.close()); + Assert.assertEquals(MessageFormatUtil.format(PdfAConformanceException.THE_DOCUMENT_DOES_NOT_CONTAIN_A_PDFA_OUTPUTINTENT_BUT_PAGE_CONTAINS_TRANSPARENCY_AND_DOES_NOT_CONTAIN_BLENDING_COLOR_SPACE), + e.getMessage()); } @Test diff --git a/pdfa/src/test/java/com/itextpdf/pdfa/checker/PdfA1CheckerTest.java b/pdfa/src/test/java/com/itextpdf/pdfa/checker/PdfA1CheckerTest.java index 5fe33cd93e..13ccbdd27a 100644 --- a/pdfa/src/test/java/com/itextpdf/pdfa/checker/PdfA1CheckerTest.java +++ b/pdfa/src/test/java/com/itextpdf/pdfa/checker/PdfA1CheckerTest.java @@ -42,32 +42,17 @@ This file is part of the iText (R) project. */ package com.itextpdf.pdfa.checker; -import com.itextpdf.kernel.colors.Color; -import com.itextpdf.kernel.colors.PatternColor; -import com.itextpdf.kernel.font.PdfFont; -import com.itextpdf.kernel.font.PdfFontFactory; import com.itextpdf.kernel.pdf.PdfAConformanceLevel; -import com.itextpdf.kernel.pdf.PdfArray; import com.itextpdf.kernel.pdf.PdfDictionary; import com.itextpdf.kernel.pdf.PdfName; -import com.itextpdf.kernel.pdf.PdfStream; -import com.itextpdf.kernel.pdf.PdfString; -import com.itextpdf.kernel.pdf.colorspace.PdfPattern; -import com.itextpdf.kernel.pdf.colorspace.PdfPattern.Shading; -import com.itextpdf.kernel.pdf.colorspace.PdfPattern.Tiling; -import com.itextpdf.kernel.pdf.xobject.PdfFormXObject; -import com.itextpdf.kernel.pdf.xobject.PdfXObject; import com.itextpdf.pdfa.PdfAConformanceException; import com.itextpdf.test.ExtendedITextTest; import com.itextpdf.test.annotations.type.UnitTest; -import java.nio.charset.StandardCharsets; import org.junit.Assert; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(UnitTest.class) public class PdfA1CheckerTest extends ExtendedITextTest { @@ -79,42 +64,40 @@ public void before() { pdfA1Checker.setFullCheckMode(true); } - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); @Test public void checkCatalogDictionaryWithoutAAEntry() { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.A_CATALOG_DICTIONARY_SHALL_NOT_CONTAIN_AA_ENTRY); - PdfDictionary catalog = new PdfDictionary(); catalog.put(PdfName.AA, new PdfDictionary()); - pdfA1Checker.checkCatalogValidEntries(catalog); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> pdfA1Checker.checkCatalogValidEntries(catalog) + ); + Assert.assertEquals(PdfAConformanceException.A_CATALOG_DICTIONARY_SHALL_NOT_CONTAIN_AA_ENTRY, e.getMessage()); } @Test public void checkCatalogDictionaryWithoutOCPropertiesEntry() { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.A_CATALOG_DICTIONARY_SHALL_NOT_CONTAIN_OCPROPERTIES_KEY); - PdfDictionary catalog = new PdfDictionary(); catalog.put(PdfName.OCProperties, new PdfDictionary()); - pdfA1Checker.checkCatalogValidEntries(catalog); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> pdfA1Checker.checkCatalogValidEntries(catalog) + ); + Assert.assertEquals(PdfAConformanceException.A_CATALOG_DICTIONARY_SHALL_NOT_CONTAIN_OCPROPERTIES_KEY, e.getMessage()); } @Test public void checkCatalogDictionaryWithoutEmbeddedFiles() { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.A_NAME_DICTIONARY_SHALL_NOT_CONTAIN_THE_EMBEDDED_FILES_KEY); - PdfDictionary names = new PdfDictionary(); names.put(PdfName.EmbeddedFiles, new PdfDictionary()); PdfDictionary catalog = new PdfDictionary(); catalog.put(PdfName.Names, names); - pdfA1Checker.checkCatalogValidEntries(catalog); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> pdfA1Checker.checkCatalogValidEntries(catalog) + ); + Assert.assertEquals(PdfAConformanceException.A_NAME_DICTIONARY_SHALL_NOT_CONTAIN_THE_EMBEDDED_FILES_KEY, e.getMessage()); } @Test diff --git a/pdfa/src/test/java/com/itextpdf/pdfa/checker/PdfA1ImplementationLimitsCheckerTest.java b/pdfa/src/test/java/com/itextpdf/pdfa/checker/PdfA1ImplementationLimitsCheckerTest.java index eb349cdffa..57529a2ffa 100644 --- a/pdfa/src/test/java/com/itextpdf/pdfa/checker/PdfA1ImplementationLimitsCheckerTest.java +++ b/pdfa/src/test/java/com/itextpdf/pdfa/checker/PdfA1ImplementationLimitsCheckerTest.java @@ -71,10 +71,8 @@ This file is part of the iText (R) project. import java.util.List; import org.junit.Assert; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(UnitTest.class) public class PdfA1ImplementationLimitsCheckerTest extends ExtendedITextTest { @@ -87,9 +85,6 @@ public void before() { pdfA1Checker.setFullCheckMode(true); } - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void validObjectsTest() { final int maxNameLength = pdfA1Checker.getMaxNameLength(); @@ -145,55 +140,54 @@ public void validStreamTest() { @Test public void independentLongStringTest() { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.PDF_STRING_IS_TOO_LONG); - PdfString longString = buildLongString(); // An exception should be thrown as provided String is longer then // it is allowed per specification - pdfA1Checker.checkPdfObject(longString); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> pdfA1Checker.checkPdfObject(longString) + ); + Assert.assertEquals(PdfAConformanceException.PDF_STRING_IS_TOO_LONG, e.getMessage()); } @Test public void independentLongNameTest() { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.PDF_NAME_IS_TOO_LONG); - PdfName longName = buildLongName(); // An exception should be thrown as provided name is longer then // it is allowed per specification - pdfA1Checker.checkPdfObject(longName); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> pdfA1Checker.checkPdfObject(longName) + ); + Assert.assertEquals(PdfAConformanceException.PDF_NAME_IS_TOO_LONG, e.getMessage()); } @Test public void independentLargeIntegerTest() { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.INTEGER_NUMBER_IS_OUT_OF_RANGE); - PdfNumber largeNumber = new PdfNumber(pdfA1Checker.getMaxIntegerValue() + 1L); // An exception should be thrown as provided integer is larger then // it is allowed per specification - pdfA1Checker.checkPdfObject(largeNumber); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> pdfA1Checker.checkPdfObject(largeNumber) + ); + Assert.assertEquals(PdfAConformanceException.INTEGER_NUMBER_IS_OUT_OF_RANGE, e.getMessage()); } @Test public void independentLargeNegativeIntegerTest() { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.INTEGER_NUMBER_IS_OUT_OF_RANGE); - PdfNumber largeNumber = new PdfNumber(pdfA1Checker.getMinIntegerValue() - 1L); // An exception should be thrown as provided integer is smaller then // it is allowed per specification - pdfA1Checker.checkPdfObject(largeNumber); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> pdfA1Checker.checkPdfObject(largeNumber) + ); + Assert.assertEquals(PdfAConformanceException.INTEGER_NUMBER_IS_OUT_OF_RANGE, e.getMessage()); } @Test public void independentLargeRealTest() { - PdfNumber largeNumber = new PdfNumber(pdfA1Checker.getMaxRealValue() + 1.0); // TODO DEVSIX-4182 @@ -203,57 +197,54 @@ public void independentLargeRealTest() { @Test public void independentLongArrayTest() { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.MAXIMUM_ARRAY_CAPACITY_IS_EXCEEDED); - PdfArray longArray = buildLongArray(); // An exception should be thrown as provided array has more elements then // it is allowed per specification - pdfA1Checker.checkPdfObject(longArray); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> pdfA1Checker.checkPdfObject(longArray) + ); + Assert.assertEquals(PdfAConformanceException.MAXIMUM_ARRAY_CAPACITY_IS_EXCEEDED, e.getMessage()); } @Test public void independentLongDictionaryTest() { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.MAXIMUM_DICTIONARY_CAPACITY_IS_EXCEEDED); - PdfDictionary longDictionary = buildLongDictionary(); // An exception should be thrown as provided dictionary has more entries // then it is allowed per specification - pdfA1Checker.checkPdfObject(longDictionary); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> pdfA1Checker.checkPdfObject(longDictionary) + ); + Assert.assertEquals(PdfAConformanceException.MAXIMUM_DICTIONARY_CAPACITY_IS_EXCEEDED, e.getMessage()); } @Test public void independentStreamWithLongDictionaryTest() { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.MAXIMUM_DICTIONARY_CAPACITY_IS_EXCEEDED); - PdfStream longStream = buildStreamWithLongDictionary(); // An exception should be thrown as dictionary of the stream has more entries // then it is allowed per specification - pdfA1Checker.checkPdfObject(longStream); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> pdfA1Checker.checkPdfObject(longStream) + ); + Assert.assertEquals(PdfAConformanceException.MAXIMUM_DICTIONARY_CAPACITY_IS_EXCEEDED, e.getMessage()); } @Test public void longStringInDictionaryTest() { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.PDF_STRING_IS_TOO_LONG); - PdfString longString = buildLongString(); // An exception should be thrown as dictionary contains value which is longer then // it is allowed per specification - checkInDictionary(longString); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> checkInDictionary(longString) + ); + Assert.assertEquals(PdfAConformanceException.PDF_STRING_IS_TOO_LONG, e.getMessage()); } @Test public void longNameAsKeyInDictionaryTest() { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.PDF_NAME_IS_TOO_LONG); - PdfName longName = buildLongName(); PdfDictionary dict = new PdfDictionary(); @@ -263,66 +254,69 @@ public void longNameAsKeyInDictionaryTest() { // An exception should be thrown as dictionary contains key which is longer then // it is allowed per specification - pdfA1Checker.checkPdfObject(dict); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> pdfA1Checker.checkPdfObject(dict) + ); + Assert.assertEquals(PdfAConformanceException.PDF_NAME_IS_TOO_LONG, e.getMessage()); } @Test public void longStringInArrayTest() { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.PDF_STRING_IS_TOO_LONG); - PdfString longString = buildLongString(); // An exception should be thrown as one element is longer then // it is allowed per specification - checkInArray(longString); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> checkInArray(longString) + ); + Assert.assertEquals(PdfAConformanceException.PDF_STRING_IS_TOO_LONG, e.getMessage()); } @Test public void longStringInContentStreamTest() { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.PDF_STRING_IS_TOO_LONG); - PdfString longString = buildLongString(); // An exception should be thrown as content stream has a string which // is longer then it is allowed per specification - checkInContentStream(longString); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> checkInContentStream(longString) + ); + Assert.assertEquals(PdfAConformanceException.PDF_STRING_IS_TOO_LONG, e.getMessage()); } @Test public void longNameInContentStreamTest() { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.PDF_NAME_IS_TOO_LONG); - PdfName longName = buildLongName(); // An exception should be thrown as content stream has a name which // is longer then it is allowed per specification - checkInContentStream(longName); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> checkInContentStream(longName) + ); + Assert.assertEquals(PdfAConformanceException.PDF_NAME_IS_TOO_LONG, e.getMessage()); } @Test public void largeIntegerInContentStreamTest() { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.INTEGER_NUMBER_IS_OUT_OF_RANGE); - PdfNumber largeNumber = new PdfNumber(pdfA1Checker.getMaxIntegerValue() + 1L); // An exception should be thrown as provided integer is larger then // it is allowed per specification - checkInContentStream(largeNumber); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> checkInContentStream(largeNumber) + ); + Assert.assertEquals(PdfAConformanceException.INTEGER_NUMBER_IS_OUT_OF_RANGE, e.getMessage()); } @Test public void largeNegativeIntegerInContentStreamTest() { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.INTEGER_NUMBER_IS_OUT_OF_RANGE); - PdfNumber largeNumber = new PdfNumber(pdfA1Checker.getMinIntegerValue() - 1L); // An exception should be thrown as provided integer is smaller then // it is allowed per specification - checkInContentStream(largeNumber); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> checkInContentStream(largeNumber) + ); + Assert.assertEquals(PdfAConformanceException.INTEGER_NUMBER_IS_OUT_OF_RANGE, e.getMessage()); } @Test @@ -337,26 +331,26 @@ public void largeRealInContentStreamTest() { @Test public void LongArrayInContentStreamTest() { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.MAXIMUM_ARRAY_CAPACITY_IS_EXCEEDED); - PdfArray longArray = buildLongArray(); // An exception should be thrown as provided array has more elements then // it is allowed per specification - checkInContentStream(longArray); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> checkInContentStream(longArray) + ); + Assert.assertEquals(PdfAConformanceException.MAXIMUM_ARRAY_CAPACITY_IS_EXCEEDED, e.getMessage()); } @Test public void longDictionaryInContentStream() { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.MAXIMUM_DICTIONARY_CAPACITY_IS_EXCEEDED); - PdfDictionary longDictionary = buildLongDictionary(); // An exception should be thrown as provided dictionary has more entries // then it is allowed per specification - checkInContentStream(longDictionary); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> checkInContentStream(longDictionary) + ); + Assert.assertEquals(PdfAConformanceException.MAXIMUM_DICTIONARY_CAPACITY_IS_EXCEEDED, e.getMessage()); } @@ -389,33 +383,30 @@ public void indirectObjectIsNotCheckTest() { @Test public void longStringInArrayInContentStreamTest() { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.PDF_STRING_IS_TOO_LONG); - PdfString longString = buildLongString(); // An exception should be thrown as content stream has a string which // is longer then it is allowed per specification - checkInArrayInContentStream(longString); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> checkInArrayInContentStream(longString) + ); + Assert.assertEquals(PdfAConformanceException.PDF_STRING_IS_TOO_LONG, e.getMessage()); } @Test public void longStringInDictionaryInContentStreamTest() { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.PDF_STRING_IS_TOO_LONG); - PdfString longString = buildLongString(); // An exception should be thrown as content stream has a string which // is longer then it is allowed per specification - checkInDictionaryInContentStream(longString); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> checkInDictionaryInContentStream(longString) + ); + Assert.assertEquals(PdfAConformanceException.PDF_STRING_IS_TOO_LONG, e.getMessage()); } @Test public void longNameAsKeyInDictionaryInContentStreamTest() { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.PDF_NAME_IS_TOO_LONG); - PdfName longName = buildLongName(); PdfDictionary dict = new PdfDictionary(); @@ -425,67 +416,69 @@ public void longNameAsKeyInDictionaryInContentStreamTest() { // An exception should be thrown as content stream has a string which // is longer then it is allowed per specification - checkInContentStream(dict); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> checkInContentStream(dict) + ); + Assert.assertEquals(PdfAConformanceException.PDF_NAME_IS_TOO_LONG, e.getMessage()); } @Test public void longStringInComplexStructureTest() { - - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.PDF_STRING_IS_TOO_LONG); - PdfString longString = buildLongString(); // An exception should be thrown as there is a string element which // doesn't match the limitations provided in specification - checkInComplexStructure(longString); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> checkInComplexStructure(longString) + ); + Assert.assertEquals(PdfAConformanceException.PDF_STRING_IS_TOO_LONG, e.getMessage()); } @Test public void LongArrayInComplexStructureTest() { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.MAXIMUM_ARRAY_CAPACITY_IS_EXCEEDED); - PdfArray longArray = buildLongArray(); // An exception should be thrown as provided array has more elements then // it is allowed per specification - checkInComplexStructure(longArray); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> checkInComplexStructure(longArray) + ); + Assert.assertEquals(PdfAConformanceException.MAXIMUM_ARRAY_CAPACITY_IS_EXCEEDED, e.getMessage()); } @Test public void longDictionaryInComplexStructureTest() { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.MAXIMUM_DICTIONARY_CAPACITY_IS_EXCEEDED); - PdfDictionary longDictionary = buildLongDictionary(); // An exception should be thrown as provided dictionary has more entries // then it is allowed per specification - checkInComplexStructure(longDictionary); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> checkInComplexStructure(longDictionary) + ); + Assert.assertEquals(PdfAConformanceException.MAXIMUM_DICTIONARY_CAPACITY_IS_EXCEEDED, e.getMessage()); } @Test public void longStringInPdfFormXObjectTest() { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.PDF_STRING_IS_TOO_LONG); - PdfString longString = buildLongString(); // An exception should be thrown as form xobject content stream has a string which // is longer then it is allowed per specification - checkInFormXObject(longString); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> checkInFormXObject(longString) + ); + Assert.assertEquals(PdfAConformanceException.PDF_STRING_IS_TOO_LONG, e.getMessage()); } @Test public void longStringInTilingPatternTest() { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.PDF_STRING_IS_TOO_LONG); - PdfString longString = buildLongString(); // An exception should be thrown as tiling pattern's content stream has a string which // is longer then it is allowed per specification - checkInTilingPattern(longString); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> checkInTilingPattern(longString) + ); + Assert.assertEquals(PdfAConformanceException.PDF_STRING_IS_TOO_LONG, e.getMessage()); } @Test @@ -499,21 +492,22 @@ public void longStringInShadingPatternTest() { @Test public void longStringInType3FontTest() { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.PDF_STRING_IS_TOO_LONG); - PdfString longString = buildLongString(); // An exception should be thrown as content stream of type3 font has a string which // is longer then it is allowed per specification - checkInType3Font(longString); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> checkInType3Font(longString) + ); + Assert.assertEquals(PdfAConformanceException.PDF_STRING_IS_TOO_LONG, e.getMessage()); } @Test public void deviceNColorspaceWithMoreThan8Components() { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.THE_NUMBER_OF_COLOR_COMPONENTS_IN_DEVICE_N_COLORSPACE_SHOULD_NOT_EXCEED); - - checkColorspace(buildDeviceNColorspace(10)); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> checkColorspace(buildDeviceNColorspace(10)) + ); + Assert.assertEquals(PdfAConformanceException.THE_NUMBER_OF_COLOR_COMPONENTS_IN_DEVICE_N_COLORSPACE_SHOULD_NOT_EXCEED, + e.getMessage()); } @Test diff --git a/pdfa/src/test/java/com/itextpdf/pdfa/checker/PdfA2CheckerGlyphsTest.java b/pdfa/src/test/java/com/itextpdf/pdfa/checker/PdfA2CheckerGlyphsTest.java index 224237cc3b..97f146130c 100644 --- a/pdfa/src/test/java/com/itextpdf/pdfa/checker/PdfA2CheckerGlyphsTest.java +++ b/pdfa/src/test/java/com/itextpdf/pdfa/checker/PdfA2CheckerGlyphsTest.java @@ -40,11 +40,10 @@ This file is part of the iText (R) project. import java.io.ByteArrayOutputStream; import java.io.IOException; +import org.junit.Assert; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(UnitTest.class) public class PdfA2CheckerGlyphsTest extends ExtendedITextTest { @@ -56,9 +55,6 @@ public void before() { pdfA2Checker.setFullCheckMode(true); } - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void checkValidFontGlyphsTest() throws IOException { try (ByteArrayOutputStream bos = new ByteArrayOutputStream(); @@ -105,11 +101,10 @@ public void checkInvalidFontGlyphsTest() throws IOException { PdfFont font = createFontWithCharProcsAndEncodingDifferences(document, charProcs, differences); - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage( - PdfAConformanceException.A_FORM_XOBJECT_DICTIONARY_SHALL_NOT_CONTAIN_SUBTYPE2_KEY_WITH_A_VALUE_OF_PS); - - pdfA2Checker.checkFontGlyphs(font, null); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> pdfA2Checker.checkFontGlyphs(font, null) + ); + Assert.assertEquals(PdfAConformanceException.A_FORM_XOBJECT_DICTIONARY_SHALL_NOT_CONTAIN_SUBTYPE2_KEY_WITH_A_VALUE_OF_PS, e.getMessage()); } } diff --git a/pdfa/src/test/java/com/itextpdf/pdfa/checker/PdfA2CheckerTest.java b/pdfa/src/test/java/com/itextpdf/pdfa/checker/PdfA2CheckerTest.java index e6d6a81795..89535d16cd 100644 --- a/pdfa/src/test/java/com/itextpdf/pdfa/checker/PdfA2CheckerTest.java +++ b/pdfa/src/test/java/com/itextpdf/pdfa/checker/PdfA2CheckerTest.java @@ -46,7 +46,6 @@ This file is part of the iText (R) project. import com.itextpdf.kernel.pdf.PdfArray; import com.itextpdf.kernel.pdf.PdfDictionary; import com.itextpdf.kernel.pdf.PdfName; -import com.itextpdf.kernel.pdf.PdfStream; import com.itextpdf.kernel.pdf.PdfString; import com.itextpdf.kernel.pdf.colorspace.PdfDeviceCs; import com.itextpdf.kernel.pdf.colorspace.PdfSpecialCs; @@ -58,23 +57,15 @@ This file is part of the iText (R) project. import java.util.ArrayList; import java.util.List; import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(UnitTest.class) public class PdfA2CheckerTest extends ExtendedITextTest { private PdfA2Checker pdfA2Checker = new PdfA2Checker(PdfAConformanceLevel.PDF_A_2B); - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void checkNameEntryShouldBeUniqueBetweenDefaultAndAdditionalConfigs() { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.VALUE_OF_NAME_ENTRY_SHALL_BE_UNIQUE_AMONG_ALL_OPTIONAL_CONTENT_CONFIGURATION_DICTIONARIES); - PdfDictionary ocProperties = new PdfDictionary(); PdfDictionary d = new PdfDictionary(); d.put(PdfName.Name, new PdfString("CustomName")); @@ -88,14 +79,15 @@ public void checkNameEntryShouldBeUniqueBetweenDefaultAndAdditionalConfigs() { PdfDictionary catalog = new PdfDictionary(); catalog.put(PdfName.OCProperties, ocProperties); - pdfA2Checker.checkCatalogValidEntries(catalog); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> pdfA2Checker.checkCatalogValidEntries(catalog) + ); + Assert.assertEquals(PdfAConformanceException.VALUE_OF_NAME_ENTRY_SHALL_BE_UNIQUE_AMONG_ALL_OPTIONAL_CONTENT_CONFIGURATION_DICTIONARIES, + e.getMessage()); } @Test public void checkNameEntryShouldBeUniqueBetweenAdditionalConfigs() { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.VALUE_OF_NAME_ENTRY_SHALL_BE_UNIQUE_AMONG_ALL_OPTIONAL_CONTENT_CONFIGURATION_DICTIONARIES); - PdfDictionary ocProperties = new PdfDictionary(); PdfDictionary d = new PdfDictionary(); d.put(PdfName.Name, new PdfString("CustomName")); @@ -112,14 +104,15 @@ public void checkNameEntryShouldBeUniqueBetweenAdditionalConfigs() { PdfDictionary catalog = new PdfDictionary(); catalog.put(PdfName.OCProperties, ocProperties); - pdfA2Checker.checkCatalogValidEntries(catalog); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> pdfA2Checker.checkCatalogValidEntries(catalog) + ); + Assert.assertEquals(PdfAConformanceException.VALUE_OF_NAME_ENTRY_SHALL_BE_UNIQUE_AMONG_ALL_OPTIONAL_CONTENT_CONFIGURATION_DICTIONARIES, + e.getMessage()); } @Test public void checkOCCDContainName() { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.OPTIONAL_CONTENT_CONFIGURATION_DICTIONARY_SHALL_CONTAIN_NAME_ENTRY); - PdfDictionary ocProperties = new PdfDictionary(); PdfDictionary d = new PdfDictionary(); PdfArray configs = new PdfArray(); @@ -135,14 +128,15 @@ public void checkOCCDContainName() { PdfDictionary catalog = new PdfDictionary(); catalog.put(PdfName.OCProperties, ocProperties); - pdfA2Checker.checkCatalogValidEntries(catalog); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> pdfA2Checker.checkCatalogValidEntries(catalog) + ); + Assert.assertEquals(PdfAConformanceException.OPTIONAL_CONTENT_CONFIGURATION_DICTIONARY_SHALL_CONTAIN_NAME_ENTRY, + e.getMessage()); } @Test public void checkOrderArrayDoesNotContainRedundantReferences() { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.ORDER_ARRAY_SHALL_CONTAIN_REFERENCES_TO_ALL_OCGS); - PdfDictionary ocProperties = new PdfDictionary(); PdfDictionary d = new PdfDictionary(); d.put(PdfName.Name, new PdfString("CustomName")); @@ -172,14 +166,14 @@ public void checkOrderArrayDoesNotContainRedundantReferences() { PdfDictionary catalog = new PdfDictionary(); catalog.put(PdfName.OCProperties, ocProperties); - pdfA2Checker.checkCatalogValidEntries(catalog); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> pdfA2Checker.checkCatalogValidEntries(catalog) + ); + Assert.assertEquals(PdfAConformanceException.ORDER_ARRAY_SHALL_CONTAIN_REFERENCES_TO_ALL_OCGS, e.getMessage()); } @Test public void checkOrderArrayContainsReferencesToAllOCGs() { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.ORDER_ARRAY_SHALL_CONTAIN_REFERENCES_TO_ALL_OCGS); - PdfDictionary ocProperties = new PdfDictionary(); PdfDictionary d = new PdfDictionary(); d.put(PdfName.Name, new PdfString("CustomName")); @@ -208,14 +202,14 @@ public void checkOrderArrayContainsReferencesToAllOCGs() { PdfDictionary catalog = new PdfDictionary(); catalog.put(PdfName.OCProperties, ocProperties); - pdfA2Checker.checkCatalogValidEntries(catalog); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> pdfA2Checker.checkCatalogValidEntries(catalog) + ); + Assert.assertEquals(PdfAConformanceException.ORDER_ARRAY_SHALL_CONTAIN_REFERENCES_TO_ALL_OCGS, e.getMessage()); } @Test public void checkOrderArrayAndOCGsMatch() { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.ORDER_ARRAY_SHALL_CONTAIN_REFERENCES_TO_ALL_OCGS); - PdfDictionary ocProperties = new PdfDictionary(); PdfDictionary d = new PdfDictionary(); d.put(PdfName.Name, new PdfString("CustomName")); @@ -249,7 +243,10 @@ public void checkOrderArrayAndOCGsMatch() { PdfDictionary catalog = new PdfDictionary(); catalog.put(PdfName.OCProperties, ocProperties); - pdfA2Checker.checkCatalogValidEntries(catalog); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> pdfA2Checker.checkCatalogValidEntries(catalog) + ); + Assert.assertEquals(PdfAConformanceException.ORDER_ARRAY_SHALL_CONTAIN_REFERENCES_TO_ALL_OCGS, e.getMessage()); } @Test @@ -317,36 +314,32 @@ public void checkAbsenceOfOptionalOrderEntryAllowed() { @Test public void checkCatalogDictionaryWithoutAlternatePresentations() { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.A_CATALOG_DICTIONARY_SHALL_NOT_CONTAIN_ALTERNATEPRESENTATIONS_NAMES_ENTRY); - PdfDictionary names = new PdfDictionary(); names.put(PdfName.AlternatePresentations, new PdfDictionary()); PdfDictionary catalog = new PdfDictionary(); catalog.put(PdfName.Names, names); - pdfA2Checker.checkCatalogValidEntries(catalog); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> pdfA2Checker.checkCatalogValidEntries(catalog) + ); + Assert.assertEquals(PdfAConformanceException.A_CATALOG_DICTIONARY_SHALL_NOT_CONTAIN_ALTERNATEPRESENTATIONS_NAMES_ENTRY, + e.getMessage()); } @Test public void checkCatalogDictionaryWithoutRequirements() { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.A_CATALOG_DICTIONARY_SHALL_NOT_CONTAIN_REQUIREMENTS_ENTRY); - PdfDictionary catalog = new PdfDictionary(); catalog.put(PdfName.Requirements, new PdfDictionary()); - pdfA2Checker.checkCatalogValidEntries(catalog); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> pdfA2Checker.checkCatalogValidEntries(catalog) + ); + Assert.assertEquals(PdfAConformanceException.A_CATALOG_DICTIONARY_SHALL_NOT_CONTAIN_REQUIREMENTS_ENTRY, e.getMessage()); } @Test public void deviceNColorspaceNoAttributesDictionary() { - //TODO DEVSIX-4203 should not cause an IndexOutOfBoundException. - // Should throw PdfAConformanceException as Colorants dictionary always must be present - // for Pdf/A-2 - junitExpectedException.expect(RuntimeException.class); - int numberOfComponents = 2; List tmpArray = new ArrayList(numberOfComponents); float[] transformArray = new float[numberOfComponents * 2]; @@ -360,8 +353,13 @@ public void deviceNColorspaceNoAttributesDictionary() { (new PdfArray(transformArray), new PdfArray(new float[]{0, 1, 0, 1, 0, 1}), "{0}".getBytes(StandardCharsets.ISO_8859_1)); PdfDictionary currentColorSpaces = new PdfDictionary(); - pdfA2Checker.checkColorSpace(new PdfSpecialCs.DeviceN(tmpArray, new PdfDeviceCs.Rgb(), function), - currentColorSpaces, true, false); + //TODO DEVSIX-4203 should not cause an IndexOutOfBoundException. + // Should throw PdfAConformanceException as Colorants dictionary always must be present + // for Pdf/A-2 + Assert.assertThrows(RuntimeException.class, + () -> pdfA2Checker.checkColorSpace(new PdfSpecialCs.DeviceN(tmpArray, new PdfDeviceCs.Rgb(), function), + currentColorSpaces, true, false) + ); } } diff --git a/pdfa/src/test/java/com/itextpdf/pdfa/checker/PdfA2CheckerTransparencyTest.java b/pdfa/src/test/java/com/itextpdf/pdfa/checker/PdfA2CheckerTransparencyTest.java index 993958e771..296d97e29b 100644 --- a/pdfa/src/test/java/com/itextpdf/pdfa/checker/PdfA2CheckerTransparencyTest.java +++ b/pdfa/src/test/java/com/itextpdf/pdfa/checker/PdfA2CheckerTransparencyTest.java @@ -61,11 +61,10 @@ This file is part of the iText (R) project. import java.io.ByteArrayOutputStream; import java.io.IOException; +import org.junit.Assert; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(UnitTest.class) public class PdfA2CheckerTransparencyTest extends ExtendedITextTest { @@ -78,9 +77,6 @@ public void before() { pdfA2Checker.setFullCheckMode(true); } - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void checkPatternWithFormResourceCycle() throws IOException { try (ByteArrayOutputStream bos = new ByteArrayOutputStream(); @@ -146,11 +142,11 @@ public void checkPatternWithTransparentFormResource() throws IOException { pageResources.addPattern(new PdfPattern.Shading(new PdfDictionary())); pageResources.addPattern(tillingPattern); - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage( - PdfAConformanceException.THE_DOCUMENT_DOES_NOT_CONTAIN_A_PDFA_OUTPUTINTENT_BUT_PAGE_CONTAINS_TRANSPARENCY_AND_DOES_NOT_CONTAIN_BLENDING_COLOR_SPACE); - - pdfA2Checker.checkSinglePage(pageToCheck); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> pdfA2Checker.checkSinglePage(pageToCheck) + ); + Assert.assertEquals(PdfAConformanceException.THE_DOCUMENT_DOES_NOT_CONTAIN_A_PDFA_OUTPUTINTENT_BUT_PAGE_CONTAINS_TRANSPARENCY_AND_DOES_NOT_CONTAIN_BLENDING_COLOR_SPACE, + e.getMessage()); } } @@ -194,11 +190,11 @@ public void checkAppearanceStreamWithTransparencyGroup() throws IOException { pageToCheck.addAnnotation(new PdfPopupAnnotation(new Rectangle(0f, 0f))); pageToCheck.addAnnotation(annotation); - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage( - PdfAConformanceException.THE_DOCUMENT_DOES_NOT_CONTAIN_A_PDFA_OUTPUTINTENT_BUT_PAGE_CONTAINS_TRANSPARENCY_AND_DOES_NOT_CONTAIN_BLENDING_COLOR_SPACE); - - pdfA2Checker.checkSinglePage(pageToCheck); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> pdfA2Checker.checkSinglePage(pageToCheck) + ); + Assert.assertEquals(PdfAConformanceException.THE_DOCUMENT_DOES_NOT_CONTAIN_A_PDFA_OUTPUTINTENT_BUT_PAGE_CONTAINS_TRANSPARENCY_AND_DOES_NOT_CONTAIN_BLENDING_COLOR_SPACE, + e.getMessage()); } } @@ -222,11 +218,11 @@ public void checkAppearanceStreamWithTransparencyGroup2() throws IOException { pageToCheck.addAnnotation(new PdfPopupAnnotation(new Rectangle(0f, 0f))); pageToCheck.addAnnotation(annotation); - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage( - PdfAConformanceException.THE_DOCUMENT_DOES_NOT_CONTAIN_A_PDFA_OUTPUTINTENT_BUT_PAGE_CONTAINS_TRANSPARENCY_AND_DOES_NOT_CONTAIN_BLENDING_COLOR_SPACE); - - pdfA2Checker.checkSinglePage(pageToCheck); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> pdfA2Checker.checkSinglePage(pageToCheck) + ); + Assert.assertEquals(PdfAConformanceException.THE_DOCUMENT_DOES_NOT_CONTAIN_A_PDFA_OUTPUTINTENT_BUT_PAGE_CONTAINS_TRANSPARENCY_AND_DOES_NOT_CONTAIN_BLENDING_COLOR_SPACE, + e.getMessage()); } } diff --git a/pdfa/src/test/java/com/itextpdf/pdfa/checker/PdfA2ImplementationLimitsCheckerTest.java b/pdfa/src/test/java/com/itextpdf/pdfa/checker/PdfA2ImplementationLimitsCheckerTest.java index 011b3d9d8b..844ab0e391 100644 --- a/pdfa/src/test/java/com/itextpdf/pdfa/checker/PdfA2ImplementationLimitsCheckerTest.java +++ b/pdfa/src/test/java/com/itextpdf/pdfa/checker/PdfA2ImplementationLimitsCheckerTest.java @@ -60,10 +60,8 @@ This file is part of the iText (R) project. import java.util.List; import org.junit.Assert; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(UnitTest.class) public class PdfA2ImplementationLimitsCheckerTest extends ExtendedITextTest { @@ -74,14 +72,8 @@ public void before() { pdfA2Checker.setFullCheckMode(true); } - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void independentLongStringTest() { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.PDF_STRING_IS_TOO_LONG); - final int maxAllowedLength = pdfA2Checker.getMaxStringLength(); final int testLength = maxAllowedLength + 1; @@ -90,14 +82,14 @@ public void independentLongStringTest() { // An exception should be thrown as provided String is longer then // it is allowed per specification - pdfA2Checker.checkPdfObject(longString); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> pdfA2Checker.checkPdfObject(longString) + ); + Assert.assertEquals(PdfAConformanceException.PDF_STRING_IS_TOO_LONG, e.getMessage()); } @Test public void longStringInContentStreamTest() { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.PDF_STRING_IS_TOO_LONG); - pdfA2Checker.setFullCheckMode(true); final int maxAllowedLength = pdfA2Checker.getMaxStringLength(); @@ -112,7 +104,10 @@ public void longStringInContentStreamTest() { // An exception should be thrown as content stream has a string which // is longer then it is allowed per specification - pdfA2Checker.checkContentStream(stream); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> pdfA2Checker.checkContentStream(stream) + ); + Assert.assertEquals(PdfAConformanceException.PDF_STRING_IS_TOO_LONG, e.getMessage()); } @Test @@ -144,23 +139,22 @@ public void dictionaryCapacityHasNoLimitsTest() { @Test public void independentLargeRealTest() { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.INTEGER_NUMBER_IS_OUT_OF_RANGE); - PdfNumber largeNumber = new PdfNumber(pdfA2Checker.getMaxRealValue()); // TODO DEVSIX-4182 // An exception is thrown as any number greater then 32767 is considered as Integer - pdfA2Checker.checkPdfObject(largeNumber); + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> pdfA2Checker.checkPdfObject(largeNumber) + ); + Assert.assertEquals(PdfAConformanceException.INTEGER_NUMBER_IS_OUT_OF_RANGE, e.getMessage()); } @Test public void deviceNColorspaceWithMoreThan32Components() { - junitExpectedException.expect(PdfAConformanceException.class); - junitExpectedException.expectMessage(PdfAConformanceException.THE_NUMBER_OF_COLOR_COMPONENTS_IN_DEVICE_N_COLORSPACE_SHOULD_NOT_EXCEED); - - checkColorspace(buildDeviceNColorspace(34)); - + Exception e = Assert.assertThrows(PdfAConformanceException.class, + () -> checkColorspace(buildDeviceNColorspace(34)) + ); + Assert.assertEquals(PdfAConformanceException.THE_NUMBER_OF_COLOR_COMPONENTS_IN_DEVICE_N_COLORSPACE_SHOULD_NOT_EXCEED, e.getMessage()); } @Test diff --git a/pdfa/src/test/java/com/itextpdf/pdfa/checker/PdfACheckerTest.java b/pdfa/src/test/java/com/itextpdf/pdfa/checker/PdfACheckerTest.java index 582ffdddd6..7bf844c1fb 100644 --- a/pdfa/src/test/java/com/itextpdf/pdfa/checker/PdfACheckerTest.java +++ b/pdfa/src/test/java/com/itextpdf/pdfa/checker/PdfACheckerTest.java @@ -73,10 +73,8 @@ This file is part of the iText (R) project. import java.io.IOException; import java.util.Set; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(UnitTest.class) public class PdfACheckerTest extends ExtendedITextTest { diff --git a/pdftest/pom.xml b/pdftest/pom.xml index 60c14735e6..878de783f5 100644 --- a/pdftest/pom.xml +++ b/pdftest/pom.xml @@ -4,14 +4,14 @@ com.itextpdf root - 7.1.15 + 7.1.16 pdftest iText 7 - pdftest https://itextpdf.com/ true - 1.16.1 + 1.18.2 diff --git a/pdftest/src/main/java/com/itextpdf/test/ExceptionTestUtil.java b/pdftest/src/main/java/com/itextpdf/test/ExceptionTestUtil.java new file mode 100644 index 0000000000..3665a5fbd2 --- /dev/null +++ b/pdftest/src/main/java/com/itextpdf/test/ExceptionTestUtil.java @@ -0,0 +1,53 @@ +/* + This file is part of the iText (R) project. + Copyright (c) 1998-2021 iText Group NV + Authors: iText Software. + + This program is offered under a commercial and under the AGPL license. + For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below. + + AGPL licensing: + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + */ +package com.itextpdf.test; + +/** + * Class containing the exception messages. + */ +public final class ExceptionTestUtil { + + private static final String DOCTYPE_IS_DISALLOWED = + "DOCTYPE is disallowed when the feature " + + "\"http://apache.org/xml/features/disallow-doctype-decl\" set to true."; + + private static final String TEST_MESSAGE = "Test message"; + + /** + * Returns message about disallowed DOCTYPE. + * + * @return message for case when DOCTYPE is disallowed in XML + */ + public static String getDoctypeIsDisallowedExceptionMessage() { + return DOCTYPE_IS_DISALLOWED; + } + + /** + * Returns test message for case with XXE. + * + * @return message with text for testing + */ + public static String getXxeTestMessage() { + return TEST_MESSAGE; + } +} diff --git a/pom.xml b/pom.xml index 8efac7ded3..2ea62c904c 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.itextpdf root - 7.1.15 + 7.1.16 pom iText 7 A Free Java-PDF library @@ -72,10 +72,8 @@ -Xmx1024m 1.68 - 3.1.0 6.0.3 3.0.0-M3 - 1.8.0 com.itextpdf.test.annotations.type.IntegrationTest 0.8.4 1.8 @@ -90,17 +88,14 @@ 3.1.0 3.0.1 com.itextpdf.test.annotations.type.PerformanceTest - 3.11.0 UTF-8 UTF-8 com.itextpdf.test.annotations.type.SampleTest - 7.4.7 true 1.7.30 com.itextpdf.test.annotations.type.SlowTest target/dependency-check-report.html target/dependency-check-report.xml - 3.1.11 3.0.0-M3 com.itextpdf.test.annotations.type.UnitTest @@ -282,7 +277,7 @@ false true - 7 + 8 true ${javadoc-additionalOptions} @@ -324,7 +319,6 @@ com/itextpdf/svg/utils/SvgCoordinateUtils.java - com/itextpdf/svg/utils/SvgRegexUtils.java @@ -416,29 +410,17 @@ - - com.github.spotbugs - spotbugs-maven-plugin - ${spotbugs.version} - maven-changelog-plugin 2.3 - - maven-checkstyle-plugin - ${checkstyle.version} - - true - - maven-javadoc-plugin ${javadoc.version} false true - 7 + 8 ${javadoc-additionalOptions} ${javadoc-link} @@ -456,13 +438,6 @@ true - - maven-pmd-plugin - ${pmd.version} - - true - - maven-project-info-reports-plugin 2.8 @@ -473,6 +448,7 @@ + java9+ @@ -521,37 +497,6 @@ - - com.github.spotbugs - spotbugs-maven-plugin - ${spotbugs.version} - - - verify - - check - - - - - Max - High - true - false - - - com.mebigfatguy.sb-contrib - sb-contrib - ${sb-contrib.version} - - - com.h3xstream.findsecbugs - findsecbugs-plugin - ${findsecbugs.version} - - - - org.apache.felix maven-bundle-plugin @@ -562,52 +507,12 @@ - - maven-checkstyle-plugin - ${checkstyle.version} - - - validate - validate - - check - - - true - true - false - false - false - - - - maven-javadoc-plugin true - - maven-pmd-plugin - ${pmd.version} - - - validate - validate - - check - - - true - true - false - false - false - - - - maven-resources-plugin 3.1.0 @@ -827,4 +732,4 @@ - \ No newline at end of file + diff --git a/sign/pom.xml b/sign/pom.xml index 95c671d66b..5fd226a01d 100644 --- a/sign/pom.xml +++ b/sign/pom.xml @@ -4,7 +4,7 @@ com.itextpdf root - 7.1.15 + 7.1.16 sign iText 7 - sign diff --git a/sign/src/main/java/com/itextpdf/signatures/CrlClientOnline.java b/sign/src/main/java/com/itextpdf/signatures/CrlClientOnline.java index 5d3269b6a2..bdd161dabe 100644 --- a/sign/src/main/java/com/itextpdf/signatures/CrlClientOnline.java +++ b/sign/src/main/java/com/itextpdf/signatures/CrlClientOnline.java @@ -43,12 +43,12 @@ This file is part of the iText (R) project. */ package com.itextpdf.signatures; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import com.itextpdf.io.LogMessageConstant; +import com.itextpdf.io.util.MessageFormatUtil; import java.io.ByteArrayOutputStream; -import java.io.IOException; import java.io.InputStream; +import java.net.MalformedURLException; import java.net.URL; import java.security.cert.Certificate; import java.security.cert.CertificateParsingException; @@ -56,6 +56,8 @@ This file is part of the iText (R) project. import java.util.ArrayList; import java.util.Collection; import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * An implementation of the CrlClient that fetches the CRL bytes @@ -169,7 +171,7 @@ public Collection getEncoded(X509Certificate checkCert, String url) { ar.add(bout.toByteArray()); LOGGER.info("Added CRL found at: " + urlt); } catch (Exception e) { - LOGGER.info("Skipped CRL: " + e.getMessage() + " for " + urlt); + LOGGER.info(MessageFormatUtil.format(LogMessageConstant.INVALID_DISTRIBUTION_POINT, e.getMessage())); } } return ar; @@ -183,7 +185,7 @@ public Collection getEncoded(X509Certificate checkCert, String url) { protected void addUrl(String url) { try { addUrl(new URL(url)); - } catch (IOException e) { + } catch (MalformedURLException e) { LOGGER.info("Skipped CRL url (malformed): " + url); } } diff --git a/sign/src/main/java/com/itextpdf/signatures/IOcspClient.java b/sign/src/main/java/com/itextpdf/signatures/IOcspClient.java index 713a24b619..90d7fbf141 100644 --- a/sign/src/main/java/com/itextpdf/signatures/IOcspClient.java +++ b/sign/src/main/java/com/itextpdf/signatures/IOcspClient.java @@ -51,13 +51,21 @@ This file is part of the iText (R) project. public interface IOcspClient { /** - * Gets an encoded byte array with OCSP validation. The method should not throw an exception. + * Fetch a DER-encoded BasicOCSPResponse from an OCSP responder. The method should not throw + * an exception. + * + *

+ * Note: do not pass in the full DER-encoded OCSPResponse object obtained from the responder, + * only the DER-encoded BasicOCSPResponse value contained in the response data. * * @param checkCert Certificate to check. * @param issuerCert The parent certificate. - * @param url The url to get the verification. It it's null it will be taken. - * from the check cert or from other implementation specific source - * @return A byte array with the validation or null if the validation could not be obtained + * @param url The URL of the OCSP responder endpoint. If null, implementations can + * attempt to obtain a URL from the AuthorityInformationAccess extension of + * the certificate, or from another implementation-specific source. + * @return a byte array containing a DER-encoded BasicOCSPResponse structure or null if one + * could not be obtained + * @see RFC 6960 § 4.2.1 */ byte[] getEncoded(X509Certificate checkCert, X509Certificate issuerCert, String url); } diff --git a/sign/src/main/java/com/itextpdf/signatures/LtvVerification.java b/sign/src/main/java/com/itextpdf/signatures/LtvVerification.java index 497f51c785..8c54aa352b 100644 --- a/sign/src/main/java/com/itextpdf/signatures/LtvVerification.java +++ b/sign/src/main/java/com/itextpdf/signatures/LtvVerification.java @@ -269,9 +269,9 @@ private X509Certificate getParent(X509Certificate cert, Certificate[] certs) { * Adds verification to the signature. * * @param signatureName name of the signature - * @param ocsps collection of ocsp responses - * @param crls collection of crls - * @param certs collection of certificates + * @param ocsps collection of DER-encoded BasicOCSPResponses + * @param crls collection of DER-encoded CRLs + * @param certs collection of DER-encoded certificates * @return boolean * @throws IOException signals that an I/O exception has occurred * @throws GeneralSecurityException when requested cryptographic algorithm or security provider diff --git a/sign/src/main/java/com/itextpdf/signatures/LtvVerifier.java b/sign/src/main/java/com/itextpdf/signatures/LtvVerifier.java index c039b803fb..9b99c62d6a 100644 --- a/sign/src/main/java/com/itextpdf/signatures/LtvVerifier.java +++ b/sign/src/main/java/com/itextpdf/signatures/LtvVerifier.java @@ -292,13 +292,15 @@ public void switchToPreviousRevision() throws IOException, GeneralSecurityExcept List names = sgnUtil.getSignatureNames(); if (names.size() > 1) { signatureName = names.get(names.size() - 2); - document = new PdfDocument(new PdfReader(sgnUtil.extractRevision(signatureName)), new DocumentProperties().setEventCountingMetaInfo(metaInfo)); + try (PdfReader readerTmp = new PdfReader(sgnUtil.extractRevision(signatureName))) { + document = new PdfDocument(readerTmp, new DocumentProperties().setEventCountingMetaInfo(metaInfo)); this.acroForm = PdfAcroForm.getAcroForm(document, true); this.sgnUtil = new SignatureUtil(document); names = sgnUtil.getSignatureNames(); signatureName = names.get(names.size() - 1); pkcs7 = coversWholeDocument(); LOGGER.info(MessageFormatUtil.format("Checking {0}signature {1}", pkcs7.isTsp() ? "document-level timestamp " : "", signatureName)); + } } else { LOGGER.info("No signatures in revision"); diff --git a/sign/src/main/java/com/itextpdf/signatures/OcspClientBouncyCastle.java b/sign/src/main/java/com/itextpdf/signatures/OcspClientBouncyCastle.java index ee99984e52..fe4e323b0c 100644 --- a/sign/src/main/java/com/itextpdf/signatures/OcspClientBouncyCastle.java +++ b/sign/src/main/java/com/itextpdf/signatures/OcspClientBouncyCastle.java @@ -121,13 +121,7 @@ public BasicOCSPResp getBasicOCSPResp(X509Certificate checkCert, X509Certificate } /** - * Gets an encoded byte array with OCSP validation. The method should not throw an exception. - * - * @param checkCert to certificate to check - * @param rootCert the parent certificate - * @param url to get the verification. It it's null it will be taken - * from the check cert or from other implementation specific source - * @return a byte array with the validation or null if the validation could not be obtained + * {@inheritDoc} */ @Override public byte[] getEncoded(X509Certificate checkCert, X509Certificate rootCert, String url) { diff --git a/sign/src/main/java/com/itextpdf/signatures/PdfPKCS7.java b/sign/src/main/java/com/itextpdf/signatures/PdfPKCS7.java index fdd02eca41..f24ef51afd 100644 --- a/sign/src/main/java/com/itextpdf/signatures/PdfPKCS7.java +++ b/sign/src/main/java/com/itextpdf/signatures/PdfPKCS7.java @@ -798,12 +798,20 @@ public byte[] getEncodedPKCS7(byte[] secondDigest) { * in the signerInfo can also be set, and/or a time-stamp-authority client * may be provided. * + *

+ * Note: do not pass in the full DER-encoded OCSPResponse object obtained from the responder, + * only the DER-encoded BasicOCSPResponse value contained in the response data. + * * @param secondDigest the digest in the authenticatedAttributes * @param tsaClient TSAClient - null or an optional time stamp authority client - * @param ocsp DER-encoded OCSP response for the first certificate in the signature certificates chain, or null if OCSP revocation data is not to be added. - * @param crlBytes collection of DER-encoded CRL for certificates from the signature certificates chain, or null if CRL revocation data is not to be added. - * @param sigtype specifies the PKCS7 standard flavor to which created PKCS7SignedData object will adhere: either basic CMS or CAdES + * @param ocsp DER-encoded BasicOCSPResponse for the first certificate in the signature certificates chain, + * or null if OCSP revocation data is not to be added. + * @param crlBytes collection of DER-encoded CRL for certificates from the signature certificates chain, + * or null if CRL revocation data is not to be added. + * @param sigtype specifies the PKCS7 standard flavor to which created PKCS7SignedData object will adhere: + * either basic CMS or CAdES * @return byte[] the bytes for the PKCS7SignedData object + * @see RFC 6960 § 4.2.1 * @deprecated This overload is deprecated, use {@link #getEncodedPKCS7(byte[], PdfSigner.CryptoStandard, ITSAClient, Collection, Collection)} instead. */ @Deprecated @@ -816,11 +824,18 @@ public byte[] getEncodedPKCS7(byte[] secondDigest, ITSAClient tsaClient, byte[] * in the signerInfo can also be set, and/or a time-stamp-authority client * may be provided. * + *

+ * Note: do not pass in the full DER-encoded OCSPResponse object obtained from the responder, + * only the DER-encoded BasicOCSPResponse value contained in the response data. + * * @param secondDigest the digest in the authenticatedAttributes * @param sigtype specifies the PKCS7 standard flavor to which created PKCS7SignedData object will adhere: either basic CMS or CAdES * @param tsaClient TSAClient - null or an optional time stamp authority client - * @param ocsp collection of DER-encoded OCSP responses for the certificate in the signature certificates chain, or null if OCSP revocation data is not to be added. - * @param crlBytes collection of DER-encoded CRL for certificates from the signature certificates chain, or null if CRL revocation data is not to be added. + * @param ocsp collection of DER-encoded BasicOCSPResponses for the certificate in the signature certificates + * chain, or null if OCSP revocation data is not to be added. + * @param crlBytes collection of DER-encoded CRL for certificates from the signature certificates chain, + * or null if CRL revocation data is not to be added. + * @see RFC 6960 § 4.2.1 * @return byte[] the bytes for the PKCS7SignedData object */ public byte[] getEncodedPKCS7(byte[] secondDigest, PdfSigner.CryptoStandard sigtype, ITSAClient tsaClient, Collection ocsp, Collection crlBytes) { @@ -978,6 +993,12 @@ private ASN1EncodableVector buildUnauthenticatedAttributes(byte[] timeStampToken * The document digest is generated and put inside the attribute. The signing is done over the DER encoded * authenticatedAttributes. This method provides that encoding and the parameters must be * exactly the same as in {@link #getEncodedPKCS7(byte[])}. + * + *

+ * Note: do not pass in the full DER-encoded OCSPResponse object obtained from the responder, + * only the DER-encoded BasicOCSPResponse value contained in the response data. + * + * *

* A simple example: *

@@ -997,10 +1018,14 @@ private ASN1EncodableVector buildUnauthenticatedAttributes(byte[] timeStampToken
      * 
* * @param secondDigest the content digest - * @param ocsp collection of DER-encoded OCSP responses for the certificate in the signature certificates chain, or null if OCSP revocation data is not to be added. - * @param crlBytes collection of DER-encoded CRL for certificates from the signature certificates chain, or null if CRL revocation data is not to be added. - * @param sigtype specifies the PKCS7 standard flavor to which created PKCS7SignedData object will adhere: either basic CMS or CAdES + * @param ocsp collection of DER-encoded BasicOCSPResponses for the certificate in the signature certificates + * chain, or null if OCSP revocation data is not to be added. + * @param crlBytes collection of DER-encoded CRL for certificates from the signature certificates chain, + * or null if CRL revocation data is not to be added. + * @param sigtype specifies the PKCS7 standard flavor to which created PKCS7SignedData object will adhere: + * either basic CMS or CAdES * @return the byte array representation of the authenticatedAttributes ready to be signed + * @see RFC 6960 § 4.2.1 * @deprecated This method overload is deprecated. Please use {@link #getAuthenticatedAttributeBytes(byte[], PdfSigner.CryptoStandard, Collection, Collection)} */ @Deprecated @@ -1013,6 +1038,11 @@ public byte[] getAuthenticatedAttributeBytes(byte[] secondDigest, byte[] ocsp, C * The document digest is generated and put inside the attribute. The signing is done over the DER encoded * authenticatedAttributes. This method provides that encoding and the parameters must be * exactly the same as in {@link #getEncodedPKCS7(byte[])}. + * + *

+ * Note: do not pass in the full DER-encoded OCSPResponse object obtained from the responder, + * only the DER-encoded BasicOCSPResponse value contained in the response data. + * *

* A simple example: *

@@ -1032,10 +1062,14 @@ public byte[] getAuthenticatedAttributeBytes(byte[] secondDigest, byte[] ocsp, C
      * 
* * @param secondDigest the content digest - * @param sigtype specifies the PKCS7 standard flavor to which created PKCS7SignedData object will adhere: either basic CMS or CAdES - * @param ocsp collection of DER-encoded OCSP responses for the certificate in the signature certificates chain, or null if OCSP revocation data is not to be added. - * @param crlBytes collection of DER-encoded CRL for certificates from the signature certificates chain, or null if CRL revocation data is not to be added. + * @param sigtype specifies the PKCS7 standard flavor to which created PKCS7SignedData object will adhere: + * either basic CMS or CAdES + * @param ocsp collection of DER-encoded BasicOCSPResponses for the certificate in the signature certificates + * chain, or null if OCSP revocation data is not to be added. + * @param crlBytes collection of DER-encoded CRL for certificates from the signature certificates chain, + * or null if CRL revocation data is not to be added. * @return the byte array representation of the authenticatedAttributes ready to be signed + * @see RFC 6960 § 4.2.1 */ public byte[] getAuthenticatedAttributeBytes(byte[] secondDigest, PdfSigner.CryptoStandard sigtype, Collection ocsp, Collection crlBytes) { try { diff --git a/sign/src/main/java/com/itextpdf/signatures/PdfSignature.java b/sign/src/main/java/com/itextpdf/signatures/PdfSignature.java index a1ffac283e..cb4deab321 100644 --- a/sign/src/main/java/com/itextpdf/signatures/PdfSignature.java +++ b/sign/src/main/java/com/itextpdf/signatures/PdfSignature.java @@ -60,6 +60,8 @@ This file is part of the iText (R) project. */ public class PdfSignature extends PdfObjectWrapper { + private static final long serialVersionUID = 8367728573140319531L; + /** * Creates new PdfSignature. */ @@ -168,6 +170,23 @@ public PdfString getCert() { return getPdfObject().getAsString(PdfName.Cert); } + /** + * Gets the /Cert entry value of this signature. + * /Cert entry required when SubFilter is adbe.x509.rsa_sha1. May be array or byte string. + * + * @return the signature cert value + */ + public PdfObject getCertObject() { + PdfString certAsStr = getPdfObject().getAsString(PdfName.Cert); + PdfArray certAsArray = getPdfObject().getAsArray(PdfName.Cert); + + if (certAsStr != null) { + return certAsStr; + } else { + return certAsArray; + } + } + /** * Sets the /Name of the person signing the document. * diff --git a/sign/src/main/java/com/itextpdf/signatures/PdfSigner.java b/sign/src/main/java/com/itextpdf/signatures/PdfSigner.java index 32d6251e40..2447972b95 100644 --- a/sign/src/main/java/com/itextpdf/signatures/PdfSigner.java +++ b/sign/src/main/java/com/itextpdf/signatures/PdfSigner.java @@ -887,66 +887,9 @@ protected void preClose(Map exclusionSizes) throws IOException cryptoDictionary.getPdfObject().makeIndirect(document); if (fieldExist) { - PdfSignatureFormField sigField = (PdfSignatureFormField) acroForm.getField(fieldName); - sigField.put(PdfName.V, cryptoDictionary.getPdfObject()); - - fieldLock = sigField.getSigFieldLockDictionary(); - - if (fieldLock == null && this.fieldLock != null) { - this.fieldLock.getPdfObject().makeIndirect(document); - sigField.put(PdfName.Lock, this.fieldLock.getPdfObject()); - fieldLock = this.fieldLock; - } - - sigField.put(PdfName.P, document.getPage(appearance.getPageNumber()).getPdfObject()); - sigField.put(PdfName.V, cryptoDictionary.getPdfObject()); - PdfObject obj = sigField.getPdfObject().get(PdfName.F); - int flags = 0; - - if (obj != null && obj.isNumber()) { - flags = ((PdfNumber) obj).intValue(); - } - - flags |= PdfAnnotation.LOCKED; - sigField.put(PdfName.F, new PdfNumber(flags)); - PdfDictionary ap = new PdfDictionary(); - ap.put(PdfName.N, appearance.getAppearance().getPdfObject()); - sigField.put(PdfName.AP, ap); - sigField.setModified(); + fieldLock = populateExistingSignatureFormField(acroForm); } else { - PdfWidgetAnnotation widget = new PdfWidgetAnnotation(appearance.getPageRect()); - widget.setFlags(PdfAnnotation.PRINT | PdfAnnotation.LOCKED); - - PdfSignatureFormField sigField = PdfFormField.createSignature(document); - sigField.setFieldName(name); - sigField.put(PdfName.V, cryptoDictionary.getPdfObject()); - sigField.addKid(widget); - - if (this.fieldLock != null) { - this.fieldLock.getPdfObject().makeIndirect(document); - sigField.put(PdfName.Lock, this.fieldLock.getPdfObject()); - fieldLock = this.fieldLock; - } - - int pagen = appearance.getPageNumber(); - widget.setPage(document.getPage(pagen)); - PdfDictionary ap = widget.getAppearanceDictionary(); - - if (ap == null) { - ap = new PdfDictionary(); - widget.put(PdfName.AP, ap); - } - - ap.put(PdfName.N, appearance.getAppearance().getPdfObject()); - acroForm.addField(sigField, document.getPage(pagen)); - - if (acroForm.getPdfObject().isIndirect()) { - acroForm.setModified(); - } else { - //Acroform dictionary is a Direct dictionary, - //for proper flushing, catalog needs to be marked as modified - document.getCatalog().setModified(); - } + fieldLock = createNewSignatureFormField(acroForm, name); } exclusionLocations = new HashMap<>(); @@ -1032,6 +975,106 @@ protected void preClose(Map exclusionSizes) throws IOException } } + /** + * Populates already existing signature form field in the acroForm object. + * This method is called during the {@link PdfSigner#preClose(Map)} method if the signature field already exists. + * + * @param acroForm {@link PdfAcroForm} object in which the signature field will be populated + * @return signature field lock dictionary + * @throws IOException if font for the appearance dictionary cannot be created + */ + protected PdfSigFieldLock populateExistingSignatureFormField(PdfAcroForm acroForm) throws IOException { + PdfSignatureFormField sigField = (PdfSignatureFormField) acroForm.getField(fieldName); + sigField.put(PdfName.V, cryptoDictionary.getPdfObject()); + + PdfSigFieldLock sigFieldLock = sigField.getSigFieldLockDictionary(); + + if (sigFieldLock == null && this.fieldLock != null) { + this.fieldLock.getPdfObject().makeIndirect(document); + sigField.put(PdfName.Lock, this.fieldLock.getPdfObject()); + sigFieldLock = this.fieldLock; + } + + sigField.put(PdfName.P, document.getPage(appearance.getPageNumber()).getPdfObject()); + sigField.put(PdfName.V, cryptoDictionary.getPdfObject()); + PdfObject obj = sigField.getPdfObject().get(PdfName.F); + int flags = 0; + + if (obj != null && obj.isNumber()) { + flags = ((PdfNumber) obj).intValue(); + } + + flags |= PdfAnnotation.LOCKED; + sigField.put(PdfName.F, new PdfNumber(flags)); + + if (appearance.isInvisible()) { + // According to the spec, appearance stream is not required if the width and height of the rectangle are 0 + sigField.remove(PdfName.AP); + } else { + PdfDictionary ap = new PdfDictionary(); + ap.put(PdfName.N, appearance.getAppearance().getPdfObject()); + sigField.put(PdfName.AP, ap); + } + + sigField.setModified(); + + return sigFieldLock; + } + + /** + * Creates new signature form field and adds it to the acroForm object. + * This method is called during the {@link PdfSigner#preClose(Map)} method if the signature field doesn't exist. + * + * @param acroForm {@link PdfAcroForm} object in which new signature field will be added + * @param name the name of the field + * @return signature field lock dictionary + * @throws IOException if font for the appearance dictionary cannot be created + */ + protected PdfSigFieldLock createNewSignatureFormField(PdfAcroForm acroForm, String name) throws IOException { + PdfWidgetAnnotation widget = new PdfWidgetAnnotation(appearance.getPageRect()); + widget.setFlags(PdfAnnotation.PRINT | PdfAnnotation.LOCKED); + + PdfSignatureFormField sigField = PdfFormField.createSignature(document); + sigField.setFieldName(name); + sigField.put(PdfName.V, cryptoDictionary.getPdfObject()); + sigField.addKid(widget); + + PdfSigFieldLock sigFieldLock = sigField.getSigFieldLockDictionary(); + + if (this.fieldLock != null) { + this.fieldLock.getPdfObject().makeIndirect(document); + sigField.put(PdfName.Lock, this.fieldLock.getPdfObject()); + sigFieldLock = this.fieldLock; + } + + int pagen = appearance.getPageNumber(); + widget.setPage(document.getPage(pagen)); + + if (appearance.isInvisible()) { + // According to the spec, appearance stream is not required if the width and height of the rectangle are 0 + widget.remove(PdfName.AP); + } else { + PdfDictionary ap = widget.getAppearanceDictionary(); + if (ap == null) { + ap = new PdfDictionary(); + widget.put(PdfName.AP, ap); + } + ap.put(PdfName.N, appearance.getAppearance().getPdfObject()); + } + + acroForm.addField(sigField, document.getPage(pagen)); + + if (acroForm.getPdfObject().isIndirect()) { + acroForm.setModified(); + } else { + //Acroform dictionary is a Direct dictionary, + //for proper flushing, catalog needs to be marked as modified + document.getCatalog().setModified(); + } + + return sigFieldLock; + } + /** * Gets the document bytes that are hashable when using external signatures. * The general sequence is: diff --git a/sign/src/main/java/com/itextpdf/signatures/SignatureUtil.java b/sign/src/main/java/com/itextpdf/signatures/SignatureUtil.java index c63bdccb29..e829999415 100644 --- a/sign/src/main/java/com/itextpdf/signatures/SignatureUtil.java +++ b/sign/src/main/java/com/itextpdf/signatures/SignatureUtil.java @@ -340,9 +340,8 @@ public String getTranslatedFieldName(String name) { * * @param field the signature field name * @return an InputStream covering the revision. Returns null if it's not a signature field - * @throws IOException signals that an I/O exception has occurred. */ - public InputStream extractRevision(String field) throws IOException { + public InputStream extractRevision(String field) { getSignatureNames(); if (!sigNames.containsKey(field)) return null; diff --git a/sign/src/test/java/com/itextpdf/signatures/CertificateSupportedCriticalExtensionsTest.java b/sign/src/test/java/com/itextpdf/signatures/CertificateSupportedCriticalExtensionsTest.java index 24ccafc4ca..d8e3b19a17 100644 --- a/sign/src/test/java/com/itextpdf/signatures/CertificateSupportedCriticalExtensionsTest.java +++ b/sign/src/test/java/com/itextpdf/signatures/CertificateSupportedCriticalExtensionsTest.java @@ -51,10 +51,8 @@ This file is part of the iText (R) project. import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(UnitTest.class) public class CertificateSupportedCriticalExtensionsTest extends ExtendedITextTest { @@ -64,9 +62,6 @@ public static void beforeClass() { Security.addProvider(new BouncyCastleProvider()); } - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void supportedCriticalOIDsTest() { X509MockCertificate cert = new X509MockCertificate(); @@ -146,9 +141,9 @@ public void noUnsupportedCriticalOIDsTest() { @Test public void certificateIsNullTest() { - junitExpectedException.expect(IllegalArgumentException.class); - junitExpectedException.expectMessage("X509Certificate can't be null."); - - SignUtils.hasUnsupportedCriticalExtension(null); + Exception e = Assert.assertThrows(IllegalArgumentException.class, + () -> SignUtils.hasUnsupportedCriticalExtension(null) + ); + Assert.assertEquals("X509Certificate can't be null.", e.getMessage()); } } diff --git a/sign/src/test/java/com/itextpdf/signatures/OcspClientBouncyCastleTest.java b/sign/src/test/java/com/itextpdf/signatures/OcspClientBouncyCastleTest.java index 6c89bc5b61..54010b7938 100644 --- a/sign/src/test/java/com/itextpdf/signatures/OcspClientBouncyCastleTest.java +++ b/sign/src/test/java/com/itextpdf/signatures/OcspClientBouncyCastleTest.java @@ -49,6 +49,7 @@ This file is part of the iText (R) project. import com.itextpdf.test.annotations.LogMessages; import com.itextpdf.test.annotations.type.UnitTest; import com.itextpdf.test.signutils.Pkcs12FileHelper; + import org.bouncycastle.cert.ocsp.BasicOCSPResp; import org.bouncycastle.cert.ocsp.CertificateID; import org.bouncycastle.cert.ocsp.OCSPException; @@ -58,10 +59,8 @@ This file is part of the iText (R) project. import org.junit.Assert; import org.junit.Before; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; import java.security.PrivateKey; import java.security.Security; @@ -77,9 +76,6 @@ public class OcspClientBouncyCastleTest extends ExtendedITextTest { private static X509Certificate rootCert; private static TestOcspResponseBuilder builder; - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @BeforeClass public static void before() { Security.addProvider(new BouncyCastleProvider()); diff --git a/sign/src/test/java/com/itextpdf/signatures/PdfSignerUnitTest.java b/sign/src/test/java/com/itextpdf/signatures/PdfSignerUnitTest.java new file mode 100644 index 0000000000..db0e63e256 --- /dev/null +++ b/sign/src/test/java/com/itextpdf/signatures/PdfSignerUnitTest.java @@ -0,0 +1,161 @@ +/* + This file is part of the iText (R) project. + Copyright (c) 1998-2021 iText Group NV + Authors: iText Software. + + This program is offered under a commercial and under the AGPL license. + For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below. + + AGPL licensing: + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + */ +package com.itextpdf.signatures; + +import com.itextpdf.forms.PdfAcroForm; +import com.itextpdf.forms.PdfSigFieldLock; +import com.itextpdf.forms.fields.PdfFormField; +import com.itextpdf.forms.fields.PdfSignatureFormField; +import com.itextpdf.io.source.ByteArrayOutputStream; +import com.itextpdf.kernel.geom.Rectangle; +import com.itextpdf.kernel.pdf.EncryptionConstants; +import com.itextpdf.kernel.pdf.PdfDictionary; +import com.itextpdf.kernel.pdf.PdfDocument; +import com.itextpdf.kernel.pdf.PdfName; +import com.itextpdf.kernel.pdf.PdfReader; +import com.itextpdf.kernel.pdf.PdfWriter; +import com.itextpdf.kernel.pdf.ReaderProperties; +import com.itextpdf.kernel.pdf.StampingProperties; +import com.itextpdf.kernel.pdf.WriterProperties; +import com.itextpdf.kernel.pdf.annot.PdfWidgetAnnotation; +import com.itextpdf.test.ExtendedITextTest; +import com.itextpdf.test.annotations.type.UnitTest; +import org.junit.Assert; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import java.io.ByteArrayInputStream; +import java.io.IOException; + +@Category(UnitTest.class) +public class PdfSignerUnitTest extends ExtendedITextTest { + + @Test + public void createNewSignatureFormFieldInvisibleAnnotationTest() throws IOException { + PdfSigner signer = new PdfSigner( + new PdfReader(new ByteArrayInputStream(createDocumentWithoutWidgetAnnotation()), + new ReaderProperties().setPassword("owner".getBytes())), new ByteArrayOutputStream(), new StampingProperties()); + signer.cryptoDictionary = new PdfSignature(); + signer.appearance.setPageRect(new Rectangle(100, 100, 0, 0)); + + PdfAcroForm acroForm = PdfAcroForm.getAcroForm(signer.document, true); + signer.createNewSignatureFormField(acroForm, signer.fieldName); + PdfFormField formField = acroForm.getField(signer.fieldName); + + PdfDictionary formFieldDictionary = formField.getPdfObject(); + Assert.assertNotNull(formFieldDictionary); + Assert.assertFalse(formFieldDictionary.containsKey(PdfName.AP)); + } + + @Test + public void createNewSignatureFormFieldNotInvisibleAnnotationTest() throws IOException { + PdfSigner signer = new PdfSigner( + new PdfReader(new ByteArrayInputStream(createDocumentWithoutWidgetAnnotation()), + new ReaderProperties().setPassword("owner".getBytes())), new ByteArrayOutputStream(), new StampingProperties()); + signer.cryptoDictionary = new PdfSignature(); + signer.appearance.setPageRect(new Rectangle(100, 100, 10, 10)); + PdfSigFieldLock fieldLock = new PdfSigFieldLock(); + signer.fieldLock = fieldLock; + + PdfAcroForm acroForm = PdfAcroForm.getAcroForm(signer.document, true); + Assert.assertEquals(fieldLock, signer.createNewSignatureFormField(acroForm, signer.fieldName)); + PdfFormField formField = acroForm.getField(signer.fieldName); + + PdfDictionary formFieldDictionary = formField.getPdfObject(); + Assert.assertNotNull(formFieldDictionary); + Assert.assertTrue(formFieldDictionary.containsKey(PdfName.AP)); + } + + @Test + public void populateExistingSignatureFormFieldInvisibleAnnotationTest() throws IOException { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + PdfDocument document = new PdfDocument(new PdfWriter(outputStream, + new WriterProperties().setStandardEncryption("user".getBytes(), "owner".getBytes(), 0, EncryptionConstants.STANDARD_ENCRYPTION_128))); + document.addNewPage(); + PdfWidgetAnnotation widgetAnnotation = new PdfWidgetAnnotation(new Rectangle(100, 100, 0, 0)); + document.getPage(1).addAnnotation(widgetAnnotation); + document.close(); + PdfSigner signer = new PdfSigner( + new PdfReader(new ByteArrayInputStream(outputStream.toByteArray()), new ReaderProperties().setPassword("owner".getBytes())), + new ByteArrayOutputStream(), new StampingProperties()); + signer.cryptoDictionary = new PdfSignature(); + signer.appearance.setPageRect(new Rectangle(100, 100, 0, 0)); + + widgetAnnotation = (PdfWidgetAnnotation) signer.document.getPage(1).getAnnotations().get(0); + PdfAcroForm acroForm = PdfAcroForm.getAcroForm(signer.document, true); + PdfFormField formField = new ExtendedPdfSignatureFormField(widgetAnnotation, signer.document); + formField.setFieldName(signer.fieldName); + acroForm.addField(formField); + signer.populateExistingSignatureFormField(acroForm); + formField = acroForm.getField(signer.fieldName); + + PdfDictionary formFieldDictionary = formField.getPdfObject(); + Assert.assertNotNull(formFieldDictionary); + Assert.assertFalse(formFieldDictionary.containsKey(PdfName.AP)); + } + + @Test + public void populateExistingSignatureFormFieldNotInvisibleAnnotationTest() throws IOException { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + PdfDocument document = new PdfDocument(new PdfWriter(outputStream, + new WriterProperties().setStandardEncryption("user".getBytes(), "owner".getBytes(), 0, EncryptionConstants.STANDARD_ENCRYPTION_128))); + document.addNewPage(); + PdfWidgetAnnotation widgetAnnotation = new PdfWidgetAnnotation(new Rectangle(100, 100, 0, 0)); + document.getPage(1).addAnnotation(widgetAnnotation); + document.close(); + PdfSigner signer = new PdfSigner( + new PdfReader(new ByteArrayInputStream(outputStream.toByteArray()), new ReaderProperties().setPassword("owner".getBytes())), + new ByteArrayOutputStream(), new StampingProperties()); + signer.cryptoDictionary = new PdfSignature(); + PdfSigFieldLock fieldLock = new PdfSigFieldLock(); + signer.fieldLock = fieldLock; + signer.appearance.setPageRect(new Rectangle(100, 100, 10, 10)); + + widgetAnnotation = (PdfWidgetAnnotation) signer.document.getPage(1).getAnnotations().get(0); + PdfAcroForm acroForm = PdfAcroForm.getAcroForm(signer.document, true); + PdfFormField formField = new ExtendedPdfSignatureFormField(widgetAnnotation, signer.document); + formField.setFieldName(signer.fieldName); + acroForm.addField(formField); + Assert.assertEquals(signer.populateExistingSignatureFormField(acroForm), fieldLock); + formField = acroForm.getField(signer.fieldName); + + PdfDictionary formFieldDictionary = formField.getPdfObject(); + Assert.assertNotNull(formFieldDictionary); + Assert.assertTrue(formFieldDictionary.containsKey(PdfName.AP)); + } + + private static byte[] createDocumentWithoutWidgetAnnotation() { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + PdfDocument document = new PdfDocument(new PdfWriter(outputStream, + new WriterProperties().setStandardEncryption("user".getBytes(), "owner".getBytes(), 0, EncryptionConstants.STANDARD_ENCRYPTION_128))); + document.addNewPage(); + document.close(); + return outputStream.toByteArray(); + } + + static class ExtendedPdfSignatureFormField extends PdfSignatureFormField { + public ExtendedPdfSignatureFormField(PdfWidgetAnnotation widgetAnnotation, PdfDocument document) { + super(widgetAnnotation, document); + } + } +} diff --git a/sign/src/test/java/com/itextpdf/signatures/SignaturePolicyInfoTest.java b/sign/src/test/java/com/itextpdf/signatures/SignaturePolicyInfoTest.java index 66aafbaf53..e2fbe602c2 100644 --- a/sign/src/test/java/com/itextpdf/signatures/SignaturePolicyInfoTest.java +++ b/sign/src/test/java/com/itextpdf/signatures/SignaturePolicyInfoTest.java @@ -45,6 +45,7 @@ This file is part of the iText (R) project. import com.itextpdf.io.codec.Base64; import com.itextpdf.test.ExtendedITextTest; import com.itextpdf.test.annotations.type.UnitTest; + import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.DEROctetString; @@ -55,10 +56,8 @@ This file is part of the iText (R) project. import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(UnitTest.class) public class SignaturePolicyInfoTest extends ExtendedITextTest { @@ -68,9 +67,6 @@ public class SignaturePolicyInfoTest extends ExtendedITextTest { private final static String POLICY_DIGEST_ALGORITHM = "SHA-256"; private final static String POLICY_URI = "https://sede.060.gob.es/politica_de_firma_anexo_1.pdf"; - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void checkConstructorTest() { SignaturePolicyInfo info = new SignaturePolicyInfo(POLICY_IDENTIFIER, POLICY_HASH, @@ -95,58 +91,50 @@ public void checkConstructorWithEncodedHashTest() { @Test public void nullIdentifierIsNotAllowedTest() { - junitExpectedException.expect(IllegalArgumentException.class); - junitExpectedException.expectMessage("Policy identifier cannot be null"); - - new SignaturePolicyInfo(null, POLICY_HASH, - POLICY_DIGEST_ALGORITHM, POLICY_URI); - + Exception e = Assert.assertThrows(IllegalArgumentException.class, + () -> new SignaturePolicyInfo(null, POLICY_HASH, POLICY_DIGEST_ALGORITHM, POLICY_URI) + ); + Assert.assertEquals("Policy identifier cannot be null", e.getMessage()); } @Test public void emptyIdentifierIsNotAllowedTest() { - junitExpectedException.expect(IllegalArgumentException.class); - junitExpectedException.expectMessage("Policy identifier cannot be null"); - - new SignaturePolicyInfo("", POLICY_HASH, - POLICY_DIGEST_ALGORITHM, POLICY_URI); - + Exception e = Assert.assertThrows(IllegalArgumentException.class, + () -> new SignaturePolicyInfo("", POLICY_HASH, POLICY_DIGEST_ALGORITHM, POLICY_URI) + ); + Assert.assertEquals("Policy identifier cannot be null", e.getMessage()); } @Test public void nullPolicyHashIsNotAllowedTest() { - junitExpectedException.expect(IllegalArgumentException.class); - junitExpectedException.expectMessage("Policy hash cannot be null"); - - new SignaturePolicyInfo(POLICY_IDENTIFIER, (byte[]) null, - POLICY_DIGEST_ALGORITHM, POLICY_URI); + Exception e = Assert.assertThrows(IllegalArgumentException.class, + () -> new SignaturePolicyInfo(POLICY_IDENTIFIER, (byte[]) null, POLICY_DIGEST_ALGORITHM, POLICY_URI) + ); + Assert.assertEquals("Policy hash cannot be null", e.getMessage()); } @Test public void nullEncodedPolicyHashIsNotAllowedTest() { - junitExpectedException.expect(IllegalArgumentException.class); - junitExpectedException.expectMessage("Policy hash cannot be null"); - - new SignaturePolicyInfo(POLICY_IDENTIFIER, (String) null, - POLICY_DIGEST_ALGORITHM, POLICY_URI); + Exception e = Assert.assertThrows(IllegalArgumentException.class, + () -> new SignaturePolicyInfo(POLICY_IDENTIFIER, (String) null, POLICY_DIGEST_ALGORITHM, POLICY_URI) + ); + Assert.assertEquals("Policy hash cannot be null", e.getMessage()); } @Test public void nullDigestAlgorithmIsNotAllowedTest() { - junitExpectedException.expect(IllegalArgumentException.class); - junitExpectedException.expectMessage("Policy digest algorithm cannot be null"); - - new SignaturePolicyInfo(POLICY_IDENTIFIER, POLICY_HASH, - null, POLICY_URI); + Exception e = Assert.assertThrows(IllegalArgumentException.class, + () -> new SignaturePolicyInfo(POLICY_IDENTIFIER, POLICY_HASH, null, POLICY_URI) + ); + Assert.assertEquals("Policy digest algorithm cannot be null", e.getMessage()); } @Test public void emptyDigestAlgorithmIsNotAllowedTest() { - junitExpectedException.expect(IllegalArgumentException.class); - junitExpectedException.expectMessage("Policy digest algorithm cannot be null"); - - new SignaturePolicyInfo(POLICY_IDENTIFIER, POLICY_HASH, - "", POLICY_URI); + Exception e = Assert.assertThrows(IllegalArgumentException.class, + () -> new SignaturePolicyInfo(POLICY_IDENTIFIER, POLICY_HASH, "", POLICY_URI) + ); + Assert.assertEquals("Policy digest algorithm cannot be null", e.getMessage()); } @Test @@ -176,10 +164,11 @@ public void toSignaturePolicyIdentifierTest() { @Test public void toSignaturePolicyIdentifierUnexpectedAlgorithmTest() { - junitExpectedException.expect(IllegalArgumentException.class); - junitExpectedException.expectMessage("Invalid policy hash algorithm"); + SignaturePolicyInfo info = new SignaturePolicyInfo(POLICY_IDENTIFIER, POLICY_HASH, "SHA-12345", POLICY_URI); - new SignaturePolicyInfo(POLICY_IDENTIFIER, POLICY_HASH, - "SHA-12345", POLICY_URI).toSignaturePolicyIdentifier(); + Exception e = Assert.assertThrows(IllegalArgumentException.class, + () -> info.toSignaturePolicyIdentifier() + ); + Assert.assertEquals("Invalid policy hash algorithm", e.getMessage()); } } diff --git a/sign/src/test/java/com/itextpdf/signatures/SignatureUtilTest.java b/sign/src/test/java/com/itextpdf/signatures/SignatureUtilTest.java index 65f8af8f07..85e38fcc9e 100644 --- a/sign/src/test/java/com/itextpdf/signatures/SignatureUtilTest.java +++ b/sign/src/test/java/com/itextpdf/signatures/SignatureUtilTest.java @@ -42,11 +42,16 @@ This file is part of the iText (R) project. */ package com.itextpdf.signatures; +import com.itextpdf.kernel.PdfException; import com.itextpdf.kernel.pdf.PdfDocument; import com.itextpdf.kernel.pdf.PdfReader; import com.itextpdf.test.ExtendedITextTest; import com.itextpdf.test.annotations.type.IntegrationTest; + +import java.security.Security; +import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.junit.Assert; +import org.junit.BeforeClass; import org.junit.Test; import org.junit.experimental.categories.Category; @@ -58,6 +63,11 @@ public class SignatureUtilTest extends ExtendedITextTest { private static final String sourceFolder = "./src/test/resources/com/itextpdf/signatures/SignatureUtilTest/"; + @BeforeClass + public static void before() { + Security.addProvider(new BouncyCastleProvider()); + } + @Test public void getSignaturesTest01() throws IOException { String inPdf = sourceFolder + "simpleSignature.pdf"; @@ -168,4 +178,124 @@ public void notIndirectSigDictionaryTest() throws IOException { Assert.assertTrue(signatureUtil.signatureCoversWholeDocument("Signature1")); } + + @Test + public void emptySignatureReadSignatureDataTest() throws IOException { + String inPdf = sourceFolder + "emptySignature.pdf"; + PdfDocument pdfDocument = new PdfDocument(new PdfReader(inPdf)); + SignatureUtil signatureUtil = new SignatureUtil(pdfDocument); + + Assert.assertNull(signatureUtil.readSignatureData("Signature1", null)); + } + + @Test + public void readSignatureDataTest() throws IOException { + String inPdf = sourceFolder + "simpleSignature.pdf"; + PdfDocument pdfDocument = new PdfDocument(new PdfReader(inPdf)); + SignatureUtil signatureUtil = new SignatureUtil(pdfDocument); + + Assert.assertNotNull(signatureUtil.readSignatureData("Signature1")); + Assert.assertTrue(signatureUtil.readSignatureData("Signature1") instanceof PdfPKCS7); + } + + @Test + public void readSignatureDataWithSpecialSubFilterTest() throws IOException { + String inPdf = sourceFolder + "adbe.x509.rsa_sha1_signature.pdf"; + PdfDocument pdfDocument = new PdfDocument(new PdfReader(inPdf)); + SignatureUtil signatureUtil = new SignatureUtil(pdfDocument); + + Assert.assertNotNull(signatureUtil.readSignatureData("Signature1")); + Assert.assertTrue(signatureUtil.readSignatureData("Signature1") instanceof PdfPKCS7); + } + + @Test + public void byteRangeAndContentsEntriesTest() throws IOException { + String inPdf = sourceFolder + "byteRangeAndContentsEntries.pdf"; + PdfDocument pdfDocument = new PdfDocument(new PdfReader(inPdf)); + SignatureUtil signatureUtil = new SignatureUtil(pdfDocument); + + Assert.assertThrows(PdfException.class, + () -> signatureUtil.readSignatureData("Signature1")); + } + + @Test + public void doesSignatureFieldExistTest() throws IOException { + String inPdf = sourceFolder + "simpleSignature.pdf"; + PdfDocument pdfDocument = new PdfDocument(new PdfReader(inPdf)); + SignatureUtil signatureUtil = new SignatureUtil(pdfDocument); + + Assert.assertTrue(signatureUtil.doesSignatureFieldExist("Signature1")); + } + + @Test + public void doesSignatureFieldExistEmptySignatureTest() throws IOException { + String inPdf = sourceFolder + "emptySignature.pdf"; + PdfDocument pdfDocument = new PdfDocument(new PdfReader(inPdf)); + SignatureUtil signatureUtil = new SignatureUtil(pdfDocument); + + Assert.assertTrue(signatureUtil.doesSignatureFieldExist("Signature1")); + } + + @Test + public void signatureInTextTypeFieldTest() throws IOException { + String inPdf = sourceFolder + "signatureInTextTypeField.pdf"; + PdfDocument pdfDocument = new PdfDocument(new PdfReader(inPdf)); + SignatureUtil signatureUtil = new SignatureUtil(pdfDocument); + + Assert.assertFalse(signatureUtil.doesSignatureFieldExist("Signature1")); + } + + @Test + public void getTotalRevisionsTest() throws IOException { + String inPdf = sourceFolder + "simpleSignature.pdf"; + PdfDocument pdfDocument = new PdfDocument(new PdfReader(inPdf)); + SignatureUtil signatureUtil = new SignatureUtil(pdfDocument); + + Assert.assertEquals(1, signatureUtil.getTotalRevisions()); + } + + @Test + public void getRevisionTest() throws IOException { + String inPdf = sourceFolder + "simpleSignature.pdf"; + PdfDocument pdfDocument = new PdfDocument(new PdfReader(inPdf)); + SignatureUtil signatureUtil = new SignatureUtil(pdfDocument); + + Assert.assertEquals(1, signatureUtil.getRevision("Signature1")); + } + + @Test + public void getRevisionEmptyFieldsTest() throws IOException { + String inPdf = sourceFolder + "emptySignature.pdf"; + PdfDocument pdfDocument = new PdfDocument(new PdfReader(inPdf)); + SignatureUtil signatureUtil = new SignatureUtil(pdfDocument); + + Assert.assertEquals(0, signatureUtil.getRevision("Signature1")); + } + + @Test + public void getRevisionXfaFormTest() throws IOException { + String inPdf = sourceFolder + "simpleSignatureWithXfa.pdf"; + PdfDocument pdfDocument = new PdfDocument(new PdfReader(inPdf)); + SignatureUtil signatureUtil = new SignatureUtil(pdfDocument); + + Assert.assertEquals(1, signatureUtil.getRevision("Signature1")); + } + + @Test + public void extractRevisionTest() throws IOException { + String inPdf = sourceFolder + "simpleSignature.pdf"; + PdfDocument pdfDocument = new PdfDocument(new PdfReader(inPdf)); + SignatureUtil signatureUtil = new SignatureUtil(pdfDocument); + + Assert.assertNotNull(signatureUtil.extractRevision("Signature1")); + } + + @Test + public void extractRevisionNotSignatureFieldTest() throws IOException { + String inPdf = sourceFolder + "signatureInTextTypeField.pdf"; + PdfDocument pdfDocument = new PdfDocument(new PdfReader(inPdf)); + SignatureUtil signatureUtil = new SignatureUtil(pdfDocument); + + Assert.assertNull(signatureUtil.extractRevision("Signature1")); + } } diff --git a/sign/src/test/java/com/itextpdf/signatures/sign/CrlClientOnlineTest.java b/sign/src/test/java/com/itextpdf/signatures/sign/CrlClientOnlineTest.java index a45ffafe77..44a6c5e0d7 100644 --- a/sign/src/test/java/com/itextpdf/signatures/sign/CrlClientOnlineTest.java +++ b/sign/src/test/java/com/itextpdf/signatures/sign/CrlClientOnlineTest.java @@ -42,32 +42,140 @@ This file is part of the iText (R) project. */ package com.itextpdf.signatures.sign; +import com.itextpdf.io.LogMessageConstant; +import com.itextpdf.kernel.crypto.CryptoUtil; import com.itextpdf.signatures.CrlClientOnline; +import com.itextpdf.signatures.testutils.X509MockCertificate; import com.itextpdf.test.ExtendedITextTest; +import com.itextpdf.test.LogLevelConstants; +import com.itextpdf.test.annotations.LogMessage; +import com.itextpdf.test.annotations.LogMessages; import com.itextpdf.test.annotations.type.UnitTest; -import org.junit.Assert; -import org.junit.Test; -import org.junit.experimental.categories.Category; +import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.net.MalformedURLException; import java.net.URL; +import java.security.cert.Certificate; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.Collection; +import org.junit.Assert; +import org.junit.Test; +import org.junit.experimental.categories.Category; @Category(UnitTest.class) public class CrlClientOnlineTest extends ExtendedITextTest { + private static final String certSrc = "./src/test/resources/com/itextpdf/signatures/sign/CrlClientOnlineTest/"; + private static final String certWithMalformedUrl = certSrc + "certWithMalformedUrl.crt"; + private static final String certWithCorrectUrl = certSrc + "certWithCorrectUrl.crt"; private static final String destinationFolder = "./target/test/com/itextpdf/signatures/sign/"; @Test public void crlClientOnlineURLConstructorTest() throws MalformedURLException { String PROTOCOL = "file://"; - URL[] urls = new URL[]{ + URL[] urls = new URL[] { new URL(PROTOCOL + destinationFolder + "duplicateFolder"), new URL(PROTOCOL + destinationFolder + "duplicateFolder"), new URL(PROTOCOL + destinationFolder + "uniqueFolder"), }; CrlClientOnline crlClientOnline = new CrlClientOnline(urls); - Assert.assertTrue(crlClientOnline.getUrlsSize() == 2); + Assert.assertEquals(2, crlClientOnline.getUrlsSize()); + } + + @Test + @LogMessages(messages = { + @LogMessage(messageTemplate = "Added CRL url: https://examples.com", logLevel = LogLevelConstants.INFO), + }) + public void addCrlUrlTest() { + CrlClientOnline crlClientOnline = new CrlClientOnline("https://examples.com"); + Assert.assertEquals(1, crlClientOnline.getUrlsSize()); + } + + @Test + @LogMessages(messages = { + @LogMessage(messageTemplate = "Skipped CRL url (malformed):", logLevel = LogLevelConstants.INFO), + }) + public void addEmptyCrlUrlTest() { + CrlClientOnline crlClientOnline = new CrlClientOnline(""); + Assert.assertEquals(0, crlClientOnline.getUrlsSize()); + } + + @Test + @LogMessages(messages = { + @LogMessage(messageTemplate = "Skipped CRL url (malformed):", logLevel = LogLevelConstants.INFO), + }) + public void addWrongCrlUrlTest() { + CrlClientOnline crlClientOnline = new CrlClientOnline("test"); + Assert.assertEquals(0, crlClientOnline.getUrlsSize()); + } + + @Test + @LogMessages(messages = { + @LogMessage(messageTemplate = "Checking certificate: ", logLevel = LogLevelConstants.INFO), + @LogMessage(messageTemplate = "Skipped CRL url (malformed): test", + logLevel = LogLevelConstants.INFO) + }) + public void checkCrlCertWithMalformedUrlTest() throws CertificateException, FileNotFoundException { + Certificate chain = CryptoUtil.readPublicCertificate(new FileInputStream(certWithMalformedUrl)); + CrlClientOnline crlClientOnline = new CrlClientOnline(new Certificate[] {chain}); + Assert.assertEquals(0, crlClientOnline.getUrlsSize()); + } + + @Test + @LogMessages(messages = { + @LogMessage(messageTemplate = "Checking certificate: ", logLevel = LogLevelConstants.INFO), + @LogMessage(messageTemplate = "Added CRL url: http://www.example.com/crl/test.crl", + logLevel = LogLevelConstants.INFO) + }) + public void checkCrlCertWithCorrectUrlTest() throws CertificateException, FileNotFoundException { + Certificate chain = CryptoUtil.readPublicCertificate(new FileInputStream(certWithCorrectUrl)); + CrlClientOnline crlClientOnline = new CrlClientOnline(new Certificate[] {chain}); + Assert.assertEquals(1, crlClientOnline.getUrlsSize()); + } + + @Test + public void cannotGetEncodedWhenCertIsNullTest() { + CrlClientOnline crlClientOnline = new CrlClientOnline(); + Assert.assertNull(crlClientOnline.getEncoded(null, "")); + Assert.assertEquals(0, crlClientOnline.getUrlsSize()); + } + + @Test + @LogMessages(messages = { + @LogMessage(messageTemplate = "Added CRL url: http://www.example.com/crl/test.crl", logLevel = + LogLevelConstants.INFO), + @LogMessage(messageTemplate = "Checking CRL: http://www.example.com/crl/test.crl", logLevel = + LogLevelConstants.INFO), + @LogMessage(messageTemplate = LogMessageConstant.INVALID_DISTRIBUTION_POINT, logLevel = + LogLevelConstants.INFO) + }) + public void unreachableCrlDistributionPointTest() { + CrlClientOnline crlClientOnline = new CrlClientOnline("http://www.example.com/crl/test.crl"); + X509Certificate checkCert = new X509MockCertificate(); + Collection bytes = crlClientOnline.getEncoded(checkCert, "http://www.example.com/crl/test.crl"); + Assert.assertTrue(bytes.isEmpty()); + Assert.assertEquals(1, crlClientOnline.getUrlsSize()); + } + + @Test + @LogMessages(messages = { + @LogMessage(messageTemplate = "Looking for CRL for certificate ", logLevel = LogLevelConstants.INFO), + @LogMessage(messageTemplate = "Found CRL url: http://www.example.com/crl/test.crl", logLevel = + LogLevelConstants.INFO), + @LogMessage(messageTemplate = "Checking CRL: http://www.example.com/crl/test.crl", logLevel = + LogLevelConstants.INFO), + @LogMessage(messageTemplate = LogMessageConstant.INVALID_DISTRIBUTION_POINT, logLevel = + LogLevelConstants.INFO) + }) + public void unreachableCrlDistributionPointFromCertChainTest() { + CrlClientOnline crlClientOnline = new CrlClientOnline(); + X509Certificate checkCert = new X509MockCertificate(); + Collection bytes = crlClientOnline.getEncoded(checkCert, "http://www.example.com/crl/test.crl"); + Assert.assertTrue(bytes.isEmpty()); + Assert.assertEquals(0, crlClientOnline.getUrlsSize()); } } diff --git a/sign/src/test/java/com/itextpdf/signatures/sign/PadesSigTest.java b/sign/src/test/java/com/itextpdf/signatures/sign/PadesSigTest.java index f5a9914691..4afb60491f 100644 --- a/sign/src/test/java/com/itextpdf/signatures/sign/PadesSigTest.java +++ b/sign/src/test/java/com/itextpdf/signatures/sign/PadesSigTest.java @@ -54,6 +54,7 @@ This file is part of the iText (R) project. import com.itextpdf.signatures.PrivateKeySignature; import com.itextpdf.signatures.SignaturePolicyInfo; import com.itextpdf.signatures.SignatureUtil; +import com.itextpdf.signatures.testutils.SignaturesCompareTool; import com.itextpdf.test.ExtendedITextTest; import com.itextpdf.test.annotations.type.IntegrationTest; import com.itextpdf.test.signutils.Pkcs12FileHelper; @@ -96,6 +97,8 @@ public void padesRsaSigTest01() throws IOException, GeneralSecurityException { signApproval(certsSrc + "signCertRsa01.p12", destinationFolder + "padesRsaSigTest01.pdf"); basicCheckSignedDoc(destinationFolder + "padesRsaSigTest01.pdf", "Signature1"); + Assert.assertNull(SignaturesCompareTool.compareSignatures(destinationFolder + + "padesRsaSigTest01.pdf", sourceFolder + "cmp_padesRsaSigTest01.pdf")); } @Test @@ -103,6 +106,8 @@ public void padesRsaSigTestWithChain01() throws IOException, GeneralSecurityExce signApproval(certsSrc + "signCertRsaWithChain.p12", destinationFolder + "padesRsaSigTestWithChain01.pdf"); basicCheckSignedDoc(destinationFolder + "padesRsaSigTestWithChain01.pdf", "Signature1"); + Assert.assertNull(SignaturesCompareTool.compareSignatures(destinationFolder + + "padesRsaSigTestWithChain01.pdf", sourceFolder + "cmp_padesRsaSigTestWithChain01.pdf")); } @Test @@ -117,6 +122,8 @@ public void padesEccSigTest01() throws IOException, GeneralSecurityException { destinationFolder + "padesEccSigTest01.pdf"); basicCheckSignedDoc(destinationFolder + "padesEccSigTest01.pdf", "Signature1"); + Assert.assertNull(SignaturesCompareTool.compareSignatures(destinationFolder + + "padesEccSigTest01.pdf", sourceFolder + "cmp_padesEccSigTest01.pdf")); } @Test @@ -135,6 +142,8 @@ public void padesEpesProfileTest01() throws IOException, GeneralSecurityExceptio signApproval(certsSrc + "signCertRsa01.p12", destinationFolder + "padesEpesProfileTest01.pdf", sigPolicyIdentifier); basicCheckSignedDoc(destinationFolder + "padesEpesProfileTest01.pdf", "Signature1"); + Assert.assertNull(SignaturesCompareTool.compareSignatures(destinationFolder + + "padesEpesProfileTest01.pdf", sourceFolder + "cmp_padesEpesProfileTest01.pdf")); } @Test @@ -148,6 +157,8 @@ public void signaturePolicyInfoUnavailableUrlTest() throws IOException, GeneralS signApproval(certsSrc + "signCertRsa01.p12", signedFileName, spi); basicCheckSignedDoc(signedFileName, "Signature1"); + Assert.assertNull(SignaturesCompareTool.compareSignatures(signedFileName, + sourceFolder + "cmp_signaturePolicyInfoUnavailableUrl_signed.pdf")); } private void signApproval(String signCertFileName, String outFileName) throws IOException, GeneralSecurityException { diff --git a/sign/src/test/java/com/itextpdf/signatures/sign/Pdf20SigningTest.java b/sign/src/test/java/com/itextpdf/signatures/sign/Pdf20SigningTest.java index f540696829..b20b55d5e8 100644 --- a/sign/src/test/java/com/itextpdf/signatures/sign/Pdf20SigningTest.java +++ b/sign/src/test/java/com/itextpdf/signatures/sign/Pdf20SigningTest.java @@ -50,10 +50,8 @@ This file is part of the iText (R) project. import org.junit.Assert; import org.junit.Before; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(IntegrationTest.class) public class Pdf20SigningTest extends ExtendedITextTest { @@ -65,9 +63,6 @@ public class Pdf20SigningTest extends ExtendedITextTest { private Certificate[] chain; private PrivateKey pk; - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @BeforeClass public static void before() { Security.addProvider(new BouncyCastleProvider()); diff --git a/sign/src/test/java/com/itextpdf/signatures/sign/PdfASigningTest.java b/sign/src/test/java/com/itextpdf/signatures/sign/PdfASigningTest.java index 3305625b09..f65890a7e9 100644 --- a/sign/src/test/java/com/itextpdf/signatures/sign/PdfASigningTest.java +++ b/sign/src/test/java/com/itextpdf/signatures/sign/PdfASigningTest.java @@ -58,14 +58,13 @@ This file is part of the iText (R) project. import com.itextpdf.test.signutils.Pkcs12FileHelper; import com.itextpdf.test.ExtendedITextTest; import com.itextpdf.test.annotations.type.IntegrationTest; + import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.junit.Assert; import org.junit.Before; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; import java.io.FileOutputStream; import java.io.IOException; @@ -94,9 +93,6 @@ public class PdfASigningTest extends ExtendedITextTest { private Certificate[] chain; private PrivateKey pk; - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @BeforeClass public static void before() { Security.addProvider(new BouncyCastleProvider()); diff --git a/sign/src/test/java/com/itextpdf/signatures/sign/PdfSignatureAppearanceTest.java b/sign/src/test/java/com/itextpdf/signatures/sign/PdfSignatureAppearanceTest.java index 2346b6e7fe..4952d9d23f 100644 --- a/sign/src/test/java/com/itextpdf/signatures/sign/PdfSignatureAppearanceTest.java +++ b/sign/src/test/java/com/itextpdf/signatures/sign/PdfSignatureAppearanceTest.java @@ -56,12 +56,15 @@ This file is part of the iText (R) project. import com.itextpdf.signatures.BouncyCastleDigest; import com.itextpdf.signatures.DigestAlgorithms; import com.itextpdf.signatures.IExternalSignature; +import com.itextpdf.signatures.PdfPKCS7; import com.itextpdf.signatures.PdfSignatureAppearance; import com.itextpdf.signatures.PdfSigner; import com.itextpdf.signatures.PrivateKeySignature; +import com.itextpdf.signatures.SignatureUtil; import com.itextpdf.test.signutils.Pkcs12FileHelper; import com.itextpdf.test.ExtendedITextTest; import com.itextpdf.test.annotations.type.IntegrationTest; + import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.junit.Assert; import org.junit.Before; @@ -242,6 +245,105 @@ public void signaturesOnRotatedPages() throws IOException, GeneralSecurityExcept Assert.assertEquals("", assertionResults.toString()); } + @Test + public void signatureFieldNotMergedWithWidgetTest() throws IOException, GeneralSecurityException { + try (PdfDocument outputDoc = new PdfDocument(new PdfReader( + sourceFolder + "signatureFieldNotMergedWithWidget.pdf"))) { + + SignatureUtil sigUtil = new SignatureUtil(outputDoc); + PdfPKCS7 signatureData = sigUtil.readSignatureData("Signature1"); + Assert.assertTrue(signatureData.verifySignatureIntegrityAndAuthenticity()); + } + } + + @Test + // TODO: DEVSIX-5162 (the signature is expected to have auto-generated appearance, but now it's empty) + public void signExistingNotMergedFieldNotReusedAPTest() throws GeneralSecurityException, + IOException, InterruptedException { + // Field is not merged with widget and has /P key + String src = sourceFolder + "emptyFieldNotMerged.pdf"; + String fileName = "signExistingNotMergedFieldNotReusedAP.pdf"; + String dest = destinationFolder + fileName; + + PdfReader reader = new PdfReader(src); + + PdfSigner signer = new PdfSigner(reader, new FileOutputStream(dest), new StampingProperties()); + signer.setCertificationLevel(PdfSigner.NOT_CERTIFIED); + + signer.getSignatureAppearance() + .setLayer2Text("Verified and signed by me.") + .setReason("Test 1") + .setLocation("TestCity") + .setReuseAppearance(false); + signer.setFieldName("Signature1"); + + IExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256, + BouncyCastleProvider.PROVIDER_NAME); + signer.signDetached(new BouncyCastleDigest(), pks, chain, null, null, null, + 0, PdfSigner.CryptoStandard.CADES); + + Assert.assertNull(new CompareTool().compareVisually( + dest, sourceFolder + "cmp_" + fileName, destinationFolder, "diff_")); + } + + @Test + // TODO: DEVSIX-5162 (signature appearance expected to be updated (reused appearance will be used as a background)) + public void signExistingNotMergedFieldReusedAPTest() throws GeneralSecurityException, + IOException, InterruptedException { + // Field is not merged with widget and has /P key + String src = sourceFolder + "emptyFieldNotMerged.pdf"; + String fileName = "signExistingNotMergedFieldReusedAP.pdf"; + String dest = destinationFolder + fileName; + + PdfReader reader = new PdfReader(src); + + PdfSigner signer = new PdfSigner(reader, new FileOutputStream(dest), new StampingProperties()); + signer.setCertificationLevel(PdfSigner.NOT_CERTIFIED); + + signer.getSignatureAppearance() + .setLayer2Text("Verified and signed by me.") + .setReason("Test 1") + .setLocation("TestCity") + .setReuseAppearance(true); + signer.setFieldName("Signature1"); + + IExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256, + BouncyCastleProvider.PROVIDER_NAME); + signer.signDetached(new BouncyCastleDigest(), pks, chain, null, null, null, + 0, PdfSigner.CryptoStandard.CADES); + + Assert.assertNull(new CompareTool().compareVisually( + dest, sourceFolder + "cmp_" + fileName, destinationFolder, "diff_")); + } + + @Test + // TODO: DEVSIX-5162 (remove expected exception after fix) + public void signExistingNotMergedFieldReusedAPEntryNDicTest() throws GeneralSecurityException, + IOException, InterruptedException { + // Field is not merged with widget and has /P key + String src = sourceFolder + "emptyFieldNotMergedEntryNDict.pdf"; + String fileName = "signExistingNotMergedFieldReusedAPEntryNDic.pdf"; + String dest = destinationFolder + fileName; + + PdfReader reader = new PdfReader(src); + + PdfSigner signer = new PdfSigner(reader, new FileOutputStream(dest), new StampingProperties()); + signer.setCertificationLevel(PdfSigner.NOT_CERTIFIED); + + signer.getSignatureAppearance() + .setLayer2Text("Verified and signed by me.") + .setReason("Test 1") + .setLocation("TestCity") + .setReuseAppearance(true); + signer.setFieldName("Signature1"); + + IExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256, + BouncyCastleProvider.PROVIDER_NAME); + + Assert.assertThrows(NullPointerException.class, () -> signer.signDetached(new BouncyCastleDigest(), + pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES)); + } + private void testSignatureOnRotatedPage(int pageNum, PdfSignatureAppearance.RenderingMode renderingMode, StringBuilder assertionResults) throws IOException, GeneralSecurityException, InterruptedException { String fileName = "signaturesOnRotatedPages" + pageNum + "_mode_" + renderingMode.name() + ".pdf"; String src = sourceFolder + "documentWithRotatedPages.pdf"; diff --git a/sign/src/test/java/com/itextpdf/signatures/sign/PdfSignatureTest.java b/sign/src/test/java/com/itextpdf/signatures/sign/PdfSignatureTest.java new file mode 100644 index 0000000000..d2bb0ea05f --- /dev/null +++ b/sign/src/test/java/com/itextpdf/signatures/sign/PdfSignatureTest.java @@ -0,0 +1,145 @@ +/* + This file is part of the iText (R) project. + Copyright (c) 1998-2021 iText Group NV + Authors: iText Software. + + This program is offered under a commercial and under the AGPL license. + For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below. + + AGPL licensing: + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + */ +package com.itextpdf.signatures.sign; + +import com.itextpdf.kernel.pdf.PdfArray; +import com.itextpdf.kernel.pdf.PdfDocument; +import com.itextpdf.kernel.pdf.PdfName; +import com.itextpdf.kernel.pdf.PdfReader; +import com.itextpdf.kernel.pdf.PdfString; +import com.itextpdf.signatures.PdfSignature; +import com.itextpdf.signatures.PdfSignatureApp; +import com.itextpdf.signatures.SignatureUtil; +import com.itextpdf.test.ExtendedITextTest; +import com.itextpdf.test.annotations.type.UnitTest; + +import java.io.IOException; +import org.junit.Assert; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +@Category(UnitTest.class) +public class PdfSignatureTest extends ExtendedITextTest { + public static final String sourceFolder = "./src/test/resources/com/itextpdf/signatures/sign/PdfSignatureTest/"; + + @Test + public void setByteRangeTest() throws IOException { + try (PdfDocument doc = new PdfDocument(new PdfReader( + sourceFolder + "simpleSignature.pdf"))) { + + SignatureUtil sigUtil = new SignatureUtil(doc); + PdfSignature signature = sigUtil.getSignature("Signature1"); + + int[] byteRange = {0, 141, 16526, 2494}; + signature.setByteRange(byteRange); + + PdfArray expected = new PdfArray((new int[] {0, 141, 16526, 2494})); + + Assert.assertArrayEquals(expected.toIntArray(), signature.getByteRange().toIntArray()); + } + } + + @Test + public void setContentsTest() throws IOException { + try (PdfDocument doc = new PdfDocument(new PdfReader( + sourceFolder + "simpleSignature.pdf"))) { + + SignatureUtil sigUtil = new SignatureUtil(doc); + PdfSignature signature = sigUtil.getSignature("Signature1"); + + byte[] newContents = new PdfString("new iText signature").getValueBytes(); + signature.setContents(newContents); + + Assert.assertEquals("new iText signature", signature.getContents().getValue()); + } + } + + @Test + public void setAndGetCertTest() throws IOException { + try (PdfDocument doc = new PdfDocument(new PdfReader( + sourceFolder + "adbe.x509.rsa_sha1_signature.pdf"))) { + + SignatureUtil sigUtil = new SignatureUtil(doc); + PdfSignature signature = sigUtil.getSignature("Signature1"); + + byte[] certChain = new PdfString("Hello, iText!!").getValueBytes(); + signature.setCert(certChain); + + Assert.assertEquals("Hello, iText!!", signature.getCertObject().toString()); + } + } + + @Test + public void getCertObjectTest() throws IOException { + try (PdfDocument doc = new PdfDocument(new PdfReader( + sourceFolder + "adbe.x509.rsa_sha1_signature.pdf"))) { + + SignatureUtil sigUtil = new SignatureUtil(doc); + PdfSignature signature = sigUtil.getSignature("Signature1"); + + Assert.assertTrue(signature.getCertObject().isArray()); + } + } + + @Test + public void setAndGetNameTest() throws IOException { + try (PdfDocument doc = new PdfDocument(new PdfReader( + sourceFolder + "simpleSignature.pdf"))) { + + SignatureUtil sigUtil = new SignatureUtil(doc); + PdfSignature signature = sigUtil.getSignature("Signature1"); + + Assert.assertNull(signature.getName()); + + String name = "iText person"; + signature.setName(name); + + Assert.assertEquals(name, signature.getName()); + } + } + + @Test + public void setSignatureCreatorTest() throws IOException { + try (PdfDocument doc = new PdfDocument(new PdfReader( + sourceFolder + "noPropBuilds.pdf"))) { + + SignatureUtil sigUtil = new SignatureUtil(doc); + PdfSignature signature = sigUtil.getSignature("Signature1"); + + Assert.assertNull(signature.getPdfObject().getAsDictionary(PdfName.Prop_Build)); + + signature.setSignatureCreator("iText.Name"); + + String propBuild = signature.getPdfObject().getAsDictionary(PdfName.Prop_Build) + .getAsDictionary(PdfName.App).getAsName(PdfName.Name).getValue(); + + Assert.assertEquals("iText.Name", propBuild); + } + } + + @Test + public void pdfSignatureAppDefaultConstructorTest() { + PdfSignatureApp signatureApp = new PdfSignatureApp(); + Assert.assertTrue(signatureApp.getPdfObject().isDictionary()); + } +} diff --git a/sign/src/test/java/com/itextpdf/signatures/sign/SigningTest.java b/sign/src/test/java/com/itextpdf/signatures/sign/SigningTest.java index 89209c78f4..b47391d515 100644 --- a/sign/src/test/java/com/itextpdf/signatures/sign/SigningTest.java +++ b/sign/src/test/java/com/itextpdf/signatures/sign/SigningTest.java @@ -61,14 +61,13 @@ This file is part of the iText (R) project. import com.itextpdf.test.signutils.Pkcs12FileHelper; import com.itextpdf.test.ExtendedITextTest; import com.itextpdf.test.annotations.type.IntegrationTest; + import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.junit.Assert; import org.junit.Before; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; import java.io.FileInputStream; import java.io.FileOutputStream; @@ -99,9 +98,6 @@ public class SigningTest extends ExtendedITextTest { private Certificate[] chain; private PrivateKey pk; - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @BeforeClass public static void before() { Security.addProvider(new BouncyCastleProvider()); @@ -247,9 +243,6 @@ public void signPdf2Cades() throws GeneralSecurityException, IOException, Interr @Test public void signPdf2CertificationAfterApproval() throws GeneralSecurityException, IOException { - junitExpectedException.expect(PdfException.class); - junitExpectedException.expectMessage(PdfException.CertificationSignatureCreationFailedDocShallNotContainSigs); - String srcFile = "approvalSignedDocPdf2.pdf"; String file = "signedPdf2CertificationAfterApproval.pdf"; String src = sourceFolder + srcFile; @@ -258,8 +251,11 @@ public void signPdf2CertificationAfterApproval() throws GeneralSecurityException Rectangle rect = new Rectangle(30, 50, 200, 100); String fieldName = "Signature2"; - sign(src, fieldName, dest, chain, pk, DigestAlgorithms.RIPEMD160, - PdfSigner.CryptoStandard.CADES, "Test 1", "TestCity", rect, false, true, PdfSigner.CERTIFIED_NO_CHANGES_ALLOWED, null); + + Exception e = Assert.assertThrows(PdfException.class, + () -> sign(src, fieldName, dest, chain, pk, DigestAlgorithms.RIPEMD160, PdfSigner.CryptoStandard.CADES, + "Test 1", "TestCity", rect, false, true, PdfSigner.CERTIFIED_NO_CHANGES_ALLOWED, null)); + Assert.assertEquals(PdfException.CertificationSignatureCreationFailedDocShallNotContainSigs, e.getMessage()); } @Test diff --git a/sign/src/test/java/com/itextpdf/signatures/testutils/SignaturesCompareTool.java b/sign/src/test/java/com/itextpdf/signatures/testutils/SignaturesCompareTool.java new file mode 100644 index 0000000000..1f8c31910a --- /dev/null +++ b/sign/src/test/java/com/itextpdf/signatures/testutils/SignaturesCompareTool.java @@ -0,0 +1,292 @@ +/* + + This file is part of the iText (R) project. + Copyright (c) 1998-2021 iText Group NV + Authors: Bruno Lowagie, Paulo Soares, et al. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License version 3 + as published by the Free Software Foundation with the addition of the + following permission added to Section 15 as permitted in Section 7(a): + FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY + ITEXT GROUP. ITEXT GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT + OF THIRD PARTY RIGHTS + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Affero General Public License for more details. + You should have received a copy of the GNU Affero General Public License + along with this program; if not, see http://www.gnu.org/licenses or write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA, 02110-1301 USA, or download the license from the following URL: + http://itextpdf.com/terms-of-use/ + + The interactive user interfaces in modified source and object code versions + of this program must display Appropriate Legal Notices, as required under + Section 5 of the GNU Affero General Public License. + + In accordance with Section 7(b) of the GNU Affero General Public License, + a covered work must retain the producer line in every PDF that is created + or manipulated using iText. + + You can be released from the requirements of the license by purchasing + a commercial license. Buying such a license is mandatory as soon as you + develop commercial activities involving the iText software without + disclosing the source code of your own applications. + These activities include: offering paid services to customers as an ASP, + serving PDFs on the fly in a web application, shipping iText with a closed + source product. + + For more information, please contact iText Software Corp. at this + address: sales@itextpdf.com + */ +package com.itextpdf.signatures.testutils; + +import com.itextpdf.io.util.UrlUtil; +import com.itextpdf.kernel.pdf.PdfDocument; +import com.itextpdf.kernel.pdf.PdfReader; +import com.itextpdf.signatures.PdfSignature; +import com.itextpdf.signatures.SignatureUtil; +import org.bouncycastle.asn1.ASN1InputStream; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.ASN1OctetString; +import org.bouncycastle.asn1.ASN1Primitive; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.ASN1Set; +import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.util.ASN1Dump; + +import java.io.ByteArrayInputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.util.List; + +public class SignaturesCompareTool { + private static final String OID_MESSAGE_DIGEST = "1.2.840.113549.1.9.4"; + private static final String OID_SIGNED_DATA = "1.2.840.113549.1.7.2"; + + public static String compareSignatures(String dest, String cmp) throws IOException { + StringBuilder errorText = new StringBuilder(); + + try (PdfDocument outDocument = new PdfDocument(new PdfReader(dest)); + PdfDocument cmpDocument = new PdfDocument(new PdfReader(cmp))) { + SignatureUtil outSigUtil = new SignatureUtil(outDocument); + SignatureUtil cmpSigUtil = new SignatureUtil(cmpDocument); + if (!cmpSigUtil.getSignatureNames().equals(outSigUtil.getSignatureNames())) { + addError(errorText, "Signatures lists are different:", + String.valueOf(outSigUtil.getSignatureNames()), + String.valueOf(cmpSigUtil.getSignatureNames())); + } + + List signatures = cmpSigUtil.getSignatureNames(); + for (String sig : signatures) { + boolean isFailed = false; + ASN1Sequence outSignedData = (ASN1Sequence) getSignatureContent(sig, outSigUtil); + ASN1Sequence cmpSignedData = (ASN1Sequence) getSignatureContent(sig, cmpSigUtil); + if (outSignedData.size() != cmpSignedData.size() || outSignedData.size() != 2) { + addError(errorText, "Signature top level elements count is incorrect (should be exactly 2):", + String.valueOf(outSignedData.size()), + String.valueOf(cmpSignedData.size())); + isFailed = true; + } + + ASN1ObjectIdentifier outObjId = (ASN1ObjectIdentifier) outSignedData.getObjectAt(0); + ASN1ObjectIdentifier cmpObjId = (ASN1ObjectIdentifier) cmpSignedData.getObjectAt(0); + if (!outObjId.equals(cmpObjId) || !outObjId.getId().equals(OID_SIGNED_DATA)) { + addError(errorText, "Signatures object identifier is incorrect (should be " + + OID_SIGNED_DATA + ")", + String.valueOf(outObjId.getId()), + String.valueOf(cmpObjId.getId())); + isFailed = true; + } + + ASN1Sequence outContent = (ASN1Sequence) ((ASN1TaggedObject) outSignedData.getObjectAt(1)).getObject(); + ASN1Sequence cmpContent = (ASN1Sequence) ((ASN1TaggedObject) cmpSignedData.getObjectAt(1)).getObject(); + if (outContent.size() != cmpContent.size()) { + addError(errorText, "Signatures base elements counts are different", + String.valueOf(outContent.size()), + String.valueOf(cmpContent.size())); + isFailed = true; + } + + int signerInfoIndex = getSignerInfoIndex(cmpContent); + if (outContent.getObjectAt(signerInfoIndex) instanceof ASN1TaggedObject) { + addError(errorText, "SignerInfo object indexes are different", null, null); + isFailed = true; + } + + for (int i = 0; i < cmpContent.size(); i++) { + + // SignerInfo objects will be compared separately + if (i == signerInfoIndex) { + continue; + } + + if (!cmpContent.getObjectAt(i).equals(outContent.getObjectAt(i))) { + addError(errorText, "SignedData objects are different", null, null); + isFailed = true; + } + } + + ASN1Set cmpSignerInfos = (ASN1Set) cmpContent.getObjectAt(signerInfoIndex); + ASN1Set outSignerInfos = (ASN1Set) outContent.getObjectAt(signerInfoIndex); + + // Currently, iText signature validation mechanism do not support signatures, + // containing more than one SignerInfo entry. However, it is still valid signature. + if (cmpSignerInfos.size() != outSignerInfos.size() || cmpSignerInfos.size() != 1) { + addError(errorText, "Incorrect SignerInfos objects count", String.valueOf(outSignerInfos.size()), + String.valueOf(cmpSignerInfos.size())); + isFailed = true; + } + + ASN1Sequence outSignerInfo = (ASN1Sequence) cmpSignerInfos.getObjectAt(0); + ASN1Sequence cmpSignerInfo = (ASN1Sequence) outSignerInfos.getObjectAt(0); + if (cmpSignerInfo.size() != outSignerInfo.size()) { + addError(errorText, "Incorrect SignerInfo entries count", String.valueOf(outSignerInfo.size()), + String.valueOf(cmpSignerInfo.size())); + isFailed = true; + } + + for (int i = 0; i < cmpSignerInfo.size(); i++) { + + // Skipping comparison of ASN1OctetString fields in SignerInfo. SignerInfo is expected to have + // a single field of ASN1OctetString which is SignatureValue, that is expected to be + // different in each signature instance. + if (outSignerInfo.getObjectAt(i) instanceof ASN1OctetString) { + if (cmpSignerInfo.getObjectAt(i) instanceof ASN1OctetString) { + continue; + } else { + addError(errorText, "Signature values indexes are different!", null, null); + isFailed = true; + } + } + + if (!isFailed) { + isFailed = compareAsn1Structures(outSignerInfo.getObjectAt(i).toASN1Primitive(), + cmpSignerInfo.getObjectAt(i).toASN1Primitive(), errorText); + } + } + + if (isFailed) { + String sigFileName = dest.substring(0, dest.lastIndexOf(".")); + String outSigFile = sigFileName + "_out.txt"; + String cmpSigFile = sigFileName + "_cmp.txt"; + writeToFile(outSigFile, sig + "\n" + ASN1Dump.dumpAsString(outSignedData, true)+ "\n"); + writeToFile(cmpSigFile, sig + "\n" + ASN1Dump.dumpAsString(cmpSignedData, true)+ "\n"); + + errorText.insert(0, "See signature output files: \nout: " + + UrlUtil.getNormalizedFileUriString(outSigFile) + "\ncmp: " + + UrlUtil.getNormalizedFileUriString(cmpSigFile) + "\n"); + } + } + } catch (Exception e) { + errorText.append(e.getMessage()).append("\n"); + } + + if (!errorText.toString().isEmpty()) { + return errorText.toString(); + } else { + return null; + } + } + + private static void writeToFile(String path, String content) throws IOException { + try (FileWriter writer = new FileWriter(path, true)) { + writer.write(content); + } + } + + private static int getSignerInfoIndex(ASN1Sequence baseElement) { + for (int i = 3; i < baseElement.size(); i++) { + if (!(baseElement.getObjectAt(i) instanceof ASN1TaggedObject)) { + return i; + } + } + + throw new IllegalStateException("SignerInfo entry has not been found."); + } + + private static boolean compareAsn1Structures(ASN1Primitive out, ASN1Primitive cmp, StringBuilder errorText) { + boolean isFailed = false; + if (!out.getClass().equals(cmp.getClass())) { + addError(errorText, "ASN1 objects types are different", out.getClass().getName(), + cmp.getClass().getName()); + isFailed = true; + } + + if (cmp instanceof ASN1TaggedObject || cmp instanceof ASN1Sequence) { + ASN1Sequence cmpObject; + ASN1Sequence outObject; + if (cmp instanceof ASN1TaggedObject) { + ASN1TaggedObject cmpTag = (ASN1TaggedObject) cmp; + ASN1TaggedObject outTag = (ASN1TaggedObject) out; + if (!(cmpTag.getObject() instanceof ASN1Sequence)) { + if (!cmpTag.getObject().equals(outTag.getObject())) { + addError(errorText, "ASN1 objects are different", ASN1Dump.dumpAsString(outTag, true), + ASN1Dump.dumpAsString(cmpTag, true)); + isFailed = true; + } + + return isFailed; + } + + cmpObject = (ASN1Sequence) (cmpTag).getObject(); + outObject = (ASN1Sequence) (outTag).getObject(); + } else { + cmpObject = (ASN1Sequence) cmp; + outObject = (ASN1Sequence) out; + } + + if (cmpObject.getObjectAt(0) instanceof ASN1ObjectIdentifier) { + ASN1ObjectIdentifier objectIdentifier = (ASN1ObjectIdentifier) (cmpObject.getObjectAt(0)); + + // Message digest should be ignored during comparing + if (objectIdentifier.getId().equals(OID_MESSAGE_DIGEST)) { + return isFailed; + } + } + for (int i = 0; i < cmpObject.size(); i++) { + if (!isFailed) { + isFailed = compareAsn1Structures(outObject.getObjectAt(i).toASN1Primitive(), + cmpObject.getObjectAt(i).toASN1Primitive(), errorText); + } + } + } else if (cmp instanceof ASN1Set) { + ASN1Set cmpSet = (ASN1Set) cmp; + ASN1Set outSet = (ASN1Set) out; + if (!isFailed) { + isFailed = compareAsn1Structures(cmpSet.getObjectAt(0).toASN1Primitive(), + outSet.getObjectAt(0).toASN1Primitive(), errorText); + } + } else { + if (!cmp.equals(out)) { + addError(errorText, "ASN1 objects are different", ASN1Dump.dumpAsString(out, true), + ASN1Dump.dumpAsString(cmp, true)); + isFailed = true; + } + } + + return isFailed; + } + + private static void addError(StringBuilder errorBuilder, String errorText, String out, String cmp) { + errorBuilder.append(errorText); + if (null != out) { + errorBuilder.append("\nout: ").append(out); + } + + if (null != cmp) { + errorBuilder.append("\ncmp: ").append(cmp); + } + + errorBuilder.append("\n\n"); + } + + private static ASN1Primitive getSignatureContent(String signatureName, SignatureUtil util) throws IOException { + PdfSignature signature = util.getSignature(signatureName); + byte[] contents = signature.getContents().getValueBytes(); + ASN1InputStream inputStream = new ASN1InputStream(new ByteArrayInputStream(contents)); + return inputStream.readObject(); + } +} diff --git a/sign/src/test/java/com/itextpdf/signatures/verify/CrlVerifierTest.java b/sign/src/test/java/com/itextpdf/signatures/verify/CrlVerifierTest.java index ae3907012d..e7f267bcb5 100644 --- a/sign/src/test/java/com/itextpdf/signatures/verify/CrlVerifierTest.java +++ b/sign/src/test/java/com/itextpdf/signatures/verify/CrlVerifierTest.java @@ -55,10 +55,8 @@ This file is part of the iText (R) project. import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; import java.io.ByteArrayInputStream; import java.io.IOException; @@ -74,9 +72,6 @@ public class CrlVerifierTest extends ExtendedITextTest { private static final String certsSrc = "./src/test/resources/com/itextpdf/signatures/certs/"; private static final char[] password = "testpass".toCharArray(); - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @BeforeClass public static void before() { Security.addProvider(new BouncyCastleProvider()); @@ -91,8 +86,6 @@ public void validCrl01() throws GeneralSecurityException, IOException { @Test public void invalidRevokedCrl01() throws GeneralSecurityException, IOException { - junitExpectedException.expect(VerificationException.class); - X509Certificate caCert = (X509Certificate) Pkcs12FileHelper.readFirstChain(certsSrc + "rootRsa.p12", password)[0]; TestCrlBuilder crlBuilder = new TestCrlBuilder(caCert, DateTimeUtil.addDaysToDate(DateTimeUtil.getCurrentTimeDate(), -1)); @@ -100,7 +93,7 @@ public void invalidRevokedCrl01() throws GeneralSecurityException, IOException { X509Certificate checkCert = (X509Certificate) Pkcs12FileHelper.readFirstChain(checkCertFileName, password)[0]; crlBuilder.addCrlEntry(checkCert, DateTimeUtil.addDaysToDate(DateTimeUtil.getCurrentTimeDate(), -40), CRLReason.keyCompromise); - verifyTest(crlBuilder); + Assert.assertThrows(VerificationException.class, () -> verifyTest(crlBuilder)); } @Test diff --git a/sign/src/test/java/com/itextpdf/signatures/verify/OcspVerifierTest.java b/sign/src/test/java/com/itextpdf/signatures/verify/OcspVerifierTest.java index 9888a7ff8e..320688c4ea 100644 --- a/sign/src/test/java/com/itextpdf/signatures/verify/OcspVerifierTest.java +++ b/sign/src/test/java/com/itextpdf/signatures/verify/OcspVerifierTest.java @@ -51,6 +51,7 @@ This file is part of the iText (R) project. import com.itextpdf.signatures.testutils.client.TestOcspClient; import com.itextpdf.test.ExtendedITextTest; import com.itextpdf.test.annotations.type.UnitTest; + import java.io.IOException; import java.security.GeneralSecurityException; import java.security.KeyPair; @@ -73,10 +74,8 @@ This file is part of the iText (R) project. import org.bouncycastle.operator.OperatorCreationException; import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(UnitTest.class) public class OcspVerifierTest extends ExtendedITextTest { @@ -84,9 +83,6 @@ public class OcspVerifierTest extends ExtendedITextTest { private static final char[] password = "testpass".toCharArray(); private static final String caCertFileName = certsSrc + "rootRsa.p12"; - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @BeforeClass public static void before() { Security.addProvider(new BouncyCastleProvider()); @@ -165,16 +161,15 @@ public void expiredAuthorizedOCSPResponderTest_atValidPeriod() throws GeneralSec @Test public void expiredAuthorizedOCSPResponderTest_now() throws GeneralSecurityException, IOException, OperatorCreationException { - junitExpectedException.expect(CertificateExpiredException.class); - Date ocspResponderCertStartDate = DateTimeUtil.parseSimpleFormat("15/10/2005", "dd/MM/yyyy"); Date ocspResponderCertEndDate = DateTimeUtil.parseSimpleFormat("15/10/2010", "dd/MM/yyyy"); Date checkDate = DateTimeUtil.getCurrentTimeDate(); - boolean verifyRes = verifyAuthorizedOCSPResponderTest(ocspResponderCertStartDate, ocspResponderCertEndDate, checkDate); - + Assert.assertThrows(CertificateExpiredException.class, + () -> verifyAuthorizedOCSPResponderTest(ocspResponderCertStartDate, ocspResponderCertEndDate, checkDate) + ); // Not getting here because of exception - Assert.assertFalse(verifyRes); + //Assert.assertFalse(verifyRes); } private boolean verifyTest(TestOcspResponseBuilder rootRsaOcspBuilder) throws IOException, GeneralSecurityException { diff --git a/sign/src/test/resources/com/itextpdf/signatures/SignatureUtilTest/adbe.x509.rsa_sha1_signature.pdf b/sign/src/test/resources/com/itextpdf/signatures/SignatureUtilTest/adbe.x509.rsa_sha1_signature.pdf new file mode 100644 index 0000000000..7d7087295a Binary files /dev/null and b/sign/src/test/resources/com/itextpdf/signatures/SignatureUtilTest/adbe.x509.rsa_sha1_signature.pdf differ diff --git a/sign/src/test/resources/com/itextpdf/signatures/SignatureUtilTest/byteRangeAndContentsEntries.pdf b/sign/src/test/resources/com/itextpdf/signatures/SignatureUtilTest/byteRangeAndContentsEntries.pdf new file mode 100644 index 0000000000..9a5dc6bdec Binary files /dev/null and b/sign/src/test/resources/com/itextpdf/signatures/SignatureUtilTest/byteRangeAndContentsEntries.pdf differ diff --git a/sign/src/test/resources/com/itextpdf/signatures/SignatureUtilTest/emptySignature.pdf b/sign/src/test/resources/com/itextpdf/signatures/SignatureUtilTest/emptySignature.pdf new file mode 100644 index 0000000000..27abc10e7a Binary files /dev/null and b/sign/src/test/resources/com/itextpdf/signatures/SignatureUtilTest/emptySignature.pdf differ diff --git a/sign/src/test/resources/com/itextpdf/signatures/SignatureUtilTest/signatureInTextTypeField.pdf b/sign/src/test/resources/com/itextpdf/signatures/SignatureUtilTest/signatureInTextTypeField.pdf new file mode 100644 index 0000000000..fc2283223f Binary files /dev/null and b/sign/src/test/resources/com/itextpdf/signatures/SignatureUtilTest/signatureInTextTypeField.pdf differ diff --git a/sign/src/test/resources/com/itextpdf/signatures/SignatureUtilTest/simpleSignature.pdf b/sign/src/test/resources/com/itextpdf/signatures/SignatureUtilTest/simpleSignature.pdf index 77d75abddb..d6fb2f0fcb 100644 Binary files a/sign/src/test/resources/com/itextpdf/signatures/SignatureUtilTest/simpleSignature.pdf and b/sign/src/test/resources/com/itextpdf/signatures/SignatureUtilTest/simpleSignature.pdf differ diff --git a/sign/src/test/resources/com/itextpdf/signatures/SignatureUtilTest/simpleSignatureWithXfa.pdf b/sign/src/test/resources/com/itextpdf/signatures/SignatureUtilTest/simpleSignatureWithXfa.pdf new file mode 100644 index 0000000000..4d98c92174 Binary files /dev/null and b/sign/src/test/resources/com/itextpdf/signatures/SignatureUtilTest/simpleSignatureWithXfa.pdf differ diff --git a/sign/src/test/resources/com/itextpdf/signatures/sign/CrlClientOnlineTest/certWithCorrectUrl.crt b/sign/src/test/resources/com/itextpdf/signatures/sign/CrlClientOnlineTest/certWithCorrectUrl.crt new file mode 100644 index 0000000000..ecdb81dc39 --- /dev/null +++ b/sign/src/test/resources/com/itextpdf/signatures/sign/CrlClientOnlineTest/certWithCorrectUrl.crt @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDsDCCApigAwIBAgIUNEV43yu30XhiADq991vPrx9zOoAwDQYJKoZIhvcNAQEL +BQAwdDELMAkGA1UEBhMCQlkxDjAMBgNVBAgMBU1pbnNrMQ4wDAYDVQQHDAVNaW5z +azEOMAwGA1UECgwFaVRleHQxDTALBgNVBAsMBHRlc3QxJjAkBgNVBAMMHWlUZXh0 +VGVzdENybERpc3RyaWJ1dGlvblBvaW50MCAXDTIxMDMxMDEzMTczM1oYDzIxMjEw +MjE0MTMxNzMzWjB0MQswCQYDVQQGEwJCWTEOMAwGA1UECAwFTWluc2sxDjAMBgNV +BAcMBU1pbnNrMQ4wDAYDVQQKDAVpVGV4dDENMAsGA1UECwwEdGVzdDEmMCQGA1UE +AwwdaVRleHRUZXN0Q3JsRGlzdHJpYnV0aW9uUG9pbnQwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQChNayHcvy8EvPHY14s1MLQ2OYBwoem4BHGfzFD1zHW +TMAXPtz5ilJMFeCL+j6kv/4w2YumlhGqE4Yw0nwkqCi5u8fb8Z9OevZ5jwDqPohY +B24XX/6tnwFWzgH5NPXOEyJPVzrxR6MaJohpPneXzgSH7nraz6G8MSfz+K1JRbJk +tEPcFsPOXCLCxeZjrRpNCcpZWJtG9aI6fu8Fh2x+tVeB9HvGHeTn1wrx67+w18nR +boblkU/kK+4GfkKjPX1xPTLcFXLWksCrfs5C8VgBM7ATf0S3HBFc+B4J5vuBq8Ii +ZP3JG4h5mPqBW21lYBId/eEiimuxST5wQmLU0qutj0+zAgMBAAGjODA2MDQGA1Ud +HwQtMCswKaAnoCWGI2h0dHA6Ly93d3cuZXhhbXBsZS5jb20vY3JsL3Rlc3QuY3Js +MA0GCSqGSIb3DQEBCwUAA4IBAQAIiQedJwzxEaO+x3pCk2PoDsNTjd26iz2B/UT0 +ZaLMJGAZ05TY5zPdl0XNKLtv6JWs+/Qi7aJJawIQAkXKNtIGK202zRI4O2LLTZQH +R4qZfPCol6Toa51QNlX3fRJscxFdWGV0ZVWxxWxdlM5999Uv3nyd7cPlxzMFUSmy +VJFra56yH662pRWmBOJPWqNu89mkNx+2NJQKwglc48xsoUsxioapNLlzuhUaNWjG +XE2rbsxo0SDWe+VnM84l9dy/ZNnOpgUOUKX4gX3xsFb7QqpiQsgDrBt/zlSuEYBq +xZ3KNwCgnnO08pnw+O79+K3chzDvIpb/Fspo5QfMXJ51PH+5 +-----END CERTIFICATE----- diff --git a/sign/src/test/resources/com/itextpdf/signatures/sign/CrlClientOnlineTest/certWithMalformedUrl.crt b/sign/src/test/resources/com/itextpdf/signatures/sign/CrlClientOnlineTest/certWithMalformedUrl.crt new file mode 100644 index 0000000000..3a5c23a40b --- /dev/null +++ b/sign/src/test/resources/com/itextpdf/signatures/sign/CrlClientOnlineTest/certWithMalformedUrl.crt @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDkzCCAnugAwIBAgIUNXnTZeCFNAsX+7rx1BfZdGP10eYwDQYJKoZIhvcNAQEL +BQAwdTELMAkGA1UEBhMCQlkxDjAMBgNVBAgMBU1pbnNrMQ4wDAYDVQQHDAVNaW5z +azEOMAwGA1UECgwFaVRleHQxDTALBgNVBAsMBHRlc3QxJzAlBgNVBAMMHmlUZXh0 +VGVzdENybERpc3RyaWJ1dGlvblBvaW50czAgFw0yMTAzMjMxMzA0MDNaGA8yMTIx +MDIyNzEzMDQwM1owdTELMAkGA1UEBhMCQlkxDjAMBgNVBAgMBU1pbnNrMQ4wDAYD +VQQHDAVNaW5zazEOMAwGA1UECgwFaVRleHQxDTALBgNVBAsMBHRlc3QxJzAlBgNV +BAMMHmlUZXh0VGVzdENybERpc3RyaWJ1dGlvblBvaW50czCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBALbR6klJOy08Vj5ByLGz/vpipZ3omLZA7l+YzEv1 +9NsUfE3u2dN9pqYjC/WbjlICNuZt9fZQGHYJrZgJVqK50g/dS0t4Tp+Hu1jGv8qt +cG/lOQvbxT9hs22DFWz+J87bs9bnKT4VPCnTMNwdVyLPpCWl3yv4Jc6YJZ5qoj0w +hCfx4yB+lIB2EZqH8gCPUrMA/RETY/hpH69QkUK928ht7mu0AXthR9+HWbEs9eIM +MZY2ucbr72HYm9+6fpmwnnlCj88sVuBWfyFD3pGNvkgXGFMmUJNYPzjDQkfrNHzm +aKKBenx2lmRDqtf0ThmleQOsCBgn69cMkcgJ/3nEB/Rj9eECAwEAAaMZMBcwFQYD +VR0fBA4wDDAKoAigBoYEdGVzdDANBgkqhkiG9w0BAQsFAAOCAQEAs0eBwsrKv/tt +ry04lXIIob7CYshhDPiu0+yqC2P6zS7RXJXG/0Sj0LybHdJY0kMouoOPAS5VQ7rj +ntpdn5p+iM7xZat46P2Ugvhbxm1xvJ2FH8pQvdb5px8miUqp34plRi/sLhw4S9RR +FS5DtBU03jTjfwRsxq3N/Jo16fr/VyS4oeQGXCLCjHSvEOfhaohNbvvltsueWyNz +WGGADQsSmjUTfyUjP/N25T3oU/t0GxdzvR7KyVf/q6EPbxFI8lI8InQrSRVXz/tg +yEvG6i066XYCB5CeyrWdUD1oJGA/jWSarXlYl42+IrOOjT31k6NN5IeQ+ZHI0Kn3 +WAEZ3sdEfQ== +-----END CERTIFICATE----- diff --git a/sign/src/test/resources/com/itextpdf/signatures/sign/PadesSigTest/cmp_padesEccSigTest01.pdf b/sign/src/test/resources/com/itextpdf/signatures/sign/PadesSigTest/cmp_padesEccSigTest01.pdf index 87aade0874..a3efe13968 100644 Binary files a/sign/src/test/resources/com/itextpdf/signatures/sign/PadesSigTest/cmp_padesEccSigTest01.pdf and b/sign/src/test/resources/com/itextpdf/signatures/sign/PadesSigTest/cmp_padesEccSigTest01.pdf differ diff --git a/sign/src/test/resources/com/itextpdf/signatures/sign/PadesSigTest/cmp_padesEpesProfileTest01.pdf b/sign/src/test/resources/com/itextpdf/signatures/sign/PadesSigTest/cmp_padesEpesProfileTest01.pdf index 272e9102e2..50c1357e58 100644 Binary files a/sign/src/test/resources/com/itextpdf/signatures/sign/PadesSigTest/cmp_padesEpesProfileTest01.pdf and b/sign/src/test/resources/com/itextpdf/signatures/sign/PadesSigTest/cmp_padesEpesProfileTest01.pdf differ diff --git a/sign/src/test/resources/com/itextpdf/signatures/sign/PadesSigTest/cmp_padesRsaSigTest01.pdf b/sign/src/test/resources/com/itextpdf/signatures/sign/PadesSigTest/cmp_padesRsaSigTest01.pdf index 6e4a8ee82f..898576dbba 100644 Binary files a/sign/src/test/resources/com/itextpdf/signatures/sign/PadesSigTest/cmp_padesRsaSigTest01.pdf and b/sign/src/test/resources/com/itextpdf/signatures/sign/PadesSigTest/cmp_padesRsaSigTest01.pdf differ diff --git a/sign/src/test/resources/com/itextpdf/signatures/sign/PadesSigTest/cmp_padesRsaSigTestWithChain01.pdf b/sign/src/test/resources/com/itextpdf/signatures/sign/PadesSigTest/cmp_padesRsaSigTestWithChain01.pdf new file mode 100644 index 0000000000..0a8dd03e73 Binary files /dev/null and b/sign/src/test/resources/com/itextpdf/signatures/sign/PadesSigTest/cmp_padesRsaSigTestWithChain01.pdf differ diff --git a/sign/src/test/resources/com/itextpdf/signatures/sign/PadesSigTest/cmp_signaturePolicyInfoUnavailableUrl_signed.pdf b/sign/src/test/resources/com/itextpdf/signatures/sign/PadesSigTest/cmp_signaturePolicyInfoUnavailableUrl_signed.pdf new file mode 100644 index 0000000000..4a8a85f4c2 Binary files /dev/null and b/sign/src/test/resources/com/itextpdf/signatures/sign/PadesSigTest/cmp_signaturePolicyInfoUnavailableUrl_signed.pdf differ diff --git a/sign/src/test/resources/com/itextpdf/signatures/sign/PdfSignatureAppearanceTest/cmp_signExistingNotMergedFieldNotReusedAP.pdf b/sign/src/test/resources/com/itextpdf/signatures/sign/PdfSignatureAppearanceTest/cmp_signExistingNotMergedFieldNotReusedAP.pdf new file mode 100644 index 0000000000..ae6a4703ab Binary files /dev/null and b/sign/src/test/resources/com/itextpdf/signatures/sign/PdfSignatureAppearanceTest/cmp_signExistingNotMergedFieldNotReusedAP.pdf differ diff --git a/sign/src/test/resources/com/itextpdf/signatures/sign/PdfSignatureAppearanceTest/cmp_signExistingNotMergedFieldReusedAP.pdf b/sign/src/test/resources/com/itextpdf/signatures/sign/PdfSignatureAppearanceTest/cmp_signExistingNotMergedFieldReusedAP.pdf new file mode 100644 index 0000000000..19e22c1506 Binary files /dev/null and b/sign/src/test/resources/com/itextpdf/signatures/sign/PdfSignatureAppearanceTest/cmp_signExistingNotMergedFieldReusedAP.pdf differ diff --git a/sign/src/test/resources/com/itextpdf/signatures/sign/PdfSignatureAppearanceTest/emptyFieldNotMerged.pdf b/sign/src/test/resources/com/itextpdf/signatures/sign/PdfSignatureAppearanceTest/emptyFieldNotMerged.pdf new file mode 100644 index 0000000000..fc80332f03 Binary files /dev/null and b/sign/src/test/resources/com/itextpdf/signatures/sign/PdfSignatureAppearanceTest/emptyFieldNotMerged.pdf differ diff --git a/sign/src/test/resources/com/itextpdf/signatures/sign/PdfSignatureAppearanceTest/emptyFieldNotMergedEntryNDict.pdf b/sign/src/test/resources/com/itextpdf/signatures/sign/PdfSignatureAppearanceTest/emptyFieldNotMergedEntryNDict.pdf new file mode 100644 index 0000000000..aca0c82fc4 Binary files /dev/null and b/sign/src/test/resources/com/itextpdf/signatures/sign/PdfSignatureAppearanceTest/emptyFieldNotMergedEntryNDict.pdf differ diff --git a/sign/src/test/resources/com/itextpdf/signatures/sign/PdfSignatureAppearanceTest/signatureFieldNotMergedWithWidget.pdf b/sign/src/test/resources/com/itextpdf/signatures/sign/PdfSignatureAppearanceTest/signatureFieldNotMergedWithWidget.pdf new file mode 100644 index 0000000000..d7ef3afb98 Binary files /dev/null and b/sign/src/test/resources/com/itextpdf/signatures/sign/PdfSignatureAppearanceTest/signatureFieldNotMergedWithWidget.pdf differ diff --git a/sign/src/test/resources/com/itextpdf/signatures/sign/PdfSignatureTest/adbe.x509.rsa_sha1_signature.pdf b/sign/src/test/resources/com/itextpdf/signatures/sign/PdfSignatureTest/adbe.x509.rsa_sha1_signature.pdf new file mode 100644 index 0000000000..2223c4b4db Binary files /dev/null and b/sign/src/test/resources/com/itextpdf/signatures/sign/PdfSignatureTest/adbe.x509.rsa_sha1_signature.pdf differ diff --git a/sign/src/test/resources/com/itextpdf/signatures/sign/PdfSignatureTest/emptySignature01.pdf b/sign/src/test/resources/com/itextpdf/signatures/sign/PdfSignatureTest/emptySignature01.pdf new file mode 100644 index 0000000000..27abc10e7a Binary files /dev/null and b/sign/src/test/resources/com/itextpdf/signatures/sign/PdfSignatureTest/emptySignature01.pdf differ diff --git a/sign/src/test/resources/com/itextpdf/signatures/sign/PdfSignatureTest/noPropBuilds.pdf b/sign/src/test/resources/com/itextpdf/signatures/sign/PdfSignatureTest/noPropBuilds.pdf new file mode 100644 index 0000000000..2547e2c774 Binary files /dev/null and b/sign/src/test/resources/com/itextpdf/signatures/sign/PdfSignatureTest/noPropBuilds.pdf differ diff --git a/sign/src/test/resources/com/itextpdf/signatures/sign/PdfSignatureTest/simpleSignature.pdf b/sign/src/test/resources/com/itextpdf/signatures/sign/PdfSignatureTest/simpleSignature.pdf new file mode 100644 index 0000000000..77d75abddb Binary files /dev/null and b/sign/src/test/resources/com/itextpdf/signatures/sign/PdfSignatureTest/simpleSignature.pdf differ diff --git a/styled-xml-parser/pom.xml b/styled-xml-parser/pom.xml index 1cd651948d..dc0bceef08 100644 --- a/styled-xml-parser/pom.xml +++ b/styled-xml-parser/pom.xml @@ -4,7 +4,7 @@ com.itextpdf root - 7.1.15 + 7.1.16 styled-xml-parser iText 7 - Styled XML Parser diff --git a/styled-xml-parser/src/main/java/com/itextpdf/styledxmlparser/css/CommonCssConstants.java b/styled-xml-parser/src/main/java/com/itextpdf/styledxmlparser/css/CommonCssConstants.java index 62d57e91b5..75eaeaadc9 100644 --- a/styled-xml-parser/src/main/java/com/itextpdf/styledxmlparser/css/CommonCssConstants.java +++ b/styled-xml-parser/src/main/java/com/itextpdf/styledxmlparser/css/CommonCssConstants.java @@ -84,6 +84,11 @@ public class CommonCssConstants { */ public static final String ALIGN_SELF = "align-self"; + /** + * The constant ATTRIBUTE. + */ + public static final String ATTRIBUTE = "attr"; + /** * The Constant BACKGROUND. */ @@ -1427,6 +1432,11 @@ public class CommonCssConstants { */ public static final String STRETCH = "stretch"; + /** + * The Constant STRING. + */ + public static final String STRING = "string"; + /** * The Constant THICK. */ @@ -1760,6 +1770,11 @@ public class CommonCssConstants { */ public static final String TARGET = "target"; + /** + * The Constant URL. + */ + public static final String URL = "url"; + /** * The Constant VALID. */ diff --git a/styled-xml-parser/src/main/java/com/itextpdf/styledxmlparser/css/util/CssTypesValidationUtils.java b/styled-xml-parser/src/main/java/com/itextpdf/styledxmlparser/css/util/CssTypesValidationUtils.java index 981fa620ad..82df2292cd 100644 --- a/styled-xml-parser/src/main/java/com/itextpdf/styledxmlparser/css/util/CssTypesValidationUtils.java +++ b/styled-xml-parser/src/main/java/com/itextpdf/styledxmlparser/css/util/CssTypesValidationUtils.java @@ -49,7 +49,7 @@ private CssTypesValidationUtils() { /** * Checks whether a string contains an allowed metric unit in HTML/CSS; rad, deg and grad. * - * @param value the string that needs to be checked + * @param valueArgument the string that needs to be checked * @return boolean true if value contains an allowed angle value */ public static boolean isAngleValue(final String valueArgument) { @@ -92,7 +92,7 @@ public static boolean isColorProperty(String value) { /** * Checks whether a string contains an allowed value relative to parent value. * - * @param value the string that needs to be checked + * @param valueArgument the string that needs to be checked * @return boolean true if value contains a em value */ public static boolean isEmValue(final String valueArgument) { @@ -109,7 +109,7 @@ public static boolean isEmValue(final String valueArgument) { /** * Checks whether a string contains an allowed value relative to element font height. * - * @param value the string that needs to be checked + * @param valueArgument the string that needs to be checked * @return boolean true if value contains a ex value */ public static boolean isExValue(final String valueArgument) { @@ -126,7 +126,7 @@ public static boolean isExValue(final String valueArgument) { /** * Checks whether a string contains an allowed metric unit in HTML/CSS; px, in, cm, mm, pc, Q or pt. * - * @param value the string that needs to be checked + * @param valueArgument the string that needs to be checked * @return boolean true if value contains an allowed metric value */ public static boolean isMetricValue(final String valueArgument) { @@ -178,7 +178,7 @@ public static boolean isNumericValue(final String value) { /** * Checks whether a string contains a percentage value * - * @param value the string that needs to be checked + * @param valueArgument the string that needs to be checked * @return boolean true if value contains an allowed percentage value */ public static boolean isPercentageValue(final String valueArgument) { @@ -195,7 +195,7 @@ public static boolean isPercentageValue(final String valueArgument) { /** * Checks whether a string contains an allowed value relative to previously set value. * - * @param value the string that needs to be checked + * @param valueArgument the string that needs to be checked * @return boolean true if value contains an allowed metric value */ public static boolean isRelativeValue(final String valueArgument) { @@ -217,7 +217,7 @@ public static boolean isRelativeValue(final String valueArgument) { /** * Checks whether a string contains an allowed value relative to previously set root value. * - * @param value the string that needs to be checked + * @param valueArgument the string that needs to be checked * @return boolean true if value contains a rem value */ public static boolean isRemValue(final String valueArgument) { diff --git a/styled-xml-parser/src/main/java/com/itextpdf/styledxmlparser/css/util/CssUtils.java b/styled-xml-parser/src/main/java/com/itextpdf/styledxmlparser/css/util/CssUtils.java index 2ec3a5f09b..a83d30be76 100644 --- a/styled-xml-parser/src/main/java/com/itextpdf/styledxmlparser/css/util/CssUtils.java +++ b/styled-xml-parser/src/main/java/com/itextpdf/styledxmlparser/css/util/CssUtils.java @@ -53,6 +53,8 @@ This file is part of the iText (R) project. import com.itextpdf.styledxmlparser.css.parse.CssDeclarationValueTokenizer.Token; import com.itextpdf.styledxmlparser.css.parse.CssDeclarationValueTokenizer.TokenType; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import java.util.ArrayList; import java.util.List; @@ -72,6 +74,8 @@ public class CssUtils { private static final Logger logger = LoggerFactory.getLogger(CssUtils.class); + private static final int QUANTITY_OF_PARAMS_WITH_FALLBACK_OR_TYPE = 2; + /** * Creates a new {@link CssUtils} instance. */ @@ -623,6 +627,45 @@ public static String extractUrl(final String url) { return str; } + /** + * Parses string and return attribute value. + * + * @param attrStr the string contains attr() to extract attribute value + * @param element the parentNode from which we extract information + * @return the value of attribute + */ + public static String extractAttributeValue(final String attrStr, IElementNode element) { + String attrValue = null; + if (attrStr.startsWith(CommonCssConstants.ATTRIBUTE + '(') + && attrStr.length() > CommonCssConstants.ATTRIBUTE.length() + 2 && attrStr.endsWith(")")) { + String fallback = null; + String typeOfAttribute = null; + final String stringToSplit = attrStr.substring(5, attrStr.length() - 1); + final List paramsWithFallback = splitString(stringToSplit, ',', new EscapeGroup('\"'), + new EscapeGroup('\'')); + if (paramsWithFallback.size() > QUANTITY_OF_PARAMS_WITH_FALLBACK_OR_TYPE) { + return null; + } + if (paramsWithFallback.size() == QUANTITY_OF_PARAMS_WITH_FALLBACK_OR_TYPE) { + fallback = extractFallback(paramsWithFallback.get(1)); + } + final List params = splitString(paramsWithFallback.get(0), ' '); + if (params.size() > QUANTITY_OF_PARAMS_WITH_FALLBACK_OR_TYPE) { + return null; + } else if (params.size() == QUANTITY_OF_PARAMS_WITH_FALLBACK_OR_TYPE) { + typeOfAttribute = extractTypeOfAttribute(params.get(1)); + if (typeOfAttribute == null) { + return null; + } + } + String attributeName = params.get(0); + if (isAttributeNameValid(attributeName)) { + attrValue = getAttributeValue(attributeName, typeOfAttribute, fallback, element); + } + } + return attrValue; + } + /** * Checks if a data is base 64 encoded. * @@ -810,4 +853,42 @@ private static boolean addRange(RangeBuilder builder, String left, String right) builder.addRange(l, r); return true; } + + private static boolean isAttributeNameValid(String attributeName) { + return !(attributeName.contains("'") || attributeName.contains("\"") || attributeName.contains("(") + || attributeName.contains(")")); + } + + private static String extractFallback(String fallbackString) { + String tmpString; + if ((fallbackString.startsWith("'") && fallbackString.endsWith("'")) || (fallbackString.startsWith("\"") + && fallbackString.endsWith("\""))) { + tmpString = fallbackString.substring(1, fallbackString.length() - 1); + } else { + tmpString = fallbackString; + } + return extractUrl(tmpString); + } + + private static String extractTypeOfAttribute(String typeString) { + if (typeString.equals(CommonCssConstants.URL) || typeString.equals(CommonCssConstants.STRING)) { + return typeString; + } + return null; + } + + private static String getAttributeValue(final String attributeName, final String typeOfAttribute, + final String fallback, + IElementNode elementNode) { + String returnString = elementNode.getAttribute(attributeName); + if (CommonCssConstants.URL.equals(typeOfAttribute)) { + returnString = returnString == null ? null : extractUrl(returnString); + } else { + returnString = returnString == null ? "" : returnString; + } + if (fallback != null && (returnString == null || returnString.isEmpty())) { + returnString = fallback; + } + return returnString; + } } diff --git a/styled-xml-parser/src/test/java/com/itextpdf/styledxmlparser/css/parse/CssRuleSetParserTest.java b/styled-xml-parser/src/test/java/com/itextpdf/styledxmlparser/css/parse/CssRuleSetParserTest.java new file mode 100644 index 0000000000..d03ed10b48 --- /dev/null +++ b/styled-xml-parser/src/test/java/com/itextpdf/styledxmlparser/css/parse/CssRuleSetParserTest.java @@ -0,0 +1,64 @@ +/* + This file is part of the iText (R) project. + Copyright (c) 1998-2021 iText Group NV + Authors: iText Software. + + This program is offered under a commercial and under the AGPL license. + For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below. + + AGPL licensing: + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + */ +package com.itextpdf.styledxmlparser.css.parse; + +import com.itextpdf.io.IOException; +import com.itextpdf.styledxmlparser.css.CssDeclaration; +import com.itextpdf.test.ExtendedITextTest; +import com.itextpdf.test.annotations.type.UnitTest; + +import java.util.List; +import org.junit.Assert; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +@Category(UnitTest.class) +public class CssRuleSetParserTest extends ExtendedITextTest { + + @Test + public void parsePropertyDeclarationsTest() throws IOException { + String src = "float:right; clear:right;width:22.0em; margin:0 0 1.0em 1.0em; background:#f9f9f9; " + + "border:1px solid #aaa;padding:0.2em;border-spacing:0.4em 0; text-align:center; " + + "line-height:1.4em; font-size:88%;"; + + String[] expected = new String[] { + "float: right", + "clear: right", + "width: 22.0em", + "margin: 0 0 1.0em 1.0em", + "background: #f9f9f9", + "border: 1px solid #aaa", + "padding: 0.2em", + "border-spacing: 0.4em 0", + "text-align: center", + "line-height: 1.4em", + "font-size: 88%" + }; + + List declarations = CssRuleSetParser.parsePropertyDeclarations(src); + Assert.assertEquals(expected.length, declarations.size()); + for (int i = 0; i < expected.length; i++) { + Assert.assertEquals(expected[i], declarations.get(i).toString()); + } + } +} diff --git a/styled-xml-parser/src/test/java/com/itextpdf/styledxmlparser/css/parse/CssStyleAttributeParseTest.java b/styled-xml-parser/src/test/java/com/itextpdf/styledxmlparser/css/parse/CssStyleAttributeParseTest.java new file mode 100644 index 0000000000..d00f0292f8 --- /dev/null +++ b/styled-xml-parser/src/test/java/com/itextpdf/styledxmlparser/css/parse/CssStyleAttributeParseTest.java @@ -0,0 +1,95 @@ +/* + This file is part of the iText (R) project. + Copyright (c) 1998-2021 iText Group NV + Authors: iText Software. + + This program is offered under a commercial and under the AGPL license. + For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below. + + AGPL licensing: + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + */ +package com.itextpdf.styledxmlparser.css.parse; + +import com.itextpdf.styledxmlparser.IXmlParser; +import com.itextpdf.styledxmlparser.node.IAttributes; +import com.itextpdf.styledxmlparser.node.IDocumentNode; +import com.itextpdf.styledxmlparser.node.IElementNode; +import com.itextpdf.styledxmlparser.node.INode; +import com.itextpdf.styledxmlparser.node.impl.jsoup.JsoupHtmlParser; +import com.itextpdf.test.ExtendedITextTest; +import com.itextpdf.test.annotations.type.IntegrationTest; + +import java.io.FileInputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import org.junit.Assert; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +@Category(IntegrationTest.class) +public class CssStyleAttributeParseTest extends ExtendedITextTest { + private static final String SOURCE_FOLDER = "./src/test/resources/com/itextpdf/styledxmlparser/css/parse/CssStyleAttributeParseTest/"; + + @Test + public void styleAttributeParseTest() throws IOException { + String fileName = SOURCE_FOLDER + "cssStyleAttributeParse.html"; + + IXmlParser parser = new JsoupHtmlParser(); + IDocumentNode document = parser.parse(new FileInputStream(fileName), "UTF-8"); + + List styleDeclarations = new ArrayList<>(); + + List expectStyleDeclarations = new ArrayList<>(); + expectStyleDeclarations.add("display:none;"); + expectStyleDeclarations.add("position:relative;"); + expectStyleDeclarations.add("display:none"); + expectStyleDeclarations.add("text-align:center;"); + expectStyleDeclarations.add("white-space:nowrap;"); + expectStyleDeclarations + .add("float:right; clear:right; width:22.0em; margin:0 0 1.0em 1.0em; background:#f9f9f9;" + + " border:1px solid #aaa; padding:0.2em; border-spacing:0.4em 0; text-align:center;" + + " line-height:1.4em; font-size:88%;"); + expectStyleDeclarations.add("padding:0.2em 0.4em 0.2em; font-size:145%; line-height:1.15em; font-weight:bold;" + + " display:block; margin-bottom:0.25em;"); + + parseStyleAttrForSubtree(document, styleDeclarations); + + Assert.assertEquals(styleDeclarations.size(), expectStyleDeclarations.size()); + + for (int i = 0; i < expectStyleDeclarations.size(); i++) { + Assert.assertEquals(expectStyleDeclarations.get(i), styleDeclarations.get(i)); + } + } + + private void parseOwnStyleAttr(IElementNode element, List styleDeclarations) { + IAttributes attributes = element.getAttributes(); + String styleAttr = attributes.getAttribute("style"); + + if (styleAttr != null && styleAttr.length() > 0) { + styleDeclarations.add(styleAttr); + } + } + + private void parseStyleAttrForSubtree(INode node, List styleDeclarations) { + if (node instanceof IElementNode) { + parseOwnStyleAttr((IElementNode) node, styleDeclarations); + } + for (INode child : node.childNodes()) { + parseStyleAttrForSubtree(child, styleDeclarations); + } + } +} + diff --git a/styled-xml-parser/src/test/java/com/itextpdf/styledxmlparser/css/pseudo/CssPseudoElementNodeTest.java b/styled-xml-parser/src/test/java/com/itextpdf/styledxmlparser/css/pseudo/CssPseudoElementNodeTest.java index 7764291cc9..d0268fd649 100644 --- a/styled-xml-parser/src/test/java/com/itextpdf/styledxmlparser/css/pseudo/CssPseudoElementNodeTest.java +++ b/styled-xml-parser/src/test/java/com/itextpdf/styledxmlparser/css/pseudo/CssPseudoElementNodeTest.java @@ -27,19 +27,14 @@ This file is part of the iText (R) project. import com.itextpdf.test.ExtendedITextTest; import com.itextpdf.test.annotations.type.UnitTest; -import java.util.Collections; import java.util.HashMap; import java.util.Map; import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(UnitTest.class) public class CssPseudoElementNodeTest extends ExtendedITextTest { - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); @Test public void getPseudoElementNameTest() { @@ -79,16 +74,13 @@ public void getAdditionalHtmlStylesTest() { @Test public void addAdditionalHtmlStylesTest() { - junitExpectedException.expect(UnsupportedOperationException.class); - CssPseudoElementNode pseudoElementNode = new CssPseudoElementNode(null, "after"); Map styles = new HashMap<>(); styles.put("font-size", "12px"); styles.put("color", "red"); - pseudoElementNode.addAdditionalHtmlStyles(styles); - Assert.fail(); + Assert.assertThrows(UnsupportedOperationException.class, () -> pseudoElementNode.addAdditionalHtmlStyles(styles)); } @Test @@ -100,12 +92,10 @@ public void getLangTest() { @Test public void attributesStubSetAttributeTest() { - junitExpectedException.expect(UnsupportedOperationException.class); - CssPseudoElementNode pseudoElementNode = new CssPseudoElementNode(null, "after"); - pseudoElementNode.getAttributes().setAttribute("content", "iText"); + IAttributes attributes = pseudoElementNode.getAttributes(); - Assert.fail(); + Assert.assertThrows(UnsupportedOperationException.class, () -> attributes.setAttribute("content", "iText")); } @Test diff --git a/styled-xml-parser/src/test/java/com/itextpdf/styledxmlparser/css/util/CssDimensionParsingUtilsTest.java b/styled-xml-parser/src/test/java/com/itextpdf/styledxmlparser/css/util/CssDimensionParsingUtilsTest.java index e86b82dc9e..1153884596 100644 --- a/styled-xml-parser/src/test/java/com/itextpdf/styledxmlparser/css/util/CssDimensionParsingUtilsTest.java +++ b/styled-xml-parser/src/test/java/com/itextpdf/styledxmlparser/css/util/CssDimensionParsingUtilsTest.java @@ -32,18 +32,13 @@ This file is part of the iText (R) project. import com.itextpdf.test.annotations.type.UnitTest; import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(UnitTest.class) public class CssDimensionParsingUtilsTest extends ExtendedITextTest { private static final float EPS = 0.0001f; - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void parseAbsoluteFontSizeTest() { Assert.assertEquals(75, CssDimensionParsingUtils.parseAbsoluteFontSize("100", CommonCssConstants.PX), EPS); @@ -75,10 +70,10 @@ public void parseResolutionValidDppxUnit() { @Test public void parseResolutionInvalidUnit() { - junitExpectedException.expect(StyledXMLParserException.class); - junitExpectedException.expectMessage(LogMessageConstant.INCORRECT_RESOLUTION_UNIT_VALUE); - - CssDimensionParsingUtils.parseResolution("10incorrectUnit"); + Exception e = Assert.assertThrows(StyledXMLParserException.class, + () -> CssDimensionParsingUtils.parseResolution("10incorrectUnit") + ); + Assert.assertEquals(LogMessageConstant.INCORRECT_RESOLUTION_UNIT_VALUE, e.getMessage()); } @Test @@ -152,21 +147,23 @@ public void parseAbsoluteLengthTest() { @Test public void parseAbsoluteLengthFromNAN() { - junitExpectedException.expect(StyledXMLParserException.class); - junitExpectedException.expectMessage( - MessageFormatUtil.format(StyledXMLParserException.NAN, "Definitely not a number")); - String value = "Definitely not a number"; - CssDimensionParsingUtils.parseAbsoluteLength(value); + + Exception e = Assert.assertThrows(StyledXMLParserException.class, + () -> CssDimensionParsingUtils.parseAbsoluteLength(value) + ); + Assert.assertEquals(MessageFormatUtil.format(StyledXMLParserException.NAN, "Definitely not a number"), + e.getMessage()); } @Test public void parseAbsoluteLengthFromNull() { - junitExpectedException.expect(StyledXMLParserException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(StyledXMLParserException.NAN, "null")); - String value = null; - CssDimensionParsingUtils.parseAbsoluteLength(value); + + Exception e = Assert.assertThrows(StyledXMLParserException.class, + () -> CssDimensionParsingUtils.parseAbsoluteLength(value) + ); + Assert.assertEquals(MessageFormatUtil.format(StyledXMLParserException.NAN, "null"), e.getMessage()); } @Test diff --git a/styled-xml-parser/src/test/java/com/itextpdf/styledxmlparser/css/util/CssGradientUtilTest.java b/styled-xml-parser/src/test/java/com/itextpdf/styledxmlparser/css/util/CssGradientUtilTest.java index 7b066b36d1..e8d7a0c761 100644 --- a/styled-xml-parser/src/test/java/com/itextpdf/styledxmlparser/css/util/CssGradientUtilTest.java +++ b/styled-xml-parser/src/test/java/com/itextpdf/styledxmlparser/css/util/CssGradientUtilTest.java @@ -37,17 +37,12 @@ This file is part of the iText (R) project. import java.util.ArrayList; import java.util.List; import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(UnitTest.class) public class CssGradientUtilTest extends ExtendedITextTest { - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void nullValueTest() { String gradientValue = null; @@ -162,167 +157,182 @@ public void repeatingLinearGradientWithRgbFunctionsTest() { @Test public void emptyParsedArguments1Test() { - junitExpectedException.expect(StyledXMLParserException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_FUNCTION_ARGUMENTS_LIST, "linear-gradient()")); - String gradientValue = "linear-gradient()"; Assert.assertTrue(CssGradientUtil.isCssLinearGradientValue(gradientValue)); - CssGradientUtil.parseCssLinearGradient(gradientValue, 24, 12); + Exception e = Assert.assertThrows(StyledXMLParserException.class, + () -> CssGradientUtil.parseCssLinearGradient(gradientValue, 24, 12) + ); + Assert.assertEquals(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_FUNCTION_ARGUMENTS_LIST, "linear-gradient()"), + e.getMessage()); } @Test public void emptyParsedArguments2Test() { - junitExpectedException.expect(StyledXMLParserException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_FUNCTION_ARGUMENTS_LIST, "linear-gradient( , )")); - String gradientValue = "linear-gradient( , )"; Assert.assertTrue(CssGradientUtil.isCssLinearGradientValue(gradientValue)); - CssGradientUtil.parseCssLinearGradient(gradientValue, 24, 12); + Exception e = Assert.assertThrows(StyledXMLParserException.class, + () -> CssGradientUtil.parseCssLinearGradient(gradientValue, 24, 12) + ); + Assert.assertEquals(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_FUNCTION_ARGUMENTS_LIST, "linear-gradient( , )"), + e.getMessage()); } @Test public void invalidFirstArgumentTest() { - junitExpectedException.expect(StyledXMLParserException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_COLOR_STOP_VALUE, "not-angle-or-color")); - String gradientValue = "linear-gradient(not-angle-or-color, orange 100pt, red 150pt, green 200pt, blue 250pt)"; Assert.assertTrue(CssGradientUtil.isCssLinearGradientValue(gradientValue)); - CssGradientUtil.parseCssLinearGradient(gradientValue, 24, 12); + Exception e = Assert.assertThrows(StyledXMLParserException.class, + () -> CssGradientUtil.parseCssLinearGradient(gradientValue, 24, 12) + ); + Assert.assertEquals(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_COLOR_STOP_VALUE, "not-angle-or-color"), + e.getMessage()); } @Test public void invalidToSideTest0() { - junitExpectedException.expect(StyledXMLParserException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_COLOR_STOP_VALUE, "to")); - String gradientValue = "linear-gradient(to , orange 100pt, red 150pt, green 200pt, blue 250pt)"; Assert.assertTrue(CssGradientUtil.isCssLinearGradientValue(gradientValue)); - CssGradientUtil.parseCssLinearGradient(gradientValue, 24, 12); + Exception e = Assert.assertThrows(StyledXMLParserException.class, + () -> CssGradientUtil.parseCssLinearGradient(gradientValue, 24, 12) + ); + Assert.assertEquals(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_COLOR_STOP_VALUE, "to"), + e.getMessage()); } @Test public void invalidToSideTest1() { - junitExpectedException.expect(StyledXMLParserException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_COLOR_STOP_VALUE, "to")); - String gradientValue = "linear-gradient(to, orange 100pt, red 150pt, green 200pt, blue 250pt)"; Assert.assertTrue(CssGradientUtil.isCssLinearGradientValue(gradientValue)); - CssGradientUtil.parseCssLinearGradient(gradientValue, 24, 12); + Exception e = Assert.assertThrows(StyledXMLParserException.class, + () -> CssGradientUtil.parseCssLinearGradient(gradientValue, 24, 12) + ); + Assert.assertEquals(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_COLOR_STOP_VALUE, "to"), + e.getMessage()); } @Test public void invalidToSideTest2() { - junitExpectedException.expect(StyledXMLParserException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_TO_SIDE_OR_CORNER_STRING, "to left left")); - String gradientValue = "linear-gradient(to left left, orange 100pt, red 150pt, green 200pt, blue 250pt)"; Assert.assertTrue(CssGradientUtil.isCssLinearGradientValue(gradientValue)); - CssGradientUtil.parseCssLinearGradient(gradientValue, 24, 12); + Exception e = Assert.assertThrows(StyledXMLParserException.class, + () -> CssGradientUtil.parseCssLinearGradient(gradientValue, 24, 12) + ); + Assert.assertEquals(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_TO_SIDE_OR_CORNER_STRING, "to left left"), + e.getMessage()); } @Test public void invalidToSideTest3() { - junitExpectedException.expect(StyledXMLParserException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_TO_SIDE_OR_CORNER_STRING, "to bottom top")); - String gradientValue = "linear-gradient(to bottom top, orange 100pt, red 150pt, green 200pt, blue 250pt)"; Assert.assertTrue(CssGradientUtil.isCssLinearGradientValue(gradientValue)); - CssGradientUtil.parseCssLinearGradient(gradientValue, 24, 12); + Exception e = Assert.assertThrows(StyledXMLParserException.class, + () -> CssGradientUtil.parseCssLinearGradient(gradientValue, 24, 12) + ); + Assert.assertEquals(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_TO_SIDE_OR_CORNER_STRING, "to bottom top"), + e.getMessage()); } @Test public void invalidToSideTest4() { - junitExpectedException.expect(StyledXMLParserException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_TO_SIDE_OR_CORNER_STRING, "to left right")); - String gradientValue = "linear-gradient(to left right, orange 100pt, red 150pt, green 200pt, blue 250pt)"; Assert.assertTrue(CssGradientUtil.isCssLinearGradientValue(gradientValue)); - CssGradientUtil.parseCssLinearGradient(gradientValue, 24, 12); + Exception e = Assert.assertThrows(StyledXMLParserException.class, + () -> CssGradientUtil.parseCssLinearGradient(gradientValue, 24, 12) + ); + Assert.assertEquals(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_TO_SIDE_OR_CORNER_STRING, "to left right"), + e.getMessage()); } @Test public void invalidToSideTest5() { - junitExpectedException.expect(StyledXMLParserException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_TO_SIDE_OR_CORNER_STRING, "to top right right")); - String gradientValue = "linear-gradient(to top right right, orange 100pt, red 150pt, green 200pt, blue 250pt)"; Assert.assertTrue(CssGradientUtil.isCssLinearGradientValue(gradientValue)); - CssGradientUtil.parseCssLinearGradient(gradientValue, 24, 12); + Exception e = Assert.assertThrows(StyledXMLParserException.class, + () -> CssGradientUtil.parseCssLinearGradient(gradientValue, 24, 12) + ); + Assert.assertEquals(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_TO_SIDE_OR_CORNER_STRING, "to top right right"), + e.getMessage()); } @Test public void invalidColorWithThreeOffsetsValueTest() { - junitExpectedException.expect(StyledXMLParserException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_COLOR_STOP_VALUE, "orange 20pt 30pt 100pt")); - String gradientValue = "linear-gradient(red, orange 20pt 30pt 100pt, green 200pt, blue 250pt)"; Assert.assertTrue(CssGradientUtil.isCssLinearGradientValue(gradientValue)); - CssGradientUtil.parseCssLinearGradient(gradientValue, 24, 12); + Exception e = Assert.assertThrows(StyledXMLParserException.class, + () -> CssGradientUtil.parseCssLinearGradient(gradientValue, 24, 12) + ); + Assert.assertEquals(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_COLOR_STOP_VALUE, "orange 20pt 30pt 100pt"), + e.getMessage()); } @Test public void invalidColorOffsetValueTest() { - junitExpectedException.expect(StyledXMLParserException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_COLOR_STOP_VALUE, "orange 20")); - String gradientValue = "linear-gradient(red, orange 20, green 200pt, blue 250pt)"; Assert.assertTrue(CssGradientUtil.isCssLinearGradientValue(gradientValue)); - CssGradientUtil.parseCssLinearGradient(gradientValue, 24, 12); + Exception e = Assert.assertThrows(StyledXMLParserException.class, + () -> CssGradientUtil.parseCssLinearGradient(gradientValue, 24, 12) + ); + Assert.assertEquals(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_COLOR_STOP_VALUE, "orange 20"), + e.getMessage()); } @Test public void invalidMultipleHintsInARowValueTest() { - junitExpectedException.expect(StyledXMLParserException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_COLOR_STOP_VALUE, "30%")); - String gradientValue = "linear-gradient(red, orange, 20%, 30%, green 200pt, blue 250pt)"; Assert.assertTrue(CssGradientUtil.isCssLinearGradientValue(gradientValue)); - CssGradientUtil.parseCssLinearGradient(gradientValue, 24, 12); + Exception e = Assert.assertThrows(StyledXMLParserException.class, + () -> CssGradientUtil.parseCssLinearGradient(gradientValue, 24, 12) + ); + Assert.assertEquals(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_COLOR_STOP_VALUE, "30%"), + e.getMessage()); } @Test public void invalidMultipleHintsInARowWithoutCommaValueTest() { - junitExpectedException.expect(StyledXMLParserException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_COLOR_STOP_VALUE, "20% 30%")); - String gradientValue = "linear-gradient(red, orange, 20% 30%, green 200pt, blue 250pt)"; Assert.assertTrue(CssGradientUtil.isCssLinearGradientValue(gradientValue)); - CssGradientUtil.parseCssLinearGradient(gradientValue, 24, 12); + Exception e = Assert.assertThrows(StyledXMLParserException.class, + () -> CssGradientUtil.parseCssLinearGradient(gradientValue, 24, 12) + ); + Assert.assertEquals(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_COLOR_STOP_VALUE, "20% 30%"), + e.getMessage()); } @Test public void invalidFirstElementIsAHintValueTest() { - junitExpectedException.expect(StyledXMLParserException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_COLOR_STOP_VALUE, "5%")); - String gradientValue = "linear-gradient(5%, red, orange, 30%, green 200pt, blue 250pt)"; Assert.assertTrue(CssGradientUtil.isCssLinearGradientValue(gradientValue)); - CssGradientUtil.parseCssLinearGradient(gradientValue, 24, 12); + Exception e = Assert.assertThrows(StyledXMLParserException.class, + () -> CssGradientUtil.parseCssLinearGradient(gradientValue, 24, 12) + ); + Assert.assertEquals(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_COLOR_STOP_VALUE, "5%"), + e.getMessage()); } @Test public void invalidLastElementIsAHintValueTest() { - junitExpectedException.expect(StyledXMLParserException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_COLOR_STOP_VALUE, "120%")); - String gradientValue = "linear-gradient(red, orange, 30%, green 200pt, blue 250pt, 120%)"; Assert.assertTrue(CssGradientUtil.isCssLinearGradientValue(gradientValue)); - CssGradientUtil.parseCssLinearGradient(gradientValue, 24, 12); + Exception e = Assert.assertThrows(StyledXMLParserException.class, + () -> CssGradientUtil.parseCssLinearGradient(gradientValue, 24, 12) + ); + Assert.assertEquals(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_COLOR_STOP_VALUE, "120%"), + e.getMessage()); } @Test @@ -742,42 +752,45 @@ public void linearGradDifferentGradZeroTest() { } @Test - // TODO: DEVSIX-3595. Remove junitExpectedException expectation after fix and update the logic of the test similar to the already existed tests logic + // TODO: DEVSIX-3595. Remove Exception expectation after fix and update the logic of the test similar to the already existed tests logic public void linearGradDifferentTurnPositiveTest() { - junitExpectedException.expect(StyledXMLParserException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_COLOR_STOP_VALUE, "0.17turn")); - String gradientValue = "linear-gradient(0.17turn, orange -20pt, red 0%, green, blue 100%, orange 120%)"; Assert.assertTrue(CssGradientUtil.isCssLinearGradientValue(gradientValue)); - CssGradientUtil.parseCssLinearGradient(gradientValue, 24, 12); + Exception e = Assert.assertThrows(StyledXMLParserException.class, + () -> CssGradientUtil.parseCssLinearGradient(gradientValue, 24, 12) + ); + Assert.assertEquals(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_COLOR_STOP_VALUE, "0.17turn"), + e.getMessage()); } @Test - // TODO: DEVSIX-3595. Remove junitExpectedException expectation after fix and update the logic of the test similar to the already existed tests logic + // TODO: DEVSIX-3595. Remove Exception expectation after fix and update the logic of the test similar to the already existed tests logic public void linearGradDifferentTurnNegativeTest() { - junitExpectedException.expect(StyledXMLParserException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_COLOR_STOP_VALUE, "-0.17turn")); - String gradientValue = "linear-gradient(-0.17turn, orange -20pt, red 0%, green, blue 100%, orange 120%)"; Assert.assertTrue(CssGradientUtil.isCssLinearGradientValue(gradientValue)); - CssGradientUtil.parseCssLinearGradient(gradientValue, 24, 12); + Exception e = Assert.assertThrows(StyledXMLParserException.class, + () -> CssGradientUtil.parseCssLinearGradient(gradientValue, 24, 12) + ); + Assert.assertEquals(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_COLOR_STOP_VALUE, "-0.17turn"), + e.getMessage()); } @Test - // TODO: DEVSIX-3595. Remove junitExpectedException expectation after fix and update the logic of the test similar to the already existed tests logic + // TODO: DEVSIX-3595. Remove Exception expectation after fix and update the logic of the test similar to the already existed tests logic public void linearGradDifferentTurnZeroTest() { - junitExpectedException.expect(StyledXMLParserException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_COLOR_STOP_VALUE, "0turn")); - String gradientValue = "linear-gradient(0turn, orange -20pt, red 0%, green, blue 100%, orange 120%)"; Assert.assertTrue(CssGradientUtil.isCssLinearGradientValue(gradientValue)); - CssGradientUtil.parseCssLinearGradient(gradientValue, 24, 12); + Exception e = Assert.assertThrows(StyledXMLParserException.class, + () -> CssGradientUtil.parseCssLinearGradient(gradientValue, 24, 12) + ); + Assert.assertEquals(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_COLOR_STOP_VALUE, "0turn"), + e.getMessage()); } @Test @@ -1197,42 +1210,45 @@ public void repeatingLinearGradDifferentGradZeroTest() { } @Test - // TODO: DEVSIX-3595. Remove junitExpectedException expectation after fix and update the logic of the test similar to the already existed tests logic + // TODO: DEVSIX-3595. Remove Exception expectation after fix and update the logic of the test similar to the already existed tests logic public void repeatingLinearGradDifferentTurnPositiveTest() { - junitExpectedException.expect(StyledXMLParserException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_COLOR_STOP_VALUE, "0.17turn")); - String gradientValue = "repeating-linear-gradient(0.17turn, orange -20pt, red 0%, green, blue 100%, orange 120%)"; Assert.assertTrue(CssGradientUtil.isCssLinearGradientValue(gradientValue)); - CssGradientUtil.parseCssLinearGradient(gradientValue, 24, 12); + Exception e = Assert.assertThrows(StyledXMLParserException.class, + () -> CssGradientUtil.parseCssLinearGradient(gradientValue, 24, 12) + ); + Assert.assertEquals(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_COLOR_STOP_VALUE, "0.17turn"), + e.getMessage()); } @Test - // TODO: DEVSIX-3595. Remove junitExpectedException expectation after fix and update the logic of the test similar to the already existed tests logic + // TODO: DEVSIX-3595. Remove Exception expectation after fix and update the logic of the test similar to the already existed tests logic public void repeatingLinearGradDifferentTurnNegativeTest() { - junitExpectedException.expect(StyledXMLParserException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_COLOR_STOP_VALUE, "-0.17turn")); - String gradientValue = "repeating-linear-gradient(-0.17turn, orange -20pt, red 0%, green, blue 100%, orange 120%)"; Assert.assertTrue(CssGradientUtil.isCssLinearGradientValue(gradientValue)); - CssGradientUtil.parseCssLinearGradient(gradientValue, 24, 12); + Exception e = Assert.assertThrows(StyledXMLParserException.class, + () -> CssGradientUtil.parseCssLinearGradient(gradientValue, 24, 12) + ); + Assert.assertEquals(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_COLOR_STOP_VALUE, "-0.17turn"), + e.getMessage()); } @Test - // TODO: DEVSIX-3595. Remove junitExpectedException expectation after fix and update the logic of the test similar to the already existed tests logic + // TODO: DEVSIX-3595. Remove Exception expectation after fix and update the logic of the test similar to the already existed tests logic public void repeatingLinearGradDifferentTurnZeroTest() { - junitExpectedException.expect(StyledXMLParserException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_COLOR_STOP_VALUE, "0turn")); - String gradientValue = "repeating-linear-gradient(0turn, orange -20pt, red 0%, green, blue 100%, orange 120%)"; Assert.assertTrue(CssGradientUtil.isCssLinearGradientValue(gradientValue)); - CssGradientUtil.parseCssLinearGradient(gradientValue, 24, 12); + Exception e = Assert.assertThrows(StyledXMLParserException.class, + () -> CssGradientUtil.parseCssLinearGradient(gradientValue, 24, 12) + ); + Assert.assertEquals(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_COLOR_STOP_VALUE, "0turn"), + e.getMessage()); } @Test @@ -1692,63 +1708,73 @@ public void linearGradDiffMetricsFontRelatedExTest() { } @Test - // TODO: DEVSIX-3596. Remove junitExpectedException expectation after fix and update the logic of the test similar to the already existed tests logic + // TODO: DEVSIX-3596. Remove Exception expectation after fix and update the logic of the test similar to the already existed tests logic public void linearGradDiffMetricsFontRelatedChTest() { - junitExpectedException.expect(StyledXMLParserException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_COLOR_STOP_VALUE, "orange 3ch")); String gradientValue = "linear-gradient(to right, orange 3ch, red 3ch, green 9ch, blue 9ch)"; Assert.assertTrue(CssGradientUtil.isCssLinearGradientValue(gradientValue)); - CssGradientUtil.parseCssLinearGradient(gradientValue, 12, 12); + Exception e = Assert.assertThrows(StyledXMLParserException.class, + () -> CssGradientUtil.parseCssLinearGradient(gradientValue, 24, 12) + ); + Assert.assertEquals(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_COLOR_STOP_VALUE, "orange 3ch"), + e.getMessage()); } @Test - // TODO: DEVSIX-3596. Remove junitExpectedException expectation after fix and update the logic of the test similar to the already existed tests logic + // TODO: DEVSIX-3596. Remove Exception expectation after fix and update the logic of the test similar to the already existed tests logic public void linearGradDiffMetricsFontRelatedVhTest() { - junitExpectedException.expect(StyledXMLParserException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_COLOR_STOP_VALUE, "orange 3vh")); String gradientValue = "linear-gradient(to right, orange 3vh, red 3vh, green 9vh, blue 9vh)"; Assert.assertTrue(CssGradientUtil.isCssLinearGradientValue(gradientValue)); - CssGradientUtil.parseCssLinearGradient(gradientValue, 12, 12); + Exception e = Assert.assertThrows(StyledXMLParserException.class, + () -> CssGradientUtil.parseCssLinearGradient(gradientValue, 12, 12) + ); + Assert.assertEquals(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_COLOR_STOP_VALUE, "orange 3vh"), + e.getMessage()); } @Test - // TODO: DEVSIX-3596. Remove junitExpectedException expectation after fix and update the logic of the test similar to the already existed tests logic + // TODO: DEVSIX-3596. Remove Exception expectation after fix and update the logic of the test similar to the already existed tests logic public void linearGradDiffMetricsViewPortVwTest() { - junitExpectedException.expect(StyledXMLParserException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_COLOR_STOP_VALUE, "orange 3vw")); String gradientValue = "linear-gradient(to right, orange 3vw, red 3vw, green 9vw, blue 9vw)"; Assert.assertTrue(CssGradientUtil.isCssLinearGradientValue(gradientValue)); - CssGradientUtil.parseCssLinearGradient(gradientValue, 12, 12); + Exception e = Assert.assertThrows(StyledXMLParserException.class, + () -> CssGradientUtil.parseCssLinearGradient(gradientValue, 12, 12) + ); + Assert.assertEquals(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_COLOR_STOP_VALUE, "orange 3vw"), + e.getMessage()); } @Test - // TODO: DEVSIX-3596. Remove junitExpectedException expectation after fix and update the logic of the test similar to the already existed tests logic + // TODO: DEVSIX-3596. Remove Exception expectation after fix and update the logic of the test similar to the already existed tests logic public void linearGradDiffMetricsViewPortVminTest() { - junitExpectedException.expect(StyledXMLParserException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_COLOR_STOP_VALUE, "orange 3vmin")); String gradientValue = "linear-gradient(to right, orange 3vmin, red 3vmin, green 9vmin, blue 9vmin)"; Assert.assertTrue(CssGradientUtil.isCssLinearGradientValue(gradientValue)); - CssGradientUtil.parseCssLinearGradient(gradientValue, 12, 12); + Exception e = Assert.assertThrows(StyledXMLParserException.class, + () -> CssGradientUtil.parseCssLinearGradient(gradientValue, 12, 12) + ); + Assert.assertEquals(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_COLOR_STOP_VALUE, "orange 3vmin"), + e.getMessage()); } @Test - // TODO: DEVSIX-3596. Remove junitExpectedException expectation after fix and update the logic of the test similar to the already existed tests logic + // TODO: DEVSIX-3596. Remove Exception expectation after fix and update the logic of the test similar to the already existed tests logic public void linearGradDiffMetricsViewPortVmaxTest() { - junitExpectedException.expect(StyledXMLParserException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_COLOR_STOP_VALUE, "orange 3vmax")); String gradientValue = "linear-gradient(to right, orange 3vmax, red 3vmax, green 9vmax, blue 9vmax)"; Assert.assertTrue(CssGradientUtil.isCssLinearGradientValue(gradientValue)); - CssGradientUtil.parseCssLinearGradient(gradientValue, 12, 12); + Exception e = Assert.assertThrows(StyledXMLParserException.class, + () -> CssGradientUtil.parseCssLinearGradient(gradientValue, 12, 12) + ); + Assert.assertEquals(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_COLOR_STOP_VALUE, "orange 3vmax"), + e.getMessage()); } @Test @@ -1952,63 +1978,73 @@ public void repeatLinearGradDiffMetricsFontRelatedExTest() { } @Test - // TODO: DEVSIX-3596. Remove junitExpectedException expectation after fix and update the logic of the test similar to the already existed tests logic + // TODO: DEVSIX-3596. Remove Exception expectation after fix and update the logic of the test similar to the already existed tests logic public void repeatLinearGradDiffMetricsFontRelatedChTest() { - junitExpectedException.expect(StyledXMLParserException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_COLOR_STOP_VALUE, "orange 3ch")); String gradientValue = "repeating-linear-gradient(to right, orange 3ch, red 3ch, green 9ch, blue 9ch)"; Assert.assertTrue(CssGradientUtil.isCssLinearGradientValue(gradientValue)); - CssGradientUtil.parseCssLinearGradient(gradientValue, 12, 12); + Exception e = Assert.assertThrows(StyledXMLParserException.class, + () -> CssGradientUtil.parseCssLinearGradient(gradientValue, 12, 12) + ); + Assert.assertEquals(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_COLOR_STOP_VALUE, "orange 3ch"), + e.getMessage()); } @Test - // TODO: DEVSIX-3596. Remove junitExpectedException expectation after fix and update the logic of the test similar to the already existed tests logic + // TODO: DEVSIX-3596. Remove Exception expectation after fix and update the logic of the test similar to the already existed tests logic public void repeatLinearGradDiffMetricsFontRelatedVhTest() { - junitExpectedException.expect(StyledXMLParserException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_COLOR_STOP_VALUE, "orange 3vh")); String gradientValue = "repeating-linear-gradient(to right, orange 3vh, red 3vh, green 9vh, blue 9vh)"; Assert.assertTrue(CssGradientUtil.isCssLinearGradientValue(gradientValue)); - CssGradientUtil.parseCssLinearGradient(gradientValue, 12, 12); + Exception e = Assert.assertThrows(StyledXMLParserException.class, + () -> CssGradientUtil.parseCssLinearGradient(gradientValue, 12, 12) + ); + Assert.assertEquals(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_COLOR_STOP_VALUE, "orange 3vh"), + e.getMessage()); } @Test - // TODO: DEVSIX-3596. Remove junitExpectedException expectation after fix and update the logic of the test similar to the already existed tests logic + // TODO: DEVSIX-3596. Remove Exception expectation after fix and update the logic of the test similar to the already existed tests logic public void repeatLinearGradDiffMetricsViewPortVwTest() { - junitExpectedException.expect(StyledXMLParserException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_COLOR_STOP_VALUE, "orange 3vw")); String gradientValue = "repeating-linear-gradient(to right, orange 3vw, red 3vw, green 9vw, blue 9vw)"; Assert.assertTrue(CssGradientUtil.isCssLinearGradientValue(gradientValue)); - CssGradientUtil.parseCssLinearGradient(gradientValue, 12, 12); + Exception e = Assert.assertThrows(StyledXMLParserException.class, + () -> CssGradientUtil.parseCssLinearGradient(gradientValue, 12, 12) + ); + Assert.assertEquals(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_COLOR_STOP_VALUE, "orange 3vw"), + e.getMessage()); } @Test - // TODO: DEVSIX-3596. Remove junitExpectedException expectation after fix and update the logic of the test similar to the already existed tests logic + // TODO: DEVSIX-3596. Remove Exception expectation after fix and update the logic of the test similar to the already existed tests logic public void repeatLinearGradDiffMetricsViewPortVminTest() { - junitExpectedException.expect(StyledXMLParserException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_COLOR_STOP_VALUE, "orange 3vmin")); String gradientValue = "repeating-linear-gradient(to right, orange 3vmin, red 3vmin, green 9vmin, blue 9vmin)"; Assert.assertTrue(CssGradientUtil.isCssLinearGradientValue(gradientValue)); - CssGradientUtil.parseCssLinearGradient(gradientValue, 12, 12); + Exception e = Assert.assertThrows(StyledXMLParserException.class, + () -> CssGradientUtil.parseCssLinearGradient(gradientValue, 12, 12) + ); + Assert.assertEquals(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_COLOR_STOP_VALUE, "orange 3vmin"), + e.getMessage()); } @Test - // TODO: DEVSIX-3596. Remove junitExpectedException expectation after fix and update the logic of the test similar to the already existed tests logic + // TODO: DEVSIX-3596. Remove Exception expectation after fix and update the logic of the test similar to the already existed tests logic public void repeatLinearGradDiffMetricsViewPortVmaxTest() { - junitExpectedException.expect(StyledXMLParserException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_COLOR_STOP_VALUE, "orange 3vmax")); String gradientValue = "repeating-linear-gradient(to right, orange 3vmax, red 3vmax, green 9vmax, blue 9vmax)"; Assert.assertTrue(CssGradientUtil.isCssLinearGradientValue(gradientValue)); - CssGradientUtil.parseCssLinearGradient(gradientValue, 12, 12); + Exception e = Assert.assertThrows(StyledXMLParserException.class, + () -> CssGradientUtil.parseCssLinearGradient(gradientValue, 12, 12) + ); + Assert.assertEquals(MessageFormatUtil.format(StyledXMLParserException.INVALID_GRADIENT_COLOR_STOP_VALUE, "orange 3vmax"), + e.getMessage()); } @Test diff --git a/styled-xml-parser/src/test/java/com/itextpdf/styledxmlparser/css/util/CssUtilsTest.java b/styled-xml-parser/src/test/java/com/itextpdf/styledxmlparser/css/util/CssUtilsTest.java index 94b6e0e831..b7e14cb0c5 100644 --- a/styled-xml-parser/src/test/java/com/itextpdf/styledxmlparser/css/util/CssUtilsTest.java +++ b/styled-xml-parser/src/test/java/com/itextpdf/styledxmlparser/css/util/CssUtilsTest.java @@ -47,9 +47,12 @@ This file is part of the iText (R) project. import com.itextpdf.styledxmlparser.CommonAttributeConstants; import com.itextpdf.styledxmlparser.LogMessageConstant; import com.itextpdf.styledxmlparser.css.CommonCssConstants; +import com.itextpdf.styledxmlparser.css.pseudo.CssPseudoElementNode; import com.itextpdf.styledxmlparser.exceptions.StyledXMLParserException; import com.itextpdf.styledxmlparser.jsoup.nodes.Element; import com.itextpdf.styledxmlparser.jsoup.parser.Tag; +import com.itextpdf.styledxmlparser.node.IElementNode; +import com.itextpdf.styledxmlparser.node.INode; import com.itextpdf.styledxmlparser.node.impl.jsoup.node.JsoupElementNode; import com.itextpdf.test.ExtendedITextTest; import com.itextpdf.test.annotations.LogMessage; @@ -61,18 +64,13 @@ This file is part of the iText (R) project. import java.util.List; import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(UnitTest.class) public class CssUtilsTest extends ExtendedITextTest { private static float EPS = 0.0001f; - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void extractShorthandPropertiesFromEmptyStringTest() { String sourceString = ""; @@ -116,20 +114,21 @@ public void extractShorthandPropertiesFromStringWithMultiplyPropertiesTest() { @Test public void parseAbsoluteLengthFromNAN() { - junitExpectedException.expect(StyledXMLParserException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(StyledXMLParserException.NAN, "Definitely not a number")); - String value = "Definitely not a number"; - CssUtils.parseAbsoluteLength(value); + Exception e = Assert.assertThrows(StyledXMLParserException.class, + () -> CssUtils.parseAbsoluteLength(value) + ); + Assert.assertEquals(MessageFormatUtil.format(StyledXMLParserException.NAN, "Definitely not a number"), + e.getMessage()); } @Test public void parseAbsoluteLengthFromNull() { - junitExpectedException.expect(StyledXMLParserException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(StyledXMLParserException.NAN, "null")); - String value = null; - CssUtils.parseAbsoluteLength(value); + Exception e = Assert.assertThrows(StyledXMLParserException.class, + () -> CssUtils.parseAbsoluteLength(value) + ); + Assert.assertEquals(MessageFormatUtil.format(StyledXMLParserException.NAN, "null"), e.getMessage()); } @Test @@ -353,10 +352,10 @@ public void parseResolutionValidDppxUnit() { @Test public void parseResolutionInvalidUnit() { - junitExpectedException.expect(StyledXMLParserException.class); - junitExpectedException.expectMessage(LogMessageConstant.INCORRECT_RESOLUTION_UNIT_VALUE); - - CssUtils.parseResolution("10incorrectUnit"); + Exception e = Assert.assertThrows(StyledXMLParserException.class, + () -> CssUtils.parseResolution("10incorrectUnit") + ); + Assert.assertEquals(LogMessageConstant.INCORRECT_RESOLUTION_UNIT_VALUE, e.getMessage()); } @Test @@ -469,4 +468,129 @@ public void isNegativeValueTest() { Assert.assertTrue(CssUtils.isNegativeValue("-0.123")); Assert.assertTrue(CssUtils.isNegativeValue("-.34")); } + + @Test + public void testWrongAttrTest01() { + String strToParse = "attr((href))"; + String result = CssUtils.extractAttributeValue(strToParse, null); + Assert.assertNull(result); + } + + @Test + public void testWrongAttrTest02() { + String strToParse = "attr('href')"; + String result = CssUtils.extractAttributeValue(strToParse, null); + Assert.assertNull(result); + } + + @Test + public void testWrongAttrTest03() { + String strToParse = "attrrname)"; + String result = CssUtils.extractAttributeValue(strToParse, null); + Assert.assertNull(result); + } + + @Test + public void testExtractingAttrTest01() { + IElementNode iNode = new CssPseudoElementNode(null, "url"); + String strToParse = "attr(url)"; + String result = CssUtils.extractAttributeValue(strToParse, iNode); + Assert.assertEquals("", result); + } + + @Test + public void testExtractingAttrTest02() { + IElementNode iNode = new CssPseudoElementNode(null, "test"); + String strToParse = "attr(url url)"; + String result = CssUtils.extractAttributeValue(strToParse, iNode); + Assert.assertNull(result); + } + + @Test + public void testExtractingAttrTest03() { + IElementNode iNode = new CssPseudoElementNode(null, "test"); + String strToParse = "attr(url url,#one)"; + String result = CssUtils.extractAttributeValue(strToParse, iNode); + Assert.assertEquals("#one", result); + } + + @Test + public void testExtractingAttrTest04() { + IElementNode iNode = new CssPseudoElementNode(null, "test"); + String strToParse = "attr()"; + String result = CssUtils.extractAttributeValue(strToParse, iNode); + Assert.assertNull(result); + } + + @Test + public void testExtractingAttrTest05() { + IElementNode iNode = new CssPseudoElementNode(null, "test"); + String strToParse = "attr('\')"; + String result = CssUtils.extractAttributeValue(strToParse, iNode); + Assert.assertNull(result); + } + + @Test + public void testExtractingAttrTest06() { + IElementNode iNode = new CssPseudoElementNode(null, "test"); + String strToParse = "attr(str,\"hey\")"; + String result = CssUtils.extractAttributeValue(strToParse, iNode); + Assert.assertEquals("hey", result); + } + + @Test + public void testExtractingAttrTest07() { + IElementNode iNode = new CssPseudoElementNode(null, "test"); + String strToParse = "attr(str string)"; + String result = CssUtils.extractAttributeValue(strToParse, iNode); + Assert.assertEquals("", result); + } + + @Test + public void testExtractingAttrTest08() { + IElementNode iNode = new CssPseudoElementNode(null, "test"); + String strToParse = "attr(str string,\"value\")"; + String result = CssUtils.extractAttributeValue(strToParse, iNode); + Assert.assertEquals("value", result); + } + + @Test + public void testExtractingAttrTest09() { + IElementNode iNode = new CssPseudoElementNode(null, "test"); + String strToParse = "attr(str string,\"val,ue\")"; + String result = CssUtils.extractAttributeValue(strToParse, iNode); + Assert.assertEquals("val,ue", result); + } + + @Test + public void testExtractingAttrTest10() { + IElementNode iNode = new CssPseudoElementNode(null, "test"); + String strToParse = "attr(str string,'val,ue')"; + String result = CssUtils.extractAttributeValue(strToParse, iNode); + Assert.assertEquals("val,ue", result); + } + + @Test + public void testExtractingAttrTest11() { + IElementNode iNode = new CssPseudoElementNode(null, "test"); + String strToParse = "attr(name, \"value\", \"value\", \"value\")"; + String result = CssUtils.extractAttributeValue(strToParse, iNode); + Assert.assertNull(result); + } + + @Test + public void wrongAttributeTypeTest() { + IElementNode iNode = new CssPseudoElementNode(null, "test"); + String strToParse = "attr(str mem)"; + String result = CssUtils.extractAttributeValue(strToParse, iNode); + Assert.assertNull(result); + } + + @Test + public void wrongParamsInAttrFunctionTest() { + IElementNode iNode = new CssPseudoElementNode(null, "test"); + String strToParse = "attr(str mem lol)"; + String result = CssUtils.extractAttributeValue(strToParse, iNode); + Assert.assertNull(result); + } } diff --git a/styled-xml-parser/src/test/java/com/itextpdf/styledxmlparser/resolver/resource/LimitedInputStreamTest.java b/styled-xml-parser/src/test/java/com/itextpdf/styledxmlparser/resolver/resource/LimitedInputStreamTest.java index 177624e151..7e99081720 100644 --- a/styled-xml-parser/src/test/java/com/itextpdf/styledxmlparser/resolver/resource/LimitedInputStreamTest.java +++ b/styled-xml-parser/src/test/java/com/itextpdf/styledxmlparser/resolver/resource/LimitedInputStreamTest.java @@ -34,18 +34,13 @@ This file is part of the iText (R) project. import java.net.URL; import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(UnitTest.class) public class LimitedInputStreamTest extends ExtendedITextTest { private final String baseUri = "./src/test/resources/com/itextpdf/styledxmlparser/resolver/retrieveStreamTest/"; - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void readingByteAfterFileReadingTest() throws IOException { UriResolver uriResolver = new UriResolver(baseUri); @@ -92,8 +87,8 @@ public void readingByteWithLimitOfOneLessThenFileSizeTest() throws IOException { for (int i = 0; i < 88; i++) { Assert.assertNotEquals(-1, stream.read()); } - junitExpectedException.expect(ReadingByteLimitException.class); - stream.read(); + + Assert.assertThrows(ReadingByteLimitException.class, () -> stream.read()); } @Test @@ -107,8 +102,7 @@ public void readingByteArrayWithLimitOfOneLessThenFileSizeTest() throws IOExcept Assert.assertEquals(88, numOfReadBytes); Assert.assertEquals(10, bytes[87]); Assert.assertEquals(0, bytes[88]); - junitExpectedException.expect(ReadingByteLimitException.class); - stream.read(new byte[1]); + Assert.assertThrows(ReadingByteLimitException.class, () -> stream.read(new byte[1])); } @Test @@ -122,8 +116,7 @@ public void readingByteArrayWithOffsetAndLimitOfOneLessThenFileSizeTest() throws Assert.assertEquals(88, numOfReadBytes); Assert.assertEquals(10, bytes[87]); Assert.assertEquals(0, bytes[88]); - junitExpectedException.expect(ReadingByteLimitException.class); - stream.read(bytes, 88, 1); + Assert.assertThrows(ReadingByteLimitException.class, () -> stream.read(bytes, 88, 1)); } @Test @@ -193,24 +186,24 @@ public void byteArrayOverwritingTest() throws IOException { @Test public void readingByteWithZeroLimitTest() throws IOException { LimitedInputStream stream = new LimitedInputStream(new ByteArrayInputStream(new byte[1]), 0); - junitExpectedException.expect(ReadingByteLimitException.class); - stream.read(); + + Assert.assertThrows(ReadingByteLimitException.class, () -> stream.read()); } @Test public void readingByteArrayWithZeroLimitTest() throws IOException { LimitedInputStream stream = new LimitedInputStream(new ByteArrayInputStream(new byte[1]), 0); byte[] bytes = new byte[100]; - junitExpectedException.expect(ReadingByteLimitException.class); - stream.read(bytes); + + Assert.assertThrows(ReadingByteLimitException.class, () -> stream.read(bytes)); } @Test public void readingByteArrayWithOffsetAndZeroLimitTest() throws IOException { LimitedInputStream stream = new LimitedInputStream(new ByteArrayInputStream(new byte[1]), 0); byte[] bytes = new byte[100]; - junitExpectedException.expect(ReadingByteLimitException.class); - stream.read(bytes, 0, 100); + + Assert.assertThrows(ReadingByteLimitException.class, () -> stream.read(bytes, 0, 100)); } @Test @@ -235,8 +228,9 @@ public void readingEmptyByteArrayWithOffsetAndZeroLimitTest() throws IOException @Test public void illegalReadingByteLimitValueTest() { - junitExpectedException.expect(IllegalArgumentException.class); - junitExpectedException.expectMessage(StyledXmlParserExceptionMessage.READING_BYTE_LIMIT_MUST_NOT_BE_LESS_ZERO); - new LimitedInputStream(new ByteArrayInputStream(new byte[0]), -1); + Exception e = Assert.assertThrows(IllegalArgumentException.class, + () -> new LimitedInputStream(new ByteArrayInputStream(new byte[0]), -1) + ); + Assert.assertEquals(StyledXmlParserExceptionMessage.READING_BYTE_LIMIT_MUST_NOT_BE_LESS_ZERO, e.getMessage()); } } diff --git a/styled-xml-parser/src/test/java/com/itextpdf/styledxmlparser/resolver/resource/ResourceResolverTest.java b/styled-xml-parser/src/test/java/com/itextpdf/styledxmlparser/resolver/resource/ResourceResolverTest.java index c45997eef0..e1b7d75b45 100644 --- a/styled-xml-parser/src/test/java/com/itextpdf/styledxmlparser/resolver/resource/ResourceResolverTest.java +++ b/styled-xml-parser/src/test/java/com/itextpdf/styledxmlparser/resolver/resource/ResourceResolverTest.java @@ -60,10 +60,8 @@ This file is part of the iText (R) project. import java.io.IOException; import java.io.InputStream; import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(UnitTest.class) public class ResourceResolverTest extends ExtendedITextTest { @@ -76,9 +74,6 @@ public class ResourceResolverTest extends ExtendedITextTest { private final String bLogo = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAVoAAAAxCAMAAACsy5FpAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAqUExURQAAAPicJAdJdQdJdQdJdficJjBUbPicJgdJdQdJdficJficJQdJdficJlrFe50AAAAMdFJOUwCBe8I/Phe+65/saIJg0K4AAAMOSURBVHja7ZvbmqsgDIU5Bo/v/7q7/WZXsQYNuGy1muuZFH7DIiSglFLU6pZUbGQQNvXpNcC4caoNRvNxOuDUdf80HXk3VYewKp516DHWxuOc/0ye/U00duAwU+/qkWzfh9F9hzIHJxuzNa+fsa4I7Ihx+H+qUFN/sKVhzP7lH+a+qwY1gJHtmwFDPBHK1wLLjLOGTb2jIWhHScAF7RgOGod2CAGTFB8J2JodJ3Dq5kNow95oH3BdtsjGHE6LVu+P9iG5UlVwNjXOndGeRWuZEBBJLtWcMMK11nFoDfDL4TOEMUu0K/leIpNNpUrYFVsrDi2Mbb1DXqv5PV4quWzKHikJKq99utTsoI1dsMjBkr2dctoAMO3XQS2ogrNrJ5vH1OvtU6/ddIPR0k1g9K++bcSKo6Htf8wbdxpK2rnRigJRqAU3WiEylzzVlubCF0TLb/pTyZXH9o1WoKLVoKK8yBbUHS6IdjksZYpxo82WXIzIXhptYtmDRPbQaDXiPBZaaQl26ZBI6pfQ+gZ00A3CxkH6COo2rIwjom12KM/IJRehBUdF2wLrtUWS+56P/Q7aPUrheYnYRpE9LtrwSbSp7cxuJnv1qCWzk9AeEy3t0MAp2ccq93NogWHry3QWowqHPDK0mPSr8aXZAWQzO+hB17ebb9P5ZbDCu2obJPeiNQQWbAUse10VbbKqSLm9yRutQGT/8wO0G6+LdvV2Aaq0eDW0kmI3SHKvhZZkESnoTd5o5SIr+gb0A2g9wGQi67KUw5wdLajNEHymyCqo5B4RLawWHp10XcEC528suBOjJVwDZ2iOca9lBNsSl4jZE6Ntd6jXmtKVzeiIOy/aDzwTydmPZpJrzov2A89EsrKod8mVoq1y0LbsE02Zf/sVQSAObXa5ZSq5UkGoZw9LlqwRNkai5ZT7rRXyHkJgQqioSBipgjhGHPdMYy3hbLx8UDbDPTatndyeeW1HpaXtodxYyUO+zmoDUWjeUnHRB7d5E/KQnazRs0VdbWjI/EluloPnb26+KXIGI+e+7CBt/wAetDeCKwxY6QAAAABJRU5ErkJggg=="; - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - // Constructor tests block @Test @@ -122,10 +117,9 @@ public void retrieveStreamByMalformedResourceNameTest() { @Test public void retrieveStyleSheetByMalformedResourceNameTest() throws IOException { - junitExpectedException.expect(IOException.class); String fileName = "retrieveStyl eSheetTest.css"; ResourceResolver resourceResolver = new ResourceResolver(baseUri); - resourceResolver.retrieveStyleSheet(fileName); + Assert.assertThrows(IOException.class, () -> resourceResolver.retrieveStyleSheet(fileName)); } @Test @@ -366,15 +360,17 @@ public void retrieveBytesFromLocalWithResourceSizeByteLimitTest() { @Test public void attemptToReadBytesFromLimitedInputStreamTest() throws IOException { - junitExpectedException.expect(ReadingByteLimitException.class); String fileName = "retrieveStyleSheetTest.css.dat"; // retrieveStyleSheetTest.css.dat size is 89 bytes IResourceRetriever retriever = new DefaultResourceRetriever().setResourceSizeByteLimit(40); ResourceResolver resourceResolver = new ResourceResolver(baseUri, retriever); InputStream stream = resourceResolver.retrieveResourceAsInputStream(fileName); - for (int i = 0; i < 41; i++) { + + for (int i = 0; i < 40; i++) { stream.read(); } + + Assert.assertThrows(ReadingByteLimitException.class, () -> stream.read()); } @Test diff --git a/styled-xml-parser/src/test/java/com/itextpdf/styledxmlparser/resolver/resource/UriResolverTest.java b/styled-xml-parser/src/test/java/com/itextpdf/styledxmlparser/resolver/resource/UriResolverTest.java index dc89673432..ff224fc489 100644 --- a/styled-xml-parser/src/test/java/com/itextpdf/styledxmlparser/resolver/resource/UriResolverTest.java +++ b/styled-xml-parser/src/test/java/com/itextpdf/styledxmlparser/resolver/resource/UriResolverTest.java @@ -44,12 +44,11 @@ This file is part of the iText (R) project. import com.itextpdf.test.ExtendedITextTest; import com.itextpdf.test.annotations.type.UnitTest; + import org.junit.Assert; import org.junit.Ignore; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; import java.net.MalformedURLException; import java.nio.file.Paths; @@ -57,9 +56,6 @@ This file is part of the iText (R) project. @Category(UnitTest.class) public class UriResolverTest extends ExtendedITextTest { - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void uriResolverTest01() throws MalformedURLException { String absolutePathRoot = Paths.get("").toAbsolutePath().getRoot().toUri().toURL().toExternalForm(); diff --git a/styled-xml-parser/src/test/resources/com/itextpdf/styledxmlparser/css/parse/CssStyleAttributeParseTest/cssStyleAttributeParse.html b/styled-xml-parser/src/test/resources/com/itextpdf/styledxmlparser/css/parse/CssStyleAttributeParseTest/cssStyleAttributeParse.html new file mode 100644 index 0000000000..56e1d1f985 --- /dev/null +++ b/styled-xml-parser/src/test/resources/com/itextpdf/styledxmlparser/css/parse/CssStyleAttributeParseTest/cssStyleAttributeParse.html @@ -0,0 +1,57 @@ + + + + +

Hello

+
+
Good morning
+
+
Have a nice day
+
+
+

today

+
+
Hello!!!
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
Hello, iText!

text/css

Monday
Tuesday

morning

Wednesday +

evening

+
Thursday +

afternoon

+
+

+
+ + + + +
Good bye
+ + diff --git a/svg/pom.xml b/svg/pom.xml index b2e97becc8..0ae9e7bcb8 100644 --- a/svg/pom.xml +++ b/svg/pom.xml @@ -4,7 +4,7 @@ com.itextpdf root - 7.1.15 + 7.1.16 svg iText 7 - SVG diff --git a/svg/src/main/java/com/itextpdf/svg/SvgConstants.java b/svg/src/main/java/com/itextpdf/svg/SvgConstants.java index 42dcb3feb9..4901a59cff 100644 --- a/svg/src/main/java/com/itextpdf/svg/SvgConstants.java +++ b/svg/src/main/java/com/itextpdf/svg/SvgConstants.java @@ -458,6 +458,11 @@ public static final class Tags { */ public static final String TEXT = "text"; + /** + * Phantom tag for text leaf. + */ + public static final String TEXT_LEAF = ":text-leaf"; + /** * Tag defining a path on which text can be drawn. */ diff --git a/svg/src/main/java/com/itextpdf/svg/converter/SvgConverter.java b/svg/src/main/java/com/itextpdf/svg/converter/SvgConverter.java index 2ba629def1..665c39774d 100644 --- a/svg/src/main/java/com/itextpdf/svg/converter/SvgConverter.java +++ b/svg/src/main/java/com/itextpdf/svg/converter/SvgConverter.java @@ -546,39 +546,40 @@ public static void createPdf(InputStream svgStream, OutputStream pdfDest, ISvgCo if (writerProps == null) { writerProps = new WriterProperties(); } - PdfDocument pdfDocument = new PdfDocument(new PdfWriter(pdfDest, writerProps)); - // Process - ISvgProcessorResult processorResult = process(parse(svgStream, props), props); + try (PdfWriter writer = new PdfWriter(pdfDest, writerProps); + PdfDocument pdfDocument = new PdfDocument(writer)) { + // Process + ISvgProcessorResult processorResult = process(parse(svgStream, props), props); + + ResourceResolver resourceResolver = SvgConverter.getResourceResolver(processorResult, props); + SvgDrawContext drawContext = new SvgDrawContext(resourceResolver, processorResult.getFontProvider()); + if (processorResult instanceof SvgProcessorResult) { + drawContext.setCssContext(((SvgProcessorResult) processorResult).getContext().getCssContext()); + } - ResourceResolver resourceResolver = SvgConverter.getResourceResolver(processorResult, props); - SvgDrawContext drawContext = new SvgDrawContext(resourceResolver, processorResult.getFontProvider()); - if (processorResult instanceof SvgProcessorResult) { - drawContext.setCssContext(((SvgProcessorResult) processorResult).getContext().getCssContext()); + drawContext.addNamedObjects(processorResult.getNamedObjects()); + // Add temp fonts + drawContext.setTempFonts(processorResult.getTempFonts()); + + ISvgNodeRenderer topSvgRenderer = processorResult.getRootRenderer(); + // Extract topmost dimensions + checkNull(topSvgRenderer); + checkNull(pdfDocument); + float width, height; + + float[] wh = extractWidthAndHeight(topSvgRenderer); + width = wh[0]; + height = wh[1]; + + // Adjust pagesize and create new page + pdfDocument.setDefaultPageSize(new PageSize(width, height)); + PdfPage page = pdfDocument.addNewPage(); + PdfCanvas pageCanvas = new PdfCanvas(page); + // Add to the first page + PdfFormXObject xObject = convertToXObject(topSvgRenderer, pdfDocument, drawContext); + // Draw + draw(xObject, pageCanvas); } - - drawContext.addNamedObjects(processorResult.getNamedObjects()); - // Add temp fonts - drawContext.setTempFonts(processorResult.getTempFonts()); - - ISvgNodeRenderer topSvgRenderer = processorResult.getRootRenderer(); - // Extract topmost dimensions - checkNull(topSvgRenderer); - checkNull(pdfDocument); - float width, height; - - float[] wh = extractWidthAndHeight(topSvgRenderer); - width = wh[0]; - height = wh[1]; - - // Adjust pagesize and create new page - pdfDocument.setDefaultPageSize(new PageSize(width, height)); - PdfPage page = pdfDocument.addNewPage(); - PdfCanvas pageCanvas = new PdfCanvas(page); - // Add to the first page - PdfFormXObject xObject = convertToXObject(topSvgRenderer, pdfDocument, drawContext); - // Draw - draw(xObject, pageCanvas); - pdfDocument.close(); } /** diff --git a/svg/src/main/java/com/itextpdf/svg/processors/impl/DefaultSvgProcessor.java b/svg/src/main/java/com/itextpdf/svg/processors/impl/DefaultSvgProcessor.java index bbff1855c0..3daccf2e8e 100644 --- a/svg/src/main/java/com/itextpdf/svg/processors/impl/DefaultSvgProcessor.java +++ b/svg/src/main/java/com/itextpdf/svg/processors/impl/DefaultSvgProcessor.java @@ -43,10 +43,14 @@ This file is part of the iText (R) project. package com.itextpdf.svg.processors.impl; import com.itextpdf.styledxmlparser.css.ICssResolver; +import com.itextpdf.styledxmlparser.jsoup.nodes.Element; +import com.itextpdf.styledxmlparser.jsoup.parser.Tag; import com.itextpdf.styledxmlparser.node.IElementNode; import com.itextpdf.styledxmlparser.node.INode; import com.itextpdf.styledxmlparser.node.ITextNode; +import com.itextpdf.styledxmlparser.node.impl.jsoup.node.JsoupElementNode; import com.itextpdf.svg.SvgConstants; +import com.itextpdf.svg.SvgConstants.Tags; import com.itextpdf.svg.css.impl.SvgStyleResolver; import com.itextpdf.svg.exceptions.SvgLogMessageConstant; import com.itextpdf.svg.exceptions.SvgProcessingException; @@ -63,7 +67,6 @@ This file is part of the iText (R) project. import com.itextpdf.svg.renderers.impl.ISvgTextNodeRenderer; import com.itextpdf.svg.renderers.impl.LinearGradientSvgNodeRenderer; import com.itextpdf.svg.renderers.impl.StopSvgNodeRenderer; -import com.itextpdf.svg.renderers.impl.TextLeafSvgNodeRenderer; import com.itextpdf.svg.renderers.impl.TextSvgBranchRenderer; import com.itextpdf.svg.utils.SvgTextUtil; @@ -255,7 +258,9 @@ private void processText(ITextNode textNode) { if (parentRenderer instanceof TextSvgBranchRenderer) { String wholeText = textNode.wholeText(); if (!"".equals(wholeText) && !SvgTextUtil.isOnlyWhiteSpace(wholeText)) { - TextLeafSvgNodeRenderer textLeaf = new TextLeafSvgNodeRenderer(); + final IElementNode textLeafElement = new JsoupElementNode(new Element(Tag.valueOf(Tags.TEXT_LEAF), "")); + ISvgTextNodeRenderer textLeaf = (ISvgTextNodeRenderer) this.rendererFactory + .createSvgNodeRendererForTag(textLeafElement, parentRenderer); textLeaf.setParent(parentRenderer); textLeaf.setAttribute(SvgConstants.Attributes.TEXT_CONTENT, wholeText); ((TextSvgBranchRenderer) parentRenderer).addChild(textLeaf); diff --git a/svg/src/main/java/com/itextpdf/svg/renderers/factories/DefaultSvgNodeRendererMapper.java b/svg/src/main/java/com/itextpdf/svg/renderers/factories/DefaultSvgNodeRendererMapper.java index f5d9b33ce0..6edf99ed8b 100644 --- a/svg/src/main/java/com/itextpdf/svg/renderers/factories/DefaultSvgNodeRendererMapper.java +++ b/svg/src/main/java/com/itextpdf/svg/renderers/factories/DefaultSvgNodeRendererMapper.java @@ -61,6 +61,7 @@ This file is part of the iText (R) project. import com.itextpdf.svg.renderers.impl.StopSvgNodeRenderer; import com.itextpdf.svg.renderers.impl.SvgTagSvgNodeRenderer; import com.itextpdf.svg.renderers.impl.SymbolSvgNodeRenderer; +import com.itextpdf.svg.renderers.impl.TextLeafSvgNodeRenderer; import com.itextpdf.svg.renderers.impl.TextSvgBranchRenderer; import com.itextpdf.svg.renderers.impl.TextSvgTSpanBranchRenderer; import com.itextpdf.svg.renderers.impl.UseSvgNodeRenderer; @@ -109,6 +110,7 @@ public Map> getMapping() { result.put(SvgConstants.Tags.TEXT, TextSvgBranchRenderer.class); result.put(SvgConstants.Tags.TSPAN, TextSvgTSpanBranchRenderer.class); result.put(SvgConstants.Tags.USE, UseSvgNodeRenderer.class); + result.put(SvgConstants.Tags.TEXT_LEAF, TextLeafSvgNodeRenderer.class); return result; } diff --git a/svg/src/test/java/com/itextpdf/svg/DeprecatedApiTest.java b/svg/src/test/java/com/itextpdf/svg/DeprecatedApiTest.java index 1b7743c777..8dd844e690 100644 --- a/svg/src/test/java/com/itextpdf/svg/DeprecatedApiTest.java +++ b/svg/src/test/java/com/itextpdf/svg/DeprecatedApiTest.java @@ -34,21 +34,16 @@ This file is part of the iText (R) project. import com.itextpdf.test.annotations.type.UnitTest; import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(UnitTest.class) //This test class can safely be removed in 7.2 public class DeprecatedApiTest extends ExtendedITextTest { - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); @Test public void processNullTest() { - junitExpectedException.expect(SvgProcessingException.class); - SvgConverter.process(null); + Assert.assertThrows(SvgProcessingException.class, () -> SvgConverter.process(null)); } @Test diff --git a/svg/src/test/java/com/itextpdf/svg/converter/SvgConverterIntegrationTest.java b/svg/src/test/java/com/itextpdf/svg/converter/SvgConverterIntegrationTest.java index 899dacece3..df17ebf270 100644 --- a/svg/src/test/java/com/itextpdf/svg/converter/SvgConverterIntegrationTest.java +++ b/svg/src/test/java/com/itextpdf/svg/converter/SvgConverterIntegrationTest.java @@ -72,12 +72,11 @@ This file is part of the iText (R) project. import com.itextpdf.test.annotations.LogMessage; import com.itextpdf.test.annotations.LogMessages; import com.itextpdf.test.annotations.type.IntegrationTest; + import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; import java.io.ByteArrayOutputStream; import java.io.FileInputStream; @@ -119,9 +118,6 @@ public static void beforeClass() { ITextTest.createDestinationFolder(destinationFolder); } - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void unusedXObjectIntegrationTest() throws IOException, InterruptedException { // This method tests that making an XObject does not, in itself, influence the document it's for. @@ -651,10 +647,9 @@ public void parseAndProcessSuccessTest() throws IOException { @Test public void parseAndProcessIOExceptionTest() throws IOException { - junitExpectedException.expect(SvgProcessingException.class); InputStream fis = new ExceptionInputStream(); - ISvgProcessorResult result = SvgConverter.parseAndProcess(fis); + Assert.assertThrows(SvgProcessingException.class, () -> SvgConverter.parseAndProcess(fis)); } @Test diff --git a/svg/src/test/java/com/itextpdf/svg/converter/SvgConverterUnitNullTest.java b/svg/src/test/java/com/itextpdf/svg/converter/SvgConverterUnitNullTest.java index 5155d2f47a..41f6756d8a 100644 --- a/svg/src/test/java/com/itextpdf/svg/converter/SvgConverterUnitNullTest.java +++ b/svg/src/test/java/com/itextpdf/svg/converter/SvgConverterUnitNullTest.java @@ -55,17 +55,17 @@ This file is part of the iText (R) project. import com.itextpdf.svg.renderers.ISvgNodeRenderer; import com.itextpdf.test.ExtendedITextTest; import com.itextpdf.test.annotations.type.UnitTest; + import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; import org.junit.After; +import org.junit.Assert; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; /** * These tests will make sure that a NullPointerException is never thrown: if a @@ -83,9 +83,6 @@ public class SvgConverterUnitNullTest extends ExtendedITextTest { private final String content = ""; private InputStream is; - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Before public void setup() { doc = new PdfDocument(new PdfWriter(new ByteArrayOutputStream())); @@ -100,32 +97,31 @@ public void teardown() { @Test public void drawOnDocumentStringNullTest() { - junitExpectedException.expect(SvgProcessingException.class); - SvgConverter.drawOnDocument((String) null, doc, 1); + Assert.assertThrows(SvgProcessingException.class, () -> SvgConverter.drawOnDocument((String) null, doc, 1)); } @Test public void drawOnDocumentInputStreamNullTest() throws IOException { - junitExpectedException.expect(SvgProcessingException.class); - SvgConverter.drawOnDocument((InputStream) null, doc, 1); + Assert.assertThrows(SvgProcessingException.class, + () -> SvgConverter.drawOnDocument((InputStream) null, doc, 1) + ); } @Test public void drawOnDocumentDocNullTest() throws IOException { - junitExpectedException.expect(SvgProcessingException.class); - SvgConverter.drawOnDocument(is, null, 1); + Assert.assertThrows(SvgProcessingException.class, () -> SvgConverter.drawOnDocument(is, null, 1)); } @Test public void drawOnDocumentAllNullTest() { - junitExpectedException.expect(SvgProcessingException.class); - SvgConverter.drawOnDocument((String) null, null, 1); + Assert.assertThrows(SvgProcessingException.class, () -> SvgConverter.drawOnDocument((String) null, null, 1)); } @Test public void drawOnDocumentAllNullTest2() throws IOException { - junitExpectedException.expect(SvgProcessingException.class); - SvgConverter.drawOnDocument((InputStream) null, null, 1); + Assert.assertThrows(SvgProcessingException.class, + () -> SvgConverter.drawOnDocument((InputStream) null, null, 1) + ); } @Test @@ -140,34 +136,29 @@ public void drawOnDocumentInputStreamPropsNullTest() throws IOException { @Test public void drawOnPageStringNullTest() { - junitExpectedException.expect(SvgProcessingException.class); PdfPage page = doc.getFirstPage(); - SvgConverter.drawOnPage((String) null, page); + Assert.assertThrows(SvgProcessingException.class, () -> SvgConverter.drawOnPage((String) null, page)); } @Test public void drawOnPageInputStreamNullTest() throws IOException { - junitExpectedException.expect(SvgProcessingException.class); PdfPage page = doc.getFirstPage(); - SvgConverter.drawOnPage((InputStream) null, page); + Assert.assertThrows(SvgProcessingException.class, () -> SvgConverter.drawOnPage((InputStream) null, page)); } @Test public void drawOnPageDocNullTest() throws IOException { - junitExpectedException.expect(SvgProcessingException.class); - SvgConverter.drawOnPage(is, null); + Assert.assertThrows(SvgProcessingException.class, () -> SvgConverter.drawOnPage(is, null)); } @Test public void drawOnPageAllNullTest() { - junitExpectedException.expect(SvgProcessingException.class); - SvgConverter.drawOnPage((String) null, null); + Assert.assertThrows(SvgProcessingException.class, () -> SvgConverter.drawOnPage((String) null, null)); } @Test public void drawOnPageAllNullTest2() throws IOException { - junitExpectedException.expect(SvgProcessingException.class); - SvgConverter.drawOnPage((InputStream) null, null); + Assert.assertThrows(SvgProcessingException.class, () -> SvgConverter.drawOnPage((InputStream) null, null)); } @Test @@ -184,34 +175,29 @@ public void drawOnPageInputStreamPropsNullTest() throws IOException { @Test public void drawOnCanvasStringNullTest() { - junitExpectedException.expect(SvgProcessingException.class); PdfCanvas canvas = new PdfCanvas(doc.getLastPage()); - SvgConverter.drawOnCanvas((String) null, canvas); + Assert.assertThrows(SvgProcessingException.class, () -> SvgConverter.drawOnDocument((String) null, doc, 1)); } @Test public void drawOnCanvasInputStreamNullTest() throws IOException { - junitExpectedException.expect(SvgProcessingException.class); PdfCanvas canvas = new PdfCanvas(doc.getLastPage()); - SvgConverter.drawOnCanvas((InputStream) null, canvas); + Assert.assertThrows(SvgProcessingException.class, () -> SvgConverter.drawOnCanvas((InputStream) null, canvas)); } @Test public void drawOnCanvasDocNullTest() throws IOException { - junitExpectedException.expect(SvgProcessingException.class); - SvgConverter.drawOnCanvas(is, null); + Assert.assertThrows(SvgProcessingException.class, () -> SvgConverter.drawOnCanvas(is, null)); } @Test public void drawOnCanvasAllNullTest() { - junitExpectedException.expect(SvgProcessingException.class); - SvgConverter.drawOnCanvas((String) null, null); + Assert.assertThrows(SvgProcessingException.class, () -> SvgConverter.drawOnCanvas((String) null, null)); } @Test public void drawOnCanvasAllNullTest2() throws IOException { - junitExpectedException.expect(SvgProcessingException.class); - SvgConverter.drawOnCanvas((InputStream) null, null); + Assert.assertThrows(SvgProcessingException.class, () -> SvgConverter.drawOnCanvas((InputStream) null, null)); } @Test @@ -228,57 +214,48 @@ public void drawOnCanvasInputStreamPropsNullTest() throws IOException { @Test public void convertToXObjectStringNullTest() { - junitExpectedException.expect(SvgProcessingException.class); - SvgConverter.convertToXObject((String) null, doc); + Assert.assertThrows(SvgProcessingException.class, () -> SvgConverter.convertToXObject((String) null, doc)); } @Test public void convertToXObjectInputStreamNullTest() throws IOException { - junitExpectedException.expect(SvgProcessingException.class); - SvgConverter.convertToXObject((InputStream) null, doc); + Assert.assertThrows(SvgProcessingException.class, () -> SvgConverter.convertToXObject((InputStream) null, doc)); } @Test public void convertToXObjectRendererNullTest() { - junitExpectedException.expect(SvgProcessingException.class); - SvgConverter.convertToXObject((ISvgNodeRenderer) null, doc); + Assert.assertThrows(SvgProcessingException.class, () -> SvgConverter.convertToXObject((ISvgNodeRenderer) null, doc)); } @Test public void convertToXObjectDocWithStringNullTest() throws IOException { - junitExpectedException.expect(SvgProcessingException.class); - SvgConverter.convertToXObject(is, null); + Assert.assertThrows(SvgProcessingException.class, () -> SvgConverter.convertToXObject(is, null)); } @Test public void convertToXObjectDocWithStreamNullTest() throws IOException { - junitExpectedException.expect(SvgProcessingException.class); - SvgConverter.convertToXObject(is, null); + Assert.assertThrows(SvgProcessingException.class, () -> SvgConverter.convertToXObject(is, null)); } @Test public void convertToXObjectDocWithRendererNullTest() throws IOException { - junitExpectedException.expect(SvgProcessingException.class); ISvgNodeRenderer renderer = SvgConverter.process(SvgConverter.parse(is), null).getRootRenderer(); - SvgConverter.convertToXObject(renderer, null); + Assert.assertThrows(SvgProcessingException.class, () -> SvgConverter.convertToXObject(renderer, null)); } @Test public void convertToXObjectAllWithStringNullTest() { - junitExpectedException.expect(SvgProcessingException.class); - SvgConverter.convertToXObject((String) null, null); + Assert.assertThrows(SvgProcessingException.class, () -> SvgConverter.convertToXObject((String) null, null)); } @Test public void convertToXObjectAllWithStreamNullTest() throws IOException { - junitExpectedException.expect(SvgProcessingException.class); - SvgConverter.convertToXObject((InputStream) null, null); + Assert.assertThrows(SvgProcessingException.class, () -> SvgConverter.convertToXObject((InputStream) null, null)); } @Test public void convertToXObjectAllWithRendererNullTest() { - junitExpectedException.expect(SvgProcessingException.class); - SvgConverter.convertToXObject((ISvgNodeRenderer) null, null); + Assert.assertThrows(SvgProcessingException.class, () -> SvgConverter.convertToXObject((ISvgNodeRenderer) null, null)); } @Test @@ -293,14 +270,12 @@ public void convertToXObjectInputStreamPropsNullTest() throws IOException { @Test public void parseStringNullTest() { - junitExpectedException.expect(SvgProcessingException.class); - SvgConverter.parse((String) null); + Assert.assertThrows(SvgProcessingException.class, () -> SvgConverter.parse((String) null)); } @Test public void parseStreamNullTest() throws IOException { - junitExpectedException.expect(SvgProcessingException.class); - SvgConverter.parse((InputStream) null); + Assert.assertThrows(SvgProcessingException.class, () -> SvgConverter.parse((InputStream) null)); } @Test @@ -310,14 +285,12 @@ public void parseStreamPropsNullTest() throws IOException { @Test public void parseStringPropsNullTest() throws IOException { - junitExpectedException.expect(SvgProcessingException.class); - SvgConverter.parse(null, null); + Assert.assertThrows(SvgProcessingException.class, () -> SvgConverter.parse(null, null)); } @Test public void processAllNullTest() { - junitExpectedException.expect(SvgProcessingException.class); - SvgConverter.process(null, null); + Assert.assertThrows(SvgProcessingException.class, () -> SvgConverter.process(null, null)); } @Test diff --git a/svg/src/test/java/com/itextpdf/svg/converter/SvgConverterUnitTest.java b/svg/src/test/java/com/itextpdf/svg/converter/SvgConverterUnitTest.java index b3ff8f4dcd..63ffe8f1af 100644 --- a/svg/src/test/java/com/itextpdf/svg/converter/SvgConverterUnitTest.java +++ b/svg/src/test/java/com/itextpdf/svg/converter/SvgConverterUnitTest.java @@ -68,6 +68,7 @@ This file is part of the iText (R) project. import com.itextpdf.svg.renderers.impl.SvgTagSvgNodeRenderer; import com.itextpdf.test.ExtendedITextTest; import com.itextpdf.test.annotations.type.UnitTest; + import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -79,10 +80,8 @@ This file is part of the iText (R) project. import org.junit.After; import org.junit.Assert; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(UnitTest.class) public class SvgConverterUnitTest extends ExtendedITextTest { @@ -92,10 +91,6 @@ public class SvgConverterUnitTest extends ExtendedITextTest { private final String content = ""; private InputStream is; - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - - @Before public void setup() { doc = new PdfDocument(new PdfWriter(new ByteArrayOutputStream())); @@ -322,10 +317,10 @@ public void parseStreamErrorOtherCharset() throws IOException { @Test public void checkNullTest(){ - junitExpectedException.expect(SvgProcessingException.class); - junitExpectedException.expectMessage(SvgLogMessageConstant.PARAMETER_CANNOT_BE_NULL); - SvgConverter.drawOnDocument("test",null,1); - + Exception e = Assert.assertThrows(SvgProcessingException.class, + () -> SvgConverter.drawOnDocument("test",null,1) + ); + Assert.assertEquals(SvgLogMessageConstant.PARAMETER_CANNOT_BE_NULL, e.getMessage()); } @Test diff --git a/svg/src/test/java/com/itextpdf/svg/css/DefaultStylesTest.java b/svg/src/test/java/com/itextpdf/svg/css/DefaultStylesTest.java index 630e7f21c9..ca2b169137 100644 --- a/svg/src/test/java/com/itextpdf/svg/css/DefaultStylesTest.java +++ b/svg/src/test/java/com/itextpdf/svg/css/DefaultStylesTest.java @@ -61,17 +61,12 @@ This file is part of the iText (R) project. import java.util.Map; import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(UnitTest.class) public class DefaultStylesTest extends ExtendedITextTest { - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void checkDefaultStrokeValuesTest() { ICssResolver styleResolver = new SvgStyleResolver(new SvgProcessorContext(new SvgConverterProperties())); @@ -125,7 +120,7 @@ public void emptyStreamTest() throws IOException { @Test public void emptyStylesFallbackTest() throws IOException { - junitExpectedException.expect(IOException.class); - new SvgStyleResolver(new ExceptionInputStream(), new SvgProcessorContext(new SvgConverterProperties())); + Assert.assertThrows(IOException.class, () -> new SvgStyleResolver(new ExceptionInputStream(), + new SvgProcessorContext(new SvgConverterProperties()))); } } diff --git a/svg/src/test/java/com/itextpdf/svg/customization/CustomizeTextLeafSvgNodeRendererTest.java b/svg/src/test/java/com/itextpdf/svg/customization/CustomizeTextLeafSvgNodeRendererTest.java new file mode 100644 index 0000000000..e799177cbd --- /dev/null +++ b/svg/src/test/java/com/itextpdf/svg/customization/CustomizeTextLeafSvgNodeRendererTest.java @@ -0,0 +1,110 @@ +/* + This file is part of the iText (R) project. + Copyright (c) 1998-2021 iText Group NV + Authors: iText Software. + + This program is offered under a commercial and under the AGPL license. + For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below. + + AGPL licensing: + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + */ +package com.itextpdf.svg.customization; + +import com.itextpdf.kernel.colors.ColorConstants; +import com.itextpdf.kernel.geom.Rectangle; +import com.itextpdf.kernel.pdf.PdfDocument; +import com.itextpdf.kernel.pdf.PdfWriter; +import com.itextpdf.kernel.pdf.canvas.PdfCanvas; +import com.itextpdf.kernel.pdf.xobject.PdfFormXObject; +import com.itextpdf.kernel.utils.CompareTool; +import com.itextpdf.styledxmlparser.node.IElementNode; +import com.itextpdf.svg.SvgConstants; +import com.itextpdf.svg.SvgConstants.Tags; +import com.itextpdf.svg.converter.SvgConverter; +import com.itextpdf.svg.processors.impl.SvgConverterProperties; +import com.itextpdf.svg.renderers.ISvgNodeRenderer; +import com.itextpdf.svg.renderers.SvgDrawContext; +import com.itextpdf.svg.renderers.SvgIntegrationTest; +import com.itextpdf.svg.renderers.factories.DefaultSvgNodeRendererFactory; +import com.itextpdf.svg.renderers.impl.TextLeafSvgNodeRenderer; +import com.itextpdf.test.ITextTest; + +import java.io.IOException; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +public class CustomizeTextLeafSvgNodeRendererTest extends SvgIntegrationTest { + + public static final String SOURCE_FOLDER = "./src/test/resources/com/itextpdf/svg/customization/CustomizeTextLeafSvgNodeRendererTest/"; + public static final String DESTINATION_FOLDER = "./target/test/com/itextpdf/svg/customization/CustomizeTextLeafSvgNodeRendererTest/"; + + @BeforeClass + public static void beforeClass() { + ITextTest.createDestinationFolder(DESTINATION_FOLDER); + } + + @Test + public void testCustomizeTextLeafSvgNodeRenderer() throws IOException, InterruptedException { + String pdfFilename = "customizeTextLeafSvgNodeRenderer.pdf"; + PdfDocument doc = new PdfDocument(new PdfWriter(DESTINATION_FOLDER + pdfFilename)); + doc.addNewPage(); + + SvgConverterProperties properties = new SvgConverterProperties(); + properties.setRendererFactory(new CustomTextLeafOverridingSvgNodeRendererFactory()); + + String svg = "\n" + + " Hello world\n" + + ""; + + PdfFormXObject form = SvgConverter.convertToXObject(svg, doc, properties); + new PdfCanvas(doc.getPage(1)).addXObjectFittedIntoRectangle(form, new Rectangle(100, 100, 240, 80)); + + doc.close(); + Assert.assertNull(new CompareTool().compareByContent(DESTINATION_FOLDER + pdfFilename, SOURCE_FOLDER + "cmp_" + pdfFilename, DESTINATION_FOLDER, "diff_")); + } + + private static class CustomTextLeafOverridingSvgNodeRendererFactory extends DefaultSvgNodeRendererFactory { + @Override + public ISvgNodeRenderer createSvgNodeRendererForTag(IElementNode tag, ISvgNodeRenderer parent) { + if (Tags.TEXT_LEAF.equals(tag.name())) { + return new CustomTextLeafSvgNodeRenderer(); + } else { + return super.createSvgNodeRendererForTag(tag, parent); + } + } + } + + private static class CustomTextLeafSvgNodeRenderer extends TextLeafSvgNodeRenderer { + @Override + public ISvgNodeRenderer createDeepCopy() { + CustomTextLeafSvgNodeRenderer copy = new CustomTextLeafSvgNodeRenderer(); + deepCopyAttributesAndStyles(copy); + return copy; + } + + @Override + protected void doDraw(SvgDrawContext context) { + if (this.attributesAndStyles != null && this.attributesAndStyles.containsKey(SvgConstants.Attributes.TEXT_CONTENT)) { + PdfCanvas currentCanvas = context.getCurrentCanvas(); + currentCanvas.setFillColor(ColorConstants.RED); + currentCanvas.moveText(context.getTextMove()[0], context.getTextMove()[1]); + String initialText = this.attributesAndStyles.get(SvgConstants.Attributes.TEXT_CONTENT); + String amendedText = "_" + initialText + "_"; + currentCanvas.showText(amendedText); + } + } + } +} diff --git a/svg/src/test/java/com/itextpdf/svg/processors/DefaultSvgProcessorIntegrationTest.java b/svg/src/test/java/com/itextpdf/svg/processors/DefaultSvgProcessorIntegrationTest.java index b564561cc1..4d57d971f1 100644 --- a/svg/src/test/java/com/itextpdf/svg/processors/DefaultSvgProcessorIntegrationTest.java +++ b/svg/src/test/java/com/itextpdf/svg/processors/DefaultSvgProcessorIntegrationTest.java @@ -55,10 +55,8 @@ This file is part of the iText (R) project. import java.io.InputStream; import java.util.Map; import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(IntegrationTest.class) public class DefaultSvgProcessorIntegrationTest extends SvgIntegrationTest { @@ -66,9 +64,6 @@ public class DefaultSvgProcessorIntegrationTest extends SvgIntegrationTest { public static final String sourceFolder = "./src/test/resources/com/itextpdf/svg/processors/impl/DefaultSvgProcessorIntegrationTest/"; public static final String destinationFolder = "./target/test/com/itextpdf/svg/processors/impl/DefaultSvgProcessorIntegrationTest/"; - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void DefaultBehaviourTest() throws IOException { String svgFile = sourceFolder + "RedCircle.svg"; diff --git a/svg/src/test/java/com/itextpdf/svg/processors/ProcessorStateTest.java b/svg/src/test/java/com/itextpdf/svg/processors/ProcessorStateTest.java index d06dc45f42..287d184d2b 100644 --- a/svg/src/test/java/com/itextpdf/svg/processors/ProcessorStateTest.java +++ b/svg/src/test/java/com/itextpdf/svg/processors/ProcessorStateTest.java @@ -51,17 +51,12 @@ This file is part of the iText (R) project. import java.util.EmptyStackException; import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category( UnitTest.class ) public class ProcessorStateTest extends ExtendedITextTest{ - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - /** * Push test */ @@ -120,10 +115,9 @@ public void processorStateTestMultiplePushesPopAndPeek() { @Test public void processorStateTestPopEmpty() { - junitExpectedException.expect(EmptyStackException.class); ProcessorState testProcessorState = new ProcessorState(); - testProcessorState.pop(); + Assert.assertThrows(EmptyStackException.class, () -> testProcessorState.pop()); } @Test @@ -142,9 +136,9 @@ public void processorStateTestPushSameElementTwice() { @Test public void processorStateTestPeekEmpty() { - junitExpectedException.expect(EmptyStackException.class); ProcessorState testProcessorState = new ProcessorState(); - testProcessorState.pop(); + + Assert.assertThrows(EmptyStackException.class, () -> testProcessorState.pop()); } diff --git a/svg/src/test/java/com/itextpdf/svg/processors/impl/DefaultSvgProcessorUnitTest.java b/svg/src/test/java/com/itextpdf/svg/processors/impl/DefaultSvgProcessorUnitTest.java index 85c93b66da..b3fe4feee5 100644 --- a/svg/src/test/java/com/itextpdf/svg/processors/impl/DefaultSvgProcessorUnitTest.java +++ b/svg/src/test/java/com/itextpdf/svg/processors/impl/DefaultSvgProcessorUnitTest.java @@ -71,17 +71,12 @@ This file is part of the iText (R) project. import java.util.List; import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(UnitTest.class) public class DefaultSvgProcessorUnitTest extends ExtendedITextTest { - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - //Main success scenario /** @@ -188,9 +183,6 @@ public void dummyProcessingSvgTagIsNotRootOfInput() { @Test public void dummyProcessingNoSvgTagInInput() { - junitExpectedException.expect(SvgProcessingException.class); - junitExpectedException.expectMessage(SvgLogMessageConstant.NOROOT); - Element jsoupSVGRoot = new Element(Tag.valueOf("polygon"), ""); Element jsoupSVGCircle = new Element(Tag.valueOf("circle"), ""); INode root = new JsoupElementNode(jsoupSVGRoot); @@ -199,15 +191,17 @@ public void dummyProcessingNoSvgTagInInput() { DefaultSvgProcessor processor = new DefaultSvgProcessor(); ISvgConverterProperties props = new DummySvgConverterProperties(); - processor.process(root, props).getRootRenderer(); + Exception e = Assert.assertThrows(SvgProcessingException.class, + () -> processor.process(root, props).getRootRenderer() + ); + Assert.assertEquals(SvgLogMessageConstant.NOROOT, e.getMessage()); } @Test public void dummyProcessingTestNullInput() { - junitExpectedException.expect(SvgProcessingException.class); DefaultSvgProcessor processor = new DefaultSvgProcessor(); - processor.process(null, null); + Assert.assertThrows(SvgProcessingException.class, () -> processor.process(null, null)); } @Test diff --git a/svg/src/test/java/com/itextpdf/svg/renderers/DefaultSvgNodeRendererFactoryTest.java b/svg/src/test/java/com/itextpdf/svg/renderers/DefaultSvgNodeRendererFactoryTest.java index b2c2571c96..bc4b852ee3 100644 --- a/svg/src/test/java/com/itextpdf/svg/renderers/DefaultSvgNodeRendererFactoryTest.java +++ b/svg/src/test/java/com/itextpdf/svg/renderers/DefaultSvgNodeRendererFactoryTest.java @@ -66,19 +66,14 @@ This file is part of the iText (R) project. import org.junit.Assert; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(UnitTest.class) public class DefaultSvgNodeRendererFactoryTest extends ExtendedITextTest { private ISvgNodeRendererFactory fact; - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Before public void setUp() { fact = new DefaultSvgNodeRendererFactory(new DummySvgNodeMapper()); @@ -96,42 +91,39 @@ public void nonExistingTagTest() { @Test public void protectedConstructorTest() { - junitExpectedException.expect(SvgProcessingException.class); Element protectedElement = new Element(Tag.valueOf("protected"), ""); IElementNode tag = new JsoupElementNode(protectedElement); - fact.createSvgNodeRendererForTag(tag, null); + + Assert.assertThrows(SvgProcessingException.class, () -> fact.createSvgNodeRendererForTag(tag, null)); } @Test public void protectedConstructorInnerTest() throws ReflectiveOperationException { - junitExpectedException.expect(ReflectiveOperationException.class); Element protectedElement = new Element(Tag.valueOf("protected"), ""); IElementNode tag = new JsoupElementNode(protectedElement); - try { - fact.createSvgNodeRendererForTag(tag, null); - } catch (SvgProcessingException spe) { - throw (ReflectiveOperationException) spe.getCause(); - } + + Exception e = Assert.assertThrows(SvgProcessingException.class, + () -> fact.createSvgNodeRendererForTag(tag, null) + ); + Assert.assertTrue(e.getCause() instanceof ReflectiveOperationException); } @Test public void argumentedConstructorTest() { - junitExpectedException.expect(SvgProcessingException.class); Element protectedElement = new Element(Tag.valueOf("argumented"), ""); IElementNode tag = new JsoupElementNode(protectedElement); - Assert.assertNull(fact.createSvgNodeRendererForTag(tag, null)); + Assert.assertThrows(SvgProcessingException.class, () -> Assert.assertNull(fact.createSvgNodeRendererForTag(tag, null))); } @Test public void argumentedConstructorInnerTest() throws ReflectiveOperationException { - junitExpectedException.expect(ReflectiveOperationException.class); Element protectedElement = new Element(Tag.valueOf("argumented"), ""); IElementNode tag = new JsoupElementNode(protectedElement); - try { - fact.createSvgNodeRendererForTag(tag, null); - } catch (SvgProcessingException spe) { - throw (ReflectiveOperationException) spe.getCause(); - } + + Exception e = Assert.assertThrows(SvgProcessingException.class, + () -> fact.createSvgNodeRendererForTag(tag, null) + ); + Assert.assertTrue(e.getCause() instanceof ReflectiveOperationException); } @Test @@ -196,8 +188,7 @@ public Collection getIgnoredTags() { */ @Test public void faultyMapperTest() { - junitExpectedException.expect(RuntimeException.class); - fact = new DefaultSvgNodeRendererFactory(new FaultyTestMapper()); + Assert.assertThrows(RuntimeException.class, () -> new DefaultSvgNodeRendererFactory(new FaultyTestMapper())); } } diff --git a/svg/src/test/java/com/itextpdf/svg/renderers/FillTest.java b/svg/src/test/java/com/itextpdf/svg/renderers/FillTest.java index 04f5d389a7..997617f844 100644 --- a/svg/src/test/java/com/itextpdf/svg/renderers/FillTest.java +++ b/svg/src/test/java/com/itextpdf/svg/renderers/FillTest.java @@ -48,18 +48,14 @@ This file is part of the iText (R) project. import java.io.IOException; +import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(IntegrationTest.class) public class FillTest extends SvgIntegrationTest { - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - private static final String SOURCE_FOLDER = "./src/test/resources/com/itextpdf/svg/renderers/impl/FillTest/"; private static final String DESTINATION_FOLDER = "./target/test/com/itextpdf/svg/renderers/impl/FillTest/"; @@ -127,8 +123,9 @@ public void opacityFillTest() throws IOException, InterruptedException { @Test public void eofillUnsuportedAtributeTest() throws IOException, InterruptedException { - junitExpectedException.expect(SvgProcessingException.class); - convertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER, "eofillUnsuportedAtributeTest"); + Assert.assertThrows(SvgProcessingException.class, + () -> convertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER, "eofillUnsuportedAtributeTest") + ); } @Test diff --git a/svg/src/test/java/com/itextpdf/svg/renderers/OpacityTest.java b/svg/src/test/java/com/itextpdf/svg/renderers/OpacityTest.java index f43e48e798..e9f14c0871 100644 --- a/svg/src/test/java/com/itextpdf/svg/renderers/OpacityTest.java +++ b/svg/src/test/java/com/itextpdf/svg/renderers/OpacityTest.java @@ -44,19 +44,16 @@ This file is part of the iText (R) project. import com.itextpdf.test.ITextTest; import com.itextpdf.test.annotations.type.IntegrationTest; + +import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; - import java.io.IOException; + @Category(IntegrationTest.class) public class OpacityTest extends SvgIntegrationTest { - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - private static final String SOURCE_FOLDER = "./src/test/resources/com/itextpdf/svg/renderers/impl/OpacityTest/"; private static final String DESTINATION_FOLDER = "./target/test/com/itextpdf/svg/renderers/impl/OpacityTest/"; @@ -89,15 +86,17 @@ public void testRGBA() throws IOException, InterruptedException { @Test //TODO DEVSIX-2678 public void testFillOpacityWithComma() throws IOException, InterruptedException { - junitExpectedException.expect(NumberFormatException.class); - convertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER, "testFillOpacityWithComma"); + Assert.assertThrows(NumberFormatException.class, + () -> convertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER, "testFillOpacityWithComma") + ); } @Test //TODO DEVSIX-2678 public void testFillOpacityWithPercents() throws IOException, InterruptedException { - junitExpectedException.expect(NumberFormatException.class); - convertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER, "testFillOpacityWithPercents"); + Assert.assertThrows(NumberFormatException.class, + () -> convertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER, "testFillOpacityWithPercents") + ); } @Test @@ -109,15 +108,17 @@ public void testFillOpacity() throws IOException, InterruptedException { @Test //TODO DEVSIX-2679 public void testStrokeOpacityWithComma() throws IOException, InterruptedException { - junitExpectedException.expect(Exception.class); - convertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER, "testStrokeOpacityWithComma"); + Assert.assertThrows(Exception.class, + () -> convertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER, "testStrokeOpacityWithComma") + ); } @Test //TODO DEVSIX-2679 public void testStrokeOpacityWithPercents() throws IOException, InterruptedException { - junitExpectedException.expect(NumberFormatException.class); - convertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER, "testStrokeOpacityWithPercents"); + Assert.assertThrows(NumberFormatException.class, + () -> convertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER, "testStrokeOpacityWithPercents") + ); } @Test diff --git a/svg/src/test/java/com/itextpdf/svg/renderers/StrokeTest.java b/svg/src/test/java/com/itextpdf/svg/renderers/StrokeTest.java index 432f1a652a..e76289a927 100644 --- a/svg/src/test/java/com/itextpdf/svg/renderers/StrokeTest.java +++ b/svg/src/test/java/com/itextpdf/svg/renderers/StrokeTest.java @@ -51,17 +51,12 @@ This file is part of the iText (R) project. import java.io.IOException; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(IntegrationTest.class) public class StrokeTest extends SvgIntegrationTest { - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - private static final String SOURCE_FOLDER = "./src/test/resources/com/itextpdf/svg/renderers/impl/StrokeTest/"; private static final String DESTINATION_FOLDER = "./target/test/com/itextpdf/svg/renderers/impl/StrokeTest/"; diff --git a/svg/src/test/java/com/itextpdf/svg/renderers/SvgDrawContextTest.java b/svg/src/test/java/com/itextpdf/svg/renderers/SvgDrawContextTest.java index a1c7a1cb77..07821ac084 100644 --- a/svg/src/test/java/com/itextpdf/svg/renderers/SvgDrawContextTest.java +++ b/svg/src/test/java/com/itextpdf/svg/renderers/SvgDrawContextTest.java @@ -60,10 +60,8 @@ This file is part of the iText (R) project. import org.junit.After; import org.junit.Assert; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(UnitTest.class) public class SvgDrawContextTest extends ExtendedITextTest { @@ -72,9 +70,6 @@ public class SvgDrawContextTest extends ExtendedITextTest { private PdfCanvas page1, page2; private SvgDrawContext context; - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Before public void setUp() { tokenDoc = new PdfDocument(new PdfWriter(new ByteArrayOutputStream())); @@ -91,14 +86,12 @@ public void tearDown() { @Test public void drawContextEmptyDequeGetFirstTest() { - junitExpectedException.expect(NoSuchElementException.class); - context.getCurrentCanvas(); + Assert.assertThrows(NoSuchElementException.class, () -> context.getCurrentCanvas()); } @Test public void drawContextEmptyDequePopTest() { - junitExpectedException.expect(NoSuchElementException.class); - context.popCanvas(); + Assert.assertThrows(NoSuchElementException.class, () -> context.popCanvas()); } @Test @@ -167,29 +160,32 @@ public void addISvgNodeRender() { @Test public void addNullToNamedObjects() { - junitExpectedException.expect(SvgProcessingException.class); - junitExpectedException.expectMessage(SvgLogMessageConstant.NAMED_OBJECT_NULL); - String name = "expected"; - this.context.addNamedObject(name, null); + + Exception e = Assert.assertThrows(SvgProcessingException.class, + () -> this.context.addNamedObject(name, null) + ); + Assert.assertEquals(SvgLogMessageConstant.NAMED_OBJECT_NULL, e.getMessage()); } @Test public void addNamedObjectWithNullName() { - junitExpectedException.expect(SvgProcessingException.class); - junitExpectedException.expectMessage(SvgLogMessageConstant.NAMED_OBJECT_NAME_NULL_OR_EMPTY); - ISvgNodeRenderer expected = new DummySvgNodeRenderer(); - this.context.addNamedObject(null, expected); + + Exception e = Assert.assertThrows(SvgProcessingException.class, + () -> this.context.addNamedObject(null, expected) + ); + Assert.assertEquals(SvgLogMessageConstant.NAMED_OBJECT_NAME_NULL_OR_EMPTY, e.getMessage()); } @Test public void addNamedObjectWithEmptyName() { - junitExpectedException.expect(SvgProcessingException.class); - junitExpectedException.expectMessage(SvgLogMessageConstant.NAMED_OBJECT_NAME_NULL_OR_EMPTY); - ISvgNodeRenderer expected = new DummySvgNodeRenderer(); - this.context.addNamedObject("", expected); + + Exception e = Assert.assertThrows(SvgProcessingException.class, + () -> this.context.addNamedObject("", expected) + ); + Assert.assertEquals(SvgLogMessageConstant.NAMED_OBJECT_NAME_NULL_OR_EMPTY, e.getMessage()); } @Test diff --git a/svg/src/test/java/com/itextpdf/svg/renderers/factories/DefaultSvgNodeRendererFactoryTest.java b/svg/src/test/java/com/itextpdf/svg/renderers/factories/DefaultSvgNodeRendererFactoryTest.java index 52f93d69ed..87f3f75a1e 100644 --- a/svg/src/test/java/com/itextpdf/svg/renderers/factories/DefaultSvgNodeRendererFactoryTest.java +++ b/svg/src/test/java/com/itextpdf/svg/renderers/factories/DefaultSvgNodeRendererFactoryTest.java @@ -47,23 +47,20 @@ This file is part of the iText (R) project. import com.itextpdf.test.ExtendedITextTest; import com.itextpdf.test.annotations.type.UnitTest; -import org.junit.Rule; +import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(UnitTest.class) public class DefaultSvgNodeRendererFactoryTest extends ExtendedITextTest { - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void createSvgNodeRenderer() { - junitExpectedException.expect(SvgProcessingException.class); - junitExpectedException.expectMessage(SvgLogMessageConstant.TAGPARAMETERNULL); - ISvgNodeRendererFactory nodeRendererFactory = new DefaultSvgNodeRendererFactory(null); - nodeRendererFactory.createSvgNodeRendererForTag(null, null); + + Exception e = Assert.assertThrows(SvgProcessingException.class, + () -> nodeRendererFactory.createSvgNodeRendererForTag(null, null) + ); + Assert.assertEquals(SvgLogMessageConstant.TAGPARAMETERNULL, e.getMessage()); } } diff --git a/svg/src/test/java/com/itextpdf/svg/renderers/impl/ClipPathSvgNodeRendererIntegrationTest.java b/svg/src/test/java/com/itextpdf/svg/renderers/impl/ClipPathSvgNodeRendererIntegrationTest.java index f3c0f3fc57..a62542ae80 100644 --- a/svg/src/test/java/com/itextpdf/svg/renderers/impl/ClipPathSvgNodeRendererIntegrationTest.java +++ b/svg/src/test/java/com/itextpdf/svg/renderers/impl/ClipPathSvgNodeRendererIntegrationTest.java @@ -46,11 +46,10 @@ This file is part of the iText (R) project. import com.itextpdf.svg.renderers.SvgIntegrationTest; import com.itextpdf.test.ITextTest; import com.itextpdf.test.annotations.type.IntegrationTest; + import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; import java.io.IOException; @@ -60,9 +59,6 @@ public class ClipPathSvgNodeRendererIntegrationTest extends SvgIntegrationTest { public static final String sourceFolder = "./src/test/resources/com/itextpdf/svg/renderers/impl/ClipPathTest/"; public static final String destinationFolder = "./target/test/com/itextpdf/svg/renderers/impl/ClipPathTest/"; - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - private SvgConverterProperties properties; @BeforeClass diff --git a/svg/src/test/java/com/itextpdf/svg/renderers/impl/LineSvgNodeRendererTest.java b/svg/src/test/java/com/itextpdf/svg/renderers/impl/LineSvgNodeRendererTest.java index ccae217672..64b856d90a 100644 --- a/svg/src/test/java/com/itextpdf/svg/renderers/impl/LineSvgNodeRendererTest.java +++ b/svg/src/test/java/com/itextpdf/svg/renderers/impl/LineSvgNodeRendererTest.java @@ -64,17 +64,12 @@ This file is part of the iText (R) project. import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(IntegrationTest.class) public class LineSvgNodeRendererTest extends SvgIntegrationTest{ - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - public static final String sourceFolder = "./src/test/resources/com/itextpdf/svg/renderers/impl/LineSvgNodeRendererTest/"; public static final String destinationFolder = "./target/test/com/itextpdf/svg/renderers/impl/LineSvgNodeRendererTest/"; @@ -133,9 +128,6 @@ public void lineWithEmpyAttributesTest() throws IOException, InterruptedExceptio @Test public void invalidAttributeTest01() { - junitExpectedException.expect(StyledXMLParserException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(StyledXMLParserException.NAN, "notAnum")); - PdfDocument doc = new PdfDocument(new PdfWriter(new ByteArrayOutputStream())); doc.addNewPage(); ISvgNodeRenderer root = new LineSvgNodeRenderer(); @@ -149,7 +141,10 @@ public void invalidAttributeTest01() { PdfCanvas cv = new PdfCanvas(doc, 1); context.pushCanvas(cv); - root.draw(context); + Exception e = Assert.assertThrows(StyledXMLParserException.class, + () -> root.draw(context) + ); + Assert.assertEquals(MessageFormatUtil.format(StyledXMLParserException.NAN, "notAnum"), e.getMessage()); } diff --git a/svg/src/test/java/com/itextpdf/svg/renderers/impl/NestedSvgTagSvgNodeRendererIntegrationTest.java b/svg/src/test/java/com/itextpdf/svg/renderers/impl/NestedSvgTagSvgNodeRendererIntegrationTest.java index e8ef510b9f..ac017ed115 100644 --- a/svg/src/test/java/com/itextpdf/svg/renderers/impl/NestedSvgTagSvgNodeRendererIntegrationTest.java +++ b/svg/src/test/java/com/itextpdf/svg/renderers/impl/NestedSvgTagSvgNodeRendererIntegrationTest.java @@ -49,16 +49,12 @@ This file is part of the iText (R) project. import java.io.IOException; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(IntegrationTest.class) public class NestedSvgTagSvgNodeRendererIntegrationTest extends SvgIntegrationTest { - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); private static final String SOURCE_FOLDER = "./src/test/resources/com/itextpdf/svg/renderers/impl/RootSvgNodeRendererTest/nested/"; private static final String DESTINATION_FOLDER = "./target/test/com/itextpdf/svg/renderers/impl/RootSvgNodeRendererTest/nested/"; diff --git a/svg/src/test/java/com/itextpdf/svg/renderers/impl/NoDrawOperationSvgNodeRendererUnitTest.java b/svg/src/test/java/com/itextpdf/svg/renderers/impl/NoDrawOperationSvgNodeRendererUnitTest.java index 91f02fe839..a07e16ba6e 100644 --- a/svg/src/test/java/com/itextpdf/svg/renderers/impl/NoDrawOperationSvgNodeRendererUnitTest.java +++ b/svg/src/test/java/com/itextpdf/svg/renderers/impl/NoDrawOperationSvgNodeRendererUnitTest.java @@ -46,23 +46,20 @@ This file is part of the iText (R) project. import com.itextpdf.test.ExtendedITextTest; import com.itextpdf.test.annotations.type.UnitTest; -import org.junit.Rule; +import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(UnitTest.class) public class NoDrawOperationSvgNodeRendererUnitTest extends ExtendedITextTest { - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void dontDrawTest() { - junitExpectedException.expect(UnsupportedOperationException.class); - junitExpectedException.expectMessage(SvgLogMessageConstant.DRAW_NO_DRAW); - NoDrawOperationSvgNodeRenderer renderer = new NoDrawOperationSvgNodeRenderer(); - renderer.doDraw(null); + + Exception e = Assert.assertThrows(UnsupportedOperationException.class, + () -> renderer.doDraw(null) + ); + Assert.assertEquals(SvgLogMessageConstant.DRAW_NO_DRAW, e.getMessage()); } } diff --git a/svg/src/test/java/com/itextpdf/svg/renderers/impl/PathParsingIntegrationTest.java b/svg/src/test/java/com/itextpdf/svg/renderers/impl/PathParsingIntegrationTest.java index b76bef6b50..3ef778204f 100644 --- a/svg/src/test/java/com/itextpdf/svg/renderers/impl/PathParsingIntegrationTest.java +++ b/svg/src/test/java/com/itextpdf/svg/renderers/impl/PathParsingIntegrationTest.java @@ -49,11 +49,11 @@ This file is part of the iText (R) project. import com.itextpdf.test.annotations.LogMessage; import com.itextpdf.test.annotations.LogMessages; import com.itextpdf.test.annotations.type.IntegrationTest; + +import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; import java.io.IOException; @@ -63,9 +63,6 @@ public class PathParsingIntegrationTest extends SvgIntegrationTest { public static final String sourceFolder = "./src/test/resources/com/itextpdf/svg/renderers/impl/PathParsingIntegrationTest/"; public static final String destinationFolder = "./target/test/com/itextpdf/svg/renderers/impl/PathParsingIntegrationTest/"; - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @BeforeClass public static void beforeClass() { ITextTest.createDestinationFolder(destinationFolder); @@ -103,14 +100,16 @@ public void decimalPointHandlingTest() throws IOException, InterruptedException @Test public void invalidOperatorTest() throws IOException, InterruptedException { - junitExpectedException.expect(SvgProcessingException.class); - convertAndCompare(sourceFolder, destinationFolder, "invalidOperator"); + Assert.assertThrows(SvgProcessingException.class, + () -> convertAndCompare(sourceFolder, destinationFolder, "invalidOperator") + ); } @Test public void invalidOperatorCSensTest() throws IOException, InterruptedException { - junitExpectedException.expect(SvgProcessingException.class); - convertAndCompare(sourceFolder, destinationFolder, "invalidOperatorCSens"); + Assert.assertThrows(SvgProcessingException.class, + () -> convertAndCompare(sourceFolder, destinationFolder, "invalidOperatorCSens") + ); } @Test diff --git a/svg/src/test/java/com/itextpdf/svg/renderers/impl/PathParsingTest.java b/svg/src/test/java/com/itextpdf/svg/renderers/impl/PathParsingTest.java index 4e403c7c83..df87a4a74c 100644 --- a/svg/src/test/java/com/itextpdf/svg/renderers/impl/PathParsingTest.java +++ b/svg/src/test/java/com/itextpdf/svg/renderers/impl/PathParsingTest.java @@ -46,27 +46,23 @@ This file is part of the iText (R) project. import com.itextpdf.svg.exceptions.SvgProcessingException; import com.itextpdf.test.ExtendedITextTest; import com.itextpdf.test.annotations.type.UnitTest; + import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; import java.util.Collection; @Category(UnitTest.class) public class PathParsingTest extends ExtendedITextTest { - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void pathParsingNoDOperatorTest() { // Path objects must have a d attribute - junitExpectedException.expect(SvgProcessingException.class); PathSvgNodeRenderer path = new PathSvgNodeRenderer(); path.setAttribute(SvgConstants.Attributes.STROKE, "black"); - path.parsePathOperations(); + + Assert.assertThrows(SvgProcessingException.class, () -> path.parsePathOperations()); } @Test @@ -87,18 +83,18 @@ public void pathParsingOperatorOnlySpacesTest() { @Test public void pathParsingOperatorBadOperatorTest() { - junitExpectedException.expect(SvgProcessingException.class); PathSvgNodeRenderer path = new PathSvgNodeRenderer(); path.setAttribute(SvgConstants.Attributes.D, "b 1 1"); - path.parsePathOperations(); + + Assert.assertThrows(SvgProcessingException.class, () -> path.parsePathOperations()); } @Test public void pathParsingOperatorLaterBadOperatorTest() { - junitExpectedException.expect(SvgProcessingException.class); PathSvgNodeRenderer path = new PathSvgNodeRenderer(); path.setAttribute(SvgConstants.Attributes.D, "m 200 100 l 50 50 x"); - path.parsePathOperations(); + + Assert.assertThrows(SvgProcessingException.class, () -> path.parsePathOperations()); } @Test diff --git a/svg/src/test/java/com/itextpdf/svg/renderers/impl/PathSvgNodeRendererLowLevelIntegrationTest.java b/svg/src/test/java/com/itextpdf/svg/renderers/impl/PathSvgNodeRendererLowLevelIntegrationTest.java index 3c7a1be289..9b79a63596 100644 --- a/svg/src/test/java/com/itextpdf/svg/renderers/impl/PathSvgNodeRendererLowLevelIntegrationTest.java +++ b/svg/src/test/java/com/itextpdf/svg/renderers/impl/PathSvgNodeRendererLowLevelIntegrationTest.java @@ -53,18 +53,15 @@ This file is part of the iText (R) project. import com.itextpdf.svg.renderers.path.impl.MoveTo; import com.itextpdf.svg.renderers.path.impl.SmoothSCurveTo; import com.itextpdf.test.annotations.type.IntegrationTest; + import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; import java.util.List; @Category(IntegrationTest.class) public class PathSvgNodeRendererLowLevelIntegrationTest extends SvgIntegrationTest { - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); @Test public void testRelativeArcOperatorShapes() { @@ -136,20 +133,20 @@ public void testNonsensePathNoOperators() { @Test public void testNonsensePathNotExistingOperator() { - junitExpectedException.expect(SvgProcessingException.class); PathSvgNodeRenderer path = new PathSvgNodeRenderer(); String instructions = "F"; path.setAttribute(SvgConstants.Attributes.D, instructions); - Assert.assertTrue(path.getShapes().isEmpty()); + + Assert.assertThrows(SvgProcessingException.class, () -> path.getShapes()); } @Test public void testClosePathNoPrecedingPathsOperator() { - junitExpectedException.expect(SvgProcessingException.class); PathSvgNodeRenderer path = new PathSvgNodeRenderer(); String instructions = "z"; path.setAttribute(SvgConstants.Attributes.D, instructions); - Assert.assertTrue(path.getShapes().isEmpty()); + + Assert.assertThrows(SvgProcessingException.class, () -> path.getShapes()); } @Test @@ -204,23 +201,21 @@ public void testAddDoubleArgsOperator() { @Test public void smoothCurveAsFirstShapeTest1() { - junitExpectedException.expect(SvgProcessingException.class); - junitExpectedException.expectMessage(SvgExceptionMessageConstant.INVALID_SMOOTH_CURVE_USE); - String instructions = "S 100 200 300 400"; PathSvgNodeRenderer path = new PathSvgNodeRenderer(); path.setAttribute(SvgConstants.Attributes.D, instructions); - path.getShapes(); + + Exception e = Assert.assertThrows(SvgProcessingException.class, () -> path.getShapes()); + Assert.assertEquals(SvgExceptionMessageConstant.INVALID_SMOOTH_CURVE_USE, e.getMessage()); } @Test public void smoothCurveAsFirstShapeTest2() { - junitExpectedException.expect(SvgProcessingException.class); - junitExpectedException.expectMessage(SvgExceptionMessageConstant.INVALID_SMOOTH_CURVE_USE); - String instructions = "T 100,200"; PathSvgNodeRenderer path = new PathSvgNodeRenderer(); path.setAttribute(SvgConstants.Attributes.D, instructions); - path.getShapes(); + + Exception e = Assert.assertThrows(SvgProcessingException.class, () -> path.getShapes()); + Assert.assertEquals(SvgExceptionMessageConstant.INVALID_SMOOTH_CURVE_USE, e.getMessage()); } } diff --git a/svg/src/test/java/com/itextpdf/svg/renderers/impl/PathSvgNodeRendererTest.java b/svg/src/test/java/com/itextpdf/svg/renderers/impl/PathSvgNodeRendererTest.java index 92452e69ba..8a3221f537 100644 --- a/svg/src/test/java/com/itextpdf/svg/renderers/impl/PathSvgNodeRendererTest.java +++ b/svg/src/test/java/com/itextpdf/svg/renderers/impl/PathSvgNodeRendererTest.java @@ -56,12 +56,11 @@ This file is part of the iText (R) project. import com.itextpdf.svg.renderers.SvgIntegrationTest; import com.itextpdf.test.ITextTest; import com.itextpdf.test.annotations.type.IntegrationTest; + import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; import java.io.FileInputStream; import java.io.IOException; @@ -75,9 +74,6 @@ public class PathSvgNodeRendererTest extends SvgIntegrationTest { public static final String sourceFolder = "./src/test/resources/com/itextpdf/svg/renderers/impl/PathSvgNodeRendererTest/"; public static final String destinationFolder = "./target/test/com/itextpdf/svg/renderers/impl/PathSvgNodeRendererTest/"; - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @BeforeClass public static void beforeClass() { ITextTest.createDestinationFolder(destinationFolder); @@ -317,14 +313,16 @@ public void pathZOperatorSingleZInstructionsAfterTest() throws IOException, Inte @Test public void invalidZOperatorTest() throws IOException, InterruptedException { - junitExpectedException.expect(SvgProcessingException.class); - convertAndCompare(sourceFolder, destinationFolder, "invalidZOperatorTest01"); + Assert.assertThrows(SvgProcessingException.class, + () -> convertAndCompare(sourceFolder, destinationFolder, "invalidZOperatorTest01") + ); } @Test public void invalidOperatorTest() throws IOException, InterruptedException { - junitExpectedException.expect(SvgProcessingException.class); - convertAndCompare(sourceFolder, destinationFolder, "invalidOperatorTest01"); + Assert.assertThrows(SvgProcessingException.class, + () -> convertAndCompare(sourceFolder, destinationFolder, "invalidOperatorTest01") + ); } @@ -406,8 +404,9 @@ public void iTextLogoTest() throws IOException, InterruptedException { @Test public void eofillUnsuportedPathTest() throws IOException, InterruptedException { - junitExpectedException.expect(SvgProcessingException.class); - convertAndCompare(sourceFolder, destinationFolder, "eofillUnsuportedPathTest"); + Assert.assertThrows(SvgProcessingException.class, + () -> convertAndCompare(sourceFolder, destinationFolder, "eofillUnsuportedPathTest") + ); } @Test diff --git a/svg/src/test/java/com/itextpdf/svg/renderers/impl/PdfRootSvgNodeRendererIntegrationTest.java b/svg/src/test/java/com/itextpdf/svg/renderers/impl/PdfRootSvgNodeRendererIntegrationTest.java index 0bf678eac5..3e9a9082c0 100644 --- a/svg/src/test/java/com/itextpdf/svg/renderers/impl/PdfRootSvgNodeRendererIntegrationTest.java +++ b/svg/src/test/java/com/itextpdf/svg/renderers/impl/PdfRootSvgNodeRendererIntegrationTest.java @@ -57,11 +57,10 @@ This file is part of the iText (R) project. import com.itextpdf.svg.renderers.SvgDrawContext; import com.itextpdf.svg.renderers.SvgIntegrationTest; import com.itextpdf.test.annotations.type.IntegrationTest; + import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; import java.io.ByteArrayOutputStream; import java.util.HashMap; @@ -70,9 +69,6 @@ This file is part of the iText (R) project. @Category(IntegrationTest.class) public class PdfRootSvgNodeRendererIntegrationTest extends SvgIntegrationTest { - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void calculateOutermostViewportTest() { Rectangle expected = new Rectangle(0, 0, 600, 600); @@ -148,9 +144,6 @@ public void calculateNestedViewportDifferentFromParentTest() { @Test public void noBoundingBoxOnXObjectTest() { - junitExpectedException.expect(SvgProcessingException.class); - junitExpectedException.expectMessage(SvgLogMessageConstant.ROOT_SVG_NO_BBOX); - PdfDocument document = new PdfDocument(new PdfWriter(new ByteArrayOutputStream(), new WriterProperties().setCompressionLevel(0))); document.addNewPage(); @@ -162,7 +155,10 @@ public void noBoundingBoxOnXObjectTest() { SvgDrawContext context = new SvgDrawContext(null, null); context.pushCanvas(canvas); - root.draw(context); + Exception e = Assert.assertThrows(SvgProcessingException.class, + () -> root.draw(context) + ); + Assert.assertEquals(SvgLogMessageConstant.ROOT_SVG_NO_BBOX, e.getMessage()); } @Test diff --git a/svg/src/test/java/com/itextpdf/svg/renderers/impl/PolygonSvgNodeRendererTest.java b/svg/src/test/java/com/itextpdf/svg/renderers/impl/PolygonSvgNodeRendererTest.java index 7d76fe9a87..619cc828c6 100644 --- a/svg/src/test/java/com/itextpdf/svg/renderers/impl/PolygonSvgNodeRendererTest.java +++ b/svg/src/test/java/com/itextpdf/svg/renderers/impl/PolygonSvgNodeRendererTest.java @@ -64,19 +64,14 @@ This file is part of the iText (R) project. import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(IntegrationTest.class) public class PolygonSvgNodeRendererTest extends SvgIntegrationTest { private static final String sourceFolder = "./src/test/resources/com/itextpdf/svg/renderers/impl/PolygonSvgNoderendererTest/"; private static final String destinationFolder = "./target/test/com/itextpdf/svg/renderers/impl/PolygonSvgNoderendererTest/"; - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @BeforeClass public static void beforeClass() { ITextTest.createDestinationFolder(destinationFolder); diff --git a/svg/src/test/java/com/itextpdf/svg/renderers/impl/PolylineSvgNodeRendererTest.java b/svg/src/test/java/com/itextpdf/svg/renderers/impl/PolylineSvgNodeRendererTest.java index 3d91801b25..0979cfe07e 100644 --- a/svg/src/test/java/com/itextpdf/svg/renderers/impl/PolylineSvgNodeRendererTest.java +++ b/svg/src/test/java/com/itextpdf/svg/renderers/impl/PolylineSvgNodeRendererTest.java @@ -65,19 +65,14 @@ This file is part of the iText (R) project. import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(IntegrationTest.class) public class PolylineSvgNodeRendererTest extends SvgIntegrationTest { private static final String sourceFolder = "./src/test/resources/com/itextpdf/svg/renderers/impl/PolylineSvgNodeRendererTest/"; private static final String destinationFolder = "./target/test/com/itextpdf/svg/renderers/impl/PolylineSvgNodeRendererTest/"; - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @BeforeClass public static void beforeClass() { ITextTest.createDestinationFolder(destinationFolder); @@ -104,8 +99,6 @@ public void polylineRendererTest() throws IOException, InterruptedException { @Test public void polyLineInvalidAttributeTest01() { - junitExpectedException.expect(StyledXMLParserException.class); - PdfDocument doc = new PdfDocument(new PdfWriter(new ByteArrayOutputStream())); doc.addNewPage(); ISvgNodeRenderer root = new PolylineSvgNodeRenderer(); @@ -115,13 +108,12 @@ public void polyLineInvalidAttributeTest01() { SvgDrawContext context = new SvgDrawContext(null, null); PdfCanvas cv = new PdfCanvas(doc, 1); context.pushCanvas(cv); - root.draw(context); + + Assert.assertThrows(StyledXMLParserException.class, () -> root.draw(context)); } @Test public void polyLineInvalidAttributeTest02() { - junitExpectedException.expect(SvgProcessingException.class); - PdfDocument doc = new PdfDocument(new PdfWriter(new ByteArrayOutputStream())); doc.addNewPage(); ISvgNodeRenderer root = new PolylineSvgNodeRenderer(); @@ -131,7 +123,8 @@ public void polyLineInvalidAttributeTest02() { SvgDrawContext context = new SvgDrawContext(null, null); PdfCanvas cv = new PdfCanvas(doc, 1); context.pushCanvas(cv); - root.draw(context); + + Assert.assertThrows(SvgProcessingException.class, () -> root.draw(context)); } @Test diff --git a/svg/src/test/java/com/itextpdf/svg/renderers/impl/PreserveAspectRatioSvgNodeRendererIntegrationTest.java b/svg/src/test/java/com/itextpdf/svg/renderers/impl/PreserveAspectRatioSvgNodeRendererIntegrationTest.java index 35c6f4e6a1..2fbdaf98f3 100644 --- a/svg/src/test/java/com/itextpdf/svg/renderers/impl/PreserveAspectRatioSvgNodeRendererIntegrationTest.java +++ b/svg/src/test/java/com/itextpdf/svg/renderers/impl/PreserveAspectRatioSvgNodeRendererIntegrationTest.java @@ -51,17 +51,12 @@ This file is part of the iText (R) project. import java.io.IOException; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(IntegrationTest.class) public class PreserveAspectRatioSvgNodeRendererIntegrationTest extends SvgIntegrationTest { - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - private static final String SOURCE_FOLDER = "./src/test/resources/com/itextpdf/svg/renderers/impl/PreserveAspectRatioSvgNodeRendererIntegrationTest/"; private static final String DESTINATION_FOLDER = "./target/test/com/itextpdf/svg/renderers/impl/PreserveAspectRatioSvgNodeRendererIntegrationTest/"; diff --git a/svg/src/test/java/com/itextpdf/svg/renderers/impl/SimpleSvgTagSvgNodeRendererIntegrationTest.java b/svg/src/test/java/com/itextpdf/svg/renderers/impl/SimpleSvgTagSvgNodeRendererIntegrationTest.java index 4b80f0cab2..0c99cefd52 100644 --- a/svg/src/test/java/com/itextpdf/svg/renderers/impl/SimpleSvgTagSvgNodeRendererIntegrationTest.java +++ b/svg/src/test/java/com/itextpdf/svg/renderers/impl/SimpleSvgTagSvgNodeRendererIntegrationTest.java @@ -54,17 +54,14 @@ This file is part of the iText (R) project. import java.io.IOException; +import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(IntegrationTest.class) public class SimpleSvgTagSvgNodeRendererIntegrationTest extends SvgIntegrationTest { - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); private static final String SOURCE_FOLDER = "./src/test/resources/com/itextpdf/svg/renderers/impl/RootSvgNodeRendererTest/svg/"; private static final String DESTINATION_FOLDER = "./target/test/com/itextpdf/svg/renderers/impl/RootSvgNodeRendererTest/svg/"; @@ -125,28 +122,32 @@ public void absentY() throws IOException, InterruptedException { @Test public void invalidHeight() throws IOException, InterruptedException { - junitExpectedException.expect(StyledXMLParserException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(StyledXMLParserException.NAN, "abc")); - convertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER,"invalidHeight"); + Exception e = Assert.assertThrows(StyledXMLParserException.class, + () -> convertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER,"invalidHeight") + ); + Assert.assertEquals(MessageFormatUtil.format(StyledXMLParserException.NAN, "abc"), e.getMessage()); } @Test public void invalidWidth() throws IOException, InterruptedException { - junitExpectedException.expect(StyledXMLParserException.class); - junitExpectedException.expectMessage(MessageFormatUtil.format(StyledXMLParserException.NAN, "abc")); - convertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER,"invalidWidth"); + Exception e = Assert.assertThrows(StyledXMLParserException.class, + () -> convertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER,"invalidWidth") + ); + Assert.assertEquals(MessageFormatUtil.format(StyledXMLParserException.NAN, "abc"), e.getMessage()); } @Test public void invalidX() throws IOException, InterruptedException { - junitExpectedException.expect(StyledXMLParserException.class); - convertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER,"invalidX"); + Assert.assertThrows(StyledXMLParserException.class, + () -> convertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER,"invalidX") + ); } @Test public void invalidY() throws IOException, InterruptedException { - junitExpectedException.expect(StyledXMLParserException.class); - convertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER,"invalidY"); + Assert.assertThrows(StyledXMLParserException.class, + () -> convertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER,"invalidY") + ); } @Test diff --git a/svg/src/test/java/com/itextpdf/svg/renderers/impl/StopSvgNodeRendererUnitTest.java b/svg/src/test/java/com/itextpdf/svg/renderers/impl/StopSvgNodeRendererUnitTest.java index 6ac4b9cfae..aedfbbc0b2 100644 --- a/svg/src/test/java/com/itextpdf/svg/renderers/impl/StopSvgNodeRendererUnitTest.java +++ b/svg/src/test/java/com/itextpdf/svg/renderers/impl/StopSvgNodeRendererUnitTest.java @@ -52,18 +52,13 @@ This file is part of the iText (R) project. import java.util.HashMap; import java.util.Map; import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(UnitTest.class) public class StopSvgNodeRendererUnitTest extends ExtendedITextTest { private static final float DELTA = 0; - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void getOffsetPercentageValueTest() { Map styles = new HashMap<>(); @@ -296,8 +291,9 @@ public void createDeepCopyTest() { public void doDrawTest() { StopSvgNodeRenderer renderer = new StopSvgNodeRenderer(); - junitExpectedException.expect(UnsupportedOperationException.class); - junitExpectedException.expectMessage("Can't draw current SvgNodeRenderer."); - renderer.doDraw(new SvgDrawContext(null, null)); + Exception e = Assert.assertThrows(UnsupportedOperationException.class, + () -> renderer.doDraw(new SvgDrawContext(null, null)) + ); + Assert.assertEquals("Can't draw current SvgNodeRenderer.", e.getMessage()); } } diff --git a/svg/src/test/java/com/itextpdf/svg/renderers/impl/SvgTagSvgNodeRendererUnitTest.java b/svg/src/test/java/com/itextpdf/svg/renderers/impl/SvgTagSvgNodeRendererUnitTest.java index e234d19330..b28cabb153 100644 --- a/svg/src/test/java/com/itextpdf/svg/renderers/impl/SvgTagSvgNodeRendererUnitTest.java +++ b/svg/src/test/java/com/itextpdf/svg/renderers/impl/SvgTagSvgNodeRendererUnitTest.java @@ -55,17 +55,12 @@ This file is part of the iText (R) project. import java.io.ByteArrayOutputStream; import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(UnitTest.class) public class SvgTagSvgNodeRendererUnitTest extends ExtendedITextTest { - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void calculateNestedViewportSameAsParentTest() { Rectangle expected = new Rectangle(0, 0, 600, 600); diff --git a/svg/src/test/java/com/itextpdf/svg/renderers/impl/TSpanNodeRendererIntegrationTest.java b/svg/src/test/java/com/itextpdf/svg/renderers/impl/TSpanNodeRendererIntegrationTest.java index 2a7cde9760..7cb1216bad 100644 --- a/svg/src/test/java/com/itextpdf/svg/renderers/impl/TSpanNodeRendererIntegrationTest.java +++ b/svg/src/test/java/com/itextpdf/svg/renderers/impl/TSpanNodeRendererIntegrationTest.java @@ -49,20 +49,17 @@ This file is part of the iText (R) project. import com.itextpdf.test.annotations.LogMessage; import com.itextpdf.test.annotations.LogMessages; import com.itextpdf.test.annotations.type.IntegrationTest; + +import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; import java.io.IOException; @Category(IntegrationTest.class) public class TSpanNodeRendererIntegrationTest extends SvgIntegrationTest { - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - private static final String SOURCE_FOLDER = "./src/test/resources/com/itextpdf/svg/renderers/impl/TSpanNodeRendererIntegrationTest/"; private static final String DESTINATION_FOLDER = "./target/test/com/itextpdf/svg/renderers/impl/TSpanNodeRendererIntegrationTest/"; @@ -89,8 +86,9 @@ public void TSpanRelativeMoveZeroXTest() throws IOException, InterruptedExceptio @Test public void TSpanRelativeMoveInvalidXTest() throws IOException, InterruptedException { - junitExpectedException.expect(StyledXMLParserException.class); - convertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER, "textspan-relativeMove-invalidX"); + Assert.assertThrows(StyledXMLParserException.class, + () -> convertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER, "textspan-relativeMove-invalidX") + ); } @Test @@ -110,8 +108,9 @@ public void TSpanRelativeMoveZeroYTest() throws IOException, InterruptedExceptio @Test public void TSpanRelativeMoveInvalidYTest() throws IOException, InterruptedException { - junitExpectedException.expect(StyledXMLParserException.class); - convertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER, "textspan-relativeMove-invalidY"); + Assert.assertThrows(StyledXMLParserException.class, + () -> convertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER, "textspan-relativeMove-invalidY") + ); } @Test @@ -137,8 +136,9 @@ public void TSpanAbsolutePositionZeroXTest() throws IOException, InterruptedExce @Test public void TSpanAbsolutePositionInvalidXTest() throws IOException, InterruptedException { - junitExpectedException.expect(StyledXMLParserException.class); - convertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER, "textspan-absolutePosition-invalidX"); + Assert.assertThrows(StyledXMLParserException.class, + () -> convertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER, "textspan-absolutePosition-invalidX") + ); } @Test @@ -158,8 +158,9 @@ public void TSpanAbsolutePositionZeroYTest() throws IOException, InterruptedExce @Test public void TSpanAbsolutePositionInvalidYTest() throws IOException, InterruptedException { - junitExpectedException.expect(StyledXMLParserException.class); - convertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER, "textspan-absolutePosition-invalidY"); + Assert.assertThrows(StyledXMLParserException.class, + () -> convertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER, "textspan-absolutePosition-invalidY") + ); } @Test diff --git a/svg/src/test/java/com/itextpdf/svg/renderers/impl/TextLeafSvgNodeRendererIntegrationTest.java b/svg/src/test/java/com/itextpdf/svg/renderers/impl/TextLeafSvgNodeRendererIntegrationTest.java index e6eee7544e..ecf7df828d 100644 --- a/svg/src/test/java/com/itextpdf/svg/renderers/impl/TextLeafSvgNodeRendererIntegrationTest.java +++ b/svg/src/test/java/com/itextpdf/svg/renderers/impl/TextLeafSvgNodeRendererIntegrationTest.java @@ -44,22 +44,17 @@ This file is part of the iText (R) project. import com.itextpdf.kernel.font.PdfFont; import com.itextpdf.kernel.font.PdfFontFactory; -import com.itextpdf.styledxmlparser.exceptions.StyledXMLParserException; import com.itextpdf.svg.SvgConstants; import com.itextpdf.svg.renderers.SvgIntegrationTest; import com.itextpdf.test.annotations.type.IntegrationTest; + import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(IntegrationTest.class) public class TextLeafSvgNodeRendererIntegrationTest extends SvgIntegrationTest { - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void getContentLengthBaseTest() throws Exception { TextLeafSvgNodeRenderer toTest = new TextLeafSvgNodeRenderer(); diff --git a/svg/src/test/java/com/itextpdf/svg/renderers/impl/TextSvgBranchRendererIntegrationTest.java b/svg/src/test/java/com/itextpdf/svg/renderers/impl/TextSvgBranchRendererIntegrationTest.java index 19d5adabc4..6e00121ce9 100644 --- a/svg/src/test/java/com/itextpdf/svg/renderers/impl/TextSvgBranchRendererIntegrationTest.java +++ b/svg/src/test/java/com/itextpdf/svg/renderers/impl/TextSvgBranchRendererIntegrationTest.java @@ -49,18 +49,14 @@ This file is part of the iText (R) project. import java.io.IOException; +import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(IntegrationTest.class) public class TextSvgBranchRendererIntegrationTest extends SvgIntegrationTest { - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - private static final String SOURCE_FOLDER = "./src/test/resources/com/itextpdf/svg/renderers/impl/TextSvgBranchRendererIntegrationTest/"; private static final String DESTINATION_FOLDER = "./target/test/com/itextpdf/svg/renderers/impl/TextSvgBranchRendererIntegrationTest/"; @@ -158,8 +154,9 @@ public void textAbsolutePositionzeroXTest() throws IOException, InterruptedExcep @Test public void textAbsolutePositionInvalidXTest() throws IOException, InterruptedException { - junitExpectedException.expect(StyledXMLParserException.class); - convertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER, "text-absolutePosition-invalidX"); + Assert.assertThrows(StyledXMLParserException.class, + () -> convertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER, "text-absolutePosition-invalidX") + ); } //Y @@ -180,8 +177,9 @@ public void textAbsolutePositionZeroYTest() throws IOException, InterruptedExcep @Test public void textAbsolutePositionInvalidYTest() throws IOException, InterruptedException { - junitExpectedException.expect(StyledXMLParserException.class); - convertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER, "text-absolutePosition-invalidY"); + Assert.assertThrows(StyledXMLParserException.class, + () -> convertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER, "text-absolutePosition-invalidY") + ); } //Relative move @@ -203,8 +201,9 @@ public void textRelativeMoveZeroXTest() throws IOException, InterruptedException @Test public void textRelativeMoveInvalidXTest() throws IOException, InterruptedException { - junitExpectedException.expect(StyledXMLParserException.class); - convertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER, "text-relativeMove-invalidX"); + Assert.assertThrows(StyledXMLParserException.class, + () -> convertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER, "text-relativeMove-invalidX") + ); } //Y @@ -225,8 +224,9 @@ public void textRelativeMoveZeroYTest() throws IOException, InterruptedException @Test public void textRelativeMoveInvalidYTest() throws IOException, InterruptedException { - junitExpectedException.expect(StyledXMLParserException.class); - convertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER, "text-relativeMove-invalidY"); + Assert.assertThrows(StyledXMLParserException.class, + () -> convertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER, "text-relativeMove-invalidY") + ); } @Test diff --git a/svg/src/test/java/com/itextpdf/svg/renderers/impl/ViewBoxSvgTagSvgNodeRendererIntegrationTest.java b/svg/src/test/java/com/itextpdf/svg/renderers/impl/ViewBoxSvgTagSvgNodeRendererIntegrationTest.java index b8aa195756..a8b7b06a56 100644 --- a/svg/src/test/java/com/itextpdf/svg/renderers/impl/ViewBoxSvgTagSvgNodeRendererIntegrationTest.java +++ b/svg/src/test/java/com/itextpdf/svg/renderers/impl/ViewBoxSvgTagSvgNodeRendererIntegrationTest.java @@ -49,17 +49,12 @@ This file is part of the iText (R) project. import java.io.IOException; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(IntegrationTest.class) public class ViewBoxSvgTagSvgNodeRendererIntegrationTest extends SvgIntegrationTest { - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - private static final String SOURCE_FOLDER = "./src/test/resources/com/itextpdf/svg/renderers/impl/RootSvgNodeRendererTest/viewbox/"; private static final String DESTINATION_FOLDER = "./target/test/com/itextpdf/svg/renderers/impl/RootSvgNodeRendererTest/viewbox/"; diff --git a/svg/src/test/java/com/itextpdf/svg/renderers/impl/XLinkDataTest.java b/svg/src/test/java/com/itextpdf/svg/renderers/impl/XLinkDataTest.java index 7806ef24f9..8a612bd4a3 100644 --- a/svg/src/test/java/com/itextpdf/svg/renderers/impl/XLinkDataTest.java +++ b/svg/src/test/java/com/itextpdf/svg/renderers/impl/XLinkDataTest.java @@ -28,18 +28,15 @@ This file is part of the iText (R) project. import com.itextpdf.test.annotations.LogMessage; import com.itextpdf.test.annotations.LogMessages; import com.itextpdf.test.annotations.type.IntegrationTest; + import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; import java.io.IOException; @Category(IntegrationTest.class) public class XLinkDataTest extends SvgIntegrationTest { - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); private static final String SOURCE_FOLDER = "./src/test/resources/com/itextpdf/svg/renderers/impl/XLinkDataTest/"; private static final String DESTINATION_FOLDER = "./target/test/com/itextpdf/svg/renderers/impl/XLinkDataTest/"; diff --git a/svg/src/test/java/com/itextpdf/svg/renderers/path/impl/EllipticalPathOperatorTest.java b/svg/src/test/java/com/itextpdf/svg/renderers/path/impl/EllipticalPathOperatorTest.java index b997181064..1ecf0a9e57 100644 --- a/svg/src/test/java/com/itextpdf/svg/renderers/path/impl/EllipticalPathOperatorTest.java +++ b/svg/src/test/java/com/itextpdf/svg/renderers/path/impl/EllipticalPathOperatorTest.java @@ -45,17 +45,14 @@ This file is part of the iText (R) project. import com.itextpdf.kernel.geom.Point; import com.itextpdf.test.ExtendedITextTest; import com.itextpdf.test.annotations.type.UnitTest; + import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(UnitTest.class) public class EllipticalPathOperatorTest extends ExtendedITextTest { // tests for coordinates - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); @Test public void testBasicParameterSet() { EllipticalCurveTo absoluteElliptic = new EllipticalCurveTo(); @@ -103,22 +100,22 @@ public void testRandomParameterAmountSet() { @Test public void testNotEnoughParameterSet() { - junitExpectedException.expect(IllegalArgumentException.class); EllipticalCurveTo absoluteElliptic = new EllipticalCurveTo(); // String array length = 6 - absoluteElliptic.setCoordinates(new String[]{"40", "0", "0", "0", "20", "20"}, new Point()); - String[] result = absoluteElliptic.getCoordinates(); - Assert.assertEquals(0, result.length); + + Assert.assertThrows(IllegalArgumentException.class, + () -> absoluteElliptic.setCoordinates(new String[]{"40", "0", "0", "0", "20", "20"}, new Point()) + ); } @Test public void testNoParameterSet() { - junitExpectedException.expect(IllegalArgumentException.class); EllipticalCurveTo absoluteElliptic = new EllipticalCurveTo(); + // String array length = 0 - absoluteElliptic.setCoordinates(new String[]{}, new Point()); - String[] result = absoluteElliptic.getCoordinates(); - Assert.assertEquals(0, result.length); + Assert.assertThrows(IllegalArgumentException.class, + () -> absoluteElliptic.setCoordinates(new String[]{}, new Point()) + ); } // rotate tests diff --git a/svg/src/test/java/com/itextpdf/svg/utils/MatrixTransformationTest.java b/svg/src/test/java/com/itextpdf/svg/utils/MatrixTransformationTest.java index bbea57a7ce..bf564d0618 100644 --- a/svg/src/test/java/com/itextpdf/svg/utils/MatrixTransformationTest.java +++ b/svg/src/test/java/com/itextpdf/svg/utils/MatrixTransformationTest.java @@ -49,17 +49,12 @@ This file is part of the iText (R) project. import com.itextpdf.test.annotations.type.UnitTest; import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(UnitTest.class) public class MatrixTransformationTest extends ExtendedITextTest { - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void normalMatrixTest() { AffineTransform expected = new AffineTransform(10d, 20d, 30d, 40d, 37.5d, 45d); @@ -70,25 +65,25 @@ public void normalMatrixTest() { @Test public void noMatrixValuesTest() { - junitExpectedException.expect(SvgProcessingException.class); - junitExpectedException.expectMessage(SvgLogMessageConstant.TRANSFORM_INCORRECT_NUMBER_OF_VALUES); - - TransformUtils.parseTransform("matrix()"); + Exception e = Assert.assertThrows(SvgProcessingException.class, + () -> TransformUtils.parseTransform("matrix()") + ); + Assert.assertEquals(SvgLogMessageConstant.TRANSFORM_INCORRECT_NUMBER_OF_VALUES, e.getMessage()); } @Test public void notEnoughMatrixValuesTest() { - junitExpectedException.expect(SvgProcessingException.class); - junitExpectedException.expectMessage(SvgLogMessageConstant.TRANSFORM_INCORRECT_NUMBER_OF_VALUES); - - TransformUtils.parseTransform("matrix(0)"); + Exception e = Assert.assertThrows(SvgProcessingException.class, + () -> TransformUtils.parseTransform("matrix(0)") + ); + Assert.assertEquals(SvgLogMessageConstant.TRANSFORM_INCORRECT_NUMBER_OF_VALUES, e.getMessage()); } @Test public void tooManyMatrixValuesTest() { - junitExpectedException.expect(SvgProcessingException.class); - junitExpectedException.expectMessage(SvgLogMessageConstant.TRANSFORM_INCORRECT_NUMBER_OF_VALUES); - - TransformUtils.parseTransform("matrix(1 2 3 4 5 6 7 8)"); + Exception e = Assert.assertThrows(SvgProcessingException.class, + () -> TransformUtils.parseTransform("matrix(1 2 3 4 5 6 7 8)") + ); + Assert.assertEquals(SvgLogMessageConstant.TRANSFORM_INCORRECT_NUMBER_OF_VALUES, e.getMessage()); } } diff --git a/svg/src/test/java/com/itextpdf/svg/utils/RotateTransformationTest.java b/svg/src/test/java/com/itextpdf/svg/utils/RotateTransformationTest.java index d8a0077d44..233a2d5da5 100644 --- a/svg/src/test/java/com/itextpdf/svg/utils/RotateTransformationTest.java +++ b/svg/src/test/java/com/itextpdf/svg/utils/RotateTransformationTest.java @@ -50,15 +50,11 @@ This file is part of the iText (R) project. import com.itextpdf.test.annotations.type.UnitTest; import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(UnitTest.class) public class RotateTransformationTest extends ExtendedITextTest { - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); @Test public void normalRotateTest() { @@ -71,10 +67,10 @@ public void normalRotateTest() { @Test public void noRotateValuesTest() { - junitExpectedException.expect(SvgProcessingException.class); - junitExpectedException.expectMessage(SvgLogMessageConstant.TRANSFORM_INCORRECT_NUMBER_OF_VALUES); - - TransformUtils.parseTransform("rotate()"); + Exception e = Assert.assertThrows(SvgProcessingException.class, + () -> TransformUtils.parseTransform("rotate()") + ); + Assert.assertEquals(SvgLogMessageConstant.TRANSFORM_INCORRECT_NUMBER_OF_VALUES, e.getMessage()); } @Test @@ -87,10 +83,10 @@ public void oneRotateValuesTest() { @Test public void twoRotateValuesTest() { - junitExpectedException.expect(SvgProcessingException.class); - junitExpectedException.expectMessage(SvgLogMessageConstant.TRANSFORM_INCORRECT_NUMBER_OF_VALUES); - - TransformUtils.parseTransform("rotate(23,58)"); + Exception e = Assert.assertThrows(SvgProcessingException.class, + () -> TransformUtils.parseTransform("rotate(23,58)") + ); + Assert.assertEquals(SvgLogMessageConstant.TRANSFORM_INCORRECT_NUMBER_OF_VALUES, e.getMessage()); } @Test @@ -104,10 +100,10 @@ public void threeRotateValuesTest() { @Test public void tooManyRotateValuesTest() { - junitExpectedException.expect(SvgProcessingException.class); - junitExpectedException.expectMessage(SvgLogMessageConstant.TRANSFORM_INCORRECT_NUMBER_OF_VALUES); - - TransformUtils.parseTransform("rotate(1 2 3 4)"); + Exception e = Assert.assertThrows(SvgProcessingException.class, + () -> TransformUtils.parseTransform("rotate(1 2 3 4)") + ); + Assert.assertEquals(SvgLogMessageConstant.TRANSFORM_INCORRECT_NUMBER_OF_VALUES, e.getMessage()); } @Test diff --git a/svg/src/test/java/com/itextpdf/svg/utils/ScaleTransformationTest.java b/svg/src/test/java/com/itextpdf/svg/utils/ScaleTransformationTest.java index e46881f636..f69efb4b4b 100644 --- a/svg/src/test/java/com/itextpdf/svg/utils/ScaleTransformationTest.java +++ b/svg/src/test/java/com/itextpdf/svg/utils/ScaleTransformationTest.java @@ -49,17 +49,12 @@ This file is part of the iText (R) project. import com.itextpdf.test.annotations.type.UnitTest; import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(UnitTest.class) public class ScaleTransformationTest extends ExtendedITextTest { - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void normalScaleTest() { AffineTransform expected = AffineTransform.getScaleInstance(10d, 20d); @@ -70,10 +65,10 @@ public void normalScaleTest() { @Test public void noScaleValuesTest() { - junitExpectedException.expect(SvgProcessingException.class); - junitExpectedException.expectMessage(SvgLogMessageConstant.TRANSFORM_INCORRECT_NUMBER_OF_VALUES); - - TransformUtils.parseTransform("scale()"); + Exception e = Assert.assertThrows(SvgProcessingException.class, + () -> TransformUtils.parseTransform("scale()") + ); + Assert.assertEquals(SvgLogMessageConstant.TRANSFORM_INCORRECT_NUMBER_OF_VALUES, e.getMessage()); } @Test @@ -102,10 +97,10 @@ public void negativeScaleValuesTest() { @Test public void tooManyScaleValuesTest() { - junitExpectedException.expect(SvgProcessingException.class); - junitExpectedException.expectMessage(SvgLogMessageConstant.TRANSFORM_INCORRECT_NUMBER_OF_VALUES); - - TransformUtils.parseTransform("scale(1 2 3)"); + Exception e = Assert.assertThrows(SvgProcessingException.class, + () -> TransformUtils.parseTransform("scale(1 2 3)") + ); + Assert.assertEquals(SvgLogMessageConstant.TRANSFORM_INCORRECT_NUMBER_OF_VALUES, e.getMessage()); } } diff --git a/svg/src/test/java/com/itextpdf/svg/utils/SkewXTransformationTest.java b/svg/src/test/java/com/itextpdf/svg/utils/SkewXTransformationTest.java index 5202067e68..d18592efac 100644 --- a/svg/src/test/java/com/itextpdf/svg/utils/SkewXTransformationTest.java +++ b/svg/src/test/java/com/itextpdf/svg/utils/SkewXTransformationTest.java @@ -50,17 +50,12 @@ This file is part of the iText (R) project. import com.itextpdf.test.annotations.type.UnitTest; import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(UnitTest.class) public class SkewXTransformationTest extends ExtendedITextTest { - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void normalSkewXTest() { AffineTransform expected = new AffineTransform(1d, 0d, Math.tan(Math.toRadians((float) CssDimensionParsingUtils.parseFloat("143"))), 1d, 0d, 0d); @@ -71,18 +66,18 @@ public void normalSkewXTest() { @Test public void noSkewXValuesTest() { - junitExpectedException.expect(SvgProcessingException.class); - junitExpectedException.expectMessage(SvgLogMessageConstant.TRANSFORM_INCORRECT_NUMBER_OF_VALUES); - - TransformUtils.parseTransform("skewX()"); + Exception e = Assert.assertThrows(SvgProcessingException.class, + () -> TransformUtils.parseTransform("skewX()") + ); + Assert.assertEquals(SvgLogMessageConstant.TRANSFORM_INCORRECT_NUMBER_OF_VALUES, e.getMessage()); } @Test public void twoSkewXValuesTest() { - junitExpectedException.expect(SvgProcessingException.class); - junitExpectedException.expectMessage(SvgLogMessageConstant.TRANSFORM_INCORRECT_NUMBER_OF_VALUES); - - TransformUtils.parseTransform("skewX(1 2)"); + Exception e = Assert.assertThrows(SvgProcessingException.class, + () -> TransformUtils.parseTransform("skewX(1 2)") + ); + Assert.assertEquals(SvgLogMessageConstant.TRANSFORM_INCORRECT_NUMBER_OF_VALUES, e.getMessage()); } @Test diff --git a/svg/src/test/java/com/itextpdf/svg/utils/SkewYTransformationTest.java b/svg/src/test/java/com/itextpdf/svg/utils/SkewYTransformationTest.java index 53bbb150b4..de40499a16 100644 --- a/svg/src/test/java/com/itextpdf/svg/utils/SkewYTransformationTest.java +++ b/svg/src/test/java/com/itextpdf/svg/utils/SkewYTransformationTest.java @@ -49,17 +49,12 @@ This file is part of the iText (R) project. import com.itextpdf.test.annotations.type.UnitTest; import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(UnitTest.class) public class SkewYTransformationTest extends ExtendedITextTest { - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void normalSkewYTest() { AffineTransform expected = new AffineTransform(1d, Math.tan(Math.toRadians(143)), 0d, 1d, 0d, 0d); @@ -70,18 +65,18 @@ public void normalSkewYTest() { @Test public void noSkewYValuesTest() { - junitExpectedException.expect(SvgProcessingException.class); - junitExpectedException.expectMessage(SvgLogMessageConstant.TRANSFORM_INCORRECT_NUMBER_OF_VALUES); - - TransformUtils.parseTransform("skewY()"); + Exception e = Assert.assertThrows(SvgProcessingException.class, + () -> TransformUtils.parseTransform("skewY()") + ); + Assert.assertEquals(SvgLogMessageConstant.TRANSFORM_INCORRECT_NUMBER_OF_VALUES, e.getMessage()); } @Test public void twoSkewYValuesTest() { - junitExpectedException.expect(SvgProcessingException.class); - junitExpectedException.expectMessage(SvgLogMessageConstant.TRANSFORM_INCORRECT_NUMBER_OF_VALUES); - - TransformUtils.parseTransform("skewY(1 2)"); + Exception e = Assert.assertThrows(SvgProcessingException.class, + () -> TransformUtils.parseTransform("skewY(1 2)") + ); + Assert.assertEquals(SvgLogMessageConstant.TRANSFORM_INCORRECT_NUMBER_OF_VALUES, e.getMessage()); } @Test diff --git a/svg/src/test/java/com/itextpdf/svg/utils/SvgCoordinateUtilsTest.java b/svg/src/test/java/com/itextpdf/svg/utils/SvgCoordinateUtilsTest.java index 2a890eb538..a5d8ef0f34 100644 --- a/svg/src/test/java/com/itextpdf/svg/utils/SvgCoordinateUtilsTest.java +++ b/svg/src/test/java/com/itextpdf/svg/utils/SvgCoordinateUtilsTest.java @@ -30,17 +30,12 @@ This file is part of the iText (R) project. import com.itextpdf.test.annotations.type.UnitTest; import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(UnitTest.class) public class SvgCoordinateUtilsTest extends ExtendedITextTest { - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - private final static double DELTA = 0.0000001; private final static Rectangle VIEW_BOX = new Rectangle(20F, 20F, 20F, 20F); @@ -183,51 +178,58 @@ public void getCoordinateForObjectBoundingBoxDefaultTest() { @Test public void applyViewBoxViewBoxIsNullTest() { - junitExpectedException.expect(IllegalArgumentException.class); - junitExpectedException.expectMessage(SvgExceptionMessageConstant.VIEWBOX_IS_INCORRECT); - SvgCoordinateUtils.applyViewBox(null, new Rectangle(10F, 10F), null, null); + Exception e = Assert.assertThrows(IllegalArgumentException.class, + () -> SvgCoordinateUtils.applyViewBox(null, new Rectangle(10F, 10F), null, null) + ); + Assert.assertEquals(SvgExceptionMessageConstant.VIEWBOX_IS_INCORRECT, e.getMessage()); } @Test public void applyViewBoxViewBoxWidthIsZeroTest() { - junitExpectedException.expect(IllegalArgumentException.class); - junitExpectedException.expectMessage(SvgExceptionMessageConstant.VIEWBOX_IS_INCORRECT); - SvgCoordinateUtils.applyViewBox(new Rectangle(0F, 10F), new Rectangle(10F, 10F), null, null); + Exception e = Assert.assertThrows(IllegalArgumentException.class, + () -> SvgCoordinateUtils.applyViewBox(new Rectangle(0F, 10F), new Rectangle(10F, 10F), null, null) + ); + Assert.assertEquals(SvgExceptionMessageConstant.VIEWBOX_IS_INCORRECT, e.getMessage()); } @Test public void applyViewBoxViewBoxHeightIsZeroTest() { - junitExpectedException.expect(IllegalArgumentException.class); - junitExpectedException.expectMessage(SvgExceptionMessageConstant.VIEWBOX_IS_INCORRECT); - SvgCoordinateUtils.applyViewBox(new Rectangle(10F, 0F), new Rectangle(10F, 10F), null, null); + Exception e = Assert.assertThrows(IllegalArgumentException.class, + () -> SvgCoordinateUtils.applyViewBox(new Rectangle(10F, 0F), new Rectangle(10F, 10F), null, null) + ); + Assert.assertEquals(SvgExceptionMessageConstant.VIEWBOX_IS_INCORRECT, e.getMessage()); } @Test public void applyViewBoxViewBoxWidthIsNegativeTest() { - junitExpectedException.expect(IllegalArgumentException.class); - junitExpectedException.expectMessage(SvgExceptionMessageConstant.VIEWBOX_IS_INCORRECT); - SvgCoordinateUtils.applyViewBox(new Rectangle(-10F, 10F), new Rectangle(10F, 10F), null, null); + Exception e = Assert.assertThrows(IllegalArgumentException.class, + () -> SvgCoordinateUtils.applyViewBox(new Rectangle(-10F, 10F), new Rectangle(10F, 10F), null, null) + ); + Assert.assertEquals(SvgExceptionMessageConstant.VIEWBOX_IS_INCORRECT, e.getMessage()); } @Test public void applyViewBoxViewBoxHeightIsNegativeTest() { - junitExpectedException.expect(IllegalArgumentException.class); - junitExpectedException.expectMessage(SvgExceptionMessageConstant.VIEWBOX_IS_INCORRECT); - SvgCoordinateUtils.applyViewBox(new Rectangle(10F, -10F), new Rectangle(10F, 10F), null, null); + Exception e = Assert.assertThrows(IllegalArgumentException.class, + () -> SvgCoordinateUtils.applyViewBox(new Rectangle(10F, -10F), new Rectangle(10F, 10F), null, null) + ); + Assert.assertEquals(SvgExceptionMessageConstant.VIEWBOX_IS_INCORRECT, e.getMessage()); } @Test public void applyViewBoxCurrentViewPortIsNullTest() { - junitExpectedException.expect(IllegalArgumentException.class); - junitExpectedException.expectMessage(SvgExceptionMessageConstant.CURRENT_VIEWPORT_IS_NULL); - SvgCoordinateUtils.applyViewBox(new Rectangle(10F, 10F), null, null, null); + Exception e = Assert.assertThrows(IllegalArgumentException.class, + () -> SvgCoordinateUtils.applyViewBox(new Rectangle(10F, 10F), null, null, null) + ); + Assert.assertEquals(SvgExceptionMessageConstant.CURRENT_VIEWPORT_IS_NULL, e.getMessage()); } @Test public void applyViewBoxAllNullTest() { - junitExpectedException.expect(IllegalArgumentException.class); - junitExpectedException.expectMessage(SvgExceptionMessageConstant.CURRENT_VIEWPORT_IS_NULL); - SvgCoordinateUtils.applyViewBox(null, null, null, null); + Exception e = Assert.assertThrows(IllegalArgumentException.class, + () -> SvgCoordinateUtils.applyViewBox(null, null, null, null) + ); + Assert.assertEquals(SvgExceptionMessageConstant.CURRENT_VIEWPORT_IS_NULL, e.getMessage()); } @Test diff --git a/svg/src/test/java/com/itextpdf/svg/utils/SvgCssUtilsTest.java b/svg/src/test/java/com/itextpdf/svg/utils/SvgCssUtilsTest.java index e6e6342bac..667ad2f3c9 100644 --- a/svg/src/test/java/com/itextpdf/svg/utils/SvgCssUtilsTest.java +++ b/svg/src/test/java/com/itextpdf/svg/utils/SvgCssUtilsTest.java @@ -54,17 +54,12 @@ This file is part of the iText (R) project. import java.util.List; import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(UnitTest.class) public class SvgCssUtilsTest extends ExtendedITextTest { - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void commaSplitValueTest() { String input = "a,b,c,d"; diff --git a/svg/src/test/java/com/itextpdf/svg/utils/TransformUtilsTest.java b/svg/src/test/java/com/itextpdf/svg/utils/TransformUtilsTest.java index f294841fd2..23fd071822 100644 --- a/svg/src/test/java/com/itextpdf/svg/utils/TransformUtilsTest.java +++ b/svg/src/test/java/com/itextpdf/svg/utils/TransformUtilsTest.java @@ -42,64 +42,54 @@ This file is part of the iText (R) project. */ package com.itextpdf.svg.utils; -import com.itextpdf.io.util.MessageFormatUtil; import com.itextpdf.kernel.geom.AffineTransform; -import com.itextpdf.styledxmlparser.LogMessageConstant; -import com.itextpdf.styledxmlparser.exceptions.StyledXMLParserException; import com.itextpdf.svg.exceptions.SvgLogMessageConstant; import com.itextpdf.svg.exceptions.SvgProcessingException; import com.itextpdf.test.ExtendedITextTest; import com.itextpdf.test.annotations.type.UnitTest; import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(UnitTest.class) public class TransformUtilsTest extends ExtendedITextTest { - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void nullStringTest() { - junitExpectedException.expect(SvgProcessingException.class); - junitExpectedException.expectMessage(SvgLogMessageConstant.TRANSFORM_NULL); - - TransformUtils.parseTransform(null); + Exception e = Assert.assertThrows(SvgProcessingException.class, + () -> TransformUtils.parseTransform(null) + ); + Assert.assertEquals(SvgLogMessageConstant.TRANSFORM_NULL, e.getMessage()); } @Test public void emptyTest() { - junitExpectedException.expect(SvgProcessingException.class); - junitExpectedException.expectMessage(SvgLogMessageConstant.TRANSFORM_EMPTY); - - TransformUtils.parseTransform(""); + Exception e = Assert.assertThrows(SvgProcessingException.class, + () -> TransformUtils.parseTransform("") + ); + Assert.assertEquals(SvgLogMessageConstant.TRANSFORM_EMPTY, e.getMessage()); } @Test public void noTransformationTest() { - junitExpectedException.expect(SvgProcessingException.class); - junitExpectedException.expectMessage(SvgLogMessageConstant.INVALID_TRANSFORM_DECLARATION); - - TransformUtils.parseTransform("Lorem ipsum"); + Exception e = Assert.assertThrows(SvgProcessingException.class, + () -> TransformUtils.parseTransform("Lorem ipsum") + ); + Assert.assertEquals(SvgLogMessageConstant.INVALID_TRANSFORM_DECLARATION, e.getMessage()); } @Test public void wrongTypeOfValuesTest() { - junitExpectedException.expect(NumberFormatException.class); - - TransformUtils.parseTransform("matrix(a b c d e f)"); + Assert.assertThrows(NumberFormatException.class, () -> TransformUtils.parseTransform("matrix(a b c d e f)")); } @Test public void tooManyParenthesesTest() { - junitExpectedException.expect(SvgProcessingException.class); - junitExpectedException.expectMessage(SvgLogMessageConstant.INVALID_TRANSFORM_DECLARATION); - - TransformUtils.parseTransform("(((())))"); + Exception e = Assert.assertThrows(SvgProcessingException.class, + () -> TransformUtils.parseTransform("(((())))") + ); + Assert.assertEquals(SvgLogMessageConstant.INVALID_TRANSFORM_DECLARATION, e.getMessage()); } @Test @@ -184,10 +174,10 @@ public void oppositeTransformationSequenceTest() { @Test public void unknownTransformationTest() { - junitExpectedException.expect(SvgProcessingException.class); - junitExpectedException.expectMessage(SvgLogMessageConstant.UNKNOWN_TRANSFORMATION_TYPE); - - TransformUtils.parseTransform("unknown(1 2 3)"); + Exception e = Assert.assertThrows(SvgProcessingException.class, + () -> TransformUtils.parseTransform("unknown(1 2 3)") + ); + Assert.assertEquals(SvgLogMessageConstant.UNKNOWN_TRANSFORMATION_TYPE, e.getMessage()); } @Test diff --git a/svg/src/test/java/com/itextpdf/svg/utils/TranslateTransformationTest.java b/svg/src/test/java/com/itextpdf/svg/utils/TranslateTransformationTest.java index e7e3719c34..7ddbe9928e 100644 --- a/svg/src/test/java/com/itextpdf/svg/utils/TranslateTransformationTest.java +++ b/svg/src/test/java/com/itextpdf/svg/utils/TranslateTransformationTest.java @@ -49,17 +49,12 @@ This file is part of the iText (R) project. import com.itextpdf.test.annotations.type.UnitTest; import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; @Category(UnitTest.class) public class TranslateTransformationTest extends ExtendedITextTest { - @Rule - public ExpectedException junitExpectedException = ExpectedException.none(); - @Test public void normalTranslateTest() { AffineTransform expected = new AffineTransform(1d, 0d, 0d, 1d, 15d, 37.5d); @@ -70,10 +65,10 @@ public void normalTranslateTest() { @Test public void noTranslateValuesTest() { - junitExpectedException.expect(SvgProcessingException.class); - junitExpectedException.expectMessage(SvgLogMessageConstant.TRANSFORM_INCORRECT_NUMBER_OF_VALUES); - - TransformUtils.parseTransform("translate()"); + Exception e = Assert.assertThrows(SvgProcessingException.class, + () -> TransformUtils.parseTransform("translate()") + ); + Assert.assertEquals(SvgLogMessageConstant.TRANSFORM_INCORRECT_NUMBER_OF_VALUES, e.getMessage()); } @Test @@ -102,10 +97,9 @@ public void negativeTranslateValuesTest() { @Test public void tooManyTranslateValuesTest() { - junitExpectedException.expect(SvgProcessingException.class); - junitExpectedException.expectMessage(SvgLogMessageConstant.TRANSFORM_INCORRECT_NUMBER_OF_VALUES); - - TransformUtils.parseTransform("translate(1 2 3)"); + Exception e = Assert.assertThrows(SvgProcessingException.class, + () -> TransformUtils.parseTransform("translate(1 2 3)") + ); + Assert.assertEquals(SvgLogMessageConstant.TRANSFORM_INCORRECT_NUMBER_OF_VALUES, e.getMessage()); } - } diff --git a/svg/src/test/resources/com/itextpdf/svg/customization/CustomizeTextLeafSvgNodeRendererTest/cmp_customizeTextLeafSvgNodeRenderer.pdf b/svg/src/test/resources/com/itextpdf/svg/customization/CustomizeTextLeafSvgNodeRendererTest/cmp_customizeTextLeafSvgNodeRenderer.pdf new file mode 100644 index 0000000000..ece34c6b3b Binary files /dev/null and b/svg/src/test/resources/com/itextpdf/svg/customization/CustomizeTextLeafSvgNodeRendererTest/cmp_customizeTextLeafSvgNodeRenderer.pdf differ