/*
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;
}