-
Notifications
You must be signed in to change notification settings - Fork 2.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
StackOverflowError: Element.data()
is executed recursively without checks
#1864
Comments
Hi @biecho, I tested package org.jsoup.examples;
import org.jsoup.nodes.Element;
public class ElementTest {
public static void main(String[] args) {
Element element = new Element("elem");
Element root = element;
for (int i = 0; i < 100000; i++) {
Element elem2 = new Element("elem"+i);
element.appendChild(elem2);
element = elem2;
System.out.println(element.tagName());
}
System.out.println(root.data());;
}
}
I am not sure if this case will occur in real html, but I agree with you that iterative approach would be better. |
Makes sense, and would be happy to review a PR. Have you encountered this in the wild? |
Thanks for fixing the issue! Yes, this was encountered in the wild. It might be worth to add a test case just to be on the safe side. |
Testcase for #1864 and related -- hasText, data, parents could all overflow.
Removes chance of overflow in wrap(html) and simplifies. Related to #1864
With the above changes, there are no more recursive calls that could conceivably overflow, that I can find. The two remaining are bound. In HttpConnection, the execute method recurses to follow redirects, but that's bound already so we don't bounce between redirected URLs forever.
And in SafeList, the recursion in isSafeAttribute is only one level deep.
|
Awesome! Thank you! |
Hi there,
The implementation of the
Element.data()
function listed below is executed recursively in an unsafe manner.The recursion is not checked for depth and can lead to a
StackOverflowError
if there are enough nested children.I suggest to handle this case similar to
Element.text()
where aNodeTraversor
is used to compute the result iteratively.Another approach could be something along the lines:
The text was updated successfully, but these errors were encountered: