Mercurial > pidgin
comparison libpurple/protocols/jabber/jingle/rtp.c @ 32380:231c9635b82a
Fix crashes and memory leaks when receiving malformed voice
and video requests. Thanks to Thijs Alkemade for reporting this!
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Tue, 06 Dec 2011 07:06:01 +0000 |
parents | 76b7754ba906 |
children |
comparison
equal
deleted
inserted
replaced
32379:76b7754ba906 | 32380:231c9635b82a |
---|---|
588 media_type = jingle_rtp_get_media_type(content); | 588 media_type = jingle_rtp_get_media_type(content); |
589 remote_jid = jingle_session_get_remote_jid(session); | 589 remote_jid = jingle_session_get_remote_jid(session); |
590 senders = jingle_content_get_senders(content); | 590 senders = jingle_content_get_senders(content); |
591 transport = jingle_content_get_transport(content); | 591 transport = jingle_content_get_transport(content); |
592 | 592 |
593 if (media_type == NULL) { | |
594 g_free(name); | |
595 g_free(remote_jid); | |
596 g_free(senders); | |
597 g_free(params); | |
598 g_object_unref(transport); | |
599 g_object_unref(session); | |
600 return FALSE; | |
601 } | |
602 | |
593 if (JINGLE_IS_RAWUDP(transport)) | 603 if (JINGLE_IS_RAWUDP(transport)) |
594 transmitter = "rawudp"; | 604 transmitter = "rawudp"; |
595 else if (JINGLE_IS_ICEUDP(transport)) | 605 else if (JINGLE_IS_ICEUDP(transport)) |
596 transmitter = "nice"; | 606 transmitter = "nice"; |
597 else | 607 else |
598 transmitter = "notransmitter"; | 608 transmitter = "notransmitter"; |
599 g_object_unref(transport); | 609 g_object_unref(transport); |
600 | 610 |
601 is_audio = !strcmp(media_type, "audio"); | 611 is_audio = g_str_equal(media_type, "audio"); |
602 | 612 |
603 if (!strcmp(senders, "both")) | 613 if (purple_strequal(senders, "both")) |
604 type = is_audio == TRUE ? PURPLE_MEDIA_AUDIO | 614 type = is_audio ? PURPLE_MEDIA_AUDIO |
605 : PURPLE_MEDIA_VIDEO; | 615 : PURPLE_MEDIA_VIDEO; |
606 else if ((strcmp(senders, "initiator") == 0) == | 616 else if (purple_strequal(senders, "initiator") == |
607 jingle_session_is_initiator(session)) | 617 jingle_session_is_initiator(session)) |
608 type = is_audio == TRUE ? PURPLE_MEDIA_SEND_AUDIO | 618 type = is_audio ? PURPLE_MEDIA_SEND_AUDIO |
609 : PURPLE_MEDIA_SEND_VIDEO; | 619 : PURPLE_MEDIA_SEND_VIDEO; |
610 else | 620 else |
611 type = is_audio == TRUE ? PURPLE_MEDIA_RECV_AUDIO | 621 type = is_audio ? PURPLE_MEDIA_RECV_AUDIO |
612 : PURPLE_MEDIA_RECV_VIDEO; | 622 : PURPLE_MEDIA_RECV_VIDEO; |
613 | 623 |
614 params = | 624 params = |
615 jingle_get_params(jingle_session_get_js(session), NULL, 0, 0, 0, | 625 jingle_get_params(jingle_session_get_js(session), NULL, 0, 0, 0, |
616 NULL, NULL, &num_params); | 626 NULL, NULL, &num_params); |
617 | 627 |
618 creator = jingle_content_get_creator(content); | 628 creator = jingle_content_get_creator(content); |
619 if (!strcmp(creator, "initiator")) | 629 if (creator == NULL) { |
630 g_free(name); | |
631 g_free(media_type); | |
632 g_free(remote_jid); | |
633 g_free(senders); | |
634 g_free(params); | |
635 g_object_unref(session); | |
636 return FALSE; | |
637 } | |
638 | |
639 if (g_str_equal(creator, "initiator")) | |
620 is_creator = jingle_session_is_initiator(session); | 640 is_creator = jingle_session_is_initiator(session); |
621 else | 641 else |
622 is_creator = !jingle_session_is_initiator(session); | 642 is_creator = !jingle_session_is_initiator(session); |
623 g_free(creator); | 643 g_free(creator); |
624 | 644 |
625 if(!purple_media_add_stream(media, name, remote_jid, | 645 if(!purple_media_add_stream(media, name, remote_jid, |
626 type, is_creator, transmitter, num_params, params)) { | 646 type, is_creator, transmitter, num_params, params)) { |
627 purple_media_end(media, NULL, NULL); | 647 purple_media_end(media, NULL, NULL); |
648 /* TODO: How much clean-up is necessary here? (does calling | |
649 purple_media_end lead to cleaning up Jingle structs?) */ | |
628 return FALSE; | 650 return FALSE; |
629 } | 651 } |
630 | 652 |
631 g_free(name); | 653 g_free(name); |
632 g_free(media_type); | 654 g_free(media_type); |
644 GList *codecs = NULL; | 666 GList *codecs = NULL; |
645 xmlnode *codec_element = NULL; | 667 xmlnode *codec_element = NULL; |
646 const char *encoding_name,*id, *clock_rate; | 668 const char *encoding_name,*id, *clock_rate; |
647 PurpleMediaCodec *codec; | 669 PurpleMediaCodec *codec; |
648 const gchar *media = xmlnode_get_attrib(description, "media"); | 670 const gchar *media = xmlnode_get_attrib(description, "media"); |
649 PurpleMediaSessionType type = | 671 PurpleMediaSessionType type; |
650 !strcmp(media, "video") ? PURPLE_MEDIA_VIDEO : | 672 |
651 !strcmp(media, "audio") ? PURPLE_MEDIA_AUDIO : 0; | 673 if (media == NULL) { |
674 purple_debug_warning("jingle-rtp", "missing media type\n"); | |
675 return NULL; | |
676 } | |
677 | |
678 if (g_str_equal(media, "video")) { | |
679 type = PURPLE_MEDIA_VIDEO; | |
680 } else if (g_str_equal(media, "audio")) { | |
681 type = PURPLE_MEDIA_AUDIO; | |
682 } else { | |
683 purple_debug_warning("jingle-rtp", "unknown media type: %s\n", | |
684 media); | |
685 return NULL; | |
686 } | |
652 | 687 |
653 for (codec_element = xmlnode_get_child(description, "payload-type") ; | 688 for (codec_element = xmlnode_get_child(description, "payload-type") ; |
654 codec_element ; | 689 codec_element ; |
655 codec_element = xmlnode_get_next_twin(codec_element)) { | 690 codec_element = xmlnode_get_next_twin(codec_element)) { |
656 xmlnode *param; | 691 xmlnode *param; |
767 jingle_rtp_handle_action_internal(JingleContent *content, xmlnode *xmlcontent, JingleActionType action) | 802 jingle_rtp_handle_action_internal(JingleContent *content, xmlnode *xmlcontent, JingleActionType action) |
768 { | 803 { |
769 switch (action) { | 804 switch (action) { |
770 case JINGLE_SESSION_ACCEPT: | 805 case JINGLE_SESSION_ACCEPT: |
771 case JINGLE_SESSION_INITIATE: { | 806 case JINGLE_SESSION_INITIATE: { |
772 JingleSession *session = jingle_content_get_session(content); | 807 JingleSession *session; |
773 JingleTransport *transport = jingle_transport_parse( | 808 JingleTransport *transport; |
774 xmlnode_get_child(xmlcontent, "transport")); | 809 xmlnode *description; |
775 xmlnode *description = xmlnode_get_child(xmlcontent, "description"); | 810 GList *candidates; |
776 GList *candidates = jingle_rtp_transport_to_candidates(transport); | 811 GList *codecs; |
777 GList *codecs = jingle_rtp_parse_codecs(description); | 812 gchar *name; |
778 gchar *name = jingle_content_get_name(content); | 813 gchar *remote_jid; |
779 gchar *remote_jid = | |
780 jingle_session_get_remote_jid(session); | |
781 PurpleMedia *media; | 814 PurpleMedia *media; |
782 | 815 |
816 session = jingle_content_get_session(content); | |
817 | |
783 if (action == JINGLE_SESSION_INITIATE && | 818 if (action == JINGLE_SESSION_INITIATE && |
784 jingle_rtp_init_media(content) == FALSE) { | 819 !jingle_rtp_init_media(content)) { |
785 /* XXX: send error */ | 820 /* XXX: send error */ |
786 jabber_iq_send(jingle_session_terminate_packet( | 821 jabber_iq_send(jingle_session_terminate_packet( |
787 session, "general-error")); | 822 session, "general-error")); |
788 g_object_unref(session); | 823 g_object_unref(session); |
789 break; | 824 break; |
790 } | 825 } |
826 | |
827 transport = jingle_transport_parse( | |
828 xmlnode_get_child(xmlcontent, "transport")); | |
829 description = xmlnode_get_child(xmlcontent, "description"); | |
830 candidates = jingle_rtp_transport_to_candidates(transport); | |
831 codecs = jingle_rtp_parse_codecs(description); | |
832 name = jingle_content_get_name(content); | |
833 remote_jid = jingle_session_get_remote_jid(session); | |
791 | 834 |
792 media = jingle_rtp_get_media(session); | 835 media = jingle_rtp_get_media(session); |
793 purple_media_set_remote_codecs(media, | 836 purple_media_set_remote_codecs(media, |
794 name, remote_jid, codecs); | 837 name, remote_jid, codecs); |
795 purple_media_add_remote_candidates(media, | 838 purple_media_add_remote_candidates(media, |