Re: [Htmlparser-user] Endless recursion bug in toHtml() ?
Brought to you by:
derrickoswald
|
From: Derrick O. <Der...@Ro...> - 2006-04-13 03:44:25
|
Bram,
The mini <A/> tag in your test case is considered a content-less XML
tag (see isEmptyXmlTag() in TagNode).
This causes the parser to set the end tag reference to be the start tag
- this is done so that there will always be an end tag, which may be a
bad design decision, but it was thought to be better than inventing a
non-existent tag, or returning null.
When you add an HREF attribute in this case, the only attribute (the tag
name with the slash) is no longer the last attribute and hence
isEmptyXmlTag returns false, but the end tag reference is still pointing
to the start tag, which causes the recursion.
I guess the add attribute code could be smarter and detect this
pathological situation, but I'm wondering if that's the real solution or
just a band-aid.
Was this discovered in the wild? Why is the XML syntax used for an
empty link? Is this an XML file? Perhaps an XML parser would be a
better choice.
Derrick
Bram wrote:
>Hello,
>
>I've isolated a problem, where sometimes htmlparser runs into an
>endless recursion loop when transforming links in HTML pages.
>
>Basically, I fetch & parse a document, change attributes on links, and
>reassemble it into a HTML page again. Without changing the attributes,
>the problem does not occur.
>
>See the attached JUnit test case.
>
>Best regards,
>Bram Avontuur
>
>
>------------------------------------------------------------------------
>
>import java.util.logging.Logger;
>
>import org.htmlparser.Node;
>import org.htmlparser.Parser;
>import org.htmlparser.filters.TagNameFilter;
>import org.htmlparser.nodes.TagNode;
>import org.htmlparser.util.NodeList;
>import org.htmlparser.util.ParserException;
>
>import junit.framework.TestCase;
>
>public class TestHtmlTransformer extends TestCase {
> private static final Logger logger = Logger.global;
>
> public void testHtmlTransformer() {
> String html = "<a/>";
> NodeList nodes = null;
>
> try {
> Parser parser = Parser.createParser(html, "UTF-8");
> nodes = parser.parse(null);
> } catch (ParserException e) {
> logger.severe("ParserException: " + e.getMessage());
> fail("ParserException");
> }
>
> nodes.toHtml(); //this works fine.
> logger.info("First html conversion went OK");
>
> NodeList links = nodes.extractAllNodesThatMatch(
> new TagNameFilter("a"), true);
>
> for (int i = 0; i < links.size(); i++) {
> Node tmpNode = links.elementAt(i);
> TagNode link = null;
> if (tmpNode instanceof TagNode) {
> link = (TagNode)links.elementAt(i);
> } else {
> continue;
> }
>
> link.setAttribute("href", "http://foo.com/");
> }
>
> try {
> nodes.toHtml(); //now it starts endless recursive loop
> } catch (StackOverflowError e) {
> //e.printStackTrace();
> fail("Endless recursion detected.");
> }
> logger.info("Passed second conversion"); //you never see this
> }
>}
>
>
|