From 106ee67ae25419a2258c91b2d6e7a00312a51de0 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Mon, 8 Apr 2019 19:11:24 +0300 Subject: Jabber: merge of fixes from trunk --- protocols/JabberG/src/jabber_caps.cpp | 4 +- protocols/JabberG/src/jabber_chat.cpp | 30 +++---- protocols/JabberG/src/jabber_disco.cpp | 6 +- protocols/JabberG/src/jabber_disco.h | 2 +- protocols/JabberG/src/jabber_file.cpp | 2 +- protocols/JabberG/src/jabber_form.cpp | 2 +- protocols/JabberG/src/jabber_ft.cpp | 5 +- protocols/JabberG/src/jabber_groupchat.cpp | 16 ++-- protocols/JabberG/src/jabber_menu.cpp | 11 ++- protocols/JabberG/src/jabber_misc.cpp | 6 +- protocols/JabberG/src/jabber_omemo.cpp | 4 +- protocols/JabberG/src/jabber_proto.cpp | 3 +- protocols/JabberG/src/jabber_proto.h | 3 - protocols/JabberG/src/jabber_rc.cpp | 15 ++-- protocols/JabberG/src/jabber_search.cpp | 138 ++++++++++++++--------------- protocols/JabberG/src/jabber_search.h | 124 +++++++++++--------------- protocols/JabberG/src/jabber_svc.cpp | 18 ++-- protocols/JabberG/src/jabber_userinfo.cpp | 4 +- protocols/JabberG/src/jabber_util.cpp | 20 +++-- protocols/JabberG/src/stdafx.h | 2 + 20 files changed, 188 insertions(+), 227 deletions(-) (limited to 'protocols/JabberG/src') diff --git a/protocols/JabberG/src/jabber_caps.cpp b/protocols/JabberG/src/jabber_caps.cpp index 508b7126c1..50a94e6204 100755 --- a/protocols/JabberG/src/jabber_caps.cpp +++ b/protocols/JabberG/src/jabber_caps.cpp @@ -229,10 +229,8 @@ JabberCapsBits CJabberProto::GetTotalJidCapabilities(const char *jid) if (item) { for (auto &it : item->arResources) { - char szFullJid[JABBER_MAX_JID_LEN]; - mir_snprintf(szFullJid, "%s/%s", szBareJid, it->m_szResourceName); pResourceStatus r(it); - JabberCapsBits jcb = GetResourceCapabilities(szFullJid, r); + JabberCapsBits jcb = GetResourceCapabilities(MakeJid(szBareJid, it->m_szResourceName), r); if (!(jcb & JABBER_RESOURCE_CAPS_ERROR)) jcbToReturn |= jcb; } diff --git a/protocols/JabberG/src/jabber_chat.cpp b/protocols/JabberG/src/jabber_chat.cpp index 0eaf3012df..39ad978519 100644 --- a/protocols/JabberG/src/jabber_chat.cpp +++ b/protocols/JabberG/src/jabber_chat.cpp @@ -334,11 +334,8 @@ void CJabberProto::GcQuit(JABBER_LIST_ITEM *item, int code, const TiXmlElement * item->bChatActive = false; if (m_bJabberOnline) { - char szPresenceTo[JABBER_MAX_JID_LEN]; - mir_snprintf(szPresenceTo, "%s/%s", item->jid, item->nick); - m_ThreadInfo->send( - XmlNode("presence") << XATTR("to", szPresenceTo) << XATTR("type", "unavailable") + XmlNode("presence") << XATTR("to", MakeJid(item->jid, item->nick)) << XATTR("type", "unavailable") << XCHILD("status", szMessage)); ListRemove(LIST_CHATROOM, item->jid); @@ -1014,7 +1011,7 @@ static void sttNickListHook(CJabberProto *ppro, JABBER_LIST_ITEM *item, GCHOOK* case IDM_VCARD: { - CMStringA jid(FORMAT, "%s/%s", item->jid, him->m_szResourceName); + CMStringA jid(MakeJid(item->jid, him->m_szResourceName)); MCONTACT hContact = ppro->AddToListByJID(jid, PALF_TEMPORARY); ppro->setUString(hContact, "Nick", him->m_szResourceName); @@ -1138,7 +1135,8 @@ static void sttNickListHook(CJabberProto *ppro, JABBER_LIST_ITEM *item, GCHOOK* case IDM_LINK0: case IDM_LINK1: case IDM_LINK2: case IDM_LINK3: case IDM_LINK4: case IDM_LINK5: case IDM_LINK6: case IDM_LINK7: case IDM_LINK8: case IDM_LINK9: if ((GetTickCount() - dwLastBanKickTime) > BAN_KICK_INTERVAL) { - Utf2T resourceName_copy(him->m_szResourceName); // copy resource name to prevent possible crash if user list rebuilds + // copy resource name to prevent possible crash if user list rebuilds + char *resourceName_copy(NEWSTR_ALLOCA(him->m_szResourceName)); char *szInviteTo = nullptr; int idx = gch->dwData - IDM_LINK0; @@ -1159,10 +1157,8 @@ static void sttNickListHook(CJabberProto *ppro, JABBER_LIST_ITEM *item, GCHOOK* if (!ppro->EnterString(szBuffer, szTitle, ESF_MULTILINE)) break; - szTitle.Format(L"%s/%s", item->jid, resourceName_copy); - XmlNode msg("message"); - msg << XATTR("to", T2Utf(szTitle)) << XATTRID(ppro->SerialNext()) + msg << XATTR("to", MakeJid(item->jid, resourceName_copy)) << XATTRID(ppro->SerialNext()) << XCHILD("x", T2Utf(szBuffer)) << XATTR("xmlns", JABBER_FEAT_DIRECT_MUC_INVITE) << XATTR("jid", szInviteTo) << XCHILD("invite") << XATTR("from", item->nick); ppro->m_ThreadInfo->send(msg); @@ -1180,7 +1176,7 @@ static void sttNickListHook(CJabberProto *ppro, JABBER_LIST_ITEM *item, GCHOOK* break; case IDM_CPY_INROOMJID: - JabberCopyText(g_clistApi.hwndContactList, CMStringA(FORMAT, "%s/%s", item->jid, him->m_szResourceName)); + JabberCopyText(g_clistApi.hwndContactList, MakeJid(item->jid, him->m_szResourceName)); break; case IDM_RJID_VCARD: @@ -1254,13 +1250,9 @@ static void sttLogListHook(CJabberProto *ppro, JABBER_LIST_ITEM *item, GCHOOK* g szTitle.Format(TranslateT("Change nickname in %s"), gch->ptszID); if (item->nick) szBuffer = Utf2T(item->nick); - if (ppro->EnterString(szBuffer, szTitle, ESF_COMBO, "gcNick_")) { - if (ppro->ListGetItemPtr(LIST_CHATROOM, roomJid) != nullptr) { - char text[1024]; - mir_snprintf(text, "%s/%s", roomJid.get(), szBuffer.c_str()); - ppro->SendPresenceTo(ppro->m_iStatus == ID_STATUS_INVISIBLE ? ID_STATUS_ONLINE : ppro->m_iStatus, text); - } - } + if (ppro->EnterString(szBuffer, szTitle, ESF_COMBO, "gcNick_")) + if (ppro->ListGetItemPtr(LIST_CHATROOM, roomJid) != nullptr) + ppro->SendPresenceTo(ppro->m_iStatus == ID_STATUS_INVISIBLE ? ID_STATUS_ONLINE : ppro->m_iStatus, MakeJid(roomJid, T2Utf(szBuffer))); break; case IDM_INVITE: @@ -1341,9 +1333,7 @@ static void sttLogListHook(CJabberProto *ppro, JABBER_LIST_ITEM *item, GCHOOK* g static void sttSendPrivateMessage(CJabberProto *ppro, JABBER_LIST_ITEM *item, const char *nick) { - char szFullJid[JABBER_MAX_JID_LEN]; - mir_snprintf(szFullJid, "%s/%s", item->jid, nick); - MCONTACT hContact = ppro->DBCreateContact(szFullJid, nullptr, true, false); + MCONTACT hContact = ppro->DBCreateContact(MakeJid(item->jid, nick), nullptr, true, false); if (hContact != 0) { pResourceStatus r(item->findResource(nick)); if (r) diff --git a/protocols/JabberG/src/jabber_disco.cpp b/protocols/JabberG/src/jabber_disco.cpp index c7d12a37b8..30d9ea5519 100644 --- a/protocols/JabberG/src/jabber_disco.cpp +++ b/protocols/JabberG/src/jabber_disco.cpp @@ -187,7 +187,7 @@ void CJabberProto::OnIqResultServiceDiscoveryRootInfo(const TiXmlElement *iqNode if (pInfo->GetIqType() == JABBER_IQ_TYPE_RESULT) { for (auto *feature : TiXmlFilter(XmlFirstChild(iqNode, "query"), "feature")) { if (!mir_strcmp(XmlGetAttr(feature, "var"), (char*)pInfo->m_pUserData)) { - CJabberSDNode *pNode = m_SDManager.AddPrimaryNode(pInfo->GetReceiver(), XmlGetAttr(iqNode, "node"), nullptr); + CJabberSDNode *pNode = m_SDManager.AddPrimaryNode(pInfo->GetReceiver(), XmlGetAttr(iqNode, "node")); SendBothRequests(pNode); break; } @@ -334,7 +334,7 @@ void CJabberProto::PerformBrowse(HWND hwndDlg) if (m_lstTransports.getIndex(item->jid) == -1) m_lstTransports.insert(mir_strdup(item->jid)); - CJabberSDNode *pNode = m_SDManager.AddPrimaryNode(item->jid, nullptr, nullptr); + CJabberSDNode *pNode = m_SDManager.AddPrimaryNode(item->jid); SendBothRequests(pNode); } } @@ -374,7 +374,7 @@ void CJabberProto::PerformBrowse(HWND hwndDlg) } } else { - CJabberSDNode *pNode = m_SDManager.AddPrimaryNode(T2Utf(szJid), T2Utf(szNode), nullptr); + CJabberSDNode *pNode = m_SDManager.AddPrimaryNode(T2Utf(szJid), szNode[0] == 0 ? nullptr : T2Utf(szNode)); SendBothRequests(pNode); } lck.unlock(); diff --git a/protocols/JabberG/src/jabber_disco.h b/protocols/JabberG/src/jabber_disco.h index 4edb47c5ae..7f8c6108d0 100644 --- a/protocols/JabberG/src/jabber_disco.h +++ b/protocols/JabberG/src/jabber_disco.h @@ -424,7 +424,7 @@ public: return m_pPrimaryNodes; } - CJabberSDNode* AddPrimaryNode(const char *szJid, const char *szNode, const char *szName) + CJabberSDNode* AddPrimaryNode(const char *szJid, const char *szNode = nullptr, const char *szName = nullptr) { if (!szJid) return nullptr; diff --git a/protocols/JabberG/src/jabber_file.cpp b/protocols/JabberG/src/jabber_file.cpp index 69dc1778df..f9909972f0 100644 --- a/protocols/JabberG/src/jabber_file.cpp +++ b/protocols/JabberG/src/jabber_file.cpp @@ -295,7 +295,7 @@ void __cdecl CJabberProto::FileServerThread(filetransfer *ft) char szAddr[256]; mir_snprintf(szAddr, "http://%s:%d/%s", myAddr, nlb.wPort, pFileName.c_str()); - XmlNodeIq iq("set", ft->szId, CMStringA(FORMAT, "%s/%s", ft->jid, ptszResource)); + XmlNodeIq iq("set", ft->szId, MakeJid(ft->jid, ptszResource)); TiXmlElement *query = iq << XQUERY(JABBER_FEAT_OOB); query << XCHILD("url", szAddr); query << XCHILD("desc", T2Utf(ft->szDescription)); diff --git a/protocols/JabberG/src/jabber_form.cpp b/protocols/JabberG/src/jabber_form.cpp index 16e517c822..a24396828d 100644 --- a/protocols/JabberG/src/jabber_form.cpp +++ b/protocols/JabberG/src/jabber_form.cpp @@ -263,7 +263,7 @@ void TJabberFormLayoutInfo::PositionControl(TJabberFormControlInfo *item, const void JabberFormSetInstruction(HWND hwndForm, const char *text) { - CMStringW buf(text == nullptr ? "" : text); + CMStringW buf(text == nullptr ? "" : Utf2T(text)); buf.Replace(L"\n\r", L"\r\n"); SetDlgItemText(hwndForm, IDC_INSTRUCTION, buf); diff --git a/protocols/JabberG/src/jabber_ft.cpp b/protocols/JabberG/src/jabber_ft.cpp index cd4884ebb1..c63f50aa96 100644 --- a/protocols/JabberG/src/jabber_ft.cpp +++ b/protocols/JabberG/src/jabber_ft.cpp @@ -97,10 +97,7 @@ void CJabberProto::FtInitiate(char* jid, filetransfer *ft) if (wchar_t *p = wcsrchr(filename, '\\')) filename = p + 1; - char tszJid[512]; - mir_snprintf(tszJid, "%s/%s", jid, rs); - - XmlNodeIq iq(AddIQ(&CJabberProto::OnFtSiResult, JABBER_IQ_TYPE_SET, tszJid, JABBER_IQ_PARSE_FROM | JABBER_IQ_PARSE_TO, -1, ft)); + XmlNodeIq iq(AddIQ(&CJabberProto::OnFtSiResult, JABBER_IQ_TYPE_SET, MakeJid(jid, rs), JABBER_IQ_PARSE_FROM | JABBER_IQ_PARSE_TO, -1, ft)); TiXmlElement *si = iq << XCHILDNS("si", JABBER_FEAT_SI) << XATTR("id", sid) << XATTR("mime-type", "binary/octet-stream") << XATTR("profile", JABBER_FEAT_SI_FT); si << XCHILDNS("file", JABBER_FEAT_SI_FT) << XATTR("name", T2Utf(filename)) diff --git a/protocols/JabberG/src/jabber_groupchat.cpp b/protocols/JabberG/src/jabber_groupchat.cpp index 42d968d7c5..3fba354194 100644 --- a/protocols/JabberG/src/jabber_groupchat.cpp +++ b/protocols/JabberG/src/jabber_groupchat.cpp @@ -739,12 +739,12 @@ static VOID CALLBACK JabberGroupchatChangeNickname(void* arg) CMStringW szBuffer, szTitle; szTitle.Format(TranslateT("Change nickname in <%s>"), item->name ? item->name : Utf2T(item->jid)); if (item->nick) - szBuffer = item->nick; + szBuffer = Utf2T(item->nick); if (param->ppro->EnterString(szBuffer, szTitle, ESF_COMBO, "gcNick_")) { T2Utf newNick(szBuffer); replaceStr(item->nick, newNick); - param->ppro->SendPresenceTo(param->ppro->m_iStatus, CMStringA(FORMAT, "%s/%s", item->jid, newNick.get())); + param->ppro->SendPresenceTo(param->ppro->m_iStatus, MakeJid(item->jid, newNick)); } } @@ -824,10 +824,6 @@ void CJabberProto::GroupchatProcessPresence(const TiXmlElement *node) const char *nick = cnick ? cnick : (r && r->m_szNick ? r->m_szNick : resource); - // process custom nick change - if (cnick && r && r->m_szNick && mir_strcmp(cnick, r->m_szNick)) - r->m_szNick = mir_strdup(cnick); - const TiXmlElement *itemNode = nullptr; auto *xNode = XmlGetChildByTag(node, "x", "xmlns", JABBER_FEAT_MUC_USER); if (xNode) @@ -851,6 +847,10 @@ void CJabberProto::GroupchatProcessPresence(const TiXmlElement *node) else if (!mir_strcmp(pszStatus, "chat")) status = ID_STATUS_FREECHAT; } + // process custom nick change + if (cnick && r && r->m_szNick && mir_strcmp(cnick, r->m_szNick)) + r->m_szNick = mir_strdup(cnick); + const char *str = XmlGetChildText(node, "status"); int priority = XmlGetChildInt(node, "priority"); int newRes = ListAddResource(LIST_CHATROOM, from, status, str, priority, cnick) ? GC_EVENT_JOIN : 0; @@ -990,9 +990,7 @@ void CJabberProto::GroupchatProcessPresence(const TiXmlElement *node) ptrA newNick(getUStringA("GcAltNick")); if (++item->iChatState == 1 && newNick != nullptr && newNick[0] != 0) { replaceStr(item->nick, newNick); - char text[1024]; - mir_snprintf(text, "%s/%s", item->jid, newNick); - SendPresenceTo(m_iStatus, text); + SendPresenceTo(m_iStatus, MakeJid(item->jid, newNick)); } else { CallFunctionAsync(JabberGroupchatChangeNickname, new JabberGroupchatChangeNicknameParam(this, from)); diff --git a/protocols/JabberG/src/jabber_menu.cpp b/protocols/JabberG/src/jabber_menu.cpp index 640315f3bb..f1cbdcbae9 100644 --- a/protocols/JabberG/src/jabber_menu.cpp +++ b/protocols/JabberG/src/jabber_menu.cpp @@ -1021,9 +1021,9 @@ INT_PTR __cdecl CJabberProto::OnMenuHandleDirectPresence(WPARAM hContact, LPARAM if (!m_bJabberOnline || !hContact) return 0; - char *jid, text[1024]; - ptrA tszJid(getUStringA(hContact, "jid")); - if (tszJid == nullptr) { + CMStringA jid; + ptrA szJid(getUStringA(hContact, "jid")); + if (szJid == nullptr) { ptrA roomid(getUStringA(hContact, "ChatRoomID")); if (roomid == nullptr) return 0; @@ -1032,10 +1032,9 @@ INT_PTR __cdecl CJabberProto::OnMenuHandleDirectPresence(WPARAM hContact, LPARAM if (item == nullptr) return 0; - mir_snprintf(text, "%s/%s", item->jid, item->nick); - jid = text; + jid = MakeJid(item->jid, item->nick); } - else jid = tszJid; + else jid = szJid; CMStringW szValue; if (EnterString(szValue, TranslateT("Status Message"), ESF_MULTILINE)) diff --git a/protocols/JabberG/src/jabber_misc.cpp b/protocols/JabberG/src/jabber_misc.cpp index 1366e7c81c..7f6ccc3d53 100755 --- a/protocols/JabberG/src/jabber_misc.cpp +++ b/protocols/JabberG/src/jabber_misc.cpp @@ -350,12 +350,10 @@ void CJabberProto::UpdateMirVer(MCONTACT hContact, const pResourceStatus &r) if (jid == nullptr) return; - char szFullJid[JABBER_MAX_JID_LEN]; if (r->m_szResourceName && !strchr(jid, '/')) - mir_snprintf(szFullJid, "%s/%s", jid, r->m_szResourceName); + setUString(hContact, DBSETTING_DISPLAY_UID, MakeJid(jid, r->m_szResourceName)); else - mir_strncpy(szFullJid, jid, _countof(szFullJid)); - setUString(hContact, DBSETTING_DISPLAY_UID, szFullJid); + setUString(hContact, DBSETTING_DISPLAY_UID, jid); } void CJabberProto::UpdateSubscriptionInfo(MCONTACT hContact, JABBER_LIST_ITEM *item) diff --git a/protocols/JabberG/src/jabber_omemo.cpp b/protocols/JabberG/src/jabber_omemo.cpp index 60027fabc2..dce6f4cc7e 100755 --- a/protocols/JabberG/src/jabber_omemo.cpp +++ b/protocols/JabberG/src/jabber_omemo.cpp @@ -220,7 +220,7 @@ complete: return SG_ERR_UNKNOWN; } - if (plaintext_len > INT_MAX - EVP_CIPHER_block_size(evp_cipher)) { + if ((int)plaintext_len > INT_MAX - EVP_CIPHER_block_size(evp_cipher)) { //fprintf(stderr, "invalid plaintext length: %zu\n", plaintext_len); return SG_ERR_UNKNOWN; } @@ -300,7 +300,7 @@ complete: return SG_ERR_INVAL; } - if (ciphertext_len > INT_MAX - EVP_CIPHER_block_size(evp_cipher)) { + if ((int)ciphertext_len > INT_MAX - EVP_CIPHER_block_size(evp_cipher)) { //fprintf(stderr, "invalid ciphertext length: %zu\n", ciphertext_len); return SG_ERR_UNKNOWN; } diff --git a/protocols/JabberG/src/jabber_proto.cpp b/protocols/JabberG/src/jabber_proto.cpp index 6196fc0f13..005311104f 100755 --- a/protocols/JabberG/src/jabber_proto.cpp +++ b/protocols/JabberG/src/jabber_proto.cpp @@ -641,8 +641,7 @@ int CJabberProto::GetInfo(MCONTACT hContact, int /*infoType*/) if (item->arResources.getCount()) { for (auto &it : item->arResources) { pResourceStatus r(it); - char tmp[JABBER_MAX_JID_LEN]; - mir_snprintf(tmp, "%s/%s", szBareJid, r->m_szResourceName); + CMStringA tmp(MakeJid(szBareJid, r->m_szResourceName)); if (r->m_jcbCachedCaps & JABBER_CAPS_DISCO_INFO) m_ThreadInfo->send( diff --git a/protocols/JabberG/src/jabber_proto.h b/protocols/JabberG/src/jabber_proto.h index 58685fa31f..40227f952c 100755 --- a/protocols/JabberG/src/jabber_proto.h +++ b/protocols/JabberG/src/jabber_proto.h @@ -49,8 +49,6 @@ typedef void (CJabberProto::*JABBER_FORM_SUBMIT_FUNC)(CJabberFormDlg *pDlg, void enum TJabberGcLogInfoType { INFO_BAN, INFO_STATUS, INFO_CONFIG, INFO_AFFILIATION, INFO_ROLE }; -typedef UNIQUE_MAP U_TCHAR_MAP; - #define JABBER_DEFAULT_RECENT_COUNT 10 struct TFilterInfo @@ -702,7 +700,6 @@ struct CJabberProto : public PROTO, public IJabberInterface //---- jabber_search.cpp ------------------------------------------------------------- - void SearchReturnResults(HANDLE id, void* pvUsersInfo, U_TCHAR_MAP *pmAllFields); void OnIqResultAdvancedSearch(const TiXmlElement *iqNode, CJabberIqInfo *pInfo); void OnIqResultGetSearchFields(const TiXmlElement *iqNode, CJabberIqInfo *pInfo); int SearchRenewFields(HWND hwndDlg, JabberSearchData * dat); diff --git a/protocols/JabberG/src/jabber_rc.cpp b/protocols/JabberG/src/jabber_rc.cpp index 979d7b9a8d..1ea31f39a0 100644 --- a/protocols/JabberG/src/jabber_rc.cpp +++ b/protocols/JabberG/src/jabber_rc.cpp @@ -539,8 +539,8 @@ int CJabberProto::AdhocForwardHandler(const TiXmlElement*, CJabberIqInfo *pInfo, int nEventsSent = 0; for (auto &hContact : AccContacts()) { - ptrA tszJid(getUStringA(hContact, "jid")); - if (tszJid == nullptr) + ptrA szJid(getUStringA(hContact, "jid")); + if (szJid == nullptr) continue; for (MEVENT hDbEvent = db_event_firstUnread(hContact); hDbEvent; hDbEvent = db_event_next(hContact, hDbEvent)) { @@ -567,13 +567,12 @@ int CJabberProto::AdhocForwardHandler(const TiXmlElement*, CJabberIqInfo *pInfo, TiXmlElement *addressesNode = msg << XCHILDNS("addresses", JABBER_FEAT_EXT_ADDRESSING); - char szOFrom[JABBER_MAX_JID_LEN]; + CMStringA szOFrom; size_t cbBlob = mir_strlen((LPSTR)dbei.pBlob) + 1; - if (cbBlob < dbei.cbBlob) { // rest of message contains a sender's resource - ptrW szOResource(mir_utf8decodeW((LPSTR)dbei.pBlob + cbBlob + 1)); - mir_snprintf(szOFrom, "%s/%s", tszJid, szOResource); - } - else strncpy_s(szOFrom, tszJid, _TRUNCATE); + if (cbBlob < dbei.cbBlob) // rest of message contains a sender's resource + szOFrom = MakeJid(szJid, (LPSTR)dbei.pBlob + cbBlob + 1); + else + szOFrom = szJid; addressesNode << XCHILD("address") << XATTR("type", "ofrom") << XATTR("jid", szOFrom); addressesNode << XCHILD("address") << XATTR("type", "oto") << XATTR("jid", m_ThreadInfo->fullJID); diff --git a/protocols/JabberG/src/jabber_search.cpp b/protocols/JabberG/src/jabber_search.cpp index 8223ee5682..24bdfe9ce4 100644 --- a/protocols/JabberG/src/jabber_search.cpp +++ b/protocols/JabberG/src/jabber_search.cpp @@ -67,9 +67,10 @@ static int JabberSearchFrameProc(HWND hwnd, int msg, WPARAM wParam, LPARAM lPara dat->curPos = pos; } } - if (HIWORD(wParam) == EN_SETFOCUS) { //Transmit focus set notification to parent window + + // Transmit focus set notification to parent window + if (HIWORD(wParam) == EN_SETFOCUS) PostMessage(GetParent(hwndDlg), WM_COMMAND, MAKEWPARAM(0, EN_SETFOCUS), (LPARAM)hwndDlg); - } } if (msg == WM_PAINT) { @@ -115,8 +116,9 @@ static int JabberSearchAddField(HWND hwndDlg, Data* FieldDat) EnableWindow(hwndLabel, !FieldDat->bReadOnly); SendMessage(hwndVar, EM_SETREADONLY, (WPARAM)FieldDat->bReadOnly, 0); } - //remade list - //reallocation + + // remade list + // reallocation JabberSearchData *dat = (JabberSearchData *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); if (dat) { dat->pJSInf = (JabberSearchFieldsInfo*)realloc(dat->pJSInf, sizeof(JabberSearchFieldsInfo)*(dat->nJSInfCount + 1)); @@ -197,31 +199,35 @@ void CJabberProto::OnIqResultGetSearchFields(const TiXmlElement *iqNode, CJabber ////////////////////////////////////////////////////////////////////////////////////////// // Return results to search dialog -// The pmFields is the pointer to map of Not unical but ordered +// The pmFields is the pointer to map of Not unical but ordered // This can help to made result parser routines more simple -static wchar_t *nickfields[] = { L"nick", L"nickname", L"fullname", L"name", L"given", L"first", L"jid", nullptr }; +static char *nickfields[] = { "nick", "nickname", "fullname", "name", "given", "first", "jid", nullptr }; + +static int TCharKeyCmp(const char *p1, const char *p2) +{ + return mir_strcmpi(p1, p2); +} -void CJabberProto::SearchReturnResults(HANDLE id, void * pvUsersInfo, U_TCHAR_MAP * pmAllFields) +static void SearchReturnResults(CJabberProto *ppro, HANDLE id, LIST &plUsersInfo, UNIQUE_MAP &pmAllFields) { - LIST ListOfNonEmptyFields(20, (LIST::FTSortFunc)TCharKeyCmp); - LIST ListOfFields(20); - LIST *plUsersInfo = (LIST*)pvUsersInfo; + LIST ListOfNonEmptyFields(20, TCharKeyCmp); + LIST ListOfFields(20); // lets fill the ListOfNonEmptyFields but in users order - for (auto &pmUserData : *plUsersInfo) { + for (auto &pmUserData : plUsersInfo) { int nUserFields = pmUserData->getCount(); for (int j = 0; j < nUserFields; j++) { - wchar_t *var = pmUserData->getKeyName(j); + char *var = pmUserData->getKeyName(j); if (var && ListOfNonEmptyFields.getIndex(var) < 0) ListOfNonEmptyFields.insert(var); } } // now fill the ListOfFields but order is from pmAllFields - int nAllCount = pmAllFields->getCount(); + int nAllCount = pmAllFields.getCount(); for (int i = 0; i < nAllCount; i++) { - wchar_t *var = pmAllFields->getUnOrderedKeyName(i); + char *var = pmAllFields.getUnOrderedKeyName(i); if (var && ListOfNonEmptyFields.getIndex(var) < 0) continue; ListOfFields.insert(var); @@ -235,61 +241,55 @@ void CJabberProto::SearchReturnResults(HANDLE id, void * pvUsersInfo, U_TCHAR_M Results.pszFields = (wchar_t**)mir_alloc(sizeof(wchar_t*)*nFieldCount); Results.nFieldCount = nFieldCount; - /* Sending Columns Titles */ + // Sending Columns Titles for (int i = 0; i < nFieldCount; i++) { - wchar_t *var = ListOfFields[i]; + char *var = ListOfFields[i]; if (var) - Results.pszFields[i] = pmAllFields->operator [](var); + Results.pszFields[i] = mir_utf8decodeW(pmAllFields[var]); } Results.psr.cbSize = 0; // sending column names - ProtoBroadcastAck(0, ACKTYPE_SEARCH, ACKRESULT_SEARCHRESULT, id, (LPARAM)&Results); + ppro->ProtoBroadcastAck(0, ACKTYPE_SEARCH, ACKRESULT_SEARCHRESULT, id, (LPARAM)&Results); + for (int i = 0; i < nFieldCount; i++) + replaceStrW(Results.pszFields[i], nullptr); - /* Sending Users Data */ - Results.psr.cbSize = sizeof(Results.psr); // sending user data + // Sending Users Data + Results.psr.cbSize = sizeof(Results.psr); - for (auto &pmUserData : *plUsersInfo) { - wchar_t buff[200]; - buff[0] = 0; + for (auto &pmUserData : plUsersInfo) { for (int j = 0; j < nFieldCount; j++) { - wchar_t *var = ListOfFields[j]; - wchar_t *value = pmUserData->operator [](var); - Results.pszFields[j] = value ? value : (wchar_t *)L" "; - if (!mir_wstrcmpi(var, L"jid") && value) - Results.psr.id.w = value; + char *var = ListOfFields[j]; + char *value = pmUserData->operator [](var); + Results.pszFields[j] = value ? mir_utf8decodeW(value) : mir_wstrdup(L" "); + if (!mir_strcmpi(var, "jid") && value) + Results.psr.id.w = Results.pszFields[j]; } - wchar_t *nick = nullptr; + const char *nick = nullptr; for (int k = 0; k < _countof(nickfields) && !nick; k++) nick = pmUserData->operator [](nickfields[k]); if (nick) { - if (mir_wstrcmpi(nick, Results.psr.id.w)) - mir_snwprintf(buff, L"%s (%s)", nick, Results.psr.id.w); + Utf2T wszNick(nick); + wchar_t buff[200]; + if (mir_wstrcmpi(wszNick, Results.psr.id.w)) + mir_snwprintf(buff, L"%s (%s)", wszNick, Results.psr.id.w); else - wcsncpy_s(buff, nick, _TRUNCATE); + wcsncpy_s(buff, wszNick, _TRUNCATE); - nick = buff; + Results.psr.nick.w = buff; } - Results.psr.nick.w = nick; + else Results.psr.nick.w = L""; Results.psr.flags = PSR_UNICODE; - ProtoBroadcastAck(0, ACKTYPE_SEARCH, ACKRESULT_SEARCHRESULT, id, (LPARAM)&Results); - Results.psr.nick.w = nullptr; + ppro->ProtoBroadcastAck(0, ACKTYPE_SEARCH, ACKRESULT_SEARCHRESULT, id, (LPARAM)&Results); + for (int i = 0; i < nFieldCount; i++) + replaceStrW(Results.pszFields[i], nullptr); } + mir_free(Results.pszFields); } -void DestroyKey(wchar_t* key) -{ - mir_free(key); -} - -wchar_t* CopyKey(wchar_t* key) -{ - return mir_wstrdup(key); -} - //////////////////////////////////////////////////////////////////////////////// // Search field request result handler (XEP-0055. Examples 3, 8) @@ -298,8 +298,8 @@ void CJabberProto::OnIqResultAdvancedSearch(const TiXmlElement *iqNode, CJabberI const char *type; int id; - U_TCHAR_MAP mColumnsNames(10); - LIST SearchResults(2); + UNIQUE_MAP mColumnsNames(10); + LIST SearchResults(2); if (((id = JabberGetPacketID(iqNode)) == -1) || ((type = XmlGetAttr(iqNode, "type")) == nullptr)) { ProtoBroadcastAck(0, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)id, 0); @@ -312,22 +312,21 @@ void CJabberProto::OnIqResultAdvancedSearch(const TiXmlElement *iqNode, CJabberI if (xNode) { // 1. Form search results info for (auto *fieldNode : TiXmlFilter(XmlFirstChild(xNode, "reported"), "field")) { - const char *var = XmlGetAttr(fieldNode, "var"); + auto *var = XmlGetAttr(fieldNode, "var"); if (var) { - Utf2T wszVar(var), wszLabel(XmlGetAttr(fieldNode, "label")); - mColumnsNames.insert(wszVar, (wszLabel != nullptr) ? wszLabel: wszVar); + auto *label = XmlGetAttr(fieldNode, "label"); + mColumnsNames.insert(var, (label != nullptr) ? label : var); } } for (auto *itemNode : TiXmlFilter(xNode, "item")) { - U_TCHAR_MAP *pUserColumn = new U_TCHAR_MAP(10); + UNIQUE_MAP *pUserColumn = new UNIQUE_MAP(10); for (auto *fieldNode : TiXmlFilter(itemNode, "field")) { - if (const char* var = XmlGetAttr(fieldNode, "var")) { + if (auto *var = XmlGetAttr(fieldNode, "var")) { if (auto *textNode = XmlFirstChild(fieldNode, "value")) { - Utf2T wszVar(var), wszText(textNode->GetText()); - if (!mColumnsNames[wszVar.get()]) - mColumnsNames.insert(wszVar, wszVar); - pUserColumn->insert(wszVar, wszText); + if (!mColumnsNames[var]) + mColumnsNames.insert(var, var); + pUserColumn->insert(var, textNode->GetText()); } } } @@ -338,28 +337,27 @@ void CJabberProto::OnIqResultAdvancedSearch(const TiXmlElement *iqNode, CJabberI else { // 2. Field list search results info for (auto *itemNode : TiXmlFilter(queryNode, "item")) { - U_TCHAR_MAP *pUserColumn = new U_TCHAR_MAP(10); + UNIQUE_MAP *pUserColumn = new UNIQUE_MAP(10); - Utf2T jid(XmlGetAttr(itemNode, "jid")); - wchar_t *keyReturned; - mColumnsNames.insertCopyKey(L"jid", L"jid", &keyReturned, CopyKey, DestroyKey); - mColumnsNames.insert(L"jid", keyReturned); - pUserColumn->insertCopyKey(L"jid", jid, nullptr, CopyKey, DestroyKey); + auto *jid = XmlGetAttr(itemNode, "jid"); + char *keyReturned; + mColumnsNames.insertCopyKey("jid", "jid", &keyReturned); + mColumnsNames.insert("jid", keyReturned); + pUserColumn->insertCopyKey("jid", jid, nullptr); for (auto *child : TiXmlEnum(itemNode)) { const char *szColumnName = child->Name(); if (szColumnName) { const char *pszChild = child->GetText(); if (pszChild && *pszChild) { - Utf2T wszVar(szColumnName), wszText(pszChild); - mColumnsNames.insertCopyKey(wszVar, L"", &keyReturned, CopyKey, DestroyKey); - mColumnsNames.insert(wszVar, keyReturned); - pUserColumn->insertCopyKey(wszVar, wszText, nullptr, CopyKey, DestroyKey); + mColumnsNames.insertCopyKey(szColumnName, "", &keyReturned); + mColumnsNames.insert(szColumnName, keyReturned); + pUserColumn->insertCopyKey(szColumnName, pszChild, nullptr); } } } - SearchResults.insert((void*)pUserColumn); + SearchResults.insert(pUserColumn); } } } @@ -383,10 +381,10 @@ void CJabberProto::OnIqResultAdvancedSearch(const TiXmlElement *iqNode, CJabberI return; } - SearchReturnResults((HANDLE)id, (void*)&SearchResults, (U_TCHAR_MAP *)&mColumnsNames); + SearchReturnResults(this, (HANDLE)id, SearchResults, mColumnsNames); for (auto &it : SearchResults) - delete ((U_TCHAR_MAP*)it); + delete ((UNIQUE_MAP*)it); //send success to finish searching ProtoBroadcastAck(0, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)id, 0); diff --git a/protocols/JabberG/src/jabber_search.h b/protocols/JabberG/src/jabber_search.h index 49fc5a2d01..7cdccbba91 100644 --- a/protocols/JabberG/src/jabber_search.h +++ b/protocols/JabberG/src/jabber_search.h @@ -30,8 +30,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. struct JabberSearchFieldsInfo { - wchar_t * szFieldName; - wchar_t * szFieldCaption; + wchar_t *szFieldName; + wchar_t *szFieldCaption; HWND hwndCaptionItem; HWND hwndValueItem; }; @@ -54,54 +54,39 @@ struct JabberSearchData : public MZeroedObject struct Data { wchar_t *Label; - wchar_t * Var; - wchar_t * defValue; - BOOL bHidden; - BOOL bReadOnly; + wchar_t *Var; + wchar_t *defValue; + BOOL bHidden; + BOOL bReadOnly; int Order; - }; static HWND searchHandleDlg = nullptr; // Implementation of MAP class (the list -template class UNIQUE_MAP { + struct _RECORD + { + _RECORD(char *key, char *value = nullptr) : + _key(key), + _value(value) + { } -public: - typedef _KEYTYPE* (*COPYKEYPROC)(_KEYTYPE*); - typedef void(*DESTROYKEYPROC)(_KEYTYPE*); - -private: - typedef struct _tagRECORD - { - _tagRECORD(_KEYTYPE * key, wchar_t * value = nullptr) { _key = key; _value = value; _order = 0; _destroyKeyProc = nullptr; } - ~_tagRECORD() - { - if (_key && _destroyKeyProc) - _destroyKeyProc(_key); - _key = nullptr; - _destroyKeyProc = nullptr; - } - _KEYTYPE *_key; - wchar_t * _value; - int _order; - DESTROYKEYPROC _destroyKeyProc; - } _RECORD; + char *_key; + char *_value; + int _order = 0; + }; int _nextOrder; LIST<_RECORD> _Records; static int _KeysEqual(const _RECORD *p1, const _RECORD *p2) { - if (COMPARATOR) - return (int)(COMPARATOR((p1->_key), (p2->_key))); - else - return (int)(p1->_key < p2->_key); + return mir_strcmpi(p1->_key, p2->_key); } - inline int _remove(_RECORD* p) + inline int _remove(_RECORD *p) { int _itemOrder = p->_order; if (_Records.remove(p)) { @@ -114,7 +99,8 @@ private: } return 0; } - inline _RECORD * _getUnorderedRec(int index) + + inline _RECORD* _getUnorderedRec(int index) { for (auto &rec : _Records) if (rec->_order == index) @@ -130,14 +116,14 @@ public: }; ~UNIQUE_MAP() { - _RECORD * record; + _RECORD *record; int i = 0; while (record = _Records[i++]) delete record; } - int insert(_KEYTYPE* Key, wchar_t *Value) + int insert(const char *Key, const char *Value) { - _RECORD * rec = new _RECORD(Key, Value); + _RECORD *rec = new _RECORD((char*)Key, (char*)Value); int index = _Records.getIndex(rec); if (index < 0) { if (!_Records.insert(rec)) delete rec; @@ -147,72 +133,76 @@ public: } } else { - _Records[index]->_value = Value; + _Records[index]->_value = (char*)Value; delete rec; } return index; } - int insertCopyKey(_KEYTYPE* Key, wchar_t *Value, _KEYTYPE** _KeyReturn, COPYKEYPROC CopyProc, DESTROYKEYPROC DestroyProc) + + int insertCopyKey(const char *Key, const char *Value, char **_KeyReturn) { - _RECORD * rec = new _RECORD(Key, Value); + _RECORD *rec = new _RECORD((char*)Key, (char*)Value); int index = _Records.getIndex(rec); if (index < 0) { - _KEYTYPE* newKey = CopyProc(Key); + char *newKey = mir_strdup(Key); if (!_Records.insert(rec)) { delete rec; - DestroyProc(newKey); - if (_KeyReturn) *_KeyReturn = nullptr; + mir_free(newKey); + if (_KeyReturn) + *_KeyReturn = nullptr; } else { rec->_key = newKey; - rec->_destroyKeyProc = DestroyProc; index = _Records.getIndex(rec); rec->_order = _nextOrder++; - if (_KeyReturn) *_KeyReturn = newKey; + if (_KeyReturn) + *_KeyReturn = newKey; } } else { - _Records[index]->_value = Value; - if (_KeyReturn) *_KeyReturn = _Records[index]->_key; + _Records[index]->_value = (char*)Value; + if (_KeyReturn) + *_KeyReturn = _Records[index]->_key; delete rec; } return index; } - inline wchar_t* operator[](_KEYTYPE* _KEY) const + + inline char* operator[](const char* _KEY) const { - _RECORD rec(_KEY); + _RECORD rec((char*)_KEY); int index = _Records.getIndex(&rec); - _RECORD * rv = _Records[index]; + _RECORD *rv = _Records[index]; if (rv) { if (rv->_value) return rv->_value; else - return L""; + return ""; } else return nullptr; } - inline wchar_t* operator[](int index) const + inline char* operator[](int index) const { - _RECORD * rv = _Records[index]; + _RECORD *rv = _Records[index]; if (rv) return rv->_value; else return nullptr; } - inline _KEYTYPE* getKeyName(int index) + inline char* getKeyName(int index) { - _RECORD * rv = _Records[index]; + _RECORD *rv = _Records[index]; if (rv) return rv->_key; else return nullptr; } - inline wchar_t * getUnOrdered(int index) + inline char* getUnOrdered(int index) { - _RECORD * rec = _getUnorderedRec(index); + _RECORD *rec = _getUnorderedRec(index); if (rec) return rec->_value; else return nullptr; } - inline _KEYTYPE * getUnOrderedKeyName(int index) + inline char* getUnOrderedKeyName(int index) { - _RECORD * rec = _getUnorderedRec(index); + _RECORD *rec = _getUnorderedRec(index); if (rec) return rec->_key; else return nullptr; } @@ -222,29 +212,19 @@ public: } inline int removeUnOrdered(int index) { - _RECORD * p = _getUnorderedRec(index); + _RECORD *p = _getUnorderedRec(index); if (p) return _remove(p); else return 0; } inline int remove(int index) { - _RECORD * p = _Records[index]; + _RECORD *p = _Records[index]; if (p) return _remove(p); else return 0; } - inline int getIndex(_KEYTYPE * key) + inline int getIndex(char *key) { _RECORD temp(key); return _Records.getIndex(&temp); } }; - -inline int TCharKeyCmp(wchar_t* a, wchar_t* b) -{ - return (int)(mir_wstrcmpi(a, b)); -} - -inline int CharKeyCmp(char *a, char *b) -{ - return mir_strcmpi(a, b); -} diff --git a/protocols/JabberG/src/jabber_svc.cpp b/protocols/JabberG/src/jabber_svc.cpp index b6415a2c7e..8ac857be1b 100644 --- a/protocols/JabberG/src/jabber_svc.cpp +++ b/protocols/JabberG/src/jabber_svc.cpp @@ -146,15 +146,15 @@ INT_PTR __cdecl CJabberProto::JabberGetAvatarInfo(WPARAM wParam, LPARAM lParam) if (item != nullptr) { BOOL isXVcard = getByte(pai->hContact, "AvatarXVcard", 0); - char szJid[JABBER_MAX_JID_LEN]; szJid[0] = 0; + CMStringA szJid; if (item->arResources.getCount() != 0 && !isXVcard) if (char *bestResName = ListGetBestClientResourceNamePtr(tszJid)) - mir_snprintf(szJid, "%s/%s", tszJid, bestResName); + szJid = MakeJid(tszJid, bestResName); - if (szJid[0] == 0) - strncpy_s(szJid, tszJid, _TRUNCATE); + if (szJid.IsEmpty()) + szJid = tszJid; - debugLogA("Rereading %s for %s", isXVcard ? JABBER_FEAT_VCARD_TEMP : JABBER_FEAT_AVATAR, szJid); + debugLogA("Rereading %s for %s", isXVcard ? JABBER_FEAT_VCARD_TEMP : JABBER_FEAT_AVATAR, szJid.c_str()); m_ThreadInfo->send((isXVcard) ? XmlNodeIq(AddIQ(&CJabberProto::OnIqResultGetVCardAvatar, JABBER_IQ_TYPE_GET, szJid)) << XCHILDNS("vCard", JABBER_FEAT_VCARD_TEMP) : @@ -511,15 +511,15 @@ INT_PTR __cdecl CJabberProto::JabberSendNudge(WPARAM hContact, LPARAM) if (jid == nullptr) return 0; - char tszJid[JABBER_MAX_JID_LEN]; + CMStringA szJid; char *szResource = ListGetBestClientResourceNamePtr(jid); if (szResource) - mir_snprintf(tszJid, "%s/%s", jid, szResource); + szJid = MakeJid(jid, szResource); else - strncpy_s(tszJid, jid, _TRUNCATE); + szJid = jid; m_ThreadInfo->send( - XmlNode("message") << XATTR("type", "headline") << XATTR("to", tszJid) + XmlNode("message") << XATTR("type", "headline") << XATTR("to", szJid) << XCHILDNS("attention", JABBER_FEAT_ATTENTION)); return 0; } diff --git a/protocols/JabberG/src/jabber_userinfo.cpp b/protocols/JabberG/src/jabber_userinfo.cpp index eb4a3638b3..16a0097a95 100755 --- a/protocols/JabberG/src/jabber_userinfo.cpp +++ b/protocols/JabberG/src/jabber_userinfo.cpp @@ -231,9 +231,7 @@ static void sttFillResourceInfo(CJabberProto *ppro, HWND hwndTree, HTREEITEM hti } // caps - mir_snprintf(buf, "%s/%s", item->jid, r->m_szResourceName); - JabberCapsBits jcb = ppro->GetResourceCapabilities(buf, r); - + JabberCapsBits jcb = ppro->GetResourceCapabilities(MakeJid(item->jid, r->m_szResourceName), r); if (!(jcb & JABBER_RESOURCE_CAPS_ERROR)) { HTREEITEM htiCaps = sttFillInfoLine(hwndTree, htiResource, ppro->LoadIconEx("main"), nullptr, TranslateU("Client capabilities"), sttInfoLineId(resource, INFOLINE_CAPS)); int i; diff --git a/protocols/JabberG/src/jabber_util.cpp b/protocols/JabberG/src/jabber_util.cpp index 1d946f6a90..981610f811 100755 --- a/protocols/JabberG/src/jabber_util.cpp +++ b/protocols/JabberG/src/jabber_util.cpp @@ -66,6 +66,17 @@ MCONTACT CJabberProto::HContactFromJID(const char *jid, bool bStripResource) return 0; } +CMStringA MakeJid(const char *jid, const char *resource) +{ + CMStringA ret(jid); + if (resource != nullptr) { + ret.AppendChar('/'); + ret.Append(resource); + } + return ret; +} + + char* JabberNickFromJID(const char *jid) { if (jid == nullptr) @@ -494,11 +505,8 @@ void CJabberProto::SendPresence(int status, bool bSendToAll) LISTFOREACH(i, this, LIST_CHATROOM) { JABBER_LIST_ITEM *item = ListGetItemPtrFromIndex(i); - if (item != nullptr && item->nick != nullptr) { - char text[1024]; - mir_snprintf(text, "%s/%s", item->jid, item->nick); - SendPresenceTo(status == ID_STATUS_INVISIBLE ? ID_STATUS_ONLINE : status, text); - } + if (item != nullptr && item->nick != nullptr) + SendPresenceTo(status == ID_STATUS_INVISIBLE ? ID_STATUS_ONLINE : status, MakeJid(item->jid, item->nick)); } } } @@ -549,7 +557,7 @@ char* CJabberProto::GetClientJID(const char *jid, char *dest, size_t destLen) if (p == nullptr) { pResourceStatus r(LI->getBestResource()); if (r != nullptr) - mir_snprintf(dest, destLen, "%s/%s", jid, r->m_szResourceName); + strncpy_s(dest, destLen, MakeJid(jid, r->m_szResourceName), _TRUNCATE); } } diff --git a/protocols/JabberG/src/stdafx.h b/protocols/JabberG/src/stdafx.h index 7eb48fb6b7..f319bb16d2 100755 --- a/protocols/JabberG/src/stdafx.h +++ b/protocols/JabberG/src/stdafx.h @@ -742,6 +742,8 @@ struct TStringPairs typedef char JabberShaStrBuf[2*MIR_SHA1_HASH_SIZE + 1]; +CMStringA MakeJid(const char *jid, const char *resource); + char* JabberNickFromJID(const char *jid); char* JabberPrepareJid(const char *jid); char* JabberSha1(const char *str, JabberShaStrBuf buf); -- cgit v1.2.3