Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# jsoup Changelog

## 1.24.1 (Pending)

### Changes
* Removed APIs previously deprecated and scheduled for removal in 1.24.1. [#2597](https://github.com/jhy/jsoup/pull/2597)

### Bug Fixes
* Standardized parser normalization of tag and attribute names so that HTML comparisons use ASCII-only case folding, and accepted control characters are preserved, aligning name handling to the HTML and XML specs. [#2594](https://github.com/jhy/jsoup/issues/2594)
* Named character references without a semicolon before `-` or `_` now decode correctly in attribute values, matching HTML and browser behavior (e.g., `&copy-` becomes `©-`). [#2588](https://github.com/jhy/jsoup/issues/2588)

## 1.23.2 (2026-Aug-26)

### Improvements
Expand Down Expand Up @@ -150,7 +159,7 @@
### Changes

* Removed previously deprecated methods. [#2317](https://github.com/jhy/jsoup/pull/2317)
* Deprecated the `:matchText` pseduo-selector due to its side effects on the DOM; use the new `::textnode` selector and the `Element#selectNodes(String css, Class type)` method instead. [#2343](https://github.com/jhy/jsoup/pull/2343)
* Deprecated the `:matchText` pseduo-selector due to its side effects on the DOM; use the new `::text` selector and the `Element#selectNodes(String css, Class type)` method instead. [#2343](https://github.com/jhy/jsoup/pull/2343)
* Deprecated `Connection.Response#bufferUp()` in lieu of `Connection.Response#readFully()` which can throw a checked IOException.
* Deprecated internal methods `Validate#ensureNotNull` (replaced by typed `Validate#expectNotNull`); protected HTML appenders from Attribute and Node.
* If you happen to be using any of the deprecated methods, please take the opportunity now to migrate away from them, as they will be removed in a future release.
Expand Down
9 changes: 7 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -318,15 +318,20 @@
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.23.1</version>
<version>1.23.2</version>
<type>jar</type>
</dependency>
</oldVersion>
<parameter>
<!-- jsoup policy is ok to remove deprecated methods on minor but not builds. will need to temp remove on bump to 1.15.1 and manually validate -->
<onlyModified>false</onlyModified>
<breakBuildOnBinaryIncompatibleModifications>true</breakBuildOnBinaryIncompatibleModifications>
<breakBuildOnSourceIncompatibleModifications>true</breakBuildOnSourceIncompatibleModifications>
<excludes>
<!-- Internal APIs are explicitly unsupported and may change between releases. -->
<exclude>org.jsoup.internal.*</exclude>
<!-- Temporarily allow removals deprecated before 1.24.1. -->
<exclude>@java.lang.Deprecated</exclude>
</excludes>
<overrideCompatibilityChangeParameters>
<!-- allows new default and move to default methods. compatible as long as existing binaries aren't making calls via reflection. if so, they need to catch errors anyway. -->
<overrideCompatibilityChangeParameter>
Expand Down
37 changes: 0 additions & 37 deletions src/main/java/org/jsoup/Connection.java
Original file line number Diff line number Diff line change
Expand Up @@ -210,19 +210,6 @@ default Connection newRequest(URL url) {
*/
Connection ignoreContentType(boolean ignoreContentType);

/**
Set a custom SSL socket factory for HTTPS connections.
<p>Note: if set, the legacy <code>HttpURLConnection</code> will be used instead of the JVM's
<code>HttpClient</code>.</p>

@param sslSocketFactory SSL socket factory
@return this Connection, for chaining
@see #sslContext(SSLContext)
@deprecated use {@link #sslContext(SSLContext)} instead; will be removed in jsoup 1.24.1.
*/
@Deprecated
Connection sslSocketFactory(SSLSocketFactory sslSocketFactory);

/**
Set a custom SSL context for HTTPS connections.
<p>Note: when using the legacy <code>HttpURLConnection</code>, only the <code>SSLSocketFactory</code> from the
Expand Down Expand Up @@ -790,18 +777,6 @@ interface Request extends Base<Request> {
*/
@Nullable SSLSocketFactory sslSocketFactory();

/**
Set a custom SSL socket factory for HTTPS connections.
<p>Note: if set, the legacy <code>HttpURLConnection</code> will be used instead of the JVM's
<code>HttpClient</code>.</p>

@param sslSocketFactory SSL socket factory
@see #sslContext(SSLContext)
@deprecated use {@link #sslContext(SSLContext)} instead; will be removed in jsoup 1.24.1.
*/
@Deprecated
void sslSocketFactory(SSLSocketFactory sslSocketFactory);

/**
Get the current custom SSL context, if any.

Expand Down Expand Up @@ -1030,18 +1005,6 @@ default Response readFully() throws IOException {
throw new UnsupportedOperationException();
}

/**
* Read the body of the response into a local buffer, so that {@link #parse()} may be called repeatedly on the
* same connection response. Otherwise, once the response is read, its InputStream will have been drained and
* may not be re-read.
* <p>Calling {@link #body() } or {@link #bodyAsBytes()} has the same effect.</p>
* @return this response, for chaining
* @throws UncheckedIOException if an IO exception occurs during buffering.
* @deprecated use {@link #readFully()} instead (for the checked exception). Will be removed in jsoup 1.24.1.
*/
@Deprecated
Response bufferUp();

/**
Get the body of the response as a (buffered) InputStream. You should close the input stream when you're done
with it.
Expand Down
20 changes: 0 additions & 20 deletions src/main/java/org/jsoup/helper/HttpConnection.java
Original file line number Diff line number Diff line change
Expand Up @@ -224,13 +224,6 @@ public Connection data(String key, String value) {
return this;
}

@Override
@Deprecated
public Connection sslSocketFactory(SSLSocketFactory sslSocketFactory) {
req.sslSocketFactory(sslSocketFactory);
return this;
}

@Override
public Connection sslContext(SSLContext sslContext) {
req.sslContext(sslContext);
Expand Down Expand Up @@ -735,12 +728,6 @@ public SSLSocketFactory sslSocketFactory() {
return sslSocketFactory;
}

@Override
@Deprecated
public void sslSocketFactory(SSLSocketFactory sslSocketFactory) {
this.sslSocketFactory = sslSocketFactory;
}

@Override @Nullable
public SSLContext sslContext() {
return sslContext;
Expand Down Expand Up @@ -1149,13 +1136,6 @@ public byte[] bodyAsBytes() {
}
}

@Override
@Deprecated
public Connection.Response bufferUp() {
readByteDataUnchecked();
return this;
}

@Override
public BufferedInputStream bodyStream() {
Validate.isTrue(executed, "Request must be executed (with .execute(), .get(), or .post() before getting response body");
Expand Down
32 changes: 0 additions & 32 deletions src/main/java/org/jsoup/helper/Validate.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,38 +42,6 @@ public static void notNull(@Nullable Object obj, String msg) {
throw new ValidationException(msg);
}

/**
Verifies the input object is not null, and returns that object. Effectively this casts a nullable object to a non-
null object. (Works around lack of Objects.requestNonNull in Android version.)
* @param obj nullable object to cast to not-null
* @return the object, or throws an exception if it is null
* @throws ValidationException if the object is null
* @deprecated prefer to use {@link #expectNotNull(Object, String, Object...)} instead; will be removed in jsoup 1.24.1
*/
@Deprecated
public static Object ensureNotNull(@Nullable Object obj) {
if (obj == null)
throw new ValidationException("Object must not be null");
else return obj;
}

/**
Verifies the input object is not null, and returns that object. Effectively this casts a nullable object to a non-
null object. (Works around lack of Objects.requestNonNull in Android version.)
* @param obj nullable object to cast to not-null
* @param msg the String format message to include in the validation exception when thrown
* @param args the arguments to the msg
* @return the object, or throws an exception if it is null
* @throws ValidationException if the object is null
* @deprecated prefer to use {@link #expectNotNull(Object, String, Object...)} instead; will be removed in jsoup 1.24.1
*/
@Deprecated
public static Object ensureNotNull(@Nullable Object obj, String msg, Object... args) {
if (obj == null)
throw new ValidationException(String.format(msg, args));
else return obj;
}

/**
Verifies the input object is not null, and returns that object, maintaining its type. Effectively this casts a
nullable object to a non-null object.
Expand Down
42 changes: 0 additions & 42 deletions src/main/java/org/jsoup/internal/Functions.java

This file was deleted.

49 changes: 28 additions & 21 deletions src/main/java/org/jsoup/internal/Normalizer.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,48 @@

import org.jsoup.nodes.Attribute;
import org.jsoup.nodes.Document;
import org.jspecify.annotations.Nullable;

import java.util.Locale;

/**
* Util methods for normalizing strings. Jsoup internal use only, please don't depend on this API.
* <p>ASCII case conversion changes only A-Z; Unicode conversion uses {@link Locale#ROOT}.
* Neither trims, and the string lowercasing methods return an empty string for null input.</p>
*/
public final class Normalizer {

/** Drops the input string to lower case. */
public static String lowerCase(final String input) {
/** Lowercases Unicode text. */
public static String lowerCase(final @Nullable String input) {
return input != null ? input.toLowerCase(Locale.ROOT) : "";
}

/** Lower-cases and trims the input string. */
public static String normalize(final String input) {
return lowerCase(input).trim();
/** Lowercases ASCII letters. */
public static String asciiLowerCase(final @Nullable String input) {
if (input == null) return "";
char[] chars = null;
for (int i = 0; i < input.length(); i++) {
char c = input.charAt(i);
char lower = asciiLowerCase(c);
if (c != lower) {
if (chars == null) chars = input.toCharArray(); // set up on first change
chars[i] = lower;
}
}
return chars == null ? input : new String(chars);
}

/**
If a string literal, just lower case the string; otherwise lower-case and trim.
@deprecated internal helper; replace with {@link #lowerCase(String)} for no-trim, or {@link #normalize(String)} for trim + lowercase.
Will be removed in jsoup 1.24.1.
*/
@Deprecated
public static String normalize(final String input, boolean isStringLiteral) {
return isStringLiteral ? lowerCase(input) : normalize(input);
/** Lowercases an ASCII letter. */
public static char asciiLowerCase(char c) {
return c >= 'A' && c <= 'Z' ? (char) (c + ('a' - 'A')) : c;
}

/**
* Gets an XML-safe tag name.
* @deprecated Internal helper; use {@link Attribute#getValidKey(String, Document.OutputSettings.Syntax)}.
* Will be removed in jsoup 1.24.1.
*/
@Deprecated
public static String xmlSafeTagName(final String tagName) {
return Attribute.getValidKey(tagName, Document.OutputSettings.Syntax.xml);
/** Compares strings ignoring ASCII case. */
public static boolean equalsIgnoreAsciiCase(String first, @Nullable String second) {
if (second == null || first.length() != second.length()) return false;
for (int i = 0; i < first.length(); i++) {
if (asciiLowerCase(first.charAt(i)) != asciiLowerCase(second.charAt(i))) return false;
}
return true;
}
}
6 changes: 0 additions & 6 deletions src/main/java/org/jsoup/internal/SharedConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,6 @@
*/
public final class SharedConstants {
public static final String UserDataKey = "/jsoup.userdata";
/** @deprecated Internal source ranges now use {@link #RangeSpansKey}. */
@Deprecated public final static String AttrRangeKey = "jsoup.attrs";
/** @deprecated Internal source ranges now use {@link #RangeSpansKey}. */
@Deprecated public static final String RangeKey = "jsoup.start";
/** @deprecated Internal source ranges now use {@link #RangeSpansKey}. */
@Deprecated public static final String EndRangeKey = "jsoup.end";
public static final String RangeSpansKey = "/jsoup.spans";
public static final String XmlnsAttr = "jsoup.xmlns-";

Expand Down
8 changes: 8 additions & 0 deletions src/main/java/org/jsoup/internal/StringUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,14 @@ public static boolean isNumeric(String string) {
return true;
}

/** Trims leading and trailing ASCII whitespace. */
public static String trimAsciiWhitespace(String input) {
int start = 0, end = input.length();
while (start < end && isWhitespace(input.charAt(start))) start++;
while (end > start && isWhitespace(input.charAt(end - 1))) end--;
return input.substring(start, end);
}

/**
* Tests if a code point is "whitespace" as defined in the HTML spec. Used for output HTML.
* @param c code point to test
Expand Down
Loading