return -1;
if (DestSize > 0)
- while (NewSize <= DestSize)
+ while ((NewSize <= DestSize) && (NewSize != 0))
NewSize *= 2;
+ if (NewSize == 0)
+ return -1;
+
NewBuf= (char*) malloc(NewSize);
if (NewBuf == NULL)
return -1;
/**
* @ingroup StrBuf_DeConstructors
- * @brief shrink an _EMPTY_ buffer if its Buffer superseeds threshhold to NewSize. Buffercontent is thoroughly ignored and flushed.
+ * @brief shrink / increase an _EMPTY_ buffer to NewSize. Buffercontent is thoroughly ignored and flushed.
* @param Buf Buffer to shrink (has to be empty)
* @param ThreshHold if the buffer is bigger then this, its readjusted
* @param NewSize if we Shrink it, how big are we going to be afterwards?
*/
void ReAdjustEmptyBuf(StrBuf *Buf, long ThreshHold, long NewSize)
{
- if ((Buf != NULL) && (Buf->BufUsed > ThreshHold)) {
+ if ((Buf != NULL) &&
+ (Buf->BufUsed == 0) &&
+ (Buf->BufSize < ThreshHold)) {
free(Buf->buf);
Buf->buf = (char*) malloc(NewSize);
Buf->BufUsed = 0;
else
CopySize = nChars;
- while (Siz <= CopySize)
+ while ((Siz <= CopySize) && (Siz != 0))
Siz *= 2;
+ if (Siz == 0)
+ {
+ return NULL;
+ }
+
NewBuf->buf = (char*) malloc(Siz);
NewBuf->BufSize = Siz;
if (ptr != NULL) {
else
CopySize = nChars;
- while (Siz <= CopySize)
+ while ((Siz <= CopySize) && (Siz != 0))
Siz *= 2;
+ if (Siz == 0) {
+ FlushStrBuf(Buf);
+ return -1;
+ }
+
if (Siz != Buf->BufSize)
IncreaseBuf(Buf, 0, Siz);
memcpy(Buf->buf, ptr, CopySize);
va_end(apl);
newused = Offset + nWritten;
if (newused >= Buf->BufSize) {
- IncreaseBuf(Buf, 1, newused);
+ if (IncreaseBuf(Buf, 1, newused) == -1)
+ return; /* TODO: error handling? */
newused = Buf->BufSize + 1;
}
else {
va_end(arg_ptr);
newused = Buf->BufUsed + nWritten;
if (newused >= Buf->BufSize) {
- IncreaseBuf(Buf, 1, newused);
+ if (IncreaseBuf(Buf, 1, newused) == -1)
+ return; /* TODO: error handling? */
newused = Buf->BufSize + 1;
}
else {
nWritten = vsnprintf(Buf->buf, Buf->BufSize, format, arg_ptr);
va_end(arg_ptr);
if (nWritten >= Buf->BufSize) {
- IncreaseBuf(Buf, 0, 0);
+ if (IncreaseBuf(Buf, 0, 0) == -1)
+ return; /* TODO: error handling? */
nWritten = Buf->BufSize + 1;
continue;
}
//cit_backtrace();
//lprintf (CTDL_DEBUG, "test >: n: %d sep: %c source: %s \n willi \n", parmnum, separator, source);
- while ((s<e) && !IsEmptyStr(s)) {
+ while ((s < e) && !IsEmptyStr(s)) {
if (*s == separator) {
++current_token;
}
//cit_backtrace();
//lprintf (CTDL_DEBUG, "test >: n: %d sep: %c source: %s \n willi \n", parmnum, separator, source);
- while ((s<EndBuffer) && !IsEmptyStr(s)) {
+ while ((s < EndBuffer) && !IsEmptyStr(s)) {
if (*s == separator) {
++current_token;
}
return -1;
bptr = Target->buf + Target->BufUsed;
- eptr = Target->buf + Target->BufSize - 3; /* our biggest unit to put in... */
+ eptr = Target->buf + Target->BufSize - 7; /* our biggest unit to put in... */
while (aptr < eiptr){
if(bptr >= eptr) {
IncreaseBuf(Target, 1, -1);
- eptr = Target->buf + Target->BufSize - 3;
+ eptr = Target->buf + Target->BufSize - 7; /* our biggest unit to put in... */
bptr = Target->buf + Target->BufUsed;
}
- if (*aptr == '"') {
+ switch (*aptr) {
+ case '\n':
+ memcpy(bptr, HKEY("\\n"));
+ bptr += 2;
+ Target->BufUsed += 2;
+ break;
+ case '\r':
+ memcpy(bptr, HKEY("\\r"));
+ bptr += 2;
+ Target->BufUsed += 2;
+ break;
+ case '"':
*bptr = '\\';
bptr ++;
*bptr = '"';
bptr ++;
Target->BufUsed += 2;
- } else if (*aptr == '\\') {
+ break;
+ case '\\':
+ if ((*(aptr + 1) == 'u') &&
+ isxdigit(*(aptr + 2)) &&
+ isxdigit(*(aptr + 3)) &&
+ isxdigit(*(aptr + 4)) &&
+ isxdigit(*(aptr + 5)))
+ { /* oh, a unicode escaper. let it pass through. */
+ memcpy(bptr, aptr, 6);
+ aptr += 5;
+ bptr +=6;
+ Target->BufUsed += 6;
+ }
+ else
+ {
+ *bptr = '\\';
+ bptr ++;
+ *bptr = '\\';
+ bptr ++;
+ Target->BufUsed += 2;
+ }
+ break;
+ case '\b':
*bptr = '\\';
bptr ++;
+ *bptr = 'b';
+ bptr ++;
+ Target->BufUsed += 2;
+ break;
+ case '\f':
*bptr = '\\';
bptr ++;
+ *bptr = 'f';
+ bptr ++;
Target->BufUsed += 2;
- }
- else{
- *bptr = *aptr;
- bptr++;
- Target->BufUsed ++;
+ break;
+ case '\t':
+ *bptr = '\\';
+ bptr ++;
+ *bptr = 't';
+ bptr ++;
+ Target->BufUsed += 2;
+ break;
+ default:
+ IsUtf8Sequence = Ctdl_GetUtf8SequenceLength(aptr, eiptr);
+ while (IsUtf8Sequence > 0){
+ *bptr = *aptr;
+ Target->BufUsed ++;
+ if (--IsUtf8Sequence)
+ aptr++;
+ bptr++;
+ }
}
aptr ++;
}
eptr = Target->buf + Target->BufSize - 11; /* our biggest unit to put in... */
bptr = Target->buf + Target->BufUsed;
}
- if (*aptr == '<') {
- memcpy(bptr, "<", 4);
+ switch (*aptr) {
+ case '<':
+ memcpy(bptr, HKEY("<"));
bptr += 4;
Target->BufUsed += 4;
- }
- else if (*aptr == '>') {
- memcpy(bptr, ">", 4);
+ break;
+ case '>':
+ memcpy(bptr, HKEY(">"));
bptr += 4;
Target->BufUsed += 4;
- }
- else if (*aptr == '&') {
- memcpy(bptr, "&", 5);
+ break;
+ case '&':
+ memcpy(bptr, HKEY("&"));
bptr += 5;
Target->BufUsed += 5;
- }
- else if (*aptr == LB) {
+ break;
+ case LB:
*bptr = '<';
bptr ++;
Target->BufUsed ++;
- }
- else if (*aptr == RB) {
+ break;
+ case RB:
*bptr = '>';
bptr ++;
Target->BufUsed ++;
- }
- else if ((*aptr == 32) && (nbsp == 1)) {
- memcpy(bptr, " ", 6);
- bptr += 6;
- Target->BufUsed += 6;
- }
- else if ((*aptr == '\n') && (nolinebreaks == 1)) {
- *bptr='\0'; /* nothing */
- }
- else if ((*aptr == '\n') && (nolinebreaks == 2)) {
- memcpy(bptr, "<br/>", 11);
- bptr += 11;
- Target->BufUsed += 11;
- }
-
- else if ((*aptr == '\r') && (nolinebreaks != 0)) {
- *bptr='\0'; /* nothing */
- }
-
- else if ((*aptr == '"') || (*aptr == QU)) {
+ break;
+ case '\n':
+ switch (nolinebreaks) {
+ case 1:
+ *bptr='\0'; /* nothing */
+ break;
+ case 2:
+ memcpy(bptr, HKEY("<br/>"));
+ bptr += 11;
+ Target->BufUsed += 11;
+ break;
+ default:
+ memcpy(bptr, HKEY("\\n"));
+ bptr += 2;
+ Target->BufUsed += 2;
+ }
+ break;
+ case '\r':
+ switch (nolinebreaks) {
+ case 1:
+ case 2:
+ *bptr='\0'; /* nothing */
+ break;
+ default:
+ memcpy(bptr, HKEY("\\r"));
+ bptr += 2;
+ Target->BufUsed += 2;
+ break;
+ }
+ break;
+ case '"':
+ case QU:
*bptr = '\\';
bptr ++;
*bptr = '"';
bptr ++;
Target->BufUsed += 2;
- } else if (*aptr == '\\') {
+ break;
+ case '\\':
+ if ((*(aptr + 1) == 'u') &&
+ isxdigit(*(aptr + 2)) &&
+ isxdigit(*(aptr + 3)) &&
+ isxdigit(*(aptr + 4)) &&
+ isxdigit(*(aptr + 5)))
+ { /* oh, a unicode escaper. let it pass through. */
+ memcpy(bptr, aptr, 6);
+ aptr += 5;
+ bptr +=6;
+ Target->BufUsed += 6;
+ }
+ else
+ {
+ *bptr = '\\';
+ bptr ++;
+ *bptr = '\\';
+ bptr ++;
+ Target->BufUsed += 2;
+ }
+ break;
+ case '\b':
*bptr = '\\';
bptr ++;
+ *bptr = 'b';
+ bptr ++;
+ Target->BufUsed += 2;
+ break;
+ case '\f':
*bptr = '\\';
bptr ++;
+ *bptr = 'f';
+ bptr ++;
Target->BufUsed += 2;
- }
- else {
- if (((unsigned char)*aptr) >= 0x20)
- {
- IsUtf8Sequence = Ctdl_GetUtf8SequenceLength(aptr, eiptr);
-
+ break;
+ case '\t':
+ *bptr = '\\';
+ bptr ++;
+ *bptr = 't';
+ bptr ++;
+ Target->BufUsed += 2;
+ break;
+ case 32:
+ if (nbsp == 1) {
+ memcpy(bptr, HKEY(" "));
+ bptr += 6;
+ Target->BufUsed += 6;
+ break;
+ }
+ default:
+ IsUtf8Sequence = Ctdl_GetUtf8SequenceLength(aptr, eiptr);
+ while (IsUtf8Sequence > 0){
*bptr = *aptr;
Target->BufUsed ++;
- while (IsUtf8Sequence > 1){
- if(bptr + IsUtf8Sequence >= eptr) {
- IncreaseBuf(Target, 1, -1);
- eptr = Target->buf + Target->BufSize - 11; /* our biggest unit to put in... */
- bptr = Target->buf + Target->BufUsed - 1;
- }
- bptr++; aptr++;
- IsUtf8Sequence --;
- *bptr = *aptr;
- Target->BufUsed ++;
- }
+ if (--IsUtf8Sequence)
+ aptr++;
bptr++;
}
-
}
aptr ++;
}
if (Buf == NULL) return -1;
xferbuf = (char*) malloc(Buf->BufSize);
+ *xferbuf = '\0';
siz = CtdlDecodeBase64(xferbuf,
Buf->buf,
Buf->BufUsed);
if ((*target)->BufUsed + 4 >= (*target)->BufSize)
IncreaseBuf(*target, 1, 0);
ch = (unsigned char) source->buf[i];
- if ((ch < 32) || (ch > 126) || (ch == 61)) {
+ if ((ch < 32) ||
+ (ch > 126) ||
+ (ch == 61) ||
+ (ch == '=') ||
+ (ch == '[') ||
+ (ch == ']') )
+ {
sprintf(&(*target)->buf[(*target)->BufUsed], "=%02X", ch);
(*target)->BufUsed += 3;
}
return (*target)->BufUsed;;
}
+
+
+static void AddRecipient(StrBuf *Target,
+ StrBuf *UserName,
+ StrBuf *EmailAddress,
+ StrBuf *EncBuf)
+{
+ int QuoteMe = 0;
+
+ if (StrLength(Target) > 0) StrBufAppendBufPlain(Target, HKEY(", "), 0);
+ if (strchr(ChrPtr(UserName), ',') != NULL) QuoteMe = 1;
+
+ if (QuoteMe) StrBufAppendBufPlain(Target, HKEY("\""), 0);
+ StrBufRFC2047encode(&EncBuf, UserName);
+ StrBufAppendBuf(Target, EncBuf, 0);
+ if (QuoteMe) StrBufAppendBufPlain(Target, HKEY("\" "), 0);
+ else StrBufAppendBufPlain(Target, HKEY(" "), 0);
+
+ if (StrLength(EmailAddress) > 0){
+ StrBufAppendBufPlain(Target, HKEY("<"), 0);
+ StrBufAppendBuf(Target, EmailAddress, 0); /* TODO: what about IDN???? */
+ StrBufAppendBufPlain(Target, HKEY(">"), 0);
+ }
+}
+
+
+/**
+ * \brief QP encode parts of an email TO/CC/BCC vector, and strip/filter invalid parts
+ * \param Recp Source list of email recipients
+ * \param UserName Temporary buffer for internal use; Please provide valid buffer.
+ * \param EmailAddress Temporary buffer for internal use; Please provide valid buffer.
+ * \param EncBuf Temporary buffer for internal use; Please provide valid buffer.
+ * \returns encoded & sanitized buffer with the contents of Recp; Caller owns this memory.
+ */
+StrBuf *StrBufSanitizeEmailRecipientVector(const StrBuf *Recp,
+ StrBuf *UserName,
+ StrBuf *EmailAddress,
+ StrBuf *EncBuf)
+{
+ StrBuf *Target;
+ int need_to_encode;
+
+ const char *pch, *pche;
+ const char *UserStart, *UserEnd, *EmailStart, *EmailEnd, *At;
+
+ if ((Recp == NULL) || (StrLength(Recp) == 0))
+ return NULL;
+
+ need_to_encode = 0;
+ pch = ChrPtr(Recp);
+ pche = pch + StrLength(Recp);
+
+ if (!CheckEncode(pch, -1, pche))
+ return NewStrBufDup(Recp);
+
+ Target = NewStrBufPlain(NULL, StrLength(Recp));
+
+ while ((pch != NULL) && (pch < pche))
+ {
+ int ColonOk = 0;
+
+ while (isspace(*pch)) pch++;
+ UserStart = UserEnd = EmailStart = EmailEnd = NULL;
+
+ if ((*pch == '"') || (*pch == '\'')) {
+ UserStart = pch + 1;
+
+ UserEnd = strchr(UserStart, *pch);
+ if (UserEnd == NULL)
+ break; ///TODO: Userfeedback??
+ EmailStart = UserEnd + 1;
+ while (isspace(*EmailStart))
+ EmailStart++;
+ if (UserEnd == UserStart) {
+ UserStart = UserEnd = NULL;
+ }
+
+ if (*EmailStart == '<') {
+ EmailStart++;
+ EmailEnd = strchr(EmailStart, '>');
+ if (EmailEnd == NULL)
+ EmailEnd = strchr(EmailStart, ',');
+
+ }
+ else {
+ EmailEnd = strchr(EmailStart, ',');
+ }
+ if (EmailEnd == NULL)
+ EmailEnd = pche;
+ pch = EmailEnd + 1;
+ ColonOk = 1;
+ }
+ else {
+ int gt = 0;
+ UserStart = pch;
+ EmailEnd = strchr(UserStart, ',');
+ if (EmailEnd == NULL) {
+ EmailEnd = strchr(pch, '>');
+ pch = NULL;
+ if (EmailEnd != NULL) {
+ gt = 1;
+ }
+ else {
+ EmailEnd = pche;
+ }
+ }
+ else {
+
+ pch = EmailEnd + 1;
+ while ((EmailEnd > UserStart) && !gt &&
+ ((*EmailEnd == ',') ||
+ (*EmailEnd == '>') ||
+ (isspace(*EmailEnd))))
+ {
+ if (*EmailEnd == '>')
+ gt = 1;
+ else
+ EmailEnd--;
+ }
+ if (EmailEnd == UserStart)
+ break;
+ }
+ if (gt) {
+ EmailStart = strchr(UserStart, '<');
+ if ((EmailStart == NULL) || (EmailStart > EmailEnd))
+ break;
+ UserEnd = EmailStart;
+
+ while ((UserEnd > UserStart) &&
+ isspace (*(UserEnd - 1)))
+ UserEnd --;
+ EmailStart ++;
+ if (UserStart >= UserEnd)
+ UserStart = UserEnd = NULL;
+ At = strchr(EmailStart, '@');
+ }
+ else { /* this is a local recipient... no domain, just a realname */
+ EmailStart = UserStart;
+ At = strchr(EmailStart, '@');
+ if (At == NULL) {
+ UserEnd = EmailEnd;
+ EmailEnd = NULL;
+ }
+ else {
+ EmailStart = UserStart;
+ UserStart = NULL;
+ }
+ }
+ }
+
+ if ((UserStart != NULL) && (UserEnd != NULL))
+ StrBufPlain(UserName, UserStart, UserEnd - UserStart);
+ else if ((UserStart != NULL) && (UserEnd == NULL))
+ StrBufPlain(UserName, UserStart, UserEnd - UserStart);
+ else
+ FlushStrBuf(UserName);
+
+ if ((EmailStart != NULL) && (EmailEnd != NULL))
+ StrBufPlain(EmailAddress, EmailStart, EmailEnd - EmailStart);
+ else if ((EmailStart != NULL) && (EmailEnd == NULL))
+ StrBufPlain(EmailAddress, EmailStart, EmailEnd - pche);
+ else
+ FlushStrBuf(EmailAddress);
+
+ AddRecipient(Target, UserName, EmailAddress, EncBuf);
+
+ if (pch == NULL)
+ break;
+
+ if ((pch != NULL) && (*pch == ','))
+ pch ++;
+ if (pch != NULL) while (isspace(*pch))
+ pch ++;
+ }
+ return Target;
+}
+
+
/**
* @ingroup StrBuf
* @brief replaces all occurances of 'search' by 'replace'
*encoding = toupper(*encoding);
if (*encoding == 'B') { /**< base64 */
+ if (ConvertBuf2->BufSize < ConvertBuf->BufUsed)
+ IncreaseBuf(ConvertBuf2, 0, ConvertBuf->BufUsed);
ConvertBuf2->BufUsed = CtdlDecodeBase64(ConvertBuf2->buf,
ConvertBuf->buf,
ConvertBuf->BufUsed);
pos++;
}
+ if (ConvertBuf2->BufSize < ConvertBuf->BufUsed)
+ IncreaseBuf(ConvertBuf2, 0, ConvertBuf->BufUsed);
+
ConvertBuf2->BufUsed = CtdlDecodeQuotedPrintable(
ConvertBuf2->buf,
ConvertBuf->buf,
* @ingroup StrBuf
* @brief evaluate the length of an utf8 special character sequence
* @param Char the character to examine
- * @returns width of utf8 chars in bytes
+ * @returns width of utf8 chars in bytes; if the sequence is broken 0 is returned; 1 if its simply ASCII.
*/
static inline int Ctdl_GetUtf8SequenceLength(const char *CharS, const char *CharE)
{
int n = 1;
char test = (1<<7);
-
+
+ if ((*CharS & 0xC0) == 0)
+ return 1;
+
while ((n < 8) && ((test & *CharS) != 0)) {
test = test << 1;
n ++;
}
if ((n > 6) || ((CharE - CharS) < n))
- n = 1;
+ n = 0;
return n;
}
}
rlen = read(*fd,
ptr,
- nBytes - nRead);
+ IOBuf->BufSize - (ptr - IOBuf->buf));
if (rlen == -1) {
close(*fd);
*fd = -1;