Skip to content
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

creating a text node after add_next_sibling and then also trying to add_next_sibling() it causes mutably shared node Err #99

Open
insiderscore-jeff opened this issue Apr 1, 2022 · 1 comment
Labels

Comments

@insiderscore-jeff
Copy link

This is on 0.3. So the scenario is appending a newly created text node, after you call add_next_sibling, and then call add_next_sibling with that causes a mutable reference Err. Replacing the text nodes with "real" nodes works correctly. Could be some underlying libxml muckery when merging adjacent text nodes? I somewhat remember a long while ago running into a bug in the perl libxml wrapper in that ballpark.

You could ask "why would you insert another text node rather than append_data?" which is a valid question, but this should still work, or at least give a more concise error as to what's up

the fact the first 2 add_next_sibling work fine, it is only after creating another text node after the add_next_sibling call where this falls apart.

thanks!

use libxml::parser::Parser; 
use libxml::tree::*;


fn xml_nodes_works()
{
    println!("xml_nodes_works");

    let mut d = Document::new().unwrap();

    let mut div = Node::new("DIV", None, &d).unwrap();
    d.set_root_element(&div);

    let mut n = Node::new("SPAN", None, &d).unwrap();
    let mut nt = Node::new("SPAN", None, &d).unwrap();
    let mut nt2 = Node::new("SPAN", None, &d).unwrap();

    // add text
    div.add_child(&mut n).unwrap();

    // lets skip the fact it is questionable why I'd be adding multiple text nodes

    // but is it because we mutate it twice.
    n.add_next_sibling(&mut nt).unwrap(); // ok
    n.add_next_sibling(&mut nt2).unwrap(); // ok

    println!("{}", d.node_to_string(&div)); // "n nt nt2 "

    let mut nt4 = Node::new("SPAN", None, &d).unwrap();
    n.add_next_sibling(&mut nt4).unwrap(); // works.

    println!("{}", d.node_to_string(&div)); // "n nt nt2 "
}

fn xml_text_broken()
{
    println!("xml_text_broken");

    let mut d = Document::new().unwrap();

    let mut div = Node::new("DIV", None, &d).unwrap();
    d.set_root_element(&div);

    let mut n = Node::new_text("n ", &d).unwrap();
    let mut nt = Node::new_text("nt ", &d).unwrap();
    let mut nt2 = Node::new_text("nt2 ", &d).unwrap();

    // add text
    div.add_child(&mut n).unwrap();

    // lets skip the fact it is questionable why I'd be adding multiple text nodes like this..

    n.add_next_sibling(&mut nt).unwrap(); // ok
    n.add_next_sibling(&mut nt2).unwrap(); // ok

    println!("{}", d.node_to_string(&div)); // "n nt nt2 "

    let mut nt4 = Node::new_text("nt4 ", &d).unwrap();
    n.add_next_sibling(&mut nt4).unwrap(); // panic! with reference error.

    println!("{}", d.node_to_string(&n));
}

fn main() {

    xml_nodes_works();
    xml_text_broken();
}

output:

<DIV><SPAN/><SPAN/><SPAN/></DIV>
<DIV><SPAN/><SPAN/><SPAN/><SPAN/></DIV>
xml_text_broken
<DIV>n nt nt2 </DIV>
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: "Can not mutably reference a shared Node \"text\"! Rc: weak count: 0; strong count: 3"', src/main.rs:61:34
@dginev dginev added the bug label Apr 1, 2022
@insiderscore-jeff
Copy link
Author

Yep - so there's a case where if you call add_next_sibling with 2 text node's it converts into an append:

fn xml_test_merge()
{

    let mut d = Document::new().unwrap();

    let mut div = Node::new("DIV", None, &d).unwrap();
    d.set_root_element(&div);

    let mut n = Node::new_text("n ", &d).unwrap();
    let mut nt = Node::new_text("nt ", &d).unwrap();
    let mut nt2 = Node::new_text("nt2 ", &d).unwrap();

    // add text
    div.add_child(&mut n).unwrap();

    // lets skip the fact it is questionable why I'd be adding multiple text nodes like this..

    // but is it because we mutate it twice.
    n.add_next_sibling(&mut nt).unwrap(); // ok
    n.add_next_sibling(&mut nt2).unwrap(); // ok

    // lets look at n's content vs 
    println!("N: {}", n.get_content());     // and that it didn't actually add a sibling

    let ns = n.get_next_sibling().unwrap();

}

output:

     Running `target/debug/xmlbug`
N: n nt nt2 
thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', src/main.rs:90:35

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants