+ if (PlainIn != NULL) {
+ aptr = PlainIn;
+ len = strlen(PlainIn);
+ eiptr = aptr + len;
+ }
+ else {
+ aptr = Source->buf;
+ eiptr = aptr + Source->BufUsed;
+ len = Source->BufUsed;
+ }
+
+ if (len == 0)
+ return -1;
+
+ bptr = Target->buf + Target->BufUsed;
+ eptr = Target->buf + Target->BufSize - 11; /* our biggest unit to put in... */
+
+ while (aptr < eiptr){
+ if(bptr >= eptr) {
+ IncreaseBuf(Target, 1, -1);
+ eptr = Target->buf + Target->BufSize - 11; /* our biggest unit to put in... */
+ bptr = Target->buf + Target->BufUsed;
+ }
+ if (*aptr == '<') {
+ memcpy(bptr, "<", 4);
+ bptr += 4;
+ Target->BufUsed += 4;
+ }
+ else if (*aptr == '>') {
+ memcpy(bptr, ">", 4);
+ bptr += 4;
+ Target->BufUsed += 4;
+ }
+ else if (*aptr == '&') {
+ memcpy(bptr, "&", 5);
+ bptr += 5;
+ Target->BufUsed += 5;
+ }
+ else if (*aptr == '"') {
+ memcpy(bptr, """, 6);
+ bptr += 6;
+ Target->BufUsed += 6;
+ }
+ else if (*aptr == '\'') {
+ memcpy(bptr, "'", 5);
+ bptr += 5;
+ Target->BufUsed += 5;
+ }
+ else if (*aptr == LB) {
+ *bptr = '<';
+ bptr ++;
+ Target->BufUsed ++;
+ }
+ else if (*aptr == RB) {
+ *bptr = '>';
+ bptr ++;
+ Target->BufUsed ++;
+ }
+ else if (*aptr == QU) {
+ *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{
+ *bptr = *aptr;
+ bptr++;
+ Target->BufUsed ++;
+ }
+ aptr ++;
+ }
+ *bptr = '\0';
+ if ((bptr = eptr - 1 ) && !IsEmptyStr(aptr) )
+ return -1;
+ return Target->BufUsed;
+}
+
+/**
+ * @ingroup StrBuf_DeEnCoder
+ * @brief Append a string, escaping characters which have meaning in HTML.
+ * Converts linebreaks into blanks; escapes single quotes
+ * @param Target target buffer
+ * @param Source source buffer; set to NULL if you just have a C-String
+ * @param PlainIn Plain-C string to append; set to NULL if unused
+ */
+void StrMsgEscAppend(StrBuf *Target, const StrBuf *Source, const char *PlainIn)
+{
+ const char *aptr, *eiptr;
+ char *tptr, *eptr;
+ long len;
+
+ if (((Source == NULL) && (PlainIn == NULL)) || (Target == NULL) )
+ return ;
+
+ if (PlainIn != NULL) {
+ aptr = PlainIn;
+ len = strlen(PlainIn);
+ eiptr = aptr + len;
+ }
+ else {
+ aptr = Source->buf;
+ eiptr = aptr + Source->BufUsed;
+ len = Source->BufUsed;
+ }
+
+ if (len == 0)
+ return;
+
+ eptr = Target->buf + Target->BufSize - 8;
+ tptr = Target->buf + Target->BufUsed;
+
+ while (aptr < eiptr){
+ if(tptr >= eptr) {
+ IncreaseBuf(Target, 1, -1);
+ eptr = Target->buf + Target->BufSize - 8;
+ tptr = Target->buf + Target->BufUsed;
+ }
+
+ if (*aptr == '\n') {
+ *tptr = ' ';
+ Target->BufUsed++;
+ }
+ else if (*aptr == '\r') {
+ *tptr = ' ';
+ Target->BufUsed++;
+ }
+ else if (*aptr == '\'') {
+ *(tptr++) = '&';
+ *(tptr++) = '#';
+ *(tptr++) = '3';
+ *(tptr++) = '9';
+ *tptr = ';';
+ Target->BufUsed += 5;
+ } else {
+ *tptr = *aptr;
+ Target->BufUsed++;
+ }
+ tptr++; aptr++;
+ }
+ *tptr = '\0';
+}
+
+
+
+/**
+ * @ingroup StrBuf_DeEnCoder
+ * @brief Append a string, escaping characters which have meaning in ICAL.
+ * [\n,]
+ * @param Target target buffer
+ * @param Source source buffer; set to NULL if you just have a C-String
+ * @param PlainIn Plain-C string to append; set to NULL if unused
+ */
+void StrIcalEscAppend(StrBuf *Target, const StrBuf *Source, const char *PlainIn)
+{
+ const char *aptr, *eiptr;
+ char *tptr, *eptr;
+ long len;
+
+ if (((Source == NULL) && (PlainIn == NULL)) || (Target == NULL) )
+ return ;
+
+ if (PlainIn != NULL) {
+ aptr = PlainIn;
+ len = strlen(PlainIn);
+ eiptr = aptr + len;
+ }
+ else {
+ aptr = Source->buf;
+ eiptr = aptr + Source->BufUsed;
+ len = Source->BufUsed;
+ }
+
+ if (len == 0)
+ return;
+
+ eptr = Target->buf + Target->BufSize - 8;
+ tptr = Target->buf + Target->BufUsed;
+
+ while (aptr < eiptr){
+ if(tptr + 3 >= eptr) {
+ IncreaseBuf(Target, 1, -1);
+ eptr = Target->buf + Target->BufSize - 8;
+ tptr = Target->buf + Target->BufUsed;
+ }
+
+ if (*aptr == '\n') {
+ *tptr = '\\';
+ Target->BufUsed++;
+ tptr++;
+ *tptr = 'n';
+ Target->BufUsed++;
+ }
+ else if (*aptr == '\r') {
+ *tptr = '\\';
+ Target->BufUsed++;
+ tptr++;
+ *tptr = 'r';
+ Target->BufUsed++;
+ }
+ else if (*aptr == ',') {
+ *tptr = '\\';
+ Target->BufUsed++;
+ tptr++;
+ *tptr = ',';
+ Target->BufUsed++;
+ } else {
+ *tptr = *aptr;
+ Target->BufUsed++;
+ }
+ tptr++; aptr++;
+ }
+ *tptr = '\0';
+}
+
+/**
+ * @ingroup StrBuf_DeEnCoder
+ * @brief Append a string, escaping characters which have meaning in JavaScript strings .
+ *
+ * @param Target target buffer
+ * @param Source source buffer; set to NULL if you just have a C-String
+ * @param PlainIn Plain-C string to append; set to NULL if unused
+ * @returns size of result or -1
+ */
+long StrECMAEscAppend(StrBuf *Target, const StrBuf *Source, const char *PlainIn)
+{
+ const char *aptr, *eiptr;
+ char *bptr, *eptr;
+ long len;
+
+ if (((Source == NULL) && (PlainIn == NULL)) || (Target == NULL) )
+ return -1;
+
+ if (PlainIn != NULL) {
+ aptr = PlainIn;
+ len = strlen(PlainIn);
+ eiptr = aptr + len;
+ }
+ else {
+ aptr = Source->buf;
+ eiptr = aptr + Source->BufUsed;
+ len = Source->BufUsed;
+ }
+
+ if (len == 0)
+ return -1;
+
+ bptr = Target->buf + Target->BufUsed;
+ eptr = Target->buf + Target->BufSize - 3; /* our biggest unit to put in... */
+
+ while (aptr < eiptr){
+ if(bptr >= eptr) {
+ IncreaseBuf(Target, 1, -1);
+ eptr = Target->buf + Target->BufSize - 3;
+ bptr = Target->buf + Target->BufUsed;
+ }
+ if (*aptr == '"') {
+ *bptr = '\\';
+ bptr ++;
+ *bptr = '"';
+ bptr ++;
+ Target->BufUsed += 2;
+ } else if (*aptr == '\\') {
+ *bptr = '\\';
+ bptr ++;
+ *bptr = '\\';
+ bptr ++;
+ Target->BufUsed += 2;
+ }
+ else{
+ *bptr = *aptr;
+ bptr++;
+ Target->BufUsed ++;
+ }
+ aptr ++;
+ }
+ *bptr = '\0';
+ if ((bptr == eptr - 1 ) && !IsEmptyStr(aptr) )
+ return -1;
+ return Target->BufUsed;
+}
+
+/**
+ * @ingroup StrBuf_DeEnCoder
+ * @brief Append a string, escaping characters which have meaning in HTML + json.
+ *
+ * @param Target target buffer
+ * @param Source source buffer; set to NULL if you just have a C-String
+ * @param PlainIn Plain-C string to append; set to NULL if unused
+ * @param nbsp If nonzero, spaces are converted to non-breaking spaces.
+ * @param nolinebreaks if set to 1, linebreaks are removed from the string.
+ * if set to 2, linebreaks are replaced by <br/>
+ */
+long StrHtmlEcmaEscAppend(StrBuf *Target, const StrBuf *Source, const char *PlainIn, int nbsp, int nolinebreaks)
+{
+ const char *aptr, *eiptr;
+ char *bptr, *eptr;
+ long len;
+ int IsUtf8Sequence = 0;
+
+ if (((Source == NULL) && (PlainIn == NULL)) || (Target == NULL) )
+ return -1;
+
+ if (PlainIn != NULL) {
+ aptr = PlainIn;
+ len = strlen(PlainIn);
+ eiptr = aptr + len;
+ }
+ else {
+ aptr = Source->buf;
+ eiptr = aptr + Source->BufUsed;
+ len = Source->BufUsed;
+ }
+
+ if (len == 0)
+ return -1;
+
+ bptr = Target->buf + Target->BufUsed;
+ eptr = Target->buf + Target->BufSize - 11; /* our biggest unit to put in... */
+
+ while (aptr < eiptr){
+ if(bptr >= eptr) {
+ IncreaseBuf(Target, 1, -1);
+ eptr = Target->buf + Target->BufSize - 11; /* our biggest unit to put in... */
+ bptr = Target->buf + Target->BufUsed;
+ }
+ if (*aptr == '<') {
+ memcpy(bptr, "<", 4);
+ bptr += 4;
+ Target->BufUsed += 4;
+ }
+ else if (*aptr == '>') {
+ memcpy(bptr, ">", 4);
+ bptr += 4;
+ Target->BufUsed += 4;
+ }
+ else if (*aptr == '&') {
+ memcpy(bptr, "&", 5);
+ bptr += 5;
+ Target->BufUsed += 5;
+ }
+ else if (*aptr == LB) {
+ *bptr = '<';
+ bptr ++;
+ Target->BufUsed ++;
+ }
+ else if (*aptr == 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)) {
+ *bptr = '\\';
+ bptr ++;
+ *bptr = '"';
+ bptr ++;
+ Target->BufUsed += 2;
+ } else if (*aptr == '\\') {
+ *bptr = '\\';
+ bptr ++;
+ *bptr = '\\';
+ bptr ++;
+ Target->BufUsed += 2;
+ }
+ else {
+ if (((unsigned char)*aptr) >= 0x20)
+ {
+ IsUtf8Sequence = Ctdl_GetUtf8SequenceLength(aptr, eiptr);
+
+ *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 ++;
+ }
+ bptr++;
+ }
+
+ }
+ aptr ++;
+ }
+ *bptr = '\0';
+ if ((bptr = eptr - 1 ) && !IsEmptyStr(aptr) )
+ return -1;
+ return Target->BufUsed;
+}
+
+/**
+ * @ingroup StrBuf_DeEnCoder
+ * @brief unhide special chars hidden to the HTML escaper
+ * @param target buffer to put the unescaped string in
+ * @param source buffer to unescape
+ */
+void StrBufEUid_unescapize(StrBuf *target, const StrBuf *source)
+{
+ int a, b, len;
+ char hex[3];
+
+ if (target != NULL)
+ FlushStrBuf(target);
+
+ if (source == NULL ||target == NULL)
+ {
+ return;
+ }
+
+ len = source->BufUsed;
+ for (a = 0; a < len; ++a) {
+ if (target->BufUsed >= target->BufSize)
+ IncreaseBuf(target, 1, -1);
+
+ if (source->buf[a] == '=') {
+ hex[0] = source->buf[a + 1];
+ hex[1] = source->buf[a + 2];
+ hex[2] = 0;
+ b = 0;
+ sscanf(hex, "%02x", &b);
+ target->buf[target->BufUsed] = b;
+ target->buf[++target->BufUsed] = 0;
+ a += 2;
+ }
+ else {
+ target->buf[target->BufUsed] = source->buf[a];
+ target->buf[++target->BufUsed] = 0;
+ }
+ }
+}
+
+
+/**
+ * @ingroup StrBuf_DeEnCoder
+ * @brief hide special chars from the HTML escapers and friends
+ * @param target buffer to put the escaped string in
+ * @param source buffer to escape
+ */
+void StrBufEUid_escapize(StrBuf *target, const StrBuf *source)
+{
+ int i, len;
+
+ if (target != NULL)
+ FlushStrBuf(target);
+
+ if (source == NULL ||target == NULL)
+ {
+ return;
+ }
+
+ len = source->BufUsed;
+ for (i=0; i<len; ++i) {
+ if (target->BufUsed + 4 >= target->BufSize)
+ IncreaseBuf(target, 1, -1);
+ if ( (isalnum(source->buf[i])) ||
+ (source->buf[i]=='-') ||
+ (source->buf[i]=='_') ) {
+ target->buf[target->BufUsed++] = source->buf[i];
+ }
+ else {
+ sprintf(&target->buf[target->BufUsed],
+ "=%02X",
+ (0xFF &source->buf[i]));
+ target->BufUsed += 3;
+ }
+ }
+ target->buf[target->BufUsed + 1] = '\0';
+}
+
+
+/*******************************************************************************
+ * Quoted Printable de/encoding *
+ *******************************************************************************/
+
+/**
+ * @ingroup StrBuf_DeEnCoder
+ * @brief decode a buffer from base 64 encoding; destroys original
+ * @param Buf Buffor to transform
+ */
+int StrBufDecodeBase64(StrBuf *Buf)
+{
+ char *xferbuf;
+ size_t siz;
+ if (Buf == NULL) return -1;
+
+ xferbuf = (char*) malloc(Buf->BufSize);
+ *xferbuf = '\0';
+ siz = CtdlDecodeBase64(xferbuf,
+ Buf->buf,
+ Buf->BufUsed);
+ free(Buf->buf);
+ Buf->buf = xferbuf;
+ Buf->BufUsed = siz;
+ return siz;
+}
+
+/**
+ * @ingroup StrBuf_DeEnCoder
+ * @brief decode a buffer from base 64 encoding; destroys original
+ * @param Buf Buffor to transform
+ */
+int StrBufDecodeHex(StrBuf *Buf)
+{
+ unsigned int ch;
+ char *pch, *pche, *pchi;
+
+ if (Buf == NULL) return -1;
+
+ pch = pchi = Buf->buf;
+ pche = pch + Buf->BufUsed;
+
+ while (pchi < pche){
+ ch = decode_hex(pchi);
+ *pch = ch;
+ pch ++;
+ pchi += 2;
+ }
+
+ *pch = '\0';
+ Buf->BufUsed = pch - Buf->buf;
+ return Buf->BufUsed;
+}
+
+/**
+ * @ingroup StrBuf_DeEnCoder
+ * @brief replace all chars >0x20 && < 0x7F with Mute
+ * @param Mute char to put over invalid chars
+ * @param Buf Buffor to transform
+ */
+int StrBufSanitizeAscii(StrBuf *Buf, const char Mute)
+{
+ unsigned char *pch;
+
+ if (Buf == NULL) return -1;
+ pch = (unsigned char *)Buf->buf;
+ while (pch < (unsigned char *)Buf->buf + Buf->BufUsed) {
+ if ((*pch < 0x20) || (*pch > 0x7F))
+ *pch = Mute;
+ pch ++;
+ }
+ return Buf->BufUsed;
+}
+
+
+/**
+ * @ingroup StrBuf_DeEnCoder
+ * @brief remove escaped strings from i.e. the url string (like %20 for blanks)
+ * @param Buf Buffer to translate
+ * @param StripBlanks Reduce several blanks to one?
+ */
+long StrBufUnescape(StrBuf *Buf, int StripBlanks)
+{
+ int a, b;
+ char hex[3];
+ long len;
+
+ if (Buf == NULL)
+ return -1;
+
+ while ((Buf->BufUsed > 0) && (isspace(Buf->buf[Buf->BufUsed - 1]))){
+ Buf->buf[Buf->BufUsed - 1] = '\0';
+ Buf->BufUsed --;
+ }
+
+ a = 0;
+ while (a < Buf->BufUsed) {
+ if (Buf->buf[a] == '+')
+ Buf->buf[a] = ' ';
+ else if (Buf->buf[a] == '%') {
+ /* don't let % chars through, rather truncate the input. */
+ if (a + 2 > Buf->BufUsed) {
+ Buf->buf[a] = '\0';
+ Buf->BufUsed = a;