Merge branch 'maint-2.33' into maint-2.34

This commit is contained in:
Junio C Hamano
2022-12-13 21:15:22 +09:00
17 changed files with 545 additions and 124 deletions

View File

@ -14,6 +14,13 @@
#include "trailer.h"
#include "run-command.h"
/*
* The limit for formatting directives, which enable the caller to append
* arbitrarily many bytes to the formatted buffer. This includes padding
* and wrapping formatters.
*/
#define FORMATTING_LIMIT (16 * 1024)
static char *user_format;
static struct cmt_fmt_map {
const char *name;
@ -983,7 +990,9 @@ static void strbuf_wrap(struct strbuf *sb, size_t pos,
if (pos)
strbuf_add(&tmp, sb->buf, pos);
strbuf_add_wrapped_text(&tmp, sb->buf + pos,
(int) indent1, (int) indent2, (int) width);
cast_size_t_to_int(indent1),
cast_size_t_to_int(indent2),
cast_size_t_to_int(width));
strbuf_swap(&tmp, sb);
strbuf_release(&tmp);
}
@ -1109,9 +1118,18 @@ static size_t parse_padding_placeholder(const char *placeholder,
const char *end = start + strcspn(start, ",)");
char *next;
int width;
if (!end || end == start)
if (!*end || end == start)
return 0;
width = strtol(start, &next, 10);
/*
* We need to limit the amount of padding, or otherwise this
* would allow the user to pad the buffer by arbitrarily many
* bytes and thus cause resource exhaustion.
*/
if (width < -FORMATTING_LIMIT || width > FORMATTING_LIMIT)
return 0;
if (next == start || width == 0)
return 0;
if (width < 0) {
@ -1356,6 +1374,16 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */
if (*next != ')')
return 0;
}
/*
* We need to limit the format here as it allows the
* user to prepend arbitrarily many bytes to the buffer
* when rewrapping.
*/
if (width > FORMATTING_LIMIT ||
indent1 > FORMATTING_LIMIT ||
indent2 > FORMATTING_LIMIT)
return 0;
rewrap_message_tail(sb, c, width, indent1, indent2);
return end - placeholder + 1;
} else
@ -1637,19 +1665,21 @@ static size_t format_and_pad_commit(struct strbuf *sb, /* in UTF-8 */
struct format_commit_context *c)
{
struct strbuf local_sb = STRBUF_INIT;
int total_consumed = 0, len, padding = c->padding;
size_t total_consumed = 0;
int len, padding = c->padding;
if (padding < 0) {
const char *start = strrchr(sb->buf, '\n');
int occupied;
if (!start)
start = sb->buf;
occupied = utf8_strnwidth(start, -1, 1);
occupied = utf8_strnwidth(start, strlen(start), 1);
occupied += c->pretty_ctx->graph_width;
padding = (-padding) - occupied;
}
while (1) {
int modifier = *placeholder == 'C';
int consumed = format_commit_one(&local_sb, placeholder, c);
size_t consumed = format_commit_one(&local_sb, placeholder, c);
total_consumed += consumed;
if (!modifier)
@ -1661,7 +1691,7 @@ static size_t format_and_pad_commit(struct strbuf *sb, /* in UTF-8 */
placeholder++;
total_consumed++;
}
len = utf8_strnwidth(local_sb.buf, -1, 1);
len = utf8_strnwidth(local_sb.buf, local_sb.len, 1);
if (c->flush_type == flush_left_and_steal) {
const char *ch = sb->buf + sb->len - 1;
@ -1676,7 +1706,7 @@ static size_t format_and_pad_commit(struct strbuf *sb, /* in UTF-8 */
if (*ch != 'm')
break;
p = ch - 1;
while (ch - p < 10 && *p != '\033')
while (p > sb->buf && ch - p < 10 && *p != '\033')
p--;
if (*p != '\033' ||
ch + 1 - p != display_mode_esc_sequence_len(p))
@ -1715,7 +1745,7 @@ static size_t format_and_pad_commit(struct strbuf *sb, /* in UTF-8 */
}
strbuf_addbuf(sb, &local_sb);
} else {
int sb_len = sb->len, offset = 0;
size_t sb_len = sb->len, offset = 0;
if (c->flush_type == flush_left)
offset = padding - len;
else if (c->flush_type == flush_both)
@ -1738,8 +1768,7 @@ static size_t format_commit_item(struct strbuf *sb, /* in UTF-8 */
const char *placeholder,
void *context)
{
int consumed;
size_t orig_len;
size_t consumed, orig_len;
enum {
NO_MAGIC,
ADD_LF_BEFORE_NON_EMPTY,
@ -1760,9 +1789,21 @@ static size_t format_commit_item(struct strbuf *sb, /* in UTF-8 */
default:
break;
}
if (magic != NO_MAGIC)
if (magic != NO_MAGIC) {
placeholder++;
switch (placeholder[0]) {
case 'w':
/*
* `%+w()` cannot ever expand to a non-empty string,
* and it potentially changes the layout of preceding
* contents. We're thus not able to handle the magic in
* this combination and refuse the pattern.
*/
return 0;
};
}
orig_len = sb->len;
if (((struct format_commit_context *)context)->flush_type != no_flush)
consumed = format_and_pad_commit(sb, placeholder, context);