From 31108ef8c6a7c17d2ec80767a326e0ef6d1a4575 Mon Sep 17 00:00:00 2001 From: Andreas Hager Date: Thu, 1 Feb 2024 12:16:37 +0100 Subject: [PATCH] Fix NullPointerException in case a custom document is passed to W3CDom#convert --- src/main/java/org/jsoup/helper/W3CDom.java | 12 +++++++----- src/test/java/org/jsoup/helper/W3CDomTest.java | 15 +++++++++++++++ 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/jsoup/helper/W3CDom.java b/src/main/java/org/jsoup/helper/W3CDom.java index 6ce0abd9e5..3946366ee0 100644 --- a/src/main/java/org/jsoup/helper/W3CDom.java +++ b/src/main/java/org/jsoup/helper/W3CDom.java @@ -360,12 +360,14 @@ public W3CBuilder(Document doc) { namespacesStack.push(new HashMap<>()); dest = doc; contextElement = (org.jsoup.nodes.Element) doc.getUserData(ContextProperty); // Track the context jsoup Element, so we can save the corresponding w3c element - final org.jsoup.nodes.Document inDoc = contextElement.ownerDocument(); - if (namespaceAware && inDoc != null && inDoc.parser().getTreeBuilder() instanceof HtmlTreeBuilder) { - // as per the WHATWG HTML5 spec § 2.1.3, elements are in the HTML namespace by default - namespacesStack.peek().put("", Parser.NamespaceHtml); + if (contextElement != null) { + final org.jsoup.nodes.Document inDoc = contextElement.ownerDocument(); + if ( namespaceAware && inDoc != null && inDoc.parser().getTreeBuilder() instanceof HtmlTreeBuilder ) { + // as per the WHATWG HTML5 spec § 2.1.3, elements are in the HTML namespace by default + namespacesStack.peek().put("", Parser.NamespaceHtml); + } } - } + } public void head(org.jsoup.nodes.Node source, int depth) { namespacesStack.push(new HashMap<>(namespacesStack.peek())); // inherit from above on the stack diff --git a/src/test/java/org/jsoup/helper/W3CDomTest.java b/src/test/java/org/jsoup/helper/W3CDomTest.java index de0ce16694..e236b29fb0 100644 --- a/src/test/java/org/jsoup/helper/W3CDomTest.java +++ b/src/test/java/org/jsoup/helper/W3CDomTest.java @@ -13,6 +13,7 @@ import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.OutputKeys; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpression; @@ -187,6 +188,20 @@ public void handlesInvalidTagAsText() { assertEquals("<インセンティブで高収入!>Text

More

", xml); } + @Test + public void canConvertToCustomDocument() throws ParserConfigurationException { + org.jsoup.nodes.Document document = Jsoup.parse("
"); + + DocumentBuilderFactory localDocumentBuilderFactory = DocumentBuilderFactory.newInstance(); + Document customDocumentResult = localDocumentBuilderFactory.newDocumentBuilder().newDocument(); + + W3CDom w3cDom = new W3CDom(); + w3cDom.convert(document, customDocumentResult); + + String html = W3CDom.asString(customDocumentResult, W3CDom.OutputHtml()); + assertEquals("
", html); + } + @Test public void treatsUndeclaredNamespaceAsLocalName() { String html = "One";