/* Plugin of Miranda IM for communicating with users of the MSN Messenger protocol. Copyright (c) 2012-2013 Miranda NG Team Copyright (c) 2006-2012 Boris Krasnovskiy. Copyright (c) 2003-2005 George Hazan. Copyright (c) 2002-2003 Richard Hughes (original version). This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "msn_global.h" static TCHAR* a2tf(const TCHAR* str, bool unicode) { if (str == NULL) return NULL; return unicode ? mir_tstrdup(str) : mir_a2t((char*)str); } void overrideStr(TCHAR*& dest, const TCHAR* src, bool unicode, const TCHAR* def) { mir_free(dest); dest = NULL; if (src != NULL) dest = a2tf(src, unicode); else if (def != NULL) dest = mir_tstrdup(def); } char* arrayToHex(BYTE* data, size_t datasz) { char* res = (char*)mir_alloc(2 * datasz + 1); char* resptr = res; for (unsigned i=0; i> 4; *resptr++ = (ch0 <= 9) ? ('0' + ch0) : (('a' - 10) + ch0); const char ch1 = ch & 0xF; *resptr++ = (ch1 <= 9) ? ('0' + ch1) : (('a' - 10) + ch1); } *resptr = '\0'; return res; } bool txtParseParam (const char* szData, const char* presearch, const char* start, const char* finish, char* param, const int size) { const char *cp, *cp1; int len; if (szData == NULL) return false; if (presearch != NULL) { cp1 = strstr(szData, presearch); if (cp1 == NULL) return false; } else cp1 = szData; cp = strstr(cp1, start); if (cp == NULL) return false; cp += strlen(start); while (*cp == ' ') ++cp; if (finish) { cp1 = strstr(cp, finish); if (cp1 == NULL) return FALSE; while (*(cp1-1) == ' ' && cp1 > cp) --cp1; } else cp1 = strchr(cp, '\0'); len = min(cp1 - cp, size - 1); memmove(param, cp, len); param[len] = 0; return true; } void parseWLID(char* wlid, char** net, char** email, char** inst) { char* col = strchr(wlid, ':'); if (col && strncmp(wlid, "tel:", 4)) { *col = 0; if (net) *net = wlid; if (email) *email = col + 1; ++col; } else { if (net) *net = NULL; if (email) *email = wlid; } col = strchr(wlid, ';'); if (col) { *col = 0; if (inst) *inst = col + 1; } else if (inst) *inst = NULL; } ///////////////////////////////////////////////////////////////////////////////////////// // UrlDecode - converts URL chars like %20 into printable characters static int SingleHexToDecimal(char c) { if (c >= '0' && c <= '9') return c-'0'; if (c >= 'a' && c <= 'f') return c-'a'+10; if (c >= 'A' && c <= 'F') return c-'A'+10; return -1; } template void UrlDecode(char* str); template void UrlDecode(wchar_t* str); template void UrlDecode(chartype* str) { chartype* s = str, *d = str; while(*s) { if (*s == '%') { int digit1 = SingleHexToDecimal(s[1]); if (digit1 != -1) { int digit2 = SingleHexToDecimal(s[2]); if (digit2 != -1) { s += 3; *d++ = (char)((digit1 << 4) | digit2); continue; } } } *d++ = *s++; } *d = 0; } void HtmlDecode(char* str) { char* p, *q; if (str == NULL) return; for (p=q=str; *p!='\0'; p++,q++) { if (*p == '&') { if (!strncmp(p, "&", 5)) { *q = '&'; p += 4; } else if (!strncmp(p, "'", 6)) { *q = '\''; p += 5; } else if (!strncmp(p, ">", 4)) { *q = '>'; p += 3; } else if (!strncmp(p, "<", 4)) { *q = '<'; p += 3; } else if (!strncmp(p, """, 6)) { *q = '"'; p += 5; } else { *q = *p; } } else { *q = *p; } } *q = '\0'; } char* HtmlEncode(const char* str) { char* s, *p, *q; int c; if (str == NULL) return NULL; for (c=0,p=(char*)str; *p!='\0'; p++) { switch (*p) { case '&': c += 5; break; case '\'': c += 6; break; case '>': c += 4; break; case '<': c += 4; break; case '"': c += 6; break; default: c++; break; } } if ((s=(char*)mir_alloc(c+1)) != NULL) { for (p=(char*)str,q=s; *p!='\0'; p++) { switch (*p) { case '&': strcpy(q, "&"); q += 5; break; case '\'': strcpy(q, "'"); q += 6; break; case '>': strcpy(q, ">"); q += 4; break; case '<': strcpy(q, "<"); q += 4; break; case '"': strcpy(q, """); q += 6; break; default: *q = *p; q++; break; } } *q = '\0'; } return s; } ///////////////////////////////////////////////////////////////////////////////////////// // UrlEncode - converts printable characters into URL chars like %20 void UrlEncode(const char* src, char* dest, size_t cbDest) { unsigned char* d = (unsigned char*)dest; size_t i = 0; for (const unsigned char* s = (unsigned char*)src; *s; s++) { if ((*s <= '/' && *s != '.' && *s != '-') || (*s >= ':' && *s <= '?') || (*s >= '[' && *s <= '`' && *s != '_')) { if (i + 4 >= cbDest) break; *d++ = '%'; _itoa(*s, (char*)d, 16); d += 2; i += 3; } else { if (++i >= cbDest) break; *d++ = *s; } } *d = '\0'; } void stripBBCode(char* src) { bool tag = false; char* ps = src; char* pd = src; while (*ps != 0) { if (!tag && *ps == '[') { char ch = ps[1]; if (ch == '/') ch = ps[2]; tag = ch == 'b' || ch == 'u' || ch == 'i' || ch == 'c' || ch == 'a' || ch == 's'; } if (!tag) *(pd++) = *ps; else tag = *ps != ']'; ++ps; } *pd = 0; } void stripColorCode(char* src) { unsigned char* ps = (unsigned char*)src; unsigned char* pd = (unsigned char*)src; while (*ps != 0) { if (ps[0] == 0xc2 && ps[1] == 0xb7) { char ch = ps[2]; switch (ch) { case '#': case '&': case '\'': case '@': case '0': ps += 3; continue; case '$': if (isdigit(ps[3])) { ps += 3; if (isdigit(ps[1])) { ps += 2; } else ++ps; if (ps[0] == ',' && isdigit(ps[1])) { ps += 2; if (isdigit(ps[1])) ps += 2; else ++ps; } continue; } else if (ps[3] == '#') { ps += 4; for (int i=0; i<6; ++i) if (isxdigit(*ps)) ++ps; else break; continue; } break; } } *(pd++) = *(ps++); } *pd = 0; } // Process a string, and double all % characters, according to chat.dll's restrictions // Returns a pointer to the new string (old one is not freed) TCHAR* EscapeChatTags(const TCHAR* pszText) { int nChars = 0; for (const TCHAR* p = pszText; (p = _tcschr(p, '%')) != NULL; p++) nChars++; if (nChars == 0) return mir_tstrdup(pszText); TCHAR *pszNewText = (TCHAR*)mir_alloc(sizeof(TCHAR)*(_tcslen(pszText) + 1 + nChars)); if (pszNewText == NULL) return mir_tstrdup(pszText); const TCHAR *s = pszText; TCHAR *d = pszNewText; while (*s) { if (*s == '%') *d++ = '%'; *d++ = *s++; } *d = 0; return pszNewText; } TCHAR* UnEscapeChatTags(TCHAR* str_in) { TCHAR *s = str_in, *d = str_in; while (*s) { if ((*s == '%' && s[1] == '%') || (*s == '\n' && s[1] == '\n')) s++; *d++ = *s++; } *d = 0; return str_in; } char* getNewUuid(void) { BYTE* p; UUID id; UuidCreate(&id); UuidToStringA(&id, &p); size_t len = strlen((char*)p) + 3; char* result = (char*)mir_alloc(len); mir_snprintf(result, len, "{%s}", p); _strupr(result); RpcStringFreeA(&p); return result; }