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, "?="); }
int has_non_ascii(const char *s) { int ch; if (!s) return 0; while ((ch = *s++) != '\0') { if (non_ascii(ch)) return 1; } return 0; }
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, "?="); }
static int is_rfc2047_special(char ch, enum rfc2047_type type) { /* * rfc2047, section 4.2: * * 8-bit values which correspond to printable ASCII characters other * than "=", "?", and "_" (underscore), MAY be represented as those * characters. (But see section 5 for restrictions.) In * particular, SPACE and TAB MUST NOT be represented as themselves * within encoded words. */ /* * rule out non-ASCII characters and non-printable characters (the * non-ASCII check should be redundant as isprint() is not localized * and only knows about ASCII, but be defensive about that) */ if (non_ascii(ch) || !isprint(ch)) return 1; /* * rule out special printable characters (' ' should be the only * whitespace character considered printable, but be defensive and use * isspace()) */ if (isspace(ch) || ch == '=' || ch == '?' || ch == '_') return 1; /* * rfc2047, section 5.3: * * As a replacement for a 'word' entity within a 'phrase', for example, * one that precedes an address in a From, To, or Cc header. The ABNF * definition for 'phrase' from RFC 822 thus becomes: * * phrase = 1*( encoded-word / word ) * * In this case the set of characters that may be used in a "Q"-encoded * 'encoded-word' is restricted to: <upper and lower case ASCII * letters, decimal digits, "!", "*", "+", "-", "/", "=", and "_" * (underscore, ASCII 95.)>. An 'encoded-word' that appears within a * 'phrase' MUST be separated from any adjacent 'word', 'text' or * 'special' by 'linear-white-space'. */ if (type != RFC2047_ADDRESS) return 0; /* '=' and '_' are special cases and have been checked above */ return !(isalnum(ch) || ch == '!' || ch == '*' || ch == '+' || ch == '-' || ch == '/'); }
static int needs_rfc2047_encoding(const char *line, int len, enum rfc2047_type type) { int i; for (i = 0; i < len; i++) { int ch = line[i]; if (non_ascii(ch) || ch == '\n') return 1; if ((i + 1 < len) && (ch == '=' && line[i+1] == '?')) return 1; } return 0; }
void ascii_check::inspect( const string & library_name, const path & full_path, // example: c:/foo/boost/filesystem/path.hpp const string & contents ) // contents of file to be inspected { if (contents.find( "hpxinspect:" "noascii" ) != string::npos) return; string::const_iterator bad_char = std::find_if ( contents.begin (), contents.end (), non_ascii ()); if ( bad_char != contents.end ()) { ++m_files_with_errors; std::size_t ln = std::count( contents.begin(), bad_char, '\n' ) + 1; string the_line = find_line ( contents, bad_char ); error( library_name, full_path, "Non-ASCII: ", ln); } }
void pretty_print_commit(struct pretty_print_context *pp, const struct commit *commit, struct strbuf *sb) { unsigned long beginning_of_body; int indent = 4; const char *msg; const char *reencoded; const char *encoding; int need_8bit_cte = pp->need_8bit_cte; if (pp->fmt == CMIT_FMT_USERFORMAT) { format_commit_message(commit, user_format, sb, pp); return; } encoding = get_log_output_encoding(); msg = reencoded = logmsg_reencode(commit, NULL, encoding); if (pp->fmt == CMIT_FMT_ONELINE || pp->fmt == CMIT_FMT_EMAIL) indent = 0; /* * We need to check and emit Content-type: to mark it * as 8-bit if we haven't done so. */ if (pp->fmt == CMIT_FMT_EMAIL && need_8bit_cte == 0) { int i, ch, in_body; for (in_body = i = 0; (ch = msg[i]); i++) { if (!in_body) { /* author could be non 7-bit ASCII but * the log may be so; skip over the * header part first. */ if (ch == '\n' && msg[i+1] == '\n') in_body = 1; } else if (non_ascii(ch)) { need_8bit_cte = 1; break; } } } pp_header(pp, encoding, commit, &msg, sb); if (pp->fmt != CMIT_FMT_ONELINE && !pp->subject) { strbuf_addch(sb, '\n'); } /* Skip excess blank lines at the beginning of body, if any... */ msg = skip_empty_lines(msg); /* These formats treat the title line specially. */ if (pp->fmt == CMIT_FMT_ONELINE || pp->fmt == CMIT_FMT_EMAIL) pp_title_line(pp, &msg, sb, encoding, need_8bit_cte); beginning_of_body = sb->len; if (pp->fmt != CMIT_FMT_ONELINE) pp_remainder(pp, &msg, sb, indent); strbuf_rtrim(sb); /* Make sure there is an EOLN for the non-oneline case */ if (pp->fmt != CMIT_FMT_ONELINE) strbuf_addch(sb, '\n'); /* * The caller may append additional body text in e-mail * format. Make sure we did not strip the blank line * between the header and the body. */ if (pp->fmt == CMIT_FMT_EMAIL && sb->len <= beginning_of_body) strbuf_addch(sb, '\n'); unuse_commit_buffer(commit, reencoded); }
static int is_rfc2047_special(char ch) { return (non_ascii(ch) || (ch == '=') || (ch == '?') || (ch == '_')); }
void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit, struct strbuf *sb, const struct pretty_print_context *context) { unsigned long beginning_of_body; int indent = 4; const char *msg = commit->buffer; char *reencoded; const char *encoding; int need_8bit_cte = context->need_8bit_cte; if (fmt == CMIT_FMT_USERFORMAT) { format_commit_message(commit, user_format, sb, context); return; } reencoded = reencode_commit_message(commit, &encoding); if (reencoded) { msg = reencoded; } if (fmt == CMIT_FMT_ONELINE || fmt == CMIT_FMT_EMAIL) indent = 0; /* * We need to check and emit Content-type: to mark it * as 8-bit if we haven't done so. */ if (fmt == CMIT_FMT_EMAIL && need_8bit_cte == 0) { int i, ch, in_body; for (in_body = i = 0; (ch = msg[i]); i++) { if (!in_body) { /* author could be non 7-bit ASCII but * the log may be so; skip over the * header part first. */ if (ch == '\n' && msg[i+1] == '\n') in_body = 1; } else if (non_ascii(ch)) { need_8bit_cte = 1; break; } } } pp_header(fmt, context->abbrev, context->date_mode, encoding, commit, &msg, sb); if (fmt != CMIT_FMT_ONELINE && !context->subject) { strbuf_addch(sb, '\n'); } /* Skip excess blank lines at the beginning of body, if any... */ msg = skip_empty_lines(msg); /* These formats treat the title line specially. */ if (fmt == CMIT_FMT_ONELINE || fmt == CMIT_FMT_EMAIL) pp_title_line(fmt, &msg, sb, context->subject, context->after_subject, encoding, need_8bit_cte); beginning_of_body = sb->len; if (fmt != CMIT_FMT_ONELINE) pp_remainder(fmt, &msg, sb, indent); strbuf_rtrim(sb); /* Make sure there is an EOLN for the non-oneline case */ if (fmt != CMIT_FMT_ONELINE) strbuf_addch(sb, '\n'); /* * The caller may append additional body text in e-mail * format. Make sure we did not strip the blank line * between the header and the body. */ if (fmt == CMIT_FMT_EMAIL && sb->len <= beginning_of_body) strbuf_addch(sb, '\n'); if (context->show_notes) format_display_notes(commit->object.sha1, sb, encoding, NOTES_SHOW_HEADER | NOTES_INDENT); free(reencoded); }
void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit, struct strbuf *sb, int abbrev, const char *subject, const char *after_subject, enum date_mode dmode, int need_8bit_cte) { unsigned long beginning_of_body; int indent = 4; const char *msg = commit->buffer; char *reencoded; const char *encoding; if (fmt == CMIT_FMT_USERFORMAT) { format_commit_message(commit, user_format, sb); return; } encoding = (git_log_output_encoding ? git_log_output_encoding : git_commit_encoding); if (!encoding) encoding = "utf-8"; reencoded = logmsg_reencode(commit, encoding); if (reencoded) { msg = reencoded; } if (fmt == CMIT_FMT_ONELINE || fmt == CMIT_FMT_EMAIL) indent = 0; /* * We need to check and emit Content-type: to mark it * as 8-bit if we haven't done so. */ if (fmt == CMIT_FMT_EMAIL && need_8bit_cte == 0) { int i, ch, in_body; for (in_body = i = 0; (ch = msg[i]); i++) { if (!in_body) { /* author could be non 7-bit ASCII but * the log may be so; skip over the * header part first. */ if (ch == '\n' && msg[i+1] == '\n') in_body = 1; } else if (non_ascii(ch)) { need_8bit_cte = 1; break; } } } pp_header(fmt, abbrev, dmode, encoding, commit, &msg, sb); if (fmt != CMIT_FMT_ONELINE && !subject) { strbuf_addch(sb, '\n'); } /* Skip excess blank lines at the beginning of body, if any... */ for (;;) { int linelen = get_one_line(msg); int ll = linelen; if (!linelen) break; if (!is_empty_line(msg, &ll)) break; msg += linelen; } /* These formats treat the title line specially. */ if (fmt == CMIT_FMT_ONELINE || fmt == CMIT_FMT_EMAIL) pp_title_line(fmt, &msg, sb, subject, after_subject, encoding, need_8bit_cte); beginning_of_body = sb->len; if (fmt != CMIT_FMT_ONELINE) pp_remainder(fmt, &msg, sb, indent); strbuf_rtrim(sb); /* Make sure there is an EOLN for the non-oneline case */ if (fmt != CMIT_FMT_ONELINE) strbuf_addch(sb, '\n'); /* * The caller may append additional body text in e-mail * format. Make sure we did not strip the blank line * between the header and the body. */ if (fmt == CMIT_FMT_EMAIL && sb->len <= beginning_of_body) strbuf_addch(sb, '\n'); free(reencoded); }