comparison libpurple/protocols/yahoo/libymsg.c @ 28795:318ac22eb05d

Fix a crash on receiving an offline message from a federated buddy. Also handle federated buddy per IM. Refs #9814
author Sulabh Mahajan <sulabh@soc.pidgin.im>
date Sat, 24 Oct 2009 04:10:23 +0000
parents 29e96fb6cff3
children c46819108809
comparison
equal deleted inserted replaced
28793:a335d1bab20e 28795:318ac22eb05d
877 int utf8; 877 int utf8;
878 int buddy_icon; 878 int buddy_icon;
879 char *id; 879 char *id;
880 char *msg; 880 char *msg;
881 YahooFederation fed; 881 YahooFederation fed;
882 char *fed_from;
882 }; 883 };
883 884
884 static void yahoo_process_sms_message(PurpleConnection *gc, struct yahoo_packet *pkt) 885 static void yahoo_process_sms_message(PurpleConnection *gc, struct yahoo_packet *pkt)
885 { 886 {
886 PurpleAccount *account; 887 PurpleAccount *account;
950 GSList *l = pkt->hash; 951 GSList *l = pkt->hash;
951 GSList *list = NULL; 952 GSList *list = NULL;
952 struct _yahoo_im *im = NULL; 953 struct _yahoo_im *im = NULL;
953 const char *imv = NULL; 954 const char *imv = NULL;
954 gint val_11 = 0; 955 gint val_11 = 0;
955 char *fed_from = NULL;
956 956
957 account = purple_connection_get_account(gc); 957 account = purple_connection_get_account(gc);
958 958
959 if (pkt->status <= 1 || pkt->status == 5 || pkt->status == YAHOO_STATUS_OFFLINE) { 959 if (pkt->status <= 1 || pkt->status == 5 || pkt->status == YAHOO_STATUS_OFFLINE) {
960 /* messages are received with status YAHOO_STATUS_OFFLINE in case of p2p */ 960 /* messages are received with status YAHOO_STATUS_OFFLINE in case of p2p */
961 while (l != NULL) { 961 while (l != NULL) {
962 struct yahoo_pair *pair = l->data; 962 struct yahoo_pair *pair = l->data;
963 if (pair->key == 4 || pair->key == 1) { 963 if (pair->key == 4 || pair->key == 1) {
964 im = g_new0(struct _yahoo_im, 1); 964 im = g_new0(struct _yahoo_im, 1);
965 list = g_slist_append(list, im); 965 list = g_slist_append(list, im);
966 im->from = fed_from = pair->value; 966 im->from = pair->value;
967 im->time = time(NULL); 967 im->time = time(NULL);
968 im->utf8 = TRUE; 968 im->utf8 = TRUE;
969 im->fed = YAHOO_FEDERATION_NONE; 969 im->fed = YAHOO_FEDERATION_NONE;
970 im->fed_from = g_strdup(im->from);
970 } 971 }
971 if (im && pair->key == 5) 972 if (im && pair->key == 5)
972 im->active_id = pair->value; 973 im->active_id = pair->value;
973 if (pair->key == 97) 974 if (pair->key == 97)
974 if (im) 975 if (im)
983 if (im) 984 if (im)
984 im->msg = pair->value; 985 im->msg = pair->value;
985 } 986 }
986 if (im && pair->key == 241) { 987 if (im && pair->key == 241) {
987 im->fed = strtol(pair->value, NULL, 10); 988 im->fed = strtol(pair->value, NULL, 10);
989 g_free(im->fed_from);
988 switch (im->fed) { 990 switch (im->fed) {
989 case YAHOO_FEDERATION_MSN: 991 case YAHOO_FEDERATION_MSN:
990 fed_from = g_strconcat("msn/",im->from, NULL); 992 im->fed_from = g_strconcat("msn/",im->from, NULL);
991 break; 993 break;
992 case YAHOO_FEDERATION_OCS: 994 case YAHOO_FEDERATION_OCS:
993 fed_from = g_strconcat("ocs/",im->from, NULL); 995 im->fed_from = g_strconcat("ocs/",im->from, NULL);
994 break; 996 break;
995 case YAHOO_FEDERATION_IBM: 997 case YAHOO_FEDERATION_IBM:
996 fed_from = g_strconcat("ibm/",im->from, NULL); 998 im->fed_from = g_strconcat("ibm/",im->from, NULL);
997 break; 999 break;
998 case YAHOO_FEDERATION_NONE: 1000 case YAHOO_FEDERATION_NONE:
999 default: 1001 default:
1002 im->fed_from = g_strdup(im->from);
1000 break; 1003 break;
1001 } 1004 }
1002 purple_debug_info("yahoo", "Message from federated (%d) buddy %s.\n", im->fed, fed_from); 1005 purple_debug_info("yahoo", "Message from federated (%d) buddy %s.\n", im->fed, im->fed_from);
1003 1006
1004 } 1007 }
1005 /* peer session id */ 1008 /* peer session id */
1006 if (pair->key == 11) { 1009 if (pair->key == 11) {
1007 if (im) 1010 if (im)
1022 _("Your Yahoo! message did not get sent."), NULL); 1025 _("Your Yahoo! message did not get sent."), NULL);
1023 } 1026 }
1024 1027
1025 /* disconnect the peer if connected through p2p and sends wrong value for session id */ 1028 /* disconnect the peer if connected through p2p and sends wrong value for session id */
1026 if( (pkt_type == YAHOO_PKT_TYPE_P2P) && (val_11 != yd->session_id) ) { 1029 if( (pkt_type == YAHOO_PKT_TYPE_P2P) && (val_11 != yd->session_id) ) {
1027 purple_debug_warning("yahoo","p2p: %s sent us message with wrong session id. Disconnecting p2p connection to peer\n", im ? fed_from : "(im was null)"); 1030 purple_debug_warning("yahoo","p2p: %s sent us message with wrong session id. Disconnecting p2p connection to peer\n", im ? im->fed_from : "(im was null)");
1028 /* remove from p2p connection lists, also calls yahoo_p2p_disconnect_destroy_data */ 1031 /* remove from p2p connection lists, also calls yahoo_p2p_disconnect_destroy_data */
1029 if (im) { 1032 if (im) {
1030 g_hash_table_remove(yd->peers, fed_from); 1033 g_hash_table_remove(yd->peers, im->fed_from);
1031 g_free(im); 1034 g_free(im);
1032 } 1035 }
1033 return; 1036 return;
1034 } 1037 }
1035 1038
1070 for (l = list; l; l = l->next) { 1073 for (l = list; l; l = l->next) {
1071 YahooFriend *f; 1074 YahooFriend *f;
1072 char *m, *m2; 1075 char *m, *m2;
1073 im = l->data; 1076 im = l->data;
1074 1077
1075 if (!fed_from || !im->msg) { 1078 if (!im->fed_from || !im->msg) {
1079 g_free(im->fed_from);
1076 g_free(im); 1080 g_free(im);
1077 continue; 1081 continue;
1078 } 1082 }
1079 1083
1080 if (!purple_privacy_check(account, fed_from)) { 1084 if (!purple_privacy_check(account, im->fed_from)) {
1081 purple_debug_info("yahoo", "Message from %s dropped.\n", fed_from); 1085 purple_debug_info("yahoo", "Message from %s dropped.\n", im->fed_from);
1082 return; 1086 return;
1083 } 1087 }
1084 1088
1085 /* 1089 /*
1086 * TODO: Is there anything else we should check when determining whether 1090 * TODO: Is there anything else we should check when determining whether
1114 m = m2; 1118 m = m2;
1115 purple_util_chrreplace(m, '\r', '\n'); 1119 purple_util_chrreplace(m, '\r', '\n');
1116 if (!strcmp(m, "<ding>")) { 1120 if (!strcmp(m, "<ding>")) {
1117 char *username; 1121 char *username;
1118 1122
1119 username = g_markup_escape_text(fed_from, -1); 1123 username = g_markup_escape_text(im->fed_from, -1);
1120 purple_prpl_got_attention(gc, username, YAHOO_BUZZ); 1124 purple_prpl_got_attention(gc, username, YAHOO_BUZZ);
1121 g_free(username); 1125 g_free(username);
1122 g_free(m); 1126 g_free(m);
1127 g_free(im->fed_from);
1123 g_free(im); 1128 g_free(im);
1124 continue; 1129 continue;
1125 } 1130 }
1126 1131
1127 m2 = yahoo_codes_to_html(m); 1132 m2 = yahoo_codes_to_html(m);
1128 g_free(m); 1133 g_free(m);
1129 1134
1130 serv_got_im(gc, fed_from, m2, 0, im->time); 1135 serv_got_im(gc, im->fed_from, m2, 0, im->time);
1131 g_free(m2); 1136 g_free(m2);
1132 1137
1133 /* Official clients don't share buddy images with federated buddies */ 1138 /* Official clients don't share buddy images with federated buddies */
1134 if (im->fed == YAHOO_FEDERATION_NONE) { 1139 if (im->fed == YAHOO_FEDERATION_NONE) {
1135 if ((f = yahoo_friend_find(gc, im->from)) && im->buddy_icon == 2) { 1140 if ((f = yahoo_friend_find(gc, im->from)) && im->buddy_icon == 2) {
1138 yahoo_friend_set_buddy_icon_need_request(f, FALSE); 1143 yahoo_friend_set_buddy_icon_need_request(f, FALSE);
1139 } 1144 }
1140 } 1145 }
1141 } 1146 }
1142 1147
1143 if(im->fed != YAHOO_FEDERATION_NONE) 1148 g_free(im->fed_from);
1144 g_free(fed_from);
1145
1146 g_free(im); 1149 g_free(im);
1147 } 1150 }
1148 1151
1149 g_slist_free(list); 1152 g_slist_free(list);
1150 } 1153 }