Example #1
0
static void add_rfc2047(struct strbuf *sb, const char *line, int len,
		       const char *encoding)
{
	int i, last;

	for (i = 0; i < len; i++) {
		int ch = line[i];
		if (non_ascii(ch))
			goto needquote;
		if ((i + 1 < len) && (ch == '=' && line[i+1] == '?'))
			goto needquote;
	}
	strbuf_add(sb, line, len);
	return;

needquote:
	strbuf_grow(sb, len * 3 + strlen(encoding) + 100);
	strbuf_addf(sb, "=?%s?q?", encoding);
	for (i = last = 0; i < len; i++) {
		unsigned ch = line[i] & 0xFF;
		/*
		 * We encode ' ' using '=20' even though rfc2047
		 * allows using '_' for readability.  Unfortunately,
		 * many programs do not understand this and just
		 * leave the underscore in place.
		 */
		if (is_rfc2047_special(ch) || ch == ' ') {
			strbuf_add(sb, line + last, i - last);
			strbuf_addf(sb, "=%02X", ch);
			last = i + 1;
		}
	}
	strbuf_add(sb, line + last, len - last);
	strbuf_addstr(sb, "?=");
}
Example #2
0
File: pretty.c Project: avar/git
static void add_rfc2047(struct strbuf *sb, const char *line, int len,
                        const char *encoding)
{
    static const int max_length = 78; /* per rfc2822 */
    int i;
    int line_len;

    /* How many bytes are already used on the current line? */
    for (i = sb->len - 1; i >= 0; i--)
        if (sb->buf[i] == '\n')
            break;
    line_len = sb->len - (i+1);

    for (i = 0; i < len; i++) {
        int ch = line[i];
        if (non_ascii(ch) || ch == '\n')
            goto needquote;
        if ((i + 1 < len) && (ch == '=' && line[i+1] == '?'))
            goto needquote;
    }
    strbuf_add_wrapped_bytes(sb, line, len, 0, 1, max_length - line_len);
    return;

needquote:
    strbuf_grow(sb, len * 3 + strlen(encoding) + 100);
    strbuf_addf(sb, "=?%s?q?", encoding);
    line_len += strlen(encoding) + 5; /* 5 for =??q? */
    for (i = 0; i < len; i++) {
        unsigned ch = line[i] & 0xFF;

        if (line_len >= max_length - 2) {
            strbuf_addf(sb, "?=\n =?%s?q?", encoding);
            line_len = strlen(encoding) + 5 + 1; /* =??q? plus SP */
        }

        /*
         * We encode ' ' using '=20' even though rfc2047
         * allows using '_' for readability.  Unfortunately,
         * many programs do not understand this and just
         * leave the underscore in place.
         */
        if (is_rfc2047_special(ch) || ch == ' ' || ch == '\n') {
            strbuf_addf(sb, "=%02X", ch);
            line_len += 3;
        }
        else {
            strbuf_addch(sb, ch);
            line_len++;
        }
    }
    strbuf_addstr(sb, "?=");
}
Example #3
0
static void add_rfc2047(struct strbuf *sb, const char *line, size_t len,
		       const char *encoding, enum rfc2047_type type)
{
	static const int max_encoded_length = 76; /* per rfc2047 */
	int i;
	int line_len = last_line_length(sb);

	strbuf_grow(sb, len * 3 + strlen(encoding) + 100);
	strbuf_addf(sb, "=?%s?q?", encoding);
	line_len += strlen(encoding) + 5; /* 5 for =??q? */

	while (len) {
		/*
		 * RFC 2047, section 5 (3):
		 *
		 * Each 'encoded-word' MUST represent an integral number of
		 * characters.  A multi-octet character may not be split across
		 * adjacent 'encoded- word's.
		 */
		const unsigned char *p = (const unsigned char *)line;
		int chrlen = mbs_chrlen(&line, &len, encoding);
		int is_special = (chrlen > 1) || is_rfc2047_special(*p, type);

		/* "=%02X" * chrlen, or the byte itself */
		const char *encoded_fmt = is_special ? "=%02X"    : "%c";
		int	    encoded_len = is_special ? 3 * chrlen : 1;

		/*
		 * According to RFC 2047, we could encode the special character
		 * ' ' (space) with '_' (underscore) for readability. But many
		 * programs do not understand this and just leave the
		 * underscore in place. Thus, we do nothing special here, which
		 * causes ' ' to be encoded as '=20', avoiding this problem.
		 */

		if (line_len + encoded_len + 2 > max_encoded_length) {
			/* It won't fit with trailing "?=" --- break the line */
			strbuf_addf(sb, "?=\n =?%s?q?", encoding);
			line_len = strlen(encoding) + 5 + 1; /* =??q? plus SP */
		}

		for (i = 0; i < chrlen; i++)
			strbuf_addf(sb, encoded_fmt, p[i]);
		line_len += encoded_len;
	}
	strbuf_addstr(sb, "?=");
}
Example #4
0
static void add_rfc2047(struct strbuf *sb, const char *line, int len,
		       const char *encoding, enum rfc2047_type type)
{
	static const int max_encoded_length = 76; /* per rfc2047 */
	int i;
	int line_len = last_line_length(sb);

	strbuf_grow(sb, len * 3 + strlen(encoding) + 100);
	strbuf_addf(sb, "=?%s?q?", encoding);
	line_len += strlen(encoding) + 5; /* 5 for =??q? */
	for (i = 0; i < len; i++) {
		unsigned ch = line[i] & 0xFF;
		int is_special = is_rfc2047_special(ch, type);

		/*
		 * According to RFC 2047, we could encode the special character
		 * ' ' (space) with '_' (underscore) for readability. But many
		 * programs do not understand this and just leave the
		 * underscore in place. Thus, we do nothing special here, which
		 * causes ' ' to be encoded as '=20', avoiding this problem.
		 */

		if (line_len + 2 + (is_special ? 3 : 1) > max_encoded_length) {
			strbuf_addf(sb, "?=\n =?%s?q?", encoding);
			line_len = strlen(encoding) + 5 + 1; /* =??q? plus SP */
		}

		if (is_special) {
			strbuf_addf(sb, "=%02X", ch);
			line_len += 3;
		} else {
			strbuf_addch(sb, ch);
			line_len++;
		}
	}
	strbuf_addstr(sb, "?=");
}