Repository: jhy/jsoup
Pull request #1925 (2023-03-27 23:56:48)

Bump maven-resources-plugin from 3.3.0 to 3.3.1
Bumps [maven-resources-plugin](https://github.com/apache/maven-resources-plugin) from 3.3.0 to 3.3.1.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/apache/maven-resources-plugin/releases">maven-resources-plugin's releases</a>.</em></p>
<blockquote>
<h2>3.3.1</h2>
<!-- raw HTML omitted -->
<ul>
<li><a href="https://issues.apache.org/jira/browse/MRESOURCES-288">[MRESOURCES-288]</a> - Make tests-jar reproducible (<a href="https://redirect.github.com/apache/maven-resources-plugin/pull/56">#56</a>) <a href="https://github.com/cstamas"><code>@​cstamas</code></a></li>
<li><a href="https://issues.apache.org/jira/browse/MRESOURCES-297">[MRESOURCES-297]</a> - Update to parent POM 39, reformat (<a href="https://redirect.github.com/apache/maven-resources-plugin/pull/55">#55</a>) <a href="https://github.com/cstamas"><code>@​cstamas</code></a></li>
<li><a href="https://issues.apache.org/jira/browse/MRESOURCES-293">[MRESOURCES-293]</a> - Make resources param not read-only (<a href="https://redirect.github.com/apache/maven-resources-plugin/pull/54">#54</a>) <a href="https://github.com/cstamas"><code>@​cstamas</code></a></li>
<li><a href="https://issues.apache.org/jira/browse/MRESOURCES-295">[MRESOURCES-295]</a> - Drop Plexus legacy code (<a href="https://redirect.github.com/apache/maven-resources-plugin/pull/53">#53</a>) <a href="https://github.com/cstamas"><code>@​cstamas</code></a></li>
<li><a href="https://issues.apache.org/jira/browse/MRESOURCES-294">[MRESOURCES-294]</a> - Upgrade plexus-utils to 3.5.1 (<a href="https://redirect.github.com/apache/maven-resources-plugin/pull/52">#52</a>) <a href="https://github.com/slachiewicz"><code>@​slachiewicz</code></a></li>
</ul>
<h2>🚨 Removed</h2>
<ul>
<li>remove specific IDE m2e files (<a href="https://redirect.github.com/apache/maven-resources-plugin/pull/40">#40</a>) <a href="https://github.com/olamy"><code>@​olamy</code></a></li>
</ul>
<h2>📦 Dependency updates</h2>
<ul>
<li>Bump apache/maven-gh-actions-shared from 2 to 3 (<a href="https://redirect.github.com/apache/maven-resources-plugin/pull/46">#46</a>) <a href="https://github.com/dependabot"><code>@​dependabot</code></a></li>
</ul>
<h2>📝 Documentation updates</h2>
<ul>
<li>doc: adds alternative variable syntax using @ delimiters to the documentation (<a href="https://redirect.github.com/apache/maven-resources-plugin/pull/36">#36</a>) <a href="https://github.com/kevin0x90"><code>@​kevin0x90</code></a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/apache/maven-resources-plugin/commit/978ce1e9a1f4fb60d384a998a6ea473a21bb81d5"><code>978ce1e</code></a> [maven-release-plugin] prepare release maven-resources-plugin-3.3.1</li>
<li><a href="https://github.com/apache/maven-resources-plugin/commit/b7cd080d7ba98e5cefe58b1ef78c209cad8ae0fe"><code>b7cd080</code></a> [MRESOURCES-296] Upgrade to maven-filtering 3.3.1</li>
<li><a href="https://github.com/apache/maven-resources-plugin/commit/1c9f610d5c2866fdd7fad182709f4dff2e157787"><code>1c9f610</code></a> [MRESOURCES-288] Make tests-jar reproducible (<a href="https://redirect.github.com/apache/maven-resources-plugin/issues/56">#56</a>)</li>
<li><a href="https://github.com/apache/maven-resources-plugin/commit/1946127aac4acb752fd3018dff8c7751434d6ca7"><code>1946127</code></a> [MRESOURCES-293] Rollback</li>
<li><a href="https://github.com/apache/maven-resources-plugin/commit/f7a6f229db49673ddd21ff521027b9af49f69bb8"><code>f7a6f22</code></a> [MRESOURCES-297] Update to parent POM 39, reformat (<a href="https://redirect.github.com/apache/maven-resources-plugin/issues/55">#55</a>)</li>
<li><a href="https://github.com/apache/maven-resources-plugin/commit/22d64ca56ed38b6e8dd5af7df0d5edb230d6fb86"><code>22d64ca</code></a> remove specific IDE m2e files (<a href="https://redirect.github.com/apache/maven-resources-plugin/issues/40">#40</a>)</li>
<li><a href="https://github.com/apache/maven-resources-plugin/commit/02c2d010acfaae652bd69f447328ce14287cfbd4"><code>02c2d01</code></a> [MRESOURCES-293] Make resources param not read-only (<a href="https://redirect.github.com/apache/maven-resources-plugin/issues/54">#54</a>)</li>
<li><a href="https://github.com/apache/maven-resources-plugin/commit/6bb3e1ffb767eb00f8ebac7dadd64bc090ee3e44"><code>6bb3e1f</code></a> [MRESOURCES-295] Drop Plexus legacy code (<a href="https://redirect.github.com/apache/maven-resources-plugin/issues/53">#53</a>)</li>
<li><a href="https://github.com/apache/maven-resources-plugin/commit/df7e17212980dfd079024cb7cfdafc1a469f106b"><code>df7e172</code></a> [MRESOURCES-294] Upgrade plexus-utils to 3.5.1</li>
<li><a href="https://github.com/apache/maven-resources-plugin/commit/9354ecd248302c42be4f0822fa1c32b202a50947"><code>9354ecd</code></a> Bump apache/maven-gh-actions-shared from 2 to 3</li>
<li>Additional commits viewable in <a href="https://github.com/apache/maven-resources-plugin/compare/maven-resources-plugin-3.3.0...maven-resources-plugin-3.3.1">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.apache.maven.plugins:maven-resources-plugin&package-manager=maven&previous-version=3.3.0&new-version=3.3.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)


</details>


Patch:
diff --git a/CHANGES b/CHANGES
index b4cc2723..b6770a21 100644
--- a/CHANGES
+++ b/CHANGES
@@ -24,6 +24,9 @@ Release 1.16.1 [PENDING]
     again, causing errors when fetched.
     <https://github.com/jhy/jsoup/issues/1902>
 
+  * Bugfix: when tracking input source positions, text in tables that was fostered had invalid positions.
+    <https://github.com/jhy/jsoup/issues/1927>
+
   * Bugfix: If the Document.OutputSettings class was initialized, and then Entities.escape(String) called, an NPE may be
     thrown due to a class loading circular dependency.
     <https://github.com/jhy/jsoup/issues/1910>
diff --git a/pom.xml b/pom.xml
index 62bf6d6c..926acecd 100644
--- a/pom.xml
+++ b/pom.xml
@@ -164,7 +164,7 @@
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-resources-plugin</artifactId>
-        <version>3.3.0</version>
+        <version>3.3.1</version>
       </plugin>
       <plugin>
         <artifactId>maven-release-plugin</artifactId>
diff --git a/src/main/java/org/jsoup/parser/HtmlTreeBuilder.java b/src/main/java/org/jsoup/parser/HtmlTreeBuilder.java
index 9de525b6..06e9c749 100644
--- a/src/main/java/org/jsoup/parser/HtmlTreeBuilder.java
+++ b/src/main/java/org/jsoup/parser/HtmlTreeBuilder.java
@@ -53,7 +53,7 @@ public class HtmlTreeBuilder extends TreeBuilder {
     private @Nullable Element contextElement; // fragment parse context -- could be null even if fragment parsing
     private ArrayList<Element> formattingElements; // active (open) formatting elements
     private ArrayList<HtmlTreeBuilderState> tmplInsertMode; // stack of Template Insertion modes
-    private List<String> pendingTableCharacters; // chars in table to be shifted out
+    private List<Token.Character> pendingTableCharacters; // chars in table to be shifted out
     private Token.EndTag emptyEnd; // reused empty end tag
 
     private boolean framesetOk; // if ok to go into frameset
@@ -676,14 +676,20 @@ public class HtmlTreeBuilder extends TreeBuilder {
         this.formElement = formElement;
     }
 
-    void newPendingTableCharacters() {
+    void resetPendingTableCharacters() {
         pendingTableCharacters = new ArrayList<>();
     }
 
-    List<String> getPendingTableCharacters() {
+    List<Token.Character> getPendingTableCharacters() {
         return pendingTableCharacters;
     }
 
+    void addPendingTableCharacters(Token.Character c) {
+        // make a clone of the token to maintain its state (as Tokens are otherwise reset)
+        Token.Character clone = c.clone();
+        pendingTableCharacters.add(clone);
+    }
+
     /**
      13.2.6.3 Closing elements that have implied end tags
      When the steps below require the UA to generate implied end tags, then, while the current node is a dd element, a dt element, an li element, an optgroup element, an option element, a p element, an rb element, an rp element, an rt element, or an rtc element, the UA must pop the current node off the stack of open elements.
diff --git a/src/main/java/org/jsoup/parser/HtmlTreeBuilderState.java b/src/main/java/org/jsoup/parser/HtmlTreeBuilderState.java
index 99edf8ce..3c5352ec 100644
--- a/src/main/java/org/jsoup/parser/HtmlTreeBuilderState.java
+++ b/src/main/java/org/jsoup/parser/HtmlTreeBuilderState.java
@@ -6,7 +6,6 @@ import org.jsoup.nodes.Attributes;
 import org.jsoup.nodes.Document;
 import org.jsoup.nodes.DocumentType;
 import org.jsoup.nodes.Element;
-import org.jsoup.nodes.Node;
 
 import java.util.ArrayList;
 
@@ -995,7 +994,7 @@ enum HtmlTreeBuilderState {
     InTable {
         boolean process(Token t, HtmlTreeBuilder tb) {
             if (t.isCharacter() && inSorted(tb.currentElement().normalName(), InTableFoster)) {
-                tb.newPendingTableCharacters();
+                tb.resetPendingTableCharacters();
                 tb.markInsertionMode();
                 tb.transition(InTableText);
                 return tb.process(t);
@@ -1106,25 +1105,25 @@ enum HtmlTreeBuilderState {
                     tb.error(this);
                     return false;
                 } else {
-                    tb.getPendingTableCharacters().add(c.getData());
+                    tb.addPendingTableCharacters(c);
                 }
-            } else {// todo - don't really like the way these table character data lists are built
+            } else {
                 if (tb.getPendingTableCharacters().size() > 0) {
-                    for (String character : tb.getPendingTableCharacters()) {
-                        if (!isWhitespace(character)) {
+                    for (Token.Character c : tb.getPendingTableCharacters()) {
+                        if (!isWhitespace(c)) {
                             // InTable anything else section:
                             tb.error(this);
                             if (inSorted(tb.currentElement().normalName(), InTableFoster)) {
                                 tb.setFosterInserts(true);
-                                tb.process(new Token.Character().data(character), InBody);
+                                tb.process(c, InBody);
                                 tb.setFosterInserts(false);
                             } else {
-                                tb.process(new Token.Character().data(character), InBody);
+                                tb.process(c, InBody);
                             }
                         } else
-                            tb.insert(new Token.Character().data(character));
+                            tb.insert(c);
                     }
-                    tb.newPendingTableCharacters();
+                    tb.resetPendingTableCharacters();
                 }
                 tb.transition(tb.originalState());
                 return tb.process(t);
@@ -1759,10 +1758,6 @@ enum HtmlTreeBuilderState {
         return false;
     }
 
-    private static boolean isWhitespace(String data) {
-        return StringUtil.isBlank(data);
-    }
-
     private static void handleRcData(Token.StartTag startTag, HtmlTreeBuilder tb) {
         tb.tokeniser.transition(TokeniserState.Rcdata);
         tb.markInsertionMode();
diff --git a/src/main/java/org/jsoup/parser/Token.java b/src/main/java/org/jsoup/parser/Token.java
index 819b8aef..b0fc0af8 100644
--- a/src/main/java/org/jsoup/parser/Token.java
+++ b/src/main/java/org/jsoup/parser/Token.java
@@ -382,7 +382,7 @@ abstract class Token {
         }
     }
 
-    static class Character extends Token {
+    static class Character extends Token implements Cloneable {
         private String data;
 
         Character() {
@@ -410,6 +410,14 @@ abstract class Token {
         public String toString() {
             return getData();
         }
+
+        @Override protected Token.Character clone() {
+            try {
+                return (Token.Character) super.clone();
+            } catch (CloneNotSupportedException e) {
+                throw new RuntimeException(e);
+            }
+        }
     }
 
     final static class CData extends Character {


Test patch:
diff --git a/src/test/java/org/jsoup/nodes/PositionTest.java b/src/test/java/org/jsoup/nodes/PositionTest.java
index 813ed9b3..78df6fbb 100644
--- a/src/test/java/org/jsoup/nodes/PositionTest.java
+++ b/src/test/java/org/jsoup/nodes/PositionTest.java
@@ -3,9 +3,12 @@ package org.jsoup.nodes;
 import org.jsoup.Jsoup;
 import org.jsoup.integration.servlets.FileServlet;
 import org.jsoup.parser.Parser;
+import org.jsoup.select.NodeTraversor;
 import org.junit.jupiter.api.Test;
 
 import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
 
 import static org.junit.jupiter.api.Assertions.*;
 
@@ -169,4 +172,23 @@ class PositionTest {
         assertEquals("17,5:779-17,12:786", item.endSourceRange().toString());
     }
 
+    @Test void tracksTableMovedText() {
+        String html = "<table>foo<tr>bar<td>baz</td>qux</tr>coo</table>";
+        Document doc = Jsoup.parse(html, TrackingParser);
+
+        List<TextNode> textNodes = new ArrayList<>();
+        NodeTraversor.traverse((Node node, int depth) -> {
+            if (node instanceof TextNode) {
+                textNodes.add((TextNode) node);
+            }
+        }, doc);
+
+        assertEquals(5, textNodes.size());
+        assertEquals("1,8:7-1,11:10", textNodes.get(0).sourceRange().toString());
+        assertEquals("1,15:14-1,18:17", textNodes.get(1).sourceRange().toString());
+        assertEquals("1,22:21-1,25:24", textNodes.get(2).sourceRange().toString());
+        assertEquals("1,30:29-1,33:32", textNodes.get(3).sourceRange().toString());
+        assertEquals("1,38:37-1,41:40", textNodes.get(4).sourceRange().toString());
+    }
+
 }
\ No newline at end of file