Skip to content

Releases: jhy/jsoup

jsoup 1.19.1

04 Mar 04:20
@jhy jhy
5c4c09a
Compare
Choose a tag to compare

Changes

  • Added support for http/2 requests in Jsoup.connect(), when running on Java 11+, via the Java HttpClient
    implementation. #2257.
    • In this version of jsoup, the default is to make requests via the HttpUrlConnection implementation: use
      System.setProperty("jsoup.useHttpClient", "true"); to enable making requests via the HttpClient instead ,
      which will enable http/2 support, if available. This will become the default in a later version of jsoup, so now is
      a good time to validate it.
    • If you are repackaging the jsoup jar in your deployment (i.e. creating a shaded- or a fat-jar), make sure to specify
      that as a Multi-Release
      JAR.
    • If the HttpClient impl is not available in your JRE, requests will continue to be made via
      HttpURLConnection (in http/1.1 mode).
  • Updated the minimum Android API Level validation from 10 to 21. As with previous jsoup versions, Android
    developers need to enable core library desugaring. The minimum Java version remains Java 8.
    #2173
  • Removed previously deprecated class: org.jsoup.UncheckedIOException (replace with java.io.UncheckedIOException);
    moved previously deprecated method Element Element#forEach(Consumer) to
    void Element#forEach(Consumer()). #2246
  • Deprecated the methods Document#updateMetaCharsetElement(bool) and #Document#updateMetaCharsetElement(), as the
    setting had no effect. When Document#charset(Charset) is called, the document's meta charset or XML encoding
    instruction is always set. #2247

Improvements

  • When cleaning HTML with a Safelist that preserves relative links, the isValid() method will now consider these
    links valid. Additionally, the enforced attribute rel=nofollow will only be added to external links when configured
    in the safelist. #2245
  • Added Element#selectStream(String query) and Element#selectStream(Evaluator) methods, that return a Stream of
    matching elements. Elements are evaluated and returned as they are found, and the stream can be
    terminated early. #2092
  • Element objects now implement Iterable, enabling them to be used in enhanced for loops.
  • Added support for fragment parsing from a Reader via
    Parser#parseFragmentInput(Reader, Element, String). #1177
  • Reintroduced CLI executable examples, in jsoup-examples.jar. #1702
  • Optimized performance of selectors like #id .class (and other similar descendant queries) by around 4.6x, by better
    balancing the Ancestor evaluator's cost function in the query
    planner. #2254
  • Removed the legacy parsing rules for <isindex> tags, which would autovivify a form element with labels. This is no
    longer in the spec.
  • Added Elements.selectFirst(String cssQuery) and Elements.expectFirst(String cssQuery), to select the first
    matching element from an Elements list. #2263
  • When parsing with the XML parser, XML Declarations and Processing Instructions are directly handled, vs bouncing
    through the HTML parser's bogus comment handler. Serialization for non-doctype declarations no longer end with a
    spurious !. #2275
  • When converting parsed HTML to XML or the W3C DOM, element names containing < are normalized to _ to ensure valid
    XML. For example, <foo<bar> becomes <foo_bar>, as XML does not allow < in element names, but HTML5
    does. #2276
  • Reimplemented the HTML5 Adoption Agency Algorithm to the current spec. This handles mis-nested formating / structural elements. #2278

Bug Fixes

  • If an element has an ; in an attribute name, it could not be converted to a W3C DOM element, and so subsequent XPath
    queries could miss that element. Now, the attribute name is more completely
    normalized. #2244
  • For backwards compatibility, reverted the internal attribute key for doctype names to
    "name". #2241
  • In Connection, skip cookies that have no name, rather than throwing a validation
    exception. #2242
  • When running on JDK 1.8, the error java.lang.NoSuchMethodError: java.nio.ByteBuffer.flip()Ljava/nio/ByteBuffer;
    could be thrown when calling Response#body() after parsing from a URL and the buffer size was
    exceeded. #2250
  • For backwards compatibility, allow null InputStream inputs to Jsoup.parse(InputStream stream, ...), by returning
    an empty Document. #2252
  • A template tag containing an li within an open li would be parsed incorrectly, as it was not recognized as a
    "special" tag (which have additional processing rules). Also, added the SVG and MathML namespace tags to the list of
    special tags. #2258
  • A template tag containing a button within an open button would be parsed incorrectly, as the "in button scope"
    check was not aware of the template element. Corrected other instances including MathML and SVG elements,
    also. #2271
  • An :nth-child selector with a negative digit-less step, such as :nth-child(-n+2), would be parsed incorrectly as a
    positive step, and so would not match as expected. #1147
  • Calling doc.charset(charset) on an empty XML document would throw an
    IndexOutOfBoundsException. #2266
  • Fixed a memory leak when reusing a nested StructuralEvaluator (e.g., a selector ancestor chain like A B C) by
    ensuring cache reset calls cascade to inner members. #2277
  • Concurrent calls to doc.clone().append(html) were not supported. When a document was cloned, its Parser was not cloned but was a shallow copy of the original parser. #2281

jsoup-1.18.3

01 Dec 22:55
@jhy jhy
7c56eb2
Compare
Choose a tag to compare

1.18.3 is a quick release to fix #2235 in 1.18.2.

Please see also the full release notes for jsoup 1.18.2 if you are coming from an earlier release.

Bug Fixes

  • When serializing to XML, attribute names containing -, ., or digits were incorrectly considered invalid and removed. #2235

jsoup 1.18.2

27 Nov 01:37
@jhy jhy
71063c3
Compare
Choose a tag to compare

Improvements

  • Optimized the throughput and memory use throughout the input read and parse flows, with heap allocations and GC down between -6% and -89%, and throughput improved up to +143% for small inputs. Most inputs sizes will see throughput increases of ~ 20%. These performance improvements come through recycling the backing byte[] and char[] arrays used to read and parse the input. 2186
  • Speed optimized html() and Entities.escape() when the input contains UTF characters in a supplementary plane, by around 49%. 2183
  • The form associated elements returned by FormElement.elements() now reflect changes made to the DOM, subsequently to the original parse. 2140
  • In the TreeBuilder, the onNodeInserted() and onNodeClosed() events are now also fired for the outermost / root Document node. This enables source position tracking on the Document node (which was previously unset). And it also enables the node traversor to see the outer Document node. 2182
  • Selected Elements can now be position swapped inline using Elements#set(). 2212

Bug Fixes

  • Element.cssSelector() would fail if the element's class contained a * character. 2169
  • When tracking source ranges, a text node following an invalid self-closing element may be left untracked. 2175
  • When a document has no doctype, or a doctype not named html, it should be parsed in Quirks Mode. 2197
  • With a selector like div:has(span + a), the has() component was not working correctly, as the inner combining query caused the evaluator to match those against the outer's siblings, not children. 2187
  • A selector query that included multiple :has() components in a nested :has() might incorrectly execute. 2131
  • When cookie names in a response are duplicated, the simple view of cookies available via Connection.Response#cookies() will provide the last one set. Generally it is better to use the Jsoup.newSession method to maintain a cookie jar, as that applies appropriate path selection on cookies when making requests. 1831
  • When parsing named HTML entities, base entities should resolve if they are a prefix of the input token (and not in an attribute). 2207
  • Fixed incorrect tracking of source ranges for attributes merged from late-occurring elements that were implicitly created (html or body). 2204
  • Follow the current HTML specification in the tokenizer to allow < as part of a tag name, instead of emitting it as a character node. 2230
  • Similarly, allow a < as the start of an attribute name, vs creating a new element. The previous behavior was intended to parse closer to what we anticipated the author's intent to be, but that does not align to the spec or to how browsers behave. 1483

jsoup-1.18.1

10 Jul 08:00
@jhy jhy
19e8539
Compare
Choose a tag to compare

https://jsoup.org/news/release-1.18.1

Improvements

  • Stream Parser: A StreamParser provides a progressive parse of its input. As each Element is completed, it is
    emitted via a Stream or Iterator interface. Elements returned will be complete with all their children, and an
    (empty) next sibling, if applicable. Elements (or their children) may be removed from the DOM during the parse,
    for e.g. to conserve memory, providing a mechanism to parse an input document that would otherwise be too large to fit
    into memory, yet still providing a DOM interface to the document and its elements. Additionally, the parser provides
    a selectFirst(String query) / selectNext(String query), which will run the parser until a hit is found, at which
    point the parse is suspended. It can be resumed via another select() call, or via the stream() or iterator()
    methods. 2096
  • Download Progress: added a Response Progress event interface, which reports progress and URLs are downloaded (and
    parsed). Supported on both a session and a single connection
    level. 2164, 656
  • Added Path accepting parse methods: Jsoup.parse(Path), Jsoup.parse(path, charsetName, baseUri, parser),
    etc. 2055
  • Updated the button tag configuration to include a space between multiple button elements in the Element.text()
    method. 2105
  • Added support for the ns|* all elements in namespace Selector. 1811
  • When normalising attribute names during serialization, invalid characters are now replaced with _, vs being
    stripped. This should make the process clearer, and generally prevent an invalid attribute name being coerced
    unexpectedly. 2143

Changes

  • Removed previously deprecated internal classes and methods. 2094
  • Build change: the built jar's OSGi manifest no longer imports itself. 2158

Bug Fixes

  • When tracking source positions, if the first node was a TextNode, its position was incorrectly set
    to -1. 2106
  • When connecting (or redirecting) to URLs with characters such as {, } in the path, a Malformed URL exception would
    be thrown (if in development), or the URL might otherwise not be escaped correctly (if in
    production). The URL encoding process has been improved to handle these characters
    correctly. 2142
  • When using W3CDom with a custom output Document, a Null Pointer Exception would be
    thrown. 2114
  • The :has() selector did not match correctly when using sibling combinators (like
    e.g.: h1:has(+h2)). 2137
  • The :empty selector incorrectly matched elements that started with a blank text node and were followed by
    non-empty nodes, due to an incorrect short-circuit. 2130
  • Element.cssSelector() would fail with "Did not find balanced marker" when building a selector for elements that had
    a ( or [ in their class names. And selectors with those characters escaped would not match as
    expected. 2146
  • Updated Entities.escape(string) to make the escaped text suitable for both text nodes and attributes (previously was
    only for text nodes). This does not impact the output of Element.html() which correctly applies a minimal escape
    depending on if the use will be for text data or in a quoted
    attribute. 1278
  • Fuzz: a Stack Overflow exception could occur when resolving a crafted <base href> URL, in the normalizing regex.
    2165

jsoup Java HTML Parser release 1.17.2

29 Dec 03:29
@jhy jhy
9dec1ba
Compare
Choose a tag to compare

Improvements

  • Attribute object accessors: Added Element.attribute(String) and Attributes.attribute(String) to more simply
    obtain an Attribute object. 2069
  • Attribute source tracking: If source tracking is on, and an Attribute's key is changed (
    via Attribute.setKey(String)), the source range is now still tracked
    in Attribute.sourceRange(). 2070
  • Wildcard attribute selector: Added support for the [*] element with any attribute selector. And also restored
    support for selecting by an empty attribute name prefix ([^]). 2079

Bug Fixes

  • Mixed-cased source position: When tracking the source position of attributes, if the source attribute name was
    mix-cased but the parser was lower-case normalizing attribute names, the source position for that attribute was not
    tracked correctly. 2067
  • Source position NPE: When tracking the source position of a body fragment parse, a null pointer
    exception was thrown. 2068
  • Multi-point emoji entity: A multi-point encoded emoji entity may be incorrectly decoded to the replacement
    character. 2074
  • Selector sub-expressions: (Regression) in a selector like parent [attr=va], other, the , OR was binding
    to [attr=va] instead of parent [attr=va], causing incorrect selections. The fix includes a EvaluatorDebug class
    that generates a sexpr to represent the query, allowing simpler and more thorough query parse
    tests. 2073
  • XML CData output: When generating XML-syntax output from parsed HTML, script nodes containing (pseudo) CData
    sections would have an extraneous CData section added, causing script execution errors. Now, the data content is
    emitted in a HTML/XML/XHTML polyglot format, if the data is not already within a CData
    section. 2078
  • Thread safety: The :has evaluator held a non-thread-safe Iterator, and so if an Evaluator object was
    shared across multiple concurrent threads, a NoSuchElement exception may be thrown, and the selected results may be
    incorrect. Now, the iterator object is a thread-local. 2088

jsoup 1.17.1

27 Nov 02:57
@jhy jhy
8eecef3
Compare
Choose a tag to compare

jsoup 1.17.1 is out now with support for request-level authentication, attribute name & value source ranges, stream() iterable support, and a bunch of other improvements and bug fixes.

Many thanks to everyone who contributed to this release!

Improvements

  • Request-Level Authentication: Added support for request-level authentication in Jsoup.connect(), enabling authentication to proxies and servers. More.
  • XML OutputSettings: Automatically sets the xhtml EscapeMode as default when changing the OutputSettings syntax to XML.
  • is() Selector: Added the :is(selector list) pseudo-selector to find elements that match any selectors in the selector list. This enhances readability for large ORed selectors. More.
  • JPMS Module Support: Repackaged the library with native JPMS module support. More.
  • Source Position Fidelity: Improved fidelity of source positions when tracking is enabled. Implicitly created or closed elements are now trackable via Range.isImplicit(). More.
  • Attribute Source Positions: Enabled source position for attribute names and values when source tracking is on. Attribute#sourceRange() provides the ranges. More.
  • Virtual Threads: Enhanced performance under Java 21+ Virtual Threads by replacing the internal ConstrainableInputStream with ControllableInputStream. More.
  • XML Mimetype Support: Extended XML mimetype support in Jsoup.connect() to include any XML mimetype. More.

Bug Fixes

  • XML Data Nodes: Fixed a bug where HTML elements parsed as data nodes were not correctly emitted as CDATA nodes when outputting with XML syntax. More.
  • Immediate Parent Selector: Corrected a bug where the Immediate Parent selector > could match elements above the root context element. More.
  • Sub-Query Parsing: Resolved a bug where combinators following the , Or combinator in a sub-query were incorrectly skipped. More.
  • Empty Doctype: Fixed a bug in W3CDom where the conversion would fail if the jsoup input document contained an empty doctype. The doctype is now discarded, and the conversion continues.
  • SVG Elements Cleaning: Fixed incorrect nesting when cleaning a document containing SVG elements or other foreign elements with preserved-case names. More.
  • Unknown Self-Closing Tags: Preserved the output style of unknown self-closing tags from the input when cleaning a document. More.

Build Improvements

  • Local Test Proxy: Added a local test proxy implementation for proxy integration tests. More.
  • HTTPS Request Tests: Added tests for HTTPS request support using a local self-signed certificate. Includes proxy tests. More.

Changes

jsoup 1.16.2

20 Oct 05:48
@jhy jhy
db6dc74
Compare
Choose a tag to compare

Improvements

  • Optimized the performance of complex CSS selectors, by adding a cost-based query planner. Evaluators are sorted by their relative execution cost, and executed in order of lower to higher cost. This speeds the matching process by ensuring that simpler evaluations (such as a tag name match) are conducted prior to more complex evaluations (such as an attribute regex, or a deep child scan with a :has).
  • Added support for <svg> and <math> tags (and their children). This includes tag namespaces and case preservation on applicable tags and attributes. #2008
  • When converting jsoup Documents to W3C Documents in W3CDom, HTML documents will be placed in the http://www.w3.org/1999/xhtml namespace by default, per the HTML5 spec. This can be controlled by setting W3CDom#namespaceAware(boolean false). #1848
  • Speed optimized the Structural Evaluators by memoizing previous evaluations. Particularly the ~ (any preceding sibling) and :nth-of-type selectors are improved. #1956
  • Tweaked the performance of the Element nextElementSibling, previousElementSibling, firstElementSibling, lastElementSibling, firstElementChild, and `lastElementChild. They now inplace filter/skip in the child-node list, vs having to allocate and scan a complete Element filtered list.
  • Optimized internal methods that previously called Element.children() to use filter/skip child-node list accessors instead, reducing new Element List allocations.
  • Tweaked the performance of parsing :pseudo selectors.
  • When using the :empty pseudo-selector, blank textnodes are now considered empty. Previously, an element containing any whitespace was not considered empty. #1976
  • In forms, <input type="image"> should be excluded from Element.formData() (and hence from form submissions). #2010
  • In Safelist, made isSafeTag() and isSafeAttribute() public methods, for extensibility. #1780

Bug Fixes

  • Bugfix: form elements and empty elements (such as img) did not have their attributes de-duplicated. #1950
  • In Jsoup.connect(String url), URL paths containing a %2B were incorrectly recoded to a '+', or a '+' was recoded to a ' '. Fixed by reverting to the previous behavior of not encoding supplied paths, other than normalizing to ASCII. #1952
  • In Jsoup.connect(String url), the ConstrainableInputStream would clear Thread interrupts when reading the body. This precluded callers from spawning a thread, running a number of requests for a length of time, then joining that thread after interrupting it. #1991
  • When tracking HTML source positions, the closing tags for H1...H6 elements were not tracked correctly. #1987
  • When calling Element.cssSelector() on an extremely deeply nested element, a StackOverflowError could occur. Further, a StackOverflowError may occur when running the query. #2001
  • Appending a node back to its original Element after empty() would throw an Index out of bounds exception. Also, now the child nodes that were removed have their parent node cleared, fully detaching them from the original parent. #2013
  • In Connection when adding headers, the value may have been assumed to be an incorrectly decoded ISO_8859_1 string, and re-encoded as UTF-8. The value is now left as-is.

Changes

  • Removed previously deprecated methods Document.normalise(), Element.forEach(org.jsoup.helper.Consumer<>), Node.forEach(org.jsoup.helper.Consumer<>), and the org.jsoup.helper.Consumer interface; the latter being a previously required compatibility shim prior to Android's de-sugaring support.
  • The previous compatibility shim org.jsoup.UncheckedIOException is deprecated in favor of the now supported java.io.UncheckedIOException. If you are catching the former, modify your code to catch the latter instead. #1989
  • Blocked noscript tags from being added to Safelists, due to incompatibilities between parsers with and without script-mode enabled.

jsoup 1.16.1

29 Apr 06:32
@jhy jhy
062ebdb
Compare
Choose a tag to compare

jsoup Java HTML Parser release 1.16.1

Improvements

  • In Jsoup.connect(String url), natively support URLs with Unicode characters in the path or query string, without having to be escaped by the caller. #1914
  • Calling Node.remove() on a node with no parent is now a no-op, vs a validation error. #1898

Bug Fixes

  • Aligned the HTML Tree Builder processing steps for AfterBody and AfterAfterBody to the updated WHATWG standard, to not pop the stack to close <body> or <html> elements. This prevents an errant </html> closing the preceding structure. Also added appropriate error message outputs in this case. #1851
  • Corrected support for ruby elements (<ruby>, <rp>, <rt>, and <rtc>) to current spec. #1294
  • In Jsoup.connect(String url), if the input URL had components that were already % escaped, they would be escaped again, causing errors when fetched. #1902
  • When tracking input source positions, text in tables that was fostered had invalid positions. #1927
  • When pretty-printing, the first inline Element or Comment in a block would not be wrap-indented if it were preceded by a blank text node. #1906
  • When pretty-printing a <pre> containing block tags, those tags were incorrectly indented. #1891
  • When pretty-printing nested inlineable blocks (such as a <p> in a <td>), the inner element should be indented. #1926
  • <br> tags should be wrap-indented when in block tags (and not when in inline tags). #1911
  • The contents of a sufficiently large <textarea> with un-escaped HTML closing tags may be incorrectly parsed to an empty node. #1929

jsoup 1.15.4

18 Feb 01:46
@jhy jhy
becdd2e
Compare
Choose a tag to compare

jsoup Java HTML Parser release 1.15.4

jsoup 1.15.4 is out now, and includes a bunch of improvements, particularly when pretty-printing HTML, and bug fixes.

jsoup is a Java library for working with real-world HTML. It provides a very convenient API for extracting and manipulating data, using the best of HTML5 DOM methods and CSS selectors.

Download jsoup now.

Improvements

  • Added the ability to escape CSS selectors (tags, IDs, classes) to match elements that don't follow regular CSS syntax. For example, to match by classname <p class="one.two">, use document.select("p.one\\.two"); #838
  • When pretty-printing, wrap text that follows a <br> tag. #1858
  • When pretty-printing, normalize newlines that follow self-closing tags in custom tags. #1852
  • When pretty-printing, collapse non-significant whitespace between a block and an inline tag. #1802
  • Added a new method Document.forms(), to conveniently retrieve a List<FormElement> containing the <form> elements in a document.

Bug Fixes

  • URLs containing characters such as and <code> were not escaped correctly, and would throw a MalformedURLException when fetched. #1873
  • Element.cssSelector() would create invalid selectors for elements where the tag name, ID, or classnames needed to be escaped (e.g. if a class name contained a : or .). #1742
  • If a Node or an Element was replaced with itself, that node would incorrectly be orphaned. #1843
  • Form data on a previous request was copied to a new request in newRequest(), resulting in an accumulation of form data when executing multi-step form submissions, or data sent to later requests incorrectly. Now, newRequest() only copies session related settings (cookies, proxy settings, user-agent, etc) but not the request data nor the body. #1778
  • Fixed an issue in Safelist.removeAttributes() which could throw a ConcurrentModificationException when using the :all pseudo-attribute.
  • Given extremely deeply nested HTML, a number of methods in Element could throw a StackOverflowError due to excessive recursion. Namely: #data(), #hasText(), #parents(), and #wrap(html). #1864

Changes

  • Deprecated the unused Document.normalise() method. Normalization occurs during the HTML tree construction, and no longer as a distinct phase.


My sincere thanks to everyone who contributed patches, suggestions, and bug reports. If you have any suggestions for the next release, I would love to hear them; please get in touch with me directly.

You can also follow me (@[email protected]) on Mastodon / Fediverse to receive occasional notes about jsoup releases.

jsoup 1.15.3

24 Aug 00:49
@jhy jhy
c596417
Compare
Choose a tag to compare

jsoup 1.15.3 is out now, and includes a security fix for potential XSS attacks, along with other bug fixes and improvements, including more descriptive validation error messages.

Details: