240 lines
3.5 KiB
C++
Executable File
240 lines
3.5 KiB
C++
Executable File
#ifndef RFC2047_CPP
|
|
#define RFC2047_CPP
|
|
|
|
#ifdef ESP32
|
|
|
|
#include "RFC2047.h"
|
|
|
|
RFC2047::RFC2047(){}
|
|
|
|
|
|
void RFC2047::rfc2047Decode(char *d, const char *s, size_t dlen){
|
|
|
|
const char *p, *q;
|
|
size_t n;
|
|
int found_encoded = 0;
|
|
|
|
dlen--; /* save room for the terminal nul */
|
|
|
|
while (*s && dlen > 0)
|
|
{
|
|
if ((p = strstr (s, "=?")) == NULL ||
|
|
(q = strchr (p + 2, '?')) == NULL ||
|
|
(q = strchr (q + 1, '?')) == NULL ||
|
|
(q = strstr (q + 1, "?=")) == NULL)
|
|
{
|
|
/* no encoded words */
|
|
if (d != s)
|
|
strfcpy (d, s, dlen + 1);
|
|
return;
|
|
}
|
|
|
|
if (p != s)
|
|
{
|
|
n = (size_t) (p - s);
|
|
/* ignore spaces between encoded words */
|
|
if (!found_encoded || strspn (s, " \t\r\n") != n)
|
|
{
|
|
if (n > dlen)
|
|
n = dlen;
|
|
if (d != s)
|
|
memcpy (d, s, n);
|
|
d += n;
|
|
dlen -= n;
|
|
}
|
|
}
|
|
|
|
rfc2047DecodeWord (d, p, dlen);
|
|
found_encoded = 1;
|
|
s = q + 2;
|
|
n = strlen (d);
|
|
dlen -= n;
|
|
d += n;
|
|
}
|
|
*d = 0;
|
|
|
|
}
|
|
|
|
void RFC2047::rfc2047DecodeWord(char *d, const char *s, size_t dlen){
|
|
|
|
char *p = safe_strdup (s);
|
|
char *pp = p;
|
|
char *pd = d;
|
|
size_t len = dlen;
|
|
int enc = 0, filter = 0, count = 0, c1, c2, c3, c4;
|
|
|
|
while ((pp = strtok (pp, "?")) != NULL)
|
|
{
|
|
count++;
|
|
switch (count)
|
|
{
|
|
case 2:
|
|
if (strcasecmp (pp, Charset) != 0)
|
|
{
|
|
filter = 1;
|
|
}
|
|
break;
|
|
case 3:
|
|
if (toupper (*pp) == 'Q')
|
|
enc = ENCQUOTEDPRINTABLE;
|
|
else if (toupper (*pp) == 'B')
|
|
enc = ENCBASE64;
|
|
else
|
|
return;
|
|
break;
|
|
case 4:
|
|
if (enc == ENCQUOTEDPRINTABLE)
|
|
{
|
|
while (*pp && len > 0)
|
|
{
|
|
if (*pp == '_')
|
|
{
|
|
*pd++ = ' ';
|
|
len--;
|
|
}
|
|
else if (*pp == '=')
|
|
{
|
|
*pd++ = (hexval(pp[1]) << 4) | hexval(pp[2]);
|
|
len--;
|
|
pp += 2;
|
|
}
|
|
else
|
|
{
|
|
*pd++ = *pp;
|
|
len--;
|
|
}
|
|
pp++;
|
|
}
|
|
*pd = 0;
|
|
}
|
|
else if (enc == ENCBASE64)
|
|
{
|
|
while (*pp && len > 0)
|
|
{
|
|
c1 = base64val(pp[0]);
|
|
c2 = base64val(pp[1]);
|
|
*pd++ = (c1 << 2) | ((c2 >> 4) & 0x3);
|
|
if (--len == 0) break;
|
|
|
|
if (pp[2] == '=') break;
|
|
|
|
c3 = base64val(pp[2]);
|
|
*pd++ = ((c2 & 0xf) << 4) | ((c3 >> 2) & 0xf);
|
|
if (--len == 0)
|
|
break;
|
|
|
|
if (pp[3] == '=')
|
|
break;
|
|
|
|
c4 = base64val(pp[3]);
|
|
*pd++ = ((c3 & 0x3) << 6) | c4;
|
|
if (--len == 0)
|
|
break;
|
|
|
|
pp += 4;
|
|
}
|
|
*pd = 0;
|
|
}
|
|
break;
|
|
}
|
|
pp = 0;
|
|
}
|
|
safe_free (&p);
|
|
if (filter)
|
|
{
|
|
|
|
pd = d;
|
|
while (*pd)
|
|
{
|
|
if (!IsPrint (*pd))
|
|
*pd = '?';
|
|
pd++;
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
|
|
void *RFC2047::safe_calloc (size_t nmemb, size_t size)
|
|
{
|
|
void *p;
|
|
|
|
if (!nmemb || !size)
|
|
return NULL;
|
|
if (!(p = calloc (nmemb, size)))
|
|
{
|
|
//out of memory
|
|
return NULL;
|
|
}
|
|
return p;
|
|
}
|
|
|
|
void *RFC2047::safe_malloc (unsigned int siz)
|
|
{
|
|
void *p;
|
|
|
|
if (siz == 0)
|
|
return 0;
|
|
if ((p = (void *) malloc (siz)) == 0)
|
|
{
|
|
//out of memory
|
|
return NULL;
|
|
}
|
|
return (p);
|
|
}
|
|
|
|
void RFC2047::safe_realloc (void **p, size_t siz)
|
|
{
|
|
void *r;
|
|
|
|
if (siz == 0)
|
|
{
|
|
if (*p)
|
|
{
|
|
free (*p);
|
|
*p = NULL;
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (*p)
|
|
r = (void *) realloc (*p, siz);
|
|
else
|
|
{
|
|
r = (void *) malloc (siz);
|
|
}
|
|
|
|
if (!r)
|
|
{
|
|
//out of memory
|
|
return;
|
|
}
|
|
|
|
*p = r;
|
|
}
|
|
|
|
void RFC2047::safe_free (void *ptr)
|
|
{
|
|
void **p = (void **)ptr;
|
|
if (*p)
|
|
{
|
|
free (*p);
|
|
*p = 0;
|
|
}
|
|
}
|
|
|
|
char *RFC2047::safe_strdup (const char *s)
|
|
{
|
|
char *p;
|
|
size_t l;
|
|
|
|
if (!s || !*s) return 0;
|
|
l = strlen (s) + 1;
|
|
p = (char *)safe_malloc (l);
|
|
memcpy (p, s, l);
|
|
return (p);
|
|
}
|
|
|
|
#endif //ESP32
|
|
|
|
#endif //RFC2047_CPP
|