/* Copyright (c) 2008-2018 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "str.h"
#include "unichar.h"
#include "imap-utf7.h"
static const char imap_b64enc[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+,";
};
static void
{
while (len >= 3) {
in += 3;
len -= 3;
}
if (len > 0) {
if (len == 1)
else {
}
}
}
{
const char *p;
for (p = str; *p != '\0'; p++) {
if (*p == '&' || *p < 0x20 || *p >= 0x7f)
return p;
}
return NULL;
}
{
const char *p;
if (p == NULL) {
/* no characters that need to be encoded */
return 0;
}
/* at least one encoded character */
while (*p != '\0') {
if (*p == '&') {
p++;
continue;
}
if (*p >= 0x20 && *p < 0x7f) {
str_append_c(dest, *p);
p++;
continue;
}
u = utf16;
while (*p != '\0' && (*p < 0x20 || *p >= 0x7f)) {
if (uni_utf8_get_char(p, &chr) <= 0)
return -1;
/* @UNSAFE */
if (chr < UTF16_SURROGATE_BASE) {
*u++ = chr >> 8;
*u++ = chr & 0xff;
} else {
*u++ = u16 >> 8;
*u++ = u16 & 0xff;
*u++ = u16 >> 8;
*u++ = u16 & 0xff;
}
p += uni_utf8_char_bytes(*p);
}
}
return 0;
}
{
int ret;
return 0;
}
return ret;
}
{
if (len % 2 != 0)
return -1;
if (high < UTF16_SURROGATE_HIGH_FIRST ||
/* single byte */
if (high == 0) {
/* Encoded NUL isn't going to work in Dovecot code,
even though it's technically valid. Return failure
so the callers don't even get a chance to handle the
NUL in the string inconsistently. */
return -1;
}
return -1;
}
return 0;
}
if (high > UTF16_SURROGATE_HIGH_LAST)
return -1;
if (len != 4) {
/* missing the second character */
return -1;
}
return -1;
(low & UTF16_SURROGATE_MASK));
return 0;
}
{
while (*src != '-') {
if (input[0] == 0xff)
return -1;
return -1;
return -1;
}
return -1;
src += 2;
break;
}
return -1;
}
return -1;
src += 3;
break;
}
return -1;
}
src += 4;
}
return -1;
}
/* found ending '-' */
return 0;
}
{
const char *p;
for (p = src; *p != '\0'; p++) {
if (*p < 0x20 || *p >= 0x7f)
return -1;
if (*p == '&')
break;
}
if (*p == '\0') {
/* no IMAP-UTF-7 encoded characters */
return 0;
}
/* at least one encoded character */
while (*p != '\0') {
if (*p == '&') {
if (*++p == '-') {
p++;
} else {
if (mbase64_decode_to_utf8(dest, &p) < 0)
return -1;
if (p[0] == '&' && p[1] != '-') {
/* &...-& */
return -1;
}
}
} else {
str_append_c(dest, *p++);
}
}
return 0;
}
{
const char *p;
int ret;
for (p = src; *p != '\0'; p++) {
if (*p < 0x20 || *p >= 0x7f)
return FALSE;
if (*p == '&') {
/* slow scan */
T_BEGIN {
} T_END;
if (ret < 0)
return FALSE;
}
}
return TRUE;
}