Example #1
0
static void
filter_complete (GMimeFilter *filter, char *in, size_t len, size_t prespace,
		 char **out, size_t *outlen, size_t *outprespace)
{
	GMimeFilterYenc *yenc = (GMimeFilterYenc *) filter;
	const unsigned char *inbuf;
	unsigned char *outbuf;
	size_t newlen = 0;
	
	if (yenc->encode) {
		/* won't go to more than 2 * (x + 2) + 62 */
		g_mime_filter_set_size (filter, (len + 2) * 2 + 62, FALSE);
		outbuf = (unsigned char *) filter->outbuf;
		inbuf = (const unsigned char *) in;
		newlen = g_mime_yencode_close (inbuf, len, outbuf, &yenc->state,
					       &yenc->pcrc, &yenc->crc);
		g_assert (newlen <= (len + 2) * 2 + 62);
	} else {
		if ((yenc->state & GMIME_YDECODE_STATE_DECODE) && !(yenc->state & GMIME_YDECODE_STATE_END)) {
			/* all yEnc headers have been found so we can now start decoding */
			g_mime_filter_set_size (filter, len + 3, FALSE);
			outbuf = (unsigned char *) filter->outbuf;
			inbuf = (const unsigned char *) in;
			newlen = g_mime_ydecode_step (inbuf, len, outbuf, &yenc->state,
						      &yenc->pcrc, &yenc->crc);
			g_assert (newlen <= len + 3);
		} else {
			newlen = 0;
		}
	}
	
	*outprespace = filter->outpre;
	*out = filter->outbuf;
	*outlen = newlen;
}
static void
filter_filter (GMimeFilter *filter, char *inbuf, size_t inlen, size_t prespace,
	       char **outbuf, size_t *outlen, size_t *outprespace)
{
	GMimeFilterReply *reply = (GMimeFilterReply *) filter;
	register const char *inptr = inbuf;
	const char *inend = inbuf + inlen;
	char *outptr;

	(void) prespace;
	if (reply->encode) {
		g_mime_filter_set_size (filter, 3 * inlen, FALSE);

		outptr = filter->outbuf;
		while (inptr < inend) {
			if (reply->saw_nl) {
				*outptr++ = '>';
				*outptr++ = ' ';
				reply->saw_nl = FALSE;
			}
			if (*inptr == '\n')
				reply->saw_nl = TRUE;
			else
				reply->saw_nl = FALSE;
			if (*inptr != '\r')
				*outptr++ = *inptr;
			inptr++;
		}
	} else {
		g_mime_filter_set_size (filter, inlen + 1, FALSE);

		outptr = filter->outbuf;
		while (inptr < inend) {
			if (reply->saw_nl) {
				if (*inptr == '>')
					reply->saw_angle = TRUE;
				else
					*outptr++ = *inptr;
				reply->saw_nl = FALSE;
			} else if (reply->saw_angle) {
				if (*inptr == ' ')
					;
				else
					*outptr++ = *inptr;
				reply->saw_angle = FALSE;
			} else if (*inptr != '\r') {
				if (*inptr == '\n')
					reply->saw_nl = TRUE;
				*outptr++ = *inptr;
			}

			inptr++;
		}
	}

	*outlen = outptr - filter->outbuf;
	*outprespace = filter->outpre;
	*outbuf = filter->outbuf;
}
Example #3
0
static char *
check_size (GMimeFilter *filter, char *outptr, char **outend, size_t len)
{
	size_t outleft = (size_t) (*outend - outptr);
	size_t offset;

	if (outleft >= len)
		return outptr;

	offset = outptr - filter->outbuf;

	g_mime_filter_set_size (filter, filter->outsize + len, TRUE);

	*outend = filter->outbuf + filter->outsize;

	return filter->outbuf + offset;
}
Example #4
0
static void
convert (GMimeFilter *filter, char *inbuf, size_t inlen, size_t prespace,
	 char **outbuf, size_t *outlen, size_t *outprespace, gboolean flush)
{
	GMimeFilterDos2Unix *dos2unix = (GMimeFilterDos2Unix *) filter;
	register const char *inptr = inbuf;
	const char *inend = inbuf + inlen;
	size_t expected = inlen;
	char *outptr;
	
	if (flush && dos2unix->ensure_newline)
		expected++;
	
	if (dos2unix->pc == '\r')
		expected++;
	
	g_mime_filter_set_size (filter, expected, FALSE);
	
	outptr = filter->outbuf;
	while (inptr < inend) {
		if (*inptr == '\n') {
			*outptr++ = *inptr;
		} else {
			if (dos2unix->pc == '\r')
				*outptr++ = dos2unix->pc;
			
			if (*inptr != '\r')
				*outptr++ = *inptr;
		}
		
		dos2unix->pc = *inptr++;
	}
	
	if (flush && dos2unix->ensure_newline && dos2unix->pc != '\n')
		dos2unix->pc = *outptr++ = '\n';
	
	*outlen = outptr - filter->outbuf;
	*outprespace = filter->outpre;
	*outbuf = filter->outbuf;
}
Example #5
0
static void
html_convert (GMimeFilter *filter, char *in, size_t inlen, size_t prespace,
	      char **out, size_t *outlen, size_t *outprespace, gboolean flush)
{
  (void) (prespace);
	GMimeFilterHTMLBQ *html = (GMimeFilterHTMLBQ *) filter;
	register char *inptr, *outptr;
	char *start, *outend;
	const char *inend;
	int depth;

	g_mime_filter_set_size (filter, inlen * 2 + 6, FALSE);

	start = inptr = in;
	inend = in + inlen;
	outptr = filter->outbuf;
	outend = filter->outbuf + filter->outsize;

	if (html->flags & GMIME_FILTER_HTML_PRE && !html->pre_open) {
		outptr = g_stpcpy (outptr, "<pre>");
		html->pre_open = TRUE;
	}

	do {
		while (inptr < inend && *inptr != '\n')
			inptr++;

		if (inptr == inend && !flush)
			break;

		html->column = 0;
		depth = citation_depth (start, inend);

		if (html->flags & GMIME_FILTER_HTML_BQ_BLOCKQUOTE_CITATION) {
			if (html->prev_cit_depth < depth) {
        while (html->prev_cit_depth < depth) {
          html->prev_cit_depth++;

          char bq[33];
          int ldepth = html->prev_cit_depth > 999 ? 999 : html->prev_cit_depth;

          g_snprintf (bq, 31, "<blockquote class=\"level_%03d\">", ldepth);

          outptr = check_size (filter, outptr, &outend, 31);
          outptr = g_stpcpy (outptr, bq);
        }

        /* remove '>' */
        while (*start == '>' && start < inptr) start++;

        /* remove leading space */
        if (*start == ' ' && start < inptr) start++;

      } else if (html->prev_cit_depth > depth) {

        /* close quotes */
        while (html->prev_cit_depth > depth) {
          outptr = check_size (filter, outptr, &outend, 14);
          outptr = g_stpcpy (outptr, "</blockquote>");
          html->prev_cit_depth--;
        }

        /* remove '>' */
        while (*start == '>' && start < inptr) start++;

        /* remove leading space */
        if (*start == ' ' && start < inptr) start++;

      } else if (depth > 0) {
        /* we are still at the same depth: remove '>' */
        while (*start == '>' && start < inptr) start++;

        /* remove leading space */
        if (*start == ' ' && start < inptr) start++;

			} else if (*start == '>') {
				/* >From line */
				start++;
			}

    } else if (html->flags & GMIME_FILTER_HTML_MARK_CITATION) {
			if (depth > 0) {
				char font[25];

				/* FIXME: we could easily support multiple colour depths here */

				g_snprintf (font, 25, "<font color=\"#%06x\">", (html->colour & 0xffffff));

				outptr = check_size (filter, outptr, &outend, 25);
				outptr = g_stpcpy (outptr, font);
			} else if (*start == '>') {
				/* >From line */
				start++;
			}
		} else if (html->flags & GMIME_FILTER_HTML_CITE) {
			outptr = check_size (filter, outptr, &outend, 6);
			outptr = g_stpcpy (outptr, "&gt; ");
			html->column += 2;
		}

#define CONVERT_URLS_OR_ADDRESSES (GMIME_FILTER_HTML_CONVERT_URLS | GMIME_FILTER_HTML_CONVERT_ADDRESSES)
		if (html->flags & CONVERT_URLS_OR_ADDRESSES) {
			size_t matchlen, buflen, len;
			urlmatch_t match;

			len = inptr - start;

			do {
				if (url_scanner_scan (html->scanner, start, len, &match)) {
					/* write out anything before the first regex match */
					outptr = writeln (filter, start, start + match.um_so,
							  outptr, &outend);

					start += match.um_so;
					len -= match.um_so;

					matchlen = match.um_eo - match.um_so;

					buflen = 20 + strlen (match.prefix) + matchlen + matchlen;
					outptr = check_size (filter, outptr, &outend, buflen);

					/* write out the href tag */
					outptr = g_stpcpy (outptr, "<a href=\"");
					outptr = g_stpcpy (outptr, match.prefix);
					memcpy (outptr, start, matchlen);
					outptr += matchlen;
					outptr = g_stpcpy (outptr, "\">");

					/* now write the matched string */
					memcpy (outptr, start, matchlen);
					html->column += matchlen;
					outptr += matchlen;
					start += matchlen;
					len -= matchlen;

					/* close the href tag */
					outptr = g_stpcpy (outptr, "</a>");
				} else {
					/* nothing matched so write out the remainder of this line buffer */
					outptr = writeln (filter, start, start + len, outptr, &outend);
					break;
				}
			} while (len > 0);
		} else {
			outptr = writeln (filter, start, inptr, outptr, &outend);
		}

		if (!(html->flags & GMIME_FILTER_HTML_BQ_BLOCKQUOTE_CITATION) &&
         (html->flags & GMIME_FILTER_HTML_MARK_CITATION) && (depth > 0)) {
			outptr = check_size (filter, outptr, &outend, 8);
			outptr = g_stpcpy (outptr, "</font>");
		}

		if (html->flags & GMIME_FILTER_HTML_CONVERT_NL) {
			outptr = check_size (filter, outptr, &outend, 5);
			outptr = g_stpcpy (outptr, "<br>");
		}

		if (inptr < inend)
			*outptr++ = '\n';

		start = ++inptr;
	} while (inptr < inend);

	if (flush) {
		if (html->pre_open) {
			/* close the pre-tag */
			outptr = check_size (filter, outptr, &outend, 10);
			outptr = g_stpcpy (outptr, "</pre>");
		}

		if ((html->flags & GMIME_FILTER_HTML_BQ_BLOCKQUOTE_CITATION) &&
        (html->prev_cit_depth > 0)) {
      /* close open blockquotes */
      while (html->prev_cit_depth > 0) {
        outptr = check_size (filter, outptr, &outend, 14);
        outptr = g_stpcpy (outptr, "</blockquote>");
        html->prev_cit_depth--;
      }
    }
	} else if (start < inend) {
		/* backup */
		g_mime_filter_backup (filter, start, (unsigned) (inend - start));
	}

	*out = filter->outbuf;
	*outlen = outptr - filter->outbuf;
	*outprespace = filter->outpre;
}
Example #6
0
static void
filter_filter(GMimeFilter *filter, char *inbuf, size_t inlen, size_t prespace,
	       	  char **outbuf, size_t *outlen, size_t *outprespace)
{
	GMimeFilterHeader *self = GMIME_FILTER_HEADER(filter);

	g_mime_filter_set_size(filter, inlen, FALSE);

	if (self->headers_done) {
		memcpy(filter->outbuf, inbuf, inlen);
		*outlen = inlen;
	} else {
		gchar *newline;
		gchar *outptr;

		outptr = filter->outbuf;
		*outlen = 0U;
		newline = memchr(inbuf, '\n', inlen);
		while ((newline != NULL) && !self->headers_done) {
			size_t count;

			/* number of chars in this line */
			count = (newline - inbuf) + 1U;

			/* check for for folded header continuation */
			if ((inbuf[0] == ' ') || (inbuf[0] == '\t')) {
				/* nothing to do, do not change the state */
			} else if (newline == inbuf) {
				self->headers_done = TRUE;
			} else if (((count >= 4U) && (g_ascii_strncasecmp(inbuf, "Bcc:", 4U) == 0)) ||
				   	   ((count >= 7U) && (g_ascii_strncasecmp(inbuf, "Status:", 7U) == 0)) ||
					   ((count >= 9U) && (g_ascii_strncasecmp(inbuf, "X-Status:", 9U) == 0)) ||
					   ((count >= 8U) && (g_ascii_strncasecmp(inbuf, "X-Balsa-", 8U) == 0))) {
				self->drop_header = TRUE;
			} else {
				self->drop_header = FALSE;
			}

			/* copy if we want to keep this header */
			if (!self->drop_header) {
				memcpy(outptr, inbuf, count);
				outptr = &outptr[count];
				*outlen += count;
			}

			/* adjust */
			inbuf = &inbuf[count];
			inlen -= count;
			if (!self->headers_done && (inlen > 0)) {
				newline = memchr(inbuf, '\n', inlen);
			} else {
				newline = NULL;
			}
		}

		/* back up left-over data */
		if (inlen > 0U) {
			g_mime_filter_backup(filter, inbuf, inlen);
		}
	}
	*outprespace = filter->outpre;
	*outbuf = filter->outbuf;
}
static void
filter_filter (GMimeFilter *filter, char *inbuf, size_t inlen, size_t prespace,
	       char **outbuf, size_t *outlen, size_t *outprespace)
{
	GMimeFilterCRLF *crlf = (GMimeFilterCRLF *) filter;
	register const char *inptr = inbuf;
	const char *inend = inbuf + inlen;
	char *outptr;
	
	if (crlf->encode) {
		g_mime_filter_set_size (filter, 3 * inlen, FALSE);
		
		outptr = filter->outbuf;
		while (inptr < inend) {
			if (*inptr == '\r') {
				crlf->saw_cr = TRUE;
			} else if (*inptr == '\n') {
				crlf->saw_lf = TRUE;
				if (!crlf->saw_cr)
					*outptr++ = '\r';
				crlf->saw_cr = FALSE;
			} else {
				if (crlf->dots && *inptr == '.' && crlf->saw_lf)
					*outptr++ = '.';
				
				crlf->saw_cr = FALSE;
				crlf->saw_lf = FALSE;
			}
			
			*outptr++ = *inptr++;
		}
	} else {
		g_mime_filter_set_size (filter, inlen + 1, FALSE);
		
		outptr = filter->outbuf;
		while (inptr < inend) {
			if (*inptr == '\r') {
				crlf->saw_dot = FALSE;
				crlf->saw_cr = TRUE;
			} else {
				if (crlf->saw_cr) {
					crlf->saw_cr = FALSE;
					
					if (*inptr == '\n') {
						crlf->saw_lf = TRUE;
						*outptr++ = *inptr++;
						continue;
					} else
						*outptr++ = '\r';
				}
				
				if (!(crlf->dots && crlf->saw_dot && *inptr == '.'))
					*outptr++ = *inptr;
			}
			
			if (crlf->dots && *inptr == '.') {
				if (crlf->saw_lf) {
					crlf->saw_dot = TRUE;
				} else if (crlf->saw_dot) {
					crlf->saw_dot = FALSE;
				}
			}
			
			crlf->saw_lf = FALSE;
			
			inptr++;
		}
	}
	
	*outlen = outptr - filter->outbuf;
	*outprespace = filter->outpre;
	*outbuf = filter->outbuf;
}
Example #8
0
/* here we do all of the basic yEnc filtering */
static void
filter_filter (GMimeFilter *filter, char *in, size_t len, size_t prespace,
	       char **out, size_t *outlen, size_t *outprespace)
{
	GMimeFilterYenc *yenc = (GMimeFilterYenc *) filter;
	const unsigned char *inbuf;
	unsigned char *outbuf;
	size_t newlen = 0;
	
	if (yenc->encode) {
		/* won't go to more than 2 * (x + 2) + 62 */
		g_mime_filter_set_size (filter, (len + 2) * 2 + 62, FALSE);
		outbuf = (unsigned char *) filter->outbuf;
		inbuf = (const unsigned char *) in;
		newlen = g_mime_yencode_step (inbuf, len, outbuf, &yenc->state,
					      &yenc->pcrc, &yenc->crc);
		g_assert (newlen <= (len + 2) * 2 + 62);
	} else {
		if (!(yenc->state & GMIME_YDECODE_STATE_DECODE)) {
			register char *inptr, *inend;
			size_t left;
			
			inptr = in;
			inend = inptr + len;
			
			/* we cannot start decoding until we have found an =ybegin line */
			if (!(yenc->state & GMIME_YDECODE_STATE_BEGIN)) {
				while (inptr < inend) {
					left = inend - inptr;
					if (left < 8) {
						if (!strncmp (inptr, "=ybegin ", left))
							g_mime_filter_backup (filter, inptr, left);
						break;
					} else if (!strncmp (inptr, "=ybegin ", 8)) {
						for (in = inptr; inptr < inend && *inptr != '\n'; inptr++);
						if (inptr < inend) {
							inptr++;
							yenc->state |= GMIME_YDECODE_STATE_BEGIN;
							/* we can start ydecoding if the next line isn't
							   a ypart... */
							in = inptr;
							len = inend - in;
						} else {
							/* we don't have enough... */
							g_mime_filter_backup (filter, in, left);
						}
						break;
					}
				
					/* go to the next line */
					while (inptr < inend && *inptr != '\n')
						inptr++;
					
					if (inptr < inend)
						inptr++;
				}
			}
			
			left = inend - inptr;
			if ((yenc->state & GMIME_YDECODE_STATE_BEGIN) && left > 0) {
				/* we have found an '=ybegin' line but we may yet have an "=ypart" line to
				   yield before decoding the content */
				if (left < 7 && !strncmp (inptr, "=ypart ", left)) {
					g_mime_filter_backup (filter, inptr, left);
				} else if (!strncmp (inptr, "=ypart ", 7)) {
					for (in = inptr; inptr < inend && *inptr != '\n'; inptr++);
					if (inptr < inend) {
						inptr++;
						yenc->state |= GMIME_YDECODE_STATE_PART | GMIME_YDECODE_STATE_DECODE;
						in = inptr;
						len = inend - in;
					} else {
						g_mime_filter_backup (filter, in, left);
					}
				} else {
					/* guess it doesn't have a =ypart line */
					yenc->state |= GMIME_YDECODE_STATE_DECODE;
				}
			}
		}
		
		if ((yenc->state & GMIME_YDECODE_STATE_DECODE) && !(yenc->state & GMIME_YDECODE_STATE_END)) {
			/* all yEnc headers have been found so we can now start decoding */
			g_mime_filter_set_size (filter, len + 3, FALSE);
			outbuf = (unsigned char *) filter->outbuf;
			inbuf = (const unsigned char *) in;
			newlen = g_mime_ydecode_step (inbuf, len, outbuf, &yenc->state,
						      &yenc->pcrc, &yenc->crc);
			g_assert (newlen <= len + 3);
		} else {
			newlen = 0;
		}
	}
	
	*outprespace = filter->outpre;
	*out = filter->outbuf;
	*outlen = newlen;
}