From 21c589989224b49331c11b9e9d13b7b5bf28f4a3 Mon Sep 17 00:00:00 2001 From: Andrei Solntsev Date: Fri, 22 Nov 2024 18:32:11 +0100 Subject: [PATCH] #447 fix parsing CSS head rules the probles was in line CSSParser.java:553 - the `margins` map was overriden by the new value. Previous map content was lost. --- .../xhtmlrenderer/css/parser/CSSParser.java | 13 ++++---- .../org/xhtmlrenderer/pdf/HeaderTest.java | 24 ++++++++++++++ .../java/org/xhtmlrenderer/pdf/TestUtils.java | 19 +++++++++++ .../org/xhtmlrenderer/pdf/WordBreakTest.java | 18 +++-------- .../pdf/bug/FloatedTableCellTest.java | 21 +++--------- .../src/test/resources/page-with-header.html | 32 +++++++++++++++++++ 6 files changed, 90 insertions(+), 37 deletions(-) create mode 100644 flying-saucer-pdf/src/test/java/org/xhtmlrenderer/pdf/HeaderTest.java create mode 100644 flying-saucer-pdf/src/test/java/org/xhtmlrenderer/pdf/TestUtils.java create mode 100644 flying-saucer-pdf/src/test/resources/page-with-header.html diff --git a/flying-saucer-core/src/main/java/org/xhtmlrenderer/css/parser/CSSParser.java b/flying-saucer-core/src/main/java/org/xhtmlrenderer/css/parser/CSSParser.java index d4929d9d9..e2eade21e 100644 --- a/flying-saucer-core/src/main/java/org/xhtmlrenderer/css/parser/CSSParser.java +++ b/flying-saucer-core/src/main/java/org/xhtmlrenderer/css/parser/CSSParser.java @@ -51,6 +51,7 @@ import java.util.Map; import java.util.Set; +import static java.util.Collections.emptyMap; import static java.util.Locale.ROOT; import static org.w3c.dom.css.CSSPrimitiveValue.CSS_NUMBER; import static org.w3c.dom.css.CSSPrimitiveValue.CSS_PERCENTAGE; @@ -550,7 +551,7 @@ private void page(Stylesheet stylesheet) throws IOException { skip_whitespace(); break; } else if (t == Token.TK_AT_RULE) { - margins = margin(stylesheet); + margins.putAll(margin(stylesheet)); } else { declaration_list(ruleset, false, true, false); } @@ -576,13 +577,11 @@ private void page(Stylesheet stylesheet) throws IOException { // margin_sym S* '{' declaration [ ';' S* declaration? ]* '}' S* // ; private Map> margin(Stylesheet stylesheet) throws IOException { - Map> margins = new HashMap<>(); - Token t = next(); if (t != Token.TK_AT_RULE) { error(new CSSParseException(t, Token.TK_AT_RULE, getCurrentLine()), "at rule", true); recover(true, false); - return margins; + return emptyMap(); } String name = getTokenValue(t); @@ -590,7 +589,7 @@ private Map> margin(Stylesheet styleshe if (marginBoxName == null) { error(new CSSParseException(name + " is not a valid margin box name", getCurrentLine()), "at rule", true); recover(true, false); - return margins; + return emptyMap(); } skip_whitespace(); @@ -605,7 +604,7 @@ private Map> margin(Stylesheet styleshe push(t); throw new CSSParseException(t, Token.TK_RBRACE, getCurrentLine()); } - margins.put(marginBoxName, ruleset.getPropertyDeclarations()); + return Map.of(marginBoxName, ruleset.getPropertyDeclarations()); } else { push(t); throw new CSSParseException(t, Token.TK_LBRACE, getCurrentLine()); @@ -614,7 +613,7 @@ private Map> margin(Stylesheet styleshe error(e, "margin box", true); recover(false, false); } - return margins; + return emptyMap(); } diff --git a/flying-saucer-pdf/src/test/java/org/xhtmlrenderer/pdf/HeaderTest.java b/flying-saucer-pdf/src/test/java/org/xhtmlrenderer/pdf/HeaderTest.java new file mode 100644 index 000000000..98e0aac7a --- /dev/null +++ b/flying-saucer-pdf/src/test/java/org/xhtmlrenderer/pdf/HeaderTest.java @@ -0,0 +1,24 @@ +package org.xhtmlrenderer.pdf; + +import com.codeborne.pdftest.PDF; +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; + +import static com.codeborne.pdftest.assertj.Assertions.assertThat; +import static org.xhtmlrenderer.pdf.TestUtils.printFile; + +public class HeaderTest { + private static final Logger log = LoggerFactory.getLogger(HeaderTest.class); + + @Test + void pageWithHeader() throws IOException { + String fileName = "page-with-header.html"; + byte[] bytes = Html2Pdf.fromClasspathResource(fileName); + + PDF pdf = printFile(log, bytes, "page-with-header.pdf"); + assertThat(pdf).containsText("Header", "Body", "Footer"); + } +} diff --git a/flying-saucer-pdf/src/test/java/org/xhtmlrenderer/pdf/TestUtils.java b/flying-saucer-pdf/src/test/java/org/xhtmlrenderer/pdf/TestUtils.java new file mode 100644 index 000000000..7d8efd731 --- /dev/null +++ b/flying-saucer-pdf/src/test/java/org/xhtmlrenderer/pdf/TestUtils.java @@ -0,0 +1,19 @@ +package org.xhtmlrenderer.pdf; + +import com.codeborne.pdftest.PDF; +import org.slf4j.Logger; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; + +public class TestUtils { + public static PDF printFile(Logger log, byte[] pdf, String filename) throws IOException { + File file = new File("target", filename); + try (FileOutputStream o = new FileOutputStream(file)) { + o.write(pdf); + } + log.info("Generated PDF: {}", file.getAbsolutePath()); + return new PDF(pdf); + } +} diff --git a/flying-saucer-pdf/src/test/java/org/xhtmlrenderer/pdf/WordBreakTest.java b/flying-saucer-pdf/src/test/java/org/xhtmlrenderer/pdf/WordBreakTest.java index 27835fab1..0cd741e77 100644 --- a/flying-saucer-pdf/src/test/java/org/xhtmlrenderer/pdf/WordBreakTest.java +++ b/flying-saucer-pdf/src/test/java/org/xhtmlrenderer/pdf/WordBreakTest.java @@ -5,28 +5,18 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.File; -import java.io.FileOutputStream; import java.io.IOException; import static com.codeborne.pdftest.assertj.Assertions.assertThat; +import static org.xhtmlrenderer.pdf.TestUtils.printFile; public class WordBreakTest { private static final Logger log = LoggerFactory.getLogger(WordBreakTest.class); @Test void breakAll() throws IOException { - - byte[] pdf = Html2Pdf.fromClasspathResource("org/xhtmlrenderer/pdf/break-all.html"); - printFile(pdf, "break-all.pdf"); - assertThat(new PDF(pdf)).containsExactText("HelloWorld1\nHelloWorld2\nHelloWorld3\nHelloWorld4\nHelloWorld5\n"); - } - - private static void printFile(byte[] pdf, String filename) throws IOException { - File file = new File("target", filename); - try (FileOutputStream o = new FileOutputStream(file)) { - o.write(pdf); - } - log.info("Generated PDF: {}", file.getAbsolutePath()); + byte[] result = Html2Pdf.fromClasspathResource("org/xhtmlrenderer/pdf/break-all.html"); + PDF pdf = printFile(log, result, "break-all.pdf"); + assertThat(pdf).containsExactText("HelloWorld1\nHelloWorld2\nHelloWorld3\nHelloWorld4\nHelloWorld5\n"); } } diff --git a/flying-saucer-pdf/src/test/java/org/xhtmlrenderer/pdf/bug/FloatedTableCellTest.java b/flying-saucer-pdf/src/test/java/org/xhtmlrenderer/pdf/bug/FloatedTableCellTest.java index ed5add4db..9a67960c6 100644 --- a/flying-saucer-pdf/src/test/java/org/xhtmlrenderer/pdf/bug/FloatedTableCellTest.java +++ b/flying-saucer-pdf/src/test/java/org/xhtmlrenderer/pdf/bug/FloatedTableCellTest.java @@ -7,11 +7,10 @@ import org.xhtmlrenderer.pdf.ITextRenderer; import org.xhtmlrenderer.resource.XMLResource; -import java.io.File; -import java.io.FileOutputStream; import java.io.IOException; import static com.codeborne.pdftest.assertj.Assertions.assertThat; +import static org.xhtmlrenderer.pdf.TestUtils.printFile; /** * Reproducible example for issue 276 @@ -37,11 +36,10 @@ void tableWithFloatedCell() throws IOException { ITextRenderer renderer = new ITextRenderer(); byte[] result = renderer.createPDF(XMLResource.load(page).getDocument()); - printFile(result, "table-with-floated-cell.pdf"); - PDF pdf = new PDF(result); + PDF pdf = printFile(log, result, "table-with-floated-cell.pdf"); assertThat(pdf).containsText("first cell", "second cell"); } - + @Test void tableCell() throws IOException { String page = """ @@ -49,17 +47,8 @@ void tableCell() throws IOException { ITextRenderer renderer = new ITextRenderer(); byte[] result = renderer.createPDF(XMLResource.load(page).getDocument()); - printFile(result, "table-cell.pdf"); - - PDF pdf = new PDF(result); + + PDF pdf = printFile(log, result, "table-cell.pdf"); assertThat(pdf).containsText("first cell"); } - - private static void printFile(byte[] pdf, String filename) throws IOException { - File file = new File("target", filename); - try (FileOutputStream o = new FileOutputStream(file)) { - o.write(pdf); - } - log.info("Generated PDF: {}", file.getAbsolutePath()); - } } diff --git a/flying-saucer-pdf/src/test/resources/page-with-header.html b/flying-saucer-pdf/src/test/resources/page-with-header.html new file mode 100644 index 000000000..4182ab865 --- /dev/null +++ b/flying-saucer-pdf/src/test/resources/page-with-header.html @@ -0,0 +1,32 @@ + + + + + + + + + +
Body
+ + + + \ No newline at end of file