Improved consecutive StreamParser.selectFirst(...) calls during progressive parsing, so later matches are returned with their parsed contents when earlier selections had left them as parser lookahead. E.g., given <title>One</title><p id=hit>Full</p><p>Next</p>, selecting title and then #hit now advances the partial lookahead and returns <p id="hit">Full</p>, rather than returning an empty <p id="hit"></p> before its content is parsed. The updated readiness tracking follows StreamParser's normal emission order across implicit HTML structure and parser recovery. #2551
Improved XML parser performance and memory use for documents with many nested namespace declarations by recording namespace changes within each element scope. #2556
Improved W3CDom conversion performance for documents with many nested namespace declarations. The W3C converter now uses the same optimized namespace tracking as the XML parser. #2559
Improved W3CDom XML conversion to retain processing instructions, comments outside the root element, and CDATA sections, which were previously dropped or converted to text. #2572
DOM mutation methods, including child insertion and replacement, now reject operations that would create a cycle, such as making a node its own child or moving an ancestor beneath a descendant. #2552
Added Elements#before(Node), after(Node), prepend(Node), and append(Node) to match the existing HTML string methods. #953
Large file-backed uploads through Connection.requestBodyStream(InputStream) now stream directly with the JDK HttpClient on Java 11+, rather than being loaded fully into memory first. #2575
Extended Java 11+ HTTP client reuse from requests sharing a Jsoup.newSession() to ordinary Jsoup.connect(...) calls, reducing transport thread and connection setup churn under sustained request loads. Sessions with custom authentication or SSL contexts continue to use their own client. #2584
Changes
Aligned the XML parser stack depth and lookups to the configured maximum, which now defaults to 512 for both HTML and XML. Use Parser#setMaxDepth(int) to configure. #2570
Bug Fixes
Fixed W3CDom namespace conversion in several cases: #2559
Namespace declarations and prefixed attributes now carry the correct namespace URI, so namespace-aware DOM lookups work as expected.
Attributes added after parsing, or included through subtree conversion, now use inherited prefix declarations.
Namespace declarations now apply regardless of attribute order, and an empty declaration shadows an inherited binding only within its scope.
With namespace awareness disabled, inherited and undeclared prefixes now receive the declarations needed for XML serialization.
Valid HTML names that are not XML QNames, such as a:b:c, are normalized. Attributes that still cannot be represented are skipped, and unrepresentable elements no longer change the surrounding tree.
Fixed W3CDom conversion of programmatically created or renamed elements whose names can be represented in a jsoup HTML DOM but are not valid XML names, such as 1abc. These names are now normalized (e.g. _1abc) instead of causing a NullPointerException. #2560
Fixed XML doctype serialization when a system identifier contains a double quote, which could otherwise produce invalid XML. #2571
XML serialization now repairs element and attribute names that start with an invalid character, rather than outputting null elements or dropping attributes. For example, an attribute named 1a is written as _1a. Additional leading underscores keep repaired attribute names unique if they conflict with another attribute. #2573
Supplementary Unicode characters are now escaped correctly when serializing with non-UTF, non-ASCII output charsets such as ISO-8859-1. Previously, characters could be emitted unescaped when their low 16-bit value was representable by the configured charset, causing replacement or corruption when the output was encoded. #2578
Fixed the JDK HttpClient implementation to accept responses missing a Content-Type header, matching the HttpURLConnection implementation. #2549
Fixed HTTP response content-type matching to handle media types case-insensitively and recognize structured +xml suffixes, including vendor-specific media types. #2550
HTTP request URL normalization now percent-encodes ASCII control characters, DEL, and embedded fragment delimiters, keeping normalized URLs valid for HTTP requests while preserving existing escapes. #2585
Corrected multipart form encoding to percent-escape CR and LF in field names and filenames, matching the HTML form submission specification. Multipart file content-types containing CR or LF are now rejected with a ValidationException. #2555
Aligned trailing comment placement with the HTML specification: comments after </body> remain children of the html element, while comments after </html> remain children of the document. #2557
When using the optional re2j regular expression engine, memory allocation errors caused by complex selector patterns at match time are now normalized to a ValidationException with a Pattern complexity error message.
Fixed parsing of malformed SVG and MathML content so that breakout HTML tags are placed according to the HTML specification. #2562
Fixed deeply nested malformed HTML parsing that could lose the document body because stack lookups did not align to the configured maximum parser depth. #2569
Aligned RCDATA, RAWTEXT, and script-data parsing with the HTML specification: malformed end tags no longer consume following markup, unclosed title/textarea content stays text through EOF, and custom text tags match exact names. #2577
Improved URL validation during HTTP/HTTPS URL resolution and cleaning; resolved URLs without a host are now rejected instead of being accepted based only on their scheme prefix, aligning to RFC 9110. Valid relative links and non-HTTP(S) schemes are unchanged. #2579
Redirects with malformed single-slash HTTP locations now use standard URL resolution to align with browsers. #2580
Template fragment parsing now handles unmatched </template> tags without throwing a ValidationException. #2581
Improved source tracking for adopted formatting elements and malformed markup ending at EOF. #2582
Reduced retained memory when parsing with source position tracking enabled (Parser#setTrackPosition(true)). Source ranges are now stored in compact parser-owned span records instead of node and attribute user data, and Position objects are created lazily when source ranges are read. This cuts tracked DOM retained size by about 50-60% on representative benchmark documents, while keeping Node#sourceRange(), Element#endSourceRange(), and Attribute#sourceRange() behavior intact. #2498
Added Element#classList(), an immutable snapshot of an element's class names in attribute order. Use hasClass() when you just need to test for one class, classList() when you want to read or iterate classes without needing a mutable result, and classNames() when you want the existing mutable, deduplicated set that can be written back with classNames(Set). The class APIs now share an HTML-whitespace scanner, which also makes classNames() faster and lighter on allocation, especially when walking many elements without class names. #2500
Aligned HTML parser scope classification with the current HTML spec for select, foreignObject, and template. #2501
Simplified the HTML tree builder's scope, implied-end-tag, and special-element checks by caching parser-only options on Tag. That improves HTML parser throughput by about 10% on small inputs and up to about 30% on larger inputs in the benchmark fixtures. #2502
Improved HTML parser throughput stability by making hot tokeniser scan paths compile more predictably. #2507
<noscript> fallback markup is now parsed into an inspectable DOM subtree in both the document head and body. The fallback acts as a contained parsing island, so malformed markup cannot disrupt the surrounding document structure, while normal HTML tokenization still applies within it. This also improves round-trip serialization. #2537
Improved redirect credential handling as a defense-in-depth measure: explicit authorization headers and request cookies are no longer forwarded across origins, reducing exposure through open redirects and aligning with HTTP guidance. Cookies managed by a CookieStore continue to follow their configured scope. #2540
Elements can now append their outer HTML, including their own tags, directly to an Appendable with Node#outerHtml(Appendable), without first creating a String. This complements Element#html(Appendable), which appends inner HTML only. #2532
Aligned CDATA tokenization with the HTML spec: CDATA syntax in HTML content is parsed as a bogus comment, while it remains supported in SVG, MathML, and XML. Also improved namespace-aware fragment parsing so SVG and MathML contexts, HTML integration points, and context-sensitive tokenizer states are handled correctly. #2542
When using the optional re2j regular expression engine, stack overflows caused by complex selector patterns are now normalized to a ValidationException with a Pattern complexity error message. #2548
Bug Fixes
Fixed HTML parsing of mixed-case RCDATA end tags after tag-shaped text. For example, <title><p>Foo</TiTLE> and <textarea><img src=x></TeXtArEa> now keep the tag-shaped content as text instead of promoting it to markup. #2503
Fixed W3CDom XML conversion so plain XML elements don't serialize with the reserved XML namespace as the default namespace. Explicit XML namespaces and xml:* attributes are still preserved. #2504
Preserve control characters in parsed tag names #2538
Updated HTTP redirects to follow the specification: 307 and 308 preserve the request method and content, 301 and 302 only change POST to GET, and Location is followed only for 301, 302, 303, 307, and 308 responses. Streamed request bodies are not buffered; if an automatic redirect requires replaying one, execution fails, so the caller can resend with a fresh stream. #2540
Corrected the Cleaner's same-site link detection to compare hostnames rather than URL prefixes when applying rel=nofollow. #2543
Build Changes
Cleaned up the Maven build for the multi-release JAR so Java 8 and Java 11+ sources compile as separate source sets. This avoids spurious Java 8 compiler warnings from newer-language overlay sources, keeps long-running parser checks behind an explicit profile, and preserves the same published artifacts and runtime behavior.
Improved parallelism and tuned timing in our integration tests, so that a full mvn clean verify drops from ~ 1m18s to ~ 21 seconds.
Expanded and clarified NodeTraversor support for in-place DOM rewrites during NodeVisitor.head(). Current-node edits such as remove, replace, and unwrap now recover more predictably, while traversal stays within the original root subtree. This makes single-pass tree cleanup and normalization visitors easier to write, for example when unwrapping presentational elements or replacing text nodes as you walk the DOM. #2472
Documentation: clarified that a configured Cleaner may be reused across concurrent threads, and that shared Safelist instances should not be mutated while in use. #2473
Updated the default HTML TagSet for current HTML elements: added dialog, search, picture, and slot; made ins, del, button, audio, video, and canvas inline by default (Tag#isInline(), aligned to phrasing content in the spec); and added readable Element.text() boundaries for controls and embedded objects via the new Tag.TextBoundary option. This improves pretty-printing and keeps normalized text from running adjacent words together. #2493
Bug Fixes
Android (R8/ProGuard): added a rule to ignore the optional re2j dependency when not present. #2459
Fixed a NodeTraversor regression in 1.21.2 where removing or replacing the current node during head() could revisit the replacement node and loop indefinitely. The traversal docs now also clarify which inserted nodes are visited in the current pass. #2472
Parsing during charset sniffing no longer fails if an advisory available() call throws IOException, as seen on JDK 8 HttpURLConnection. #2474
Cleaner no longer makes relative URL attributes in the input document absolute when cleaning or validating a Document. URL normalization now applies only to the cleaned output, and Safelist.isSafeAttribute() is side effect free. #2475
Cleaner no longer duplicates enforced attributes when the input Document preserves attribute case. A case-variant source attribute is now replaced by the enforced attribute in the cleaned output. #2476
If a per-request SOCKS proxy is configured, jsoup now avoids using the JDK HttpClient, because the JDK would silently ignore that proxy and attempt to connect directly. Those requests now fall back to the legacy HttpURLConnection transport instead, which does support SOCKS. #2468
Connection.Response.streamParser() and DataUtil.streamParser(Path, ...) could fail on small inputs without a declared charset, if the initial 5 KB charset sniff fully consumed the input and closed it before the stream parse began. #2483
In XML mode, doctypes with an internal subset, such as <!DOCTYPE root [<!ENTITY name "value">]>, now round-trip correctly. The subset is preserved as raw text only; entities are not expanded and external DTDs are not loaded. #2486
Build Changes
Migrated the integration test server from Jetty to Netty, which actively maintains support for our minimum JDK target (8). #2491
Configuration
📅Schedule: (UTC)
Branch creation
At any time (no schedule defined)
Automerge
At any time (no schedule defined)
🚦Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
🔕Ignore: Close this PR and you won't be reminded about this update again.
If you want to rebase/retry this PR, check this box
This PR contains the following updates:
| Package | Type | Update | Change |
|---|---|---|---|
| [org.jsoup:jsoup](https://jsoup.org/) ([source](https://github.com/jhy/jsoup)) | compile | minor | `1.22.1` → `1.23.2` |
---
### Release Notes
<details>
<summary>jhy/jsoup (org.jsoup:jsoup)</summary>
### [`v1.23.2`](https://github.com/jhy/jsoup/blob/HEAD/CHANGES.md#1232-2026-Aug-26)
##### Improvements
- Improved consecutive `StreamParser.selectFirst(...)` calls during progressive parsing, so later matches are returned with their parsed contents when earlier selections had left them as parser lookahead. E.g., given `<title>One</title><p id=hit>Full</p><p>Next</p>`, selecting `title` and then `#hit` now advances the partial lookahead and returns `<p id="hit">Full</p>`, rather than returning an empty `<p id="hit"></p>` before its content is parsed. The updated readiness tracking follows StreamParser's normal emission order across implicit HTML structure and parser recovery. [#​2551](https://github.com/jhy/jsoup/pull/2551)
- Improved XML parser performance and memory use for documents with many nested namespace declarations by recording namespace changes within each element scope. [#​2556](https://github.com/jhy/jsoup/pull/2556)
- Improved `W3CDom` conversion performance for documents with many nested namespace declarations. The W3C converter now uses the same optimized namespace tracking as the XML parser. [#​2559](https://github.com/jhy/jsoup/pull/2559)
- Improved `W3CDom` XML conversion to retain processing instructions, comments outside the root element, and CDATA sections, which were previously dropped or converted to text. [#​2572](https://github.com/jhy/jsoup/issues/2572)
- DOM mutation methods, including child insertion and replacement, now reject operations that would create a cycle, such as making a node its own child or moving an ancestor beneath a descendant. [#​2552](https://github.com/jhy/jsoup/issues/2552)
- Added `Elements#before(Node)`, `after(Node)`, `prepend(Node)`, and `append(Node)` to match the existing HTML string methods. [#​953](https://github.com/jhy/jsoup/issues/953)
- Large file-backed uploads through `Connection.requestBodyStream(InputStream)` now stream directly with the JDK `HttpClient` on Java 11+, rather than being loaded fully into memory first. [#​2575](https://github.com/jhy/jsoup/pull/2576)
- Extended Java 11+ HTTP client reuse from requests sharing a `Jsoup.newSession()` to ordinary `Jsoup.connect(...)` calls, reducing transport thread and connection setup churn under sustained request loads. Sessions with custom authentication or SSL contexts continue to use their own client. [#​2584](https://github.com/jhy/jsoup/pull/2584)
##### Changes
- Aligned the XML parser stack depth and lookups to the configured maximum, which now defaults to 512 for both HTML and XML. Use `Parser#setMaxDepth(int)` to configure. [#​2570](https://github.com/jhy/jsoup/pull/2570)
##### Bug Fixes
- Fixed `W3CDom` namespace conversion in several cases: [#​2559](https://github.com/jhy/jsoup/pull/2559)
- Namespace declarations and prefixed attributes now carry the correct namespace URI, so namespace-aware DOM lookups work as expected.
- Attributes added after parsing, or included through subtree conversion, now use inherited prefix declarations.
- Namespace declarations now apply regardless of attribute order, and an empty declaration shadows an inherited binding only within its scope.
- With namespace awareness disabled, inherited and undeclared prefixes now receive the declarations needed for XML serialization.
- Valid HTML names that are not XML QNames, such as `a:b:c`, are normalized. Attributes that still cannot be represented are skipped, and unrepresentable elements no longer change the surrounding tree.
- Fixed `W3CDom` conversion of programmatically created or renamed elements whose names can be represented in a jsoup HTML DOM but are not valid XML names, such as `1abc`. These names are now normalized (e.g. `_1abc`) instead of causing a `NullPointerException`. [#​2560](https://github.com/jhy/jsoup/issues/2560)
- Fixed XML doctype serialization when a system identifier contains a double quote, which could otherwise produce invalid XML. [#​2571](https://github.com/jhy/jsoup/issues/2571)
- XML serialization now repairs element and attribute names that start with an invalid character, rather than outputting `null` elements or dropping attributes. For example, an attribute named `1a` is written as `_1a`. Additional leading underscores keep repaired attribute names unique if they conflict with another attribute. [#​2573](https://github.com/jhy/jsoup/issues/2573)
- Supplementary Unicode characters are now escaped correctly when serializing with non-UTF, non-ASCII output charsets such as ISO-8859-1. Previously, characters could be emitted unescaped when their low 16-bit value was representable by the configured charset, causing replacement or corruption when the output was encoded. [#​2578](https://github.com/jhy/jsoup/issues/2578)
- Fixed the JDK `HttpClient` implementation to accept responses missing a `Content-Type` header, matching the `HttpURLConnection` implementation. [#​2549](https://github.com/jhy/jsoup/pull/2549)
- Fixed HTTP response content-type matching to handle media types case-insensitively and recognize structured `+xml` suffixes, including vendor-specific media types. [#​2550](https://github.com/jhy/jsoup/pull/2550)
- HTTP request URL normalization now percent-encodes ASCII control characters, DEL, and embedded fragment delimiters, keeping normalized URLs valid for HTTP requests while preserving existing escapes. [#​2585](https://github.com/jhy/jsoup/pull/2585)
- Corrected multipart form encoding to percent-escape CR and LF in field names and filenames, matching the HTML form submission specification. Multipart file content-types containing CR or LF are now rejected with a `ValidationException`. [#​2555](https://github.com/jhy/jsoup/pull/2555)
- Aligned trailing comment placement with the HTML specification: comments after `</body>` remain children of the `html` element, while comments after `</html>` remain children of the document. [#​2557](https://github.com/jhy/jsoup/pull/2557)
- When using the optional `re2j` regular expression engine, memory allocation errors caused by complex selector patterns at match time are now normalized to a `ValidationException` with a `Pattern complexity error` message.
- Fixed parsing of malformed SVG and MathML content so that breakout HTML tags are placed according to the HTML specification. [#​2562](https://github.com/jhy/jsoup/issues/2562)
- Fixed deeply nested malformed HTML parsing that could lose the document body because stack lookups did not align to the configured maximum parser depth. [#​2569](https://github.com/jhy/jsoup/pull/2569)
- Aligned RCDATA, RAWTEXT, and script-data parsing with the HTML specification: malformed end tags no longer consume following markup, unclosed `title`/`textarea` content stays text through EOF, and custom text tags match exact names. [#​2577](https://github.com/jhy/jsoup/pull/2577)
- Improved URL validation during HTTP/HTTPS URL resolution and cleaning; resolved URLs without a host are now rejected instead of being accepted based only on their scheme prefix, aligning to RFC 9110. Valid relative links and non-HTTP(S) schemes are unchanged. [#​2579](https://github.com/jhy/jsoup/pull/2579)
- Redirects with malformed single-slash HTTP locations now use standard URL resolution to align with browsers. [#​2580](https://github.com/jhy/jsoup/pull/2580)
- Template fragment parsing now handles unmatched `</template>` tags without throwing a `ValidationException`. [#​2581](https://github.com/jhy/jsoup/pull/2581)
- Improved source tracking for adopted formatting elements and malformed markup ending at EOF. [#​2582](https://github.com/jhy/jsoup/pull/2582)
### [`v1.23.1`](https://github.com/jhy/jsoup/blob/HEAD/CHANGES.md#1231-2026-Jul-30)
##### Improvements
- Reduced retained memory when parsing with source position tracking enabled (`Parser#setTrackPosition(true)`). Source ranges are now stored in compact parser-owned span records instead of node and attribute user data, and `Position` objects are created lazily when source ranges are read. This cuts tracked DOM retained size by about 50-60% on representative benchmark documents, while keeping `Node#sourceRange()`, `Element#endSourceRange()`, and `Attribute#sourceRange()` behavior intact. [#​2498](https://github.com/jhy/jsoup/pull/2498)
- Added `Element#classList()`, an immutable snapshot of an element's class names in attribute order. Use `hasClass()` when you just need to test for one class, `classList()` when you want to read or iterate classes without needing a mutable result, and `classNames()` when you want the existing mutable, deduplicated set that can be written back with `classNames(Set)`. The class APIs now share an HTML-whitespace scanner, which also makes `classNames()` faster and lighter on allocation, especially when walking many elements without class names. [#​2500](https://github.com/jhy/jsoup/pull/2500)
- Aligned HTML parser scope classification with the current HTML spec for `select`, `foreignObject`, and `template`. [#​2501](https://github.com/jhy/jsoup/issues/2501)
- Simplified the HTML tree builder's scope, implied-end-tag, and special-element checks by caching parser-only options on Tag. That improves HTML parser throughput by about 10% on small inputs and up to about 30% on larger inputs in the benchmark fixtures. [#​2502](https://github.com/jhy/jsoup/issues/2502)
- Improved HTML parser throughput stability by making hot tokeniser scan paths compile more predictably. [#​2507](https://github.com/jhy/jsoup/pull/2507)
- `<noscript>` fallback markup is now parsed into an inspectable DOM subtree in both the document head and body. The fallback acts as a contained parsing island, so malformed markup cannot disrupt the surrounding document structure, while normal HTML tokenization still applies within it. This also improves round-trip serialization. [#​2537](https://github.com/jhy/jsoup/pull/2537)
- Improved redirect credential handling as a defense-in-depth measure: explicit authorization headers and request cookies are no longer forwarded across origins, reducing exposure through open redirects and aligning with HTTP guidance. Cookies managed by a `CookieStore` continue to follow their configured scope. [#​2540](https://github.com/jhy/jsoup/pull/2540)
- Elements can now append their outer HTML, including their own tags, directly to an `Appendable` with `Node#outerHtml(Appendable)`, without first creating a `String`. This complements `Element#html(Appendable)`, which appends inner HTML only. [#​2532](https://github.com/jhy/jsoup/issues/2532)
- Aligned CDATA tokenization with the HTML spec: CDATA syntax in HTML content is parsed as a bogus comment, while it remains supported in SVG, MathML, and XML. Also improved namespace-aware fragment parsing so SVG and MathML contexts, HTML integration points, and context-sensitive tokenizer states are handled correctly. [#​2542](https://github.com/jhy/jsoup/issues/2542)
- When using the optional `re2j` regular expression engine, stack overflows caused by complex selector patterns are now normalized to a `ValidationException` with a `Pattern complexity error` message. [#​2548](https://github.com/jhy/jsoup/issues/2548)
##### Bug Fixes
- Fixed HTML parsing of mixed-case RCDATA end tags after tag-shaped text. For example, `<title><p>Foo</TiTLE>` and `<textarea><img src=x></TeXtArEa>` now keep the tag-shaped content as text instead of promoting it to markup. [#​2503](https://github.com/jhy/jsoup/issues/2503)
- Fixed `W3CDom` XML conversion so plain XML elements don't serialize with the reserved XML namespace as the default namespace. Explicit XML namespaces and `xml:*` attributes are still preserved. [#​2504](https://github.com/jhy/jsoup/issues/2504)
- Preserve control characters in parsed tag names [#​2538](https://github.com/jhy/jsoup/issues/2538)
- Updated HTTP redirects to follow the specification: 307 and 308 preserve the request method and content, 301 and 302 only change POST to GET, and `Location` is followed only for 301, 302, 303, 307, and 308 responses. Streamed request bodies are not buffered; if an automatic redirect requires replaying one, execution fails, so the caller can resend with a fresh stream. [#​2540](https://github.com/jhy/jsoup/pull/2540)
- Corrected the Cleaner's same-site link detection to compare hostnames rather than URL prefixes when applying `rel=nofollow`. [#​2543](https://github.com/jhy/jsoup/issues/2543)
##### Build Changes
- Cleaned up the Maven build for the multi-release JAR so Java 8 and Java 11+ sources compile as separate source sets. This avoids spurious Java 8 compiler warnings from newer-language overlay sources, keeps long-running parser checks behind an explicit profile, and preserves the same published artifacts and runtime behavior.
- Improved parallelism and tuned timing in our integration tests, so that a full `mvn clean verify` drops from \~ 1m18s to \~ 21 seconds.
### [`v1.22.2`](https://github.com/jhy/jsoup/blob/HEAD/CHANGES.md#1222-2026-Apr-20)
##### Improvements
- Expanded and clarified `NodeTraversor` support for in-place DOM rewrites during `NodeVisitor.head()`. Current-node edits such as `remove`, `replace`, and `unwrap` now recover more predictably, while traversal stays within the original root subtree. This makes single-pass tree cleanup and normalization visitors easier to write, for example when unwrapping presentational elements or replacing text nodes as you walk the DOM. [#​2472](https://github.com/jhy/jsoup/issues/2472)
- Documentation: clarified that a configured `Cleaner` may be reused across concurrent threads, and that shared `Safelist` instances should not be mutated while in use. [#​2473](https://github.com/jhy/jsoup/issues/2473)
- Updated the default HTML `TagSet` for current HTML elements: added `dialog`, `search`, `picture`, and `slot`; made `ins`, `del`, `button`, `audio`, `video`, and `canvas` inline by default (`Tag#isInline()`, aligned to phrasing content in the spec); and added readable `Element.text()` boundaries for controls and embedded objects via the new `Tag.TextBoundary` option. This improves pretty-printing and keeps normalized text from running adjacent words together. [#​2493](https://github.com/jhy/jsoup/pull/2493)
##### Bug Fixes
- Android (R8/ProGuard): added a rule to ignore the optional `re2j` dependency when not present. [#​2459](https://github.com/jhy/jsoup/issues/2459)
- Fixed a `NodeTraversor` regression in 1.21.2 where removing or replacing the current node during `head()` could revisit the replacement node and loop indefinitely. The traversal docs now also clarify which inserted nodes are visited in the current pass. [#​2472](https://github.com/jhy/jsoup/issues/2472)
- Parsing during charset sniffing no longer fails if an advisory `available()` call throws `IOException`, as seen on JDK 8 `HttpURLConnection`. [#​2474](https://github.com/jhy/jsoup/issues/2474)
- `Cleaner` no longer makes relative URL attributes in the input document absolute when cleaning or validating a `Document`. URL normalization now applies only to the cleaned output, and `Safelist.isSafeAttribute()` is side effect free. [#​2475](https://github.com/jhy/jsoup/issues/2475)
- `Cleaner` no longer duplicates enforced attributes when the input `Document` preserves attribute case. A case-variant source attribute is now replaced by the enforced attribute in the cleaned output. [#​2476](https://github.com/jhy/jsoup/issues/2476)
- If a per-request SOCKS proxy is configured, jsoup now avoids using the JDK `HttpClient`, because the JDK would silently ignore that proxy and attempt to connect directly. Those requests now fall back to the legacy `HttpURLConnection` transport instead, which does support SOCKS. [#​2468](https://github.com/jhy/jsoup/issues/2468)
- `Connection.Response.streamParser()` and `DataUtil.streamParser(Path, ...)` could fail on small inputs without a declared charset, if the initial 5 KB charset sniff fully consumed the input and closed it before the stream parse began. [#​2483](https://github.com/jhy/jsoup/issues/2483)
- In XML mode, doctypes with an internal subset, such as `<!DOCTYPE root [<!ENTITY name "value">]>`, now round-trip correctly. The subset is preserved as raw text only; entities are not expanded and external DTDs are not loaded. [#​2486](https://github.com/jhy/jsoup/issues/2486)
##### Build Changes
- Migrated the integration test server from Jetty to Netty, which actively maintains support for our minimum JDK target (8). [#​2491](https://github.com/jhy/jsoup/pull/2491)
</details>
---
### Configuration
📅 **Schedule**: (UTC)
- Branch creation
- At any time (no schedule defined)
- Automerge
- At any time (no schedule defined)
🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.
♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
🔕 **Ignore**: Close this PR and you won't be reminded about this update again.
---
- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box
---
This PR has been generated by [Mend Renovate CLI](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMzIuMyIsInVwZGF0ZWRJblZlciI6IjQ0LjQ1LjQiLCJ0YXJnZXRCcmFuY2giOiJtYWluIiwibGFiZWxzIjpbXX0=-->
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
This PR contains the following updates:
1.22.1→1.23.2Release Notes
jhy/jsoup (org.jsoup:jsoup)
v1.23.2Improvements
StreamParser.selectFirst(...)calls during progressive parsing, so later matches are returned with their parsed contents when earlier selections had left them as parser lookahead. E.g., given<title>One</title><p id=hit>Full</p><p>Next</p>, selectingtitleand then#hitnow advances the partial lookahead and returns<p id="hit">Full</p>, rather than returning an empty<p id="hit"></p>before its content is parsed. The updated readiness tracking follows StreamParser's normal emission order across implicit HTML structure and parser recovery. #2551W3CDomconversion performance for documents with many nested namespace declarations. The W3C converter now uses the same optimized namespace tracking as the XML parser. #2559W3CDomXML conversion to retain processing instructions, comments outside the root element, and CDATA sections, which were previously dropped or converted to text. #2572Elements#before(Node),after(Node),prepend(Node), andappend(Node)to match the existing HTML string methods. #953Connection.requestBodyStream(InputStream)now stream directly with the JDKHttpClienton Java 11+, rather than being loaded fully into memory first. #2575Jsoup.newSession()to ordinaryJsoup.connect(...)calls, reducing transport thread and connection setup churn under sustained request loads. Sessions with custom authentication or SSL contexts continue to use their own client. #2584Changes
Parser#setMaxDepth(int)to configure. #2570Bug Fixes
W3CDomnamespace conversion in several cases: #2559a:b:c, are normalized. Attributes that still cannot be represented are skipped, and unrepresentable elements no longer change the surrounding tree.W3CDomconversion of programmatically created or renamed elements whose names can be represented in a jsoup HTML DOM but are not valid XML names, such as1abc. These names are now normalized (e.g._1abc) instead of causing aNullPointerException. #2560nullelements or dropping attributes. For example, an attribute named1ais written as_1a. Additional leading underscores keep repaired attribute names unique if they conflict with another attribute. #2573HttpClientimplementation to accept responses missing aContent-Typeheader, matching theHttpURLConnectionimplementation. #2549+xmlsuffixes, including vendor-specific media types. #2550ValidationException. #2555</body>remain children of thehtmlelement, while comments after</html>remain children of the document. #2557re2jregular expression engine, memory allocation errors caused by complex selector patterns at match time are now normalized to aValidationExceptionwith aPattern complexity errormessage.title/textareacontent stays text through EOF, and custom text tags match exact names. #2577</template>tags without throwing aValidationException. #2581v1.23.1Improvements
Parser#setTrackPosition(true)). Source ranges are now stored in compact parser-owned span records instead of node and attribute user data, andPositionobjects are created lazily when source ranges are read. This cuts tracked DOM retained size by about 50-60% on representative benchmark documents, while keepingNode#sourceRange(),Element#endSourceRange(), andAttribute#sourceRange()behavior intact. #2498Element#classList(), an immutable snapshot of an element's class names in attribute order. UsehasClass()when you just need to test for one class,classList()when you want to read or iterate classes without needing a mutable result, andclassNames()when you want the existing mutable, deduplicated set that can be written back withclassNames(Set). The class APIs now share an HTML-whitespace scanner, which also makesclassNames()faster and lighter on allocation, especially when walking many elements without class names. #2500select,foreignObject, andtemplate. #2501<noscript>fallback markup is now parsed into an inspectable DOM subtree in both the document head and body. The fallback acts as a contained parsing island, so malformed markup cannot disrupt the surrounding document structure, while normal HTML tokenization still applies within it. This also improves round-trip serialization. #2537CookieStorecontinue to follow their configured scope. #2540AppendablewithNode#outerHtml(Appendable), without first creating aString. This complementsElement#html(Appendable), which appends inner HTML only. #2532re2jregular expression engine, stack overflows caused by complex selector patterns are now normalized to aValidationExceptionwith aPattern complexity errormessage. #2548Bug Fixes
<title><p>Foo</TiTLE>and<textarea><img src=x></TeXtArEa>now keep the tag-shaped content as text instead of promoting it to markup. #2503W3CDomXML conversion so plain XML elements don't serialize with the reserved XML namespace as the default namespace. Explicit XML namespaces andxml:*attributes are still preserved. #2504Locationis followed only for 301, 302, 303, 307, and 308 responses. Streamed request bodies are not buffered; if an automatic redirect requires replaying one, execution fails, so the caller can resend with a fresh stream. #2540rel=nofollow. #2543Build Changes
mvn clean verifydrops from ~ 1m18s to ~ 21 seconds.v1.22.2Improvements
NodeTraversorsupport for in-place DOM rewrites duringNodeVisitor.head(). Current-node edits such asremove,replace, andunwrapnow recover more predictably, while traversal stays within the original root subtree. This makes single-pass tree cleanup and normalization visitors easier to write, for example when unwrapping presentational elements or replacing text nodes as you walk the DOM. #2472Cleanermay be reused across concurrent threads, and that sharedSafelistinstances should not be mutated while in use. #2473TagSetfor current HTML elements: addeddialog,search,picture, andslot; madeins,del,button,audio,video, andcanvasinline by default (Tag#isInline(), aligned to phrasing content in the spec); and added readableElement.text()boundaries for controls and embedded objects via the newTag.TextBoundaryoption. This improves pretty-printing and keeps normalized text from running adjacent words together. #2493Bug Fixes
re2jdependency when not present. #2459NodeTraversorregression in 1.21.2 where removing or replacing the current node duringhead()could revisit the replacement node and loop indefinitely. The traversal docs now also clarify which inserted nodes are visited in the current pass. #2472available()call throwsIOException, as seen on JDK 8HttpURLConnection. #2474Cleanerno longer makes relative URL attributes in the input document absolute when cleaning or validating aDocument. URL normalization now applies only to the cleaned output, andSafelist.isSafeAttribute()is side effect free. #2475Cleanerno longer duplicates enforced attributes when the inputDocumentpreserves attribute case. A case-variant source attribute is now replaced by the enforced attribute in the cleaned output. #2476HttpClient, because the JDK would silently ignore that proxy and attempt to connect directly. Those requests now fall back to the legacyHttpURLConnectiontransport instead, which does support SOCKS. #2468Connection.Response.streamParser()andDataUtil.streamParser(Path, ...)could fail on small inputs without a declared charset, if the initial 5 KB charset sniff fully consumed the input and closed it before the stream parse began. #2483<!DOCTYPE root [<!ENTITY name "value">]>, now round-trip correctly. The subset is preserved as raw text only; entities are not expanded and external DTDs are not loaded. #2486Build Changes
Configuration
📅 Schedule: (UTC)
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about this update again.
This PR has been generated by Mend Renovate CLI.
9bf9e606e5toa176e3a9b8Update dependency org.jsoup:jsoup to v1.22.2to Update dependency org.jsoup:jsoup to v1.23.1a176e3a9b8tod76da14cdbUpdate dependency org.jsoup:jsoup to v1.23.1to Update dependency org.jsoup:jsoup to v1.23.2View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.