This is an automated email from the ASF dual-hosted git repository. rmaucher pushed a commit to branch 9.0.x in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit ae976ca9326966fb6fb1b26018f4bee9366503ed Author: opencode <[email protected]> AuthorDate: Wed Oct 14 16:52:23 2026 +0200 Keep the Digester loggers usable after clear() clear() nulled log and saxLog. It runs at the end of every successful parse via endDocument(), on every failed parse via the reset added in the previous commit, and via the public reset() method, so afterwards the loggers stayed null until the next parse re-ran configure(). That left several public methods broken in exactly the empty state their Javadoc promises a null return or a plain call: peek(), peek(int) and pop() threw a NullPointerException inside their catch(EmptyStackException) handler instead of returning null, peekParams and popParams behaved the same way, popParams(), pushParams() and register() hit a NullPointerException unconditionally on the trace enablement check, and createSAXException(String, Exception) did so on its log.error path when no document locator has been set, for example after a parse failure on a file that could not be opened. The nulling also served no purpose. JULI loggers are cached by name by the logging implementation, so retaining the two handles between parses costs nothing, and configure() re-assigned equivalent handles on every subsequent parse anyway. Nothing reads the fields to test for null and no Digester subclass in the tree overrides configure(). Adds regression tests to TestDigester for the stack and parameter methods after a successful parse and for createSAXException() in the no-locator state left by a failed parse; both fail with a NullPointerException without this change. --- java/org/apache/tomcat/util/digester/Digester.java | 2 - .../apache/tomcat/util/digester/TestDigester.java | 44 ++++++++++++++++++++++ 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/java/org/apache/tomcat/util/digester/Digester.java b/java/org/apache/tomcat/util/digester/Digester.java index abccadd524..8b90503133 100644 --- a/java/org/apache/tomcat/util/digester/Digester.java +++ b/java/org/apache/tomcat/util/digester/Digester.java @@ -1876,8 +1876,6 @@ public class Digester extends DefaultHandler2 { params.clear(); publicId = null; stack.clear(); - log = null; - saxLog = null; configured = false; } diff --git a/test/org/apache/tomcat/util/digester/TestDigester.java b/test/org/apache/tomcat/util/digester/TestDigester.java index f0930c64bd..25eaf04f66 100644 --- a/test/org/apache/tomcat/util/digester/TestDigester.java +++ b/test/org/apache/tomcat/util/digester/TestDigester.java @@ -16,6 +16,8 @@ */ package org.apache.tomcat.util.digester; +import java.io.File; +import java.io.IOException; import java.io.StringReader; import org.junit.Assert; @@ -141,4 +143,46 @@ public class TestDigester { Assert.assertEquals(1, rule.getBegins()); } + + /* + * clear() runs at the end of every successful parse. The methods that are + * documented to return null on an empty stack must keep working after the + * digester has been cleared. + */ + @Test + public void testStackMethodsAfterSuccessfulParse() throws Exception { + Digester digester = new Digester(); + digester.addObjectCreate("root", "java.lang.Object"); + + digester.parse(new InputSource(new StringReader("<root/>"))); + + Assert.assertNull(digester.peek()); + Assert.assertNull(digester.peek(0)); + Assert.assertNull(digester.pop()); + Assert.assertNull(digester.peekParams()); + Assert.assertNull(digester.popParams()); + digester.pushParams(new Object()); + digester.register("public-id", "system-id"); + } + + + /* + * A parse failure before setDocumentLocator() leaves the locator null, so + * createSAXException() takes the log.error path. That path must work even + * though the failed parse has run clear() via the parse() failure handling. + */ + @Test + public void testCreateSaxExceptionAfterFailedParseWithoutLocator() throws Exception { + Digester digester = new Digester(); + + try { + digester.parse(new File("does-not-exist.xml")); + Assert.fail("Expected an IOException for the missing file"); + } catch (IOException e) { + // Expected + } + + Assert.assertNotNull(digester.createSAXException("message", new RuntimeException("cause"))); + } + } --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
