Fix the invalid handling of message stanza in both tx and rx queue#171
Fix the invalid handling of message stanza in both tx and rx queue#171root-hardenedvault wants to merge 1 commit intogkdr:devfrom
Conversation
The xmpp packet (xmlnode ** msg_stanza_pp) should be handled very carefully, and they apply different rules in sending and receiving queue. In the sending queue of libpurple, because they are sent via void jabber_send(JabberStream *js, xmlnode *packet) and released by the caller, you could set (*msg_stanza_pp) to NULL, or modify (**msg_stanza_pp) in place, but you should neither release (*msg_stanza_pp) (cause double free) nor point it to another xmlnode. (there will be nowhere to release this xmlnode, since after jabber_send() returns, the pointer value passed to its second argument `packet` remain unchanged, no matter how `packet` is changed inside the context of jabber_send(), because in C, arguments are passed to functions by value.) In the receiving queue, on the other hand, they come from void jabber_process_packet(JabberStream *js, xmlnode **packet), in this case, you could modify (**msg_stanza_pp) in place, set (*msg_stanza_pp) to NULL, or point it to another xmlnode (thus the new xmlnode will be released by the caller of jabber_process_packet() ), but if you are going to point (*msg_stanza_pp) to another place, you are responsible to release the original xmlnode in your callback first, otherwise it will be leaked. In order to modify the **msg_stanza_pp in place in the sending queue, a dedicated function replace_msg_children() is added. Signed-off-by: HardenedVault <root@hardenedvault.net>
Codecov Report
@@ Coverage Diff @@
## dev #171 +/- ##
=====================================
Coverage 0.00% 0.00%
=====================================
Files 4 4
Lines 2111 2122 +11
=====================================
- Misses 2111 2122 +11
Continue to review full report at Codecov.
|
|
hi @root-hardenedvault, thanks again for the contribution. |
|
All outgoing xml packets is sent via jabber_send(), and by searching callings of jabber_send(), you can find they are all in form: and jabber_send() is implemented in libpurple/protocols/jabber/jabber.c as such: and &packet becomes your xmlnode ** msg_stanza_pp. So, if xmlnode_free(*msg_stanza_pp) were performed, what will happen after jabber_send(js, pkt) returns, and xmlnode_free(pkt) is called? |
The xmpp packet (xmlnode ** msg_stanza_pp) should be handled very carefully,
and they apply different rules in sending and receiving queue.
In the sending queue of libpurple, because they are sent via
void jabber_send(JabberStream *js, xmlnode *packet) and released by the caller,
you could set (*msg_stanza_pp) to NULL, or modify (**msg_stanza_pp) in place,
but you should neither release (*msg_stanza_pp) (cause double free) nor point it
to another xmlnode. (there will be nowhere to release this xmlnode, since after
jabber_send() returns, the pointer value passed to its second argument
packetremain unchanged, no matter how
packetis changed inside the context ofjabber_send(), because in C, arguments are passed to functions by value.)
In the receiving queue, on the other hand, they come from
void jabber_process_packet(JabberStream *js, xmlnode **packet), in this case,
you could modify (**msg_stanza_pp) in place, set (*msg_stanza_pp) to NULL, or
point it to another xmlnode (thus the new xmlnode will be released by the caller
of jabber_process_packet() ), but if you are going to point (*msg_stanza_pp) to
another place, you are responsible to release the original xmlnode in your
callback first, otherwise it will be leaked.
In order to modify the **msg_stanza_pp in place in the sending queue, a
dedicated function replace_msg_children() is added.
Signed-off-by: HardenedVault root@hardenedvault.net