From c9e483e0fb1566d210530339d13a0e6e91260200 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Tue, 19 Feb 2019 01:13:01 +0300 Subject: more checks for GetText() --- protocols/JabberG/src/jabber_adhoc.cpp | 12 ++-- protocols/JabberG/src/jabber_agent.cpp | 4 +- protocols/JabberG/src/jabber_ft.cpp | 6 +- protocols/JabberG/src/jabber_groupchat.cpp | 20 +++--- protocols/JabberG/src/jabber_iq_handlers.cpp | 20 +++--- protocols/JabberG/src/jabber_iqid.cpp | 32 +++++----- protocols/JabberG/src/jabber_iqid_muc.cpp | 4 +- protocols/JabberG/src/jabber_omemo.cpp | 10 +-- protocols/JabberG/src/jabber_opt.cpp | 8 +-- protocols/JabberG/src/jabber_rc.cpp | 5 +- protocols/JabberG/src/jabber_search.cpp | 4 +- protocols/JabberG/src/jabber_thread.cpp | 93 +++++++++++++++++----------- protocols/JabberG/src/jabber_util.cpp | 14 +++-- protocols/JabberG/src/jabber_xml.cpp | 12 +++- protocols/JabberG/src/jabber_xml.h | 4 +- 15 files changed, 138 insertions(+), 110 deletions(-) diff --git a/protocols/JabberG/src/jabber_adhoc.cpp b/protocols/JabberG/src/jabber_adhoc.cpp index b19a76e3d5..e9856a685d 100644 --- a/protocols/JabberG/src/jabber_adhoc.cpp +++ b/protocols/JabberG/src/jabber_adhoc.cpp @@ -214,10 +214,10 @@ int CJabberProto::AdHoc_OnJAHMProcessResult(HWND hwndDlg, TiXmlElement *workNode // use jabber:x:data form HWND hFrame = GetDlgItem(hwndDlg, IDC_FRAME); ShowWindow(GetDlgItem(hwndDlg, IDC_FRAME_TEXT), SW_HIDE); - if (const char *ptszInstr = xNode->FirstChildElement("instructions")->GetText()) - JabberFormSetInstruction(hwndDlg, ptszInstr); - else if (const char *ptszTitle = xNode->FirstChildElement("title")->GetText()) - JabberFormSetInstruction(hwndDlg, ptszTitle); + if (auto *n = xNode->FirstChildElement("instructions")) + JabberFormSetInstruction(hwndDlg, n->GetText()); + else if (n = xNode->FirstChildElement("title")) + JabberFormSetInstruction(hwndDlg, n->GetText()); else JabberFormSetInstruction(hwndDlg, Translate(status)); JabberFormCreateUI(hFrame, xNode, &dat->CurrentHeight); @@ -228,8 +228,8 @@ int CJabberProto::AdHoc_OnJAHMProcessResult(HWND hwndDlg, TiXmlElement *workNode int toHide[] = { IDC_FRAME_TEXT, IDC_FRAME, IDC_VSCROLL, 0 }; sttShowControls(hwndDlg, FALSE, toHide); - const char *noteText = commandNode->FirstChildElement("note")->GetText(); - JabberFormSetInstruction(hwndDlg, noteText ? noteText : Translate(status)); + auto *note = commandNode->FirstChildElement("note"); + JabberFormSetInstruction(hwndDlg, note ? note->GetText() : Translate(status)); } // check actions diff --git a/protocols/JabberG/src/jabber_agent.cpp b/protocols/JabberG/src/jabber_agent.cpp index 4639d07795..1cb0aceae4 100644 --- a/protocols/JabberG/src/jabber_agent.cpp +++ b/protocols/JabberG/src/jabber_agent.cpp @@ -161,8 +161,8 @@ public: if (auto *xNode = queryNode->FirstChildElement("x")) { // use new jabber:x:data form - if (const char *ptszInstr = xNode->FirstChildElement("instructions")->GetText()) - JabberFormSetInstruction(m_hwnd, ptszInstr); + if (auto *n = xNode->FirstChildElement("instructions")) + JabberFormSetInstruction(m_hwnd, n->GetText()); JabberFormCreateUI(hFrame, xNode, &m_formHeight /*dummy*/); } diff --git a/protocols/JabberG/src/jabber_ft.cpp b/protocols/JabberG/src/jabber_ft.cpp index 5ba46f181e..8095a97b65 100644 --- a/protocols/JabberG/src/jabber_ft.cpp +++ b/protocols/JabberG/src/jabber_ft.cpp @@ -319,8 +319,7 @@ void CJabberProto::FtHandleSiRequest(const TiXmlElement *iqNode) if (!bIbbOnly) { for (auto *it : TiXmlFilter(fieldNode, "option")) { - auto *n = it->FirstChildElement("value"); - if (n != nullptr && n->GetText()) { + if (auto *n = it->FirstChildElement("value")) { if (!mir_strcmp(n->GetText(), JABBER_FEAT_BYTESTREAMS)) { optionNode = it; ftType = FT_BYTESTREAM; @@ -333,8 +332,7 @@ void CJabberProto::FtHandleSiRequest(const TiXmlElement *iqNode) // try IBB only if bytestreams support not found or BsOnlyIBB flag exists if (bIbbOnly || !optionNode) { for (auto *it : TiXmlFilter(fieldNode, "option")) { - auto *n = it->FirstChildElement("value"); - if (n != nullptr && n->GetText()) { + if (auto *n = it->FirstChildElement("value")) { if (!mir_strcmp(n->GetText(), JABBER_FEAT_IBB)) { optionNode = it; ftType = FT_IBB; diff --git a/protocols/JabberG/src/jabber_groupchat.cpp b/protocols/JabberG/src/jabber_groupchat.cpp index dda33f7879..d4c595d391 100644 --- a/protocols/JabberG/src/jabber_groupchat.cpp +++ b/protocols/JabberG/src/jabber_groupchat.cpp @@ -841,19 +841,21 @@ void CJabberProto::GroupchatProcessPresence(const TiXmlElement *node) // Update status of room participant int status = ID_STATUS_ONLINE; - const char *ptszShow = node->FirstChildElement("show")->GetText(); - if (ptszShow) { - if (!mir_strcmp(ptszShow, "away")) status = ID_STATUS_AWAY; - else if (!mir_strcmp(ptszShow, "xa")) status = ID_STATUS_NA; - else if (!mir_strcmp(ptszShow, "dnd")) status = ID_STATUS_DND; - else if (!mir_strcmp(ptszShow, "chat")) status = ID_STATUS_FREECHAT; + if (auto *n = node->FirstChildElement("show")) { + if (!mir_strcmp(n->GetText(), "away")) status = ID_STATUS_AWAY; + else if (!mir_strcmp(n->GetText(), "xa")) status = ID_STATUS_NA; + else if (!mir_strcmp(n->GetText(), "dnd")) status = ID_STATUS_DND; + else if (!mir_strcmp(n->GetText(), "chat")) status = ID_STATUS_FREECHAT; } - const char *str = node->FirstChildElement("status")->GetText(); + const char *str = nullptr; + if (auto *n = node->FirstChildElement("status")) + str = n->GetText(); char priority = 0; - if (auto *ptszPriority = node->FirstChildElement("priority")->GetText()) - priority = atoi(ptszPriority); + if (auto *n = node->FirstChildElement("priority")) + if (n->GetText()) + priority = atoi(n->GetText()); bool bStatusChanged = false, bRoomCreated = false, bAffiliationChanged = false, bRoleChanged = false; int newRes = ListAddResource(LIST_CHATROOM, from, status, str, priority, cnick) ? GC_EVENT_JOIN : 0; diff --git a/protocols/JabberG/src/jabber_iq_handlers.cpp b/protocols/JabberG/src/jabber_iq_handlers.cpp index cab8e52428..2050c6350e 100644 --- a/protocols/JabberG/src/jabber_iq_handlers.cpp +++ b/protocols/JabberG/src/jabber_iq_handlers.cpp @@ -331,19 +331,19 @@ BOOL CJabberProto::OnIqRequestOOB(const TiXmlElement*, CJabberIqInfo *pInfo) ft->httpPath = nullptr; // Parse the URL - wchar_t *str = (wchar_t*)n->GetText(); // URL of the file to get - if (!wcsnicmp(str, L"http://", 7)) { - wchar_t *p = str + 7, *q; - if ((q = wcschr(p, '/')) != nullptr) { - wchar_t text[1024]; + const char *str = n->GetText(); // URL of the file to get + if (!mir_strncmpi(str, "http://", 7)) { + const char *p = str + 7, *q; + if ((q = strchr(p, '/')) != nullptr) { + char text[1024]; if (q - p < _countof(text)) { - wcsncpy_s(text, p, q - p); + strncpy_s(text, p, q - p); text[q - p] = '\0'; - if ((p = wcschr(text, ':')) != nullptr) { - ft->httpPort = (WORD)_wtoi(p + 1); - *p = '\0'; + if (char *d = strchr(text, ':')) { + ft->httpPort = (WORD)atoi(d + 1); + *d = '\0'; } - ft->httpHostName = mir_u2a(text); + ft->httpHostName = mir_strdup(text); } } } diff --git a/protocols/JabberG/src/jabber_iqid.cpp b/protocols/JabberG/src/jabber_iqid.cpp index 2eb7a03690..17bb43304f 100755 --- a/protocols/JabberG/src/jabber_iqid.cpp +++ b/protocols/JabberG/src/jabber_iqid.cpp @@ -400,8 +400,8 @@ void CJabberProto::OnIqResultGetRoster(const TiXmlElement *iqNode, CJabberIqInfo mir_free(item->nick); item->nick = nick; - auto *groupNode = itemNode->FirstChildElement("group"); - replaceStr(item->group, groupNode->GetText()); + if (auto *groupNode = itemNode->FirstChildElement("group")) + replaceStr(item->group, groupNode->GetText()); // check group delimiters if (item->group && szGroupDelimeter) { @@ -573,9 +573,9 @@ void CJabberProto::OnIqResultGetVcardPhoto(const TiXmlElement *n, MCONTACT hCont return; const char *szPicType = nullptr; - if (const char *ptszType = n->FirstChildElement("TYPE")->GetText()) - if (ProtoGetAvatarFormatByMimeType(ptszType) != PA_FORMAT_UNKNOWN) - szPicType = ptszType; + if (auto *t = n->FirstChildElement("TYPE")) + if (ProtoGetAvatarFormatByMimeType(t->GetText()) != PA_FORMAT_UNKNOWN) + szPicType = t->GetText(); if (szPicType == nullptr) szPicType = ProtoGetAvatarMimeType(ProtoGetBufferFormat(buffer)); @@ -1153,14 +1153,14 @@ void CJabberProto::OnIqResultSetSearch(const TiXmlElement *iqNode, CJabberIqInfo if (auto *jid = itemNode->Attribute("jid")) { psr.id.w = mir_utf8decodeW(jid); debugLogW(L"Result jid = %s", jid); - if (auto *p = itemNode->FirstChildElement("nick")->GetText()) - psr.nick.w = mir_utf8decodeW(p); - if (auto *p = itemNode->FirstChildElement("first")->GetText()) - psr.firstName.w = mir_utf8decodeW(p); - if (auto *p = itemNode->FirstChildElement("last")->GetText()) - psr.lastName.w = mir_utf8decodeW(p); - if (auto *p = itemNode->FirstChildElement("email")->GetText()) - psr.email.w = mir_utf8decodeW(p); + if (auto *p = itemNode->FirstChildElement("nick")) + psr.nick.w = mir_utf8decodeW(p->GetText()); + if (auto *p = itemNode->FirstChildElement("first")) + psr.firstName.w = mir_utf8decodeW(p->GetText()); + if (auto *p = itemNode->FirstChildElement("last")) + psr.lastName.w = mir_utf8decodeW(p->GetText()); + if (auto *p = itemNode->FirstChildElement("email")) + psr.email.w = mir_utf8decodeW(p->GetText()); ProtoBroadcastAck(0, ACKTYPE_SEARCH, ACKRESULT_DATA, (HANDLE)id, (LPARAM)&psr); replaceStrW(psr.id.w, 0); @@ -1208,7 +1208,7 @@ void CJabberProto::OnIqResultExtSearch(const TiXmlElement *iqNode, CJabberIqInfo continue; if (!mir_strcmp(fieldName, "jid")) { - psr.id.w = (wchar_t*)n->GetText(); + psr.id.w = mir_utf8decodeW(n->GetText()); debugLogW(L"Result jid = %s", psr.id.w); } else if (!mir_strcmp(fieldName, "nickname")) @@ -1284,13 +1284,13 @@ void CJabberProto::OnIqResultGetVCardAvatar(const TiXmlElement *iqNode, CJabberI return; } - const char *mimeType = vCard->FirstChildElement("TYPE")->GetText(); + auto *mimeType = vCard->FirstChildElement("TYPE"); auto *n = vCard->FirstChildElement("BINVAL"); if (n == nullptr) return; setByte(hContact, "AvatarXVcard", 1); - OnIqResultGotAvatar(hContact, n, mimeType); + OnIqResultGotAvatar(hContact, n, mimeType->GetText()); } void CJabberProto::OnIqResultGetClientAvatar(const TiXmlElement *iqNode, CJabberIqInfo*) diff --git a/protocols/JabberG/src/jabber_iqid_muc.cpp b/protocols/JabberG/src/jabber_iqid_muc.cpp index 5a4bcade2e..ca638e28aa 100644 --- a/protocols/JabberG/src/jabber_iqid_muc.cpp +++ b/protocols/JabberG/src/jabber_iqid_muc.cpp @@ -122,9 +122,9 @@ class CJabberMucJidListDlg : public CJabberDlgBase lvi.pszText = (wchar_t*)jid; if (m_info->type == MUC_BANLIST) { - const char *reason = itemNode->FirstChildElement("reason")->GetText(); + auto *reason = itemNode->FirstChildElement("reason"); if (reason != nullptr) { - mir_snwprintf(tszItemText, L"%s (%s)", Utf2T(jid).get(), Utf2T(reason).get()); + mir_snwprintf(tszItemText, L"%s (%s)", Utf2T(jid).get(), Utf2T(reason->GetText()).get()); lvi.pszText = tszItemText; } } diff --git a/protocols/JabberG/src/jabber_omemo.cpp b/protocols/JabberG/src/jabber_omemo.cpp index 2d07e25ccd..0b363fe938 100755 --- a/protocols/JabberG/src/jabber_omemo.cpp +++ b/protocols/JabberG/src/jabber_omemo.cpp @@ -2018,22 +2018,22 @@ void CJabberProto::OmemoOnIqResultGetBundle(const TiXmlElement *iqNode, CJabberI debugLogA("Jabber OMEMO: error: device bundle does not contain bundle node"); return; } - const char *signedPreKeyPublic = bundle->FirstChildElement("signedPreKeyPublic")->GetText(); + auto *signedPreKeyPublic = bundle->FirstChildElement("signedPreKeyPublic"); if (!signedPreKeyPublic) { debugLogA("Jabber OMEMO: error: device bundle does not contain signedPreKeyPublic node"); return; } - const char *signedPreKeyId = bundle->FirstChildElement("signedPreKeyPublic")->Attribute("signedPreKeyId"); + const char *signedPreKeyId = signedPreKeyPublic->Attribute("signedPreKeyId"); if (!signedPreKeyId) { debugLogA("Jabber OMEMO: error: device bundle does not contain signedPreKeyId attr"); return; } - const char *signedPreKeySignature = bundle->FirstChildElement("signedPreKeySignature")->GetText(); + auto *signedPreKeySignature = bundle->FirstChildElement("signedPreKeySignature"); if (!signedPreKeySignature) { debugLogA("Jabber OMEMO: error: device bundle does not contain signedPreKeySignature node"); return; } - const char *identityKey = bundle->FirstChildElement("identityKey")->GetText(); + auto *identityKey = bundle->FirstChildElement("identityKey"); if (!identityKey) { debugLogA("Jabber OMEMO: error: device bundle does not contain identityKey node"); return; @@ -2068,7 +2068,7 @@ void CJabberProto::OmemoOnIqResultGetBundle(const TiXmlElement *iqNode, CJabberI return; //failed to create session store } - if (!m_omemo.build_session(hContact, jid, device_id, preKeyId, preKeyPublic, signedPreKeyId, signedPreKeyPublic, signedPreKeySignature, identityKey)) { + if (!m_omemo.build_session(hContact, jid, device_id, preKeyId, preKeyPublic, signedPreKeyId, signedPreKeyPublic->GetText(), signedPreKeySignature->GetText(), identityKey->GetText())) { debugLogA("Jabber OMEMO: error: omemo::build_session failed"); return; //failed to build signal(omemo) session } diff --git a/protocols/JabberG/src/jabber_opt.cpp b/protocols/JabberG/src/jabber_opt.cpp index f4414e36fd..05fddd6d2f 100755 --- a/protocols/JabberG/src/jabber_opt.cpp +++ b/protocols/JabberG/src/jabber_opt.cpp @@ -1006,8 +1006,8 @@ void CJabberProto::_RosterHandleGetRequest(const TiXmlElement *node, CJabberIqIn const char *name = item->Attribute("name"); const char *subscription = item->Attribute("subscription"); - const char *group = item->FirstChildElement("group")->GetText(); - _RosterInsertListItem(hList, jid, name, group, subscription, TRUE); + auto *group = item->FirstChildElement("group"); + _RosterInsertListItem(hList, jid, name, (group) ? group->GetText() : 0, subscription, TRUE); } // now it is require to process whole contact list to add not in roster contacts @@ -1080,8 +1080,8 @@ void CJabberProto::_RosterHandleGetRequest(const TiXmlElement *node, CJabberIqIn bPushed = TRUE; } if (!bPushed) { - const char *rosterGroup = itemRoster->FirstChildElement("group")->GetText(); - if ((rosterGroup != nullptr || group[0] != 0) && mir_strcmpi(rosterGroup, szGroup)) + auto *rosterGroup = itemRoster->FirstChildElement("group"); + if ((rosterGroup != nullptr || group[0] != 0) && mir_strcmpi(rosterGroup->GetText(), szGroup)) bPushed = TRUE; } } diff --git a/protocols/JabberG/src/jabber_rc.cpp b/protocols/JabberG/src/jabber_rc.cpp index 26e3b801b4..272f5b7c06 100644 --- a/protocols/JabberG/src/jabber_rc.cpp +++ b/protocols/JabberG/src/jabber_rc.cpp @@ -341,10 +341,11 @@ int CJabberProto::AdhocSetStatusHandler(const TiXmlElement*, CJabberIqInfo *pInf if (!fieldNode) return JABBER_ADHOC_HANDLER_STATUS_CANCEL; - const char *pszValue = fieldNode->FirstChildElement("value")->GetText(); - if (pszValue == nullptr) + auto *nodeValue = fieldNode->FirstChildElement("value"); + if (nodeValue == nullptr) return JABBER_ADHOC_HANDLER_STATUS_CANCEL; + const char *pszValue = nodeValue->GetText(); int status; if (!mir_strcmp(pszValue, "away")) status = ID_STATUS_AWAY; else if (!mir_strcmp(pszValue, "xa")) status = ID_STATUS_NA; diff --git a/protocols/JabberG/src/jabber_search.cpp b/protocols/JabberG/src/jabber_search.cpp index 04e8427255..ef39ad41d6 100644 --- a/protocols/JabberG/src/jabber_search.cpp +++ b/protocols/JabberG/src/jabber_search.cpp @@ -323,8 +323,8 @@ void CJabberProto::OnIqResultAdvancedSearch(const TiXmlElement *iqNode, CJabberI U_TCHAR_MAP *pUserColumn = new U_TCHAR_MAP(10); for (auto *fieldNode : TiXmlFilter(itemNode, "field")) { if (const char* var = fieldNode->Attribute("var")) { - if (const char* Text = fieldNode->FirstChildElement("value")->GetText()) { - Utf2T wszVar(var), wszText(Text); + if (auto *textNode = fieldNode->FirstChildElement("value")) { + Utf2T wszVar(var), wszText(textNode->GetText()); if (!mColumnsNames[wszVar]) mColumnsNames.insert(wszVar, wszVar); pUserColumn->insert(wszVar, wszText); diff --git a/protocols/JabberG/src/jabber_thread.cpp b/protocols/JabberG/src/jabber_thread.cpp index 843fcc6608..14c000367e 100755 --- a/protocols/JabberG/src/jabber_thread.cpp +++ b/protocols/JabberG/src/jabber_thread.cpp @@ -204,16 +204,15 @@ void CJabberProto::xmlStreamInitializeNow(ThreadData *info) m_szXmlStreamToBeInitialized = nullptr; } - XmlNode n("xml"); n << XATTR("version", "1.0") << XATTR("encoding", "UTF-8"); - - TiXmlElement *stream = n << XCHILDNS("stream:stream", "jabber:client") << XATTR("to", info->conn.server) - << XATTR("xmlns:stream", "http://etherx.jabber.org/streams"); + XmlNode n("stream:stream"); + n << XATTR("xmlns", "jabber:client") << XATTR("to", info->conn.server) << XATTR("xmlns:stream", "http://etherx.jabber.org/streams"); + n.InsertFirstChild(n.NewDeclaration("xml version=\"1.0\" encoding=\"UTF-8\"")); if (m_tszSelectedLang) - XmlAddAttr(stream, "xml:lang", m_tszSelectedLang); + n << XATTR("xml:lang", m_tszSelectedLang); if (!m_bDisable3920auth) - XmlAddAttr(stream, "version", "1.0"); + n << XATTR("version", "1.0"); tinyxml2::XMLPrinter printer(0, true); n.Print(&printer); @@ -408,7 +407,6 @@ LBL_FatalError: } xmlStreamInitializeNow(&info); - const wchar_t *tag = L"stream:stream"; debugLogA("Entering main recv loop"); int datalen = 0; @@ -451,12 +449,24 @@ LBL_FatalError: recvRest: info.buffer[datalen] = '\0'; + int bytesParsed = 0; TiXmlDocument root; - if (0 == root.Parse(info.buffer, datalen)) + if (0 == root.Parse(info.buffer)) { for (auto *n : TiXmlEnum(&root)) OnProcessProtocol(n, &info); + bytesParsed = root.BytesParsed(); + } + else if (root.ErrorID() == 14) { + root.Clear(); + strcpy(&info.buffer[datalen], ""); + datalen = (int)strlen(info.buffer); + if (0 == root.Parse(info.buffer)) { + for (auto *n : TiXmlEnum(&root)) + OnProcessProtocol(n, &info); + bytesParsed = root.BytesParsed(); + } + } - int bytesParsed = 0; debugLogA("bytesParsed = %d", bytesParsed); if (bytesParsed > 0) { @@ -475,10 +485,8 @@ recvRest: } else debugLogA("Unknown state: bytesParsed=%d, datalen=%d, jabberNetworkBufferSize=%d", bytesParsed, datalen, jabberNetworkBufferSize); - if (m_szXmlStreamToBeInitialized) { + if (m_szXmlStreamToBeInitialized) xmlStreamInitializeNow(&info); - tag = L"stream:stream"; - } if (root.FirstChild() && datalen) goto recvRest; @@ -1111,10 +1119,10 @@ void CJabberProto::OnProcessMessage(const TiXmlElement *node, ThreadData *info) if (bodyNode == nullptr) bodyNode = node->FirstChildElement("body"); - const char *ptszSubject = node->FirstChildElement("subject")->GetText(); - if (ptszSubject && *ptszSubject) { + auto *subject = node->FirstChildElement("subject"); + if (subject && subject->GetText()) { szMessage.Append("Subject: "); - szMessage.Append(ptszSubject); + szMessage.Append(subject->GetText()); szMessage.Append("\r\n"); } @@ -1212,9 +1220,9 @@ void CJabberProto::OnProcessMessage(const TiXmlElement *node, ThreadData *info) memset(pParams, 0, sizeof(CJabberHttpAuthParams)); pParams->m_nType = CJabberHttpAuthParams::MSG; pParams->m_szFrom = mir_strdup(from); - const char *ptszThread = node->FirstChildElement("thread")->GetText(); - if (ptszThread && *ptszThread) - pParams->m_szThreadId = mir_strdup(ptszThread); + auto *threadNode = node->FirstChildElement("thread"); + if (threadNode) + pParams->m_szThreadId = mir_strdup(threadNode->GetText()); pParams->m_szId = mir_strdup(szId); pParams->m_szMethod = mir_strdup(szMethod); pParams->m_szUrl = mir_strdup(szUrl); @@ -1321,23 +1329,25 @@ void CJabberProto::OnProcessMessage(const TiXmlElement *node, ThreadData *info) } } else if (!mir_strcmp(pszXmlns, JABBER_FEAT_OOB2)) { - const char *pszUrl = xNode->FirstChildElement("url")->GetText(); - if (pszUrl != nullptr && *pszUrl) { + auto *url = xNode->FirstChildElement("url"); + if (url != nullptr && url->GetText()) { if (!szMessage.IsEmpty()) szMessage.Append("\r\n"); - szMessage.Append(pszUrl); + szMessage.Append(url->GetText()); } } else if (!mir_strcmp(pszXmlns, JABBER_FEAT_MUC_USER)) { auto *inviteNode = xNode->FirstChildElement("invite"); if (inviteNode != nullptr) { inviteFromJid = inviteNode->Attribute("from"); - inviteReason = inviteNode->FirstChildElement("reason")->GetText(); + if (auto *reasonNode = inviteNode->FirstChildElement("reason")) + inviteReason = reasonNode->GetText(); inviteRoomJid = from; if (inviteReason == nullptr) inviteReason = szMessage; isChatRoomInvitation = true; - invitePassword = xNode->FirstChildElement("password")->GetText(); + if (auto *n = xNode->FirstChildElement("password")) + invitePassword = n->GetText(); } } else if (!mir_strcmp(pszXmlns, JABBER_FEAT_ROSTER_EXCHANGE) && item != nullptr && (item->subscription == SUB_BOTH || item->subscription == SUB_TO)) { @@ -1347,12 +1357,12 @@ void CJabberProto::OnProcessMessage(const TiXmlElement *node, ThreadData *info) const char *action = iNode->Attribute("action"); const char *jid = iNode->Attribute("jid"); const char *nick = iNode->Attribute("name"); - const char *group = iNode->FirstChildElement("group")->GetText(); + auto *group = iNode->FirstChildElement("group"); if (action && jid && strstr(jid, chkJID)) { if (!mir_strcmp(action, "add")) { MCONTACT cc = DBCreateContact(jid, nick, false, false); - if (group) - db_set_utf(cc, "CList", "Group", group); + if (group && group->GetText()) + db_set_utf(cc, "CList", "Group", group->GetText()); } else if (!mir_strcmp(action, "delete")) { MCONTACT cc = HContactFromJID(jid); @@ -1607,11 +1617,16 @@ void CJabberProto::OnProcessPresence(const TiXmlElement *node, ThreadData *info) } } - char priority = 0; - if (const char *ptszPriority = node->FirstChildElement("priority")->GetText()) - priority = atoi(ptszPriority); + int priority = 0; + if (auto *n = node->FirstChildElement("priority")) + if (n->GetText()) + priority = atoi(n->GetText()); + + const char *pszStatus = nullptr; + if (auto *n = node->FirstChildElement("status")) + pszStatus = n->GetText(); - ListAddResource(LIST_ROSTER, from, status, node->FirstChildElement("status")->GetText(), priority); + ListAddResource(LIST_ROSTER, from, status, pszStatus, priority); // XEP-0115: Entity Capabilities pResourceStatus r(ResourceInfoFromJID(from)); @@ -1631,14 +1646,14 @@ void CJabberProto::OnProcessPresence(const TiXmlElement *node, ThreadData *info) debugLogA("Avatar enabled"); for (auto *xNode : TiXmlFilter(node, "x")) { if (!bHasAvatar && !mir_strcmp(xNode->Attribute("xmlns"), "jabber:x:avatar")) { - const char *ptszHash = xNode->FirstChildElement("hash")->GetText(); - if (ptszHash != nullptr) { + auto *xmlHash = xNode->FirstChildElement("hash"); + if (xmlHash != nullptr && xmlHash->GetText()) { delSetting(hContact, "AvatarXVcard"); debugLogA("AvatarXVcard deleted"); - setString(hContact, "AvatarHash", ptszHash); + setString(hContact, "AvatarHash", xmlHash->GetText()); bHasAvatar = true; ptrA saved(getStringA(hContact, "AvatarSaved")); - if (saved == nullptr || mir_strcmp(saved, ptszHash)) { + if (saved == nullptr || mir_strcmp(saved, xmlHash->GetText())) { debugLogA("Avatar was changed"); ProtoBroadcastAck(hContact, ACKTYPE_AVATAR, ACKRESULT_STATUS, nullptr, 0); } @@ -1705,7 +1720,8 @@ void CJabberProto::OnProcessPresence(const TiXmlElement *node, ThreadData *info) // set status only if no more available resources if (!item->arResources.getCount()) { item->getTemp()->m_iStatus = ID_STATUS_OFFLINE; - item->getTemp()->m_szStatusMessage = mir_strdup(node->FirstChildElement("status")->GetText()); + if (auto *n = node->FirstChildElement("status")) + item->getTemp()->m_szStatusMessage = mir_strdup(n->GetText()); } } else debugLogW(L"SKIP Receive presence offline from %s (who is not in my roster)", from); @@ -2057,8 +2073,11 @@ int ThreadData::send(TiXmlElement *node) if (this == nullptr) return 0; - while (auto *parent = node->Parent()->ToElement()) - node = parent; + while (auto *parent = node->Parent()) { + if (parent->ToDocument()) + break; + node = parent->ToElement(); + } if (proto->m_bEnableStreamMgmt) proto->m_StrmMgmt.HandleOutgoingNode(node); //TODO: is this a correct place ?, looks like some nodes does not goes here... diff --git a/protocols/JabberG/src/jabber_util.cpp b/protocols/JabberG/src/jabber_util.cpp index fcd925f5d7..b19fe77437 100755 --- a/protocols/JabberG/src/jabber_util.cpp +++ b/protocols/JabberG/src/jabber_util.cpp @@ -66,7 +66,7 @@ MCONTACT CJabberProto::HContactFromJID(const char *jid, bool bStripResource) return 0; } -char* JabberNickFromJID(const char *jid) +char* JabberNickFromJID(const char *jid) { if (jid == nullptr) return mir_strdup(""); @@ -165,7 +165,7 @@ wchar_t* JabberStrFixLines(const wchar_t *str) return buf; } -void JabberHttpUrlDecode(wchar_t *str) +void JabberHttpUrlDecode(wchar_t *str) { wchar_t *p, *q; unsigned int code; @@ -183,7 +183,7 @@ void JabberHttpUrlDecode(wchar_t *str) *q = '\0'; } -int JabberCombineStatus(int status1, int status2) +int JabberCombineStatus(int status1, int status2) { // Combine according to the following priority (high to low) // ID_STATUS_FREECHAT @@ -258,7 +258,9 @@ wchar_t* JabberErrorMsg(const TiXmlElement *errorNode, int* pErrorCode) auto *str = errorNode->GetText(); if (str == nullptr) - str = errorNode->FirstChildElement("text")->GetText(); + if (auto *n = errorNode->FirstChildElement("text")) + str = n->GetText(); + if (str == nullptr) { for (auto *c : TiXmlEnum(errorNode)) { const char *attr = c->Attribute("xmlns"); @@ -502,7 +504,7 @@ void CJabberProto::SendPresence(int status, bool bSendToAll) /////////////////////////////////////////////////////////////////////////////// // JabberGetPacketID - converts the xml id attribute into an integer -int JabberGetPacketID(const TiXmlElement *n) +int JabberGetPacketID(const TiXmlElement *n) { const char *str = n->Attribute("id"); if (str) @@ -512,7 +514,7 @@ int JabberGetPacketID(const TiXmlElement *n) return -1; } -char* JabberId2string(int id) +char* JabberId2string(int id) { char text[100]; mir_snprintf(text, JABBER_IQID "%d", id); diff --git a/protocols/JabberG/src/jabber_xml.cpp b/protocols/JabberG/src/jabber_xml.cpp index 66cb7a73bc..def4bf2463 100644 --- a/protocols/JabberG/src/jabber_xml.cpp +++ b/protocols/JabberG/src/jabber_xml.cpp @@ -132,7 +132,9 @@ TiXmlElement* XmlAddChild(TiXmlElement *hXml, const char *name) if (hXml == nullptr) return nullptr; - return hXml->GetDocument()->NewElement(name); + auto *res = hXml->GetDocument()->NewElement(name); + hXml->InsertEndChild(res); + return res; } TiXmlElement* XmlAddChild(TiXmlElement *hXml, const char *name, const char *value) @@ -141,7 +143,9 @@ TiXmlElement* XmlAddChild(TiXmlElement *hXml, const char *name, const char *valu return nullptr; auto *res = hXml->GetDocument()->NewElement(name); - res->SetText(value); + if (value) + res->SetText(value); + hXml->InsertEndChild(res); return res; } @@ -151,7 +155,9 @@ TiXmlElement* XmlAddChild(TiXmlElement *hXml, const char *name, int value) return nullptr; auto *res = hXml->GetDocument()->NewElement(name); - res->SetText(value); + if (value) + res->SetText(value); + hXml->InsertEndChild(res); return res; } diff --git a/protocols/JabberG/src/jabber_xml.h b/protocols/JabberG/src/jabber_xml.h index b1ee52586f..c194307efd 100644 --- a/protocols/JabberG/src/jabber_xml.h +++ b/protocols/JabberG/src/jabber_xml.h @@ -138,7 +138,7 @@ struct XATTRID __forceinline TiXmlElement *operator<<(TiXmlElement *node, const XATTRID& attr) { - node->SetAttribute("id", attr.id); + XmlAddAttrID(node, attr.id); return node; } @@ -224,7 +224,7 @@ public: { case T_ATTRIBUTE: return m_hXml->Attribute(m_szParam); case T_NODE: return m_hXml->GetText(); - case T_NODESET: return m_hXml->FirstChildElement()->GetText(); + case T_NODESET: return (m_hXml->FirstChildElement()) ? m_hXml->FirstChildElement()->GetText() : 0; } return nullptr; } -- cgit v1.2.3