mirror of
https://github.com/tmux/tmux.git
synced 2026-05-30 14:16:18 +00:00
Add a fairly low time limit to format evaluation to stop absurdly nested
formats from making tmux appear to hang.
This commit is contained in:
16
format.c
16
format.c
@@ -120,6 +120,9 @@ format_job_cmp(struct format_job *fj1, struct format_job *fj2)
|
|||||||
/* Limit on recursion. */
|
/* Limit on recursion. */
|
||||||
#define FORMAT_LOOP_LIMIT 100
|
#define FORMAT_LOOP_LIMIT 100
|
||||||
|
|
||||||
|
/* Limit on time taken (milliseconds). */
|
||||||
|
#define FORMAT_TIME_LIMIT 100
|
||||||
|
|
||||||
/* Format expand flags. */
|
/* Format expand flags. */
|
||||||
#define FORMAT_EXPAND_TIME 0x1
|
#define FORMAT_EXPAND_TIME 0x1
|
||||||
#define FORMAT_EXPAND_NOJOBS 0x2
|
#define FORMAT_EXPAND_NOJOBS 0x2
|
||||||
@@ -169,9 +172,11 @@ RB_GENERATE_STATIC(format_entry_tree, format_entry, entry, format_entry_cmp);
|
|||||||
struct format_expand_state {
|
struct format_expand_state {
|
||||||
struct format_tree *ft;
|
struct format_tree *ft;
|
||||||
u_int loop;
|
u_int loop;
|
||||||
|
uint64_t start_time;
|
||||||
|
int flags;
|
||||||
|
|
||||||
time_t time;
|
time_t time;
|
||||||
struct tm tm;
|
struct tm tm;
|
||||||
int flags;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Format modifier. */
|
/* Format modifier. */
|
||||||
@@ -292,6 +297,7 @@ format_copy_state(struct format_expand_state *to,
|
|||||||
to->time = from->time;
|
to->time = from->time;
|
||||||
memcpy(&to->tm, &from->tm, sizeof to->tm);
|
memcpy(&to->tm, &from->tm, sizeof to->tm);
|
||||||
to->flags = from->flags|flags;
|
to->flags = from->flags|flags;
|
||||||
|
to->start_time = from->start_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Format job update callback. */
|
/* Format job update callback. */
|
||||||
@@ -5514,10 +5520,16 @@ format_expand1(struct format_expand_state *es, const char *fmt)
|
|||||||
size_t off, len, n, outlen;
|
size_t off, len, n, outlen;
|
||||||
int ch, brackets;
|
int ch, brackets;
|
||||||
char expanded[8192];
|
char expanded[8192];
|
||||||
|
uint64_t t = get_timer();
|
||||||
|
|
||||||
if (fmt == NULL || *fmt == '\0')
|
if (fmt == NULL || *fmt == '\0')
|
||||||
return (xstrdup(""));
|
return (xstrdup(""));
|
||||||
|
|
||||||
|
if (t - es->start_time >= FORMAT_TIME_LIMIT) {
|
||||||
|
format_log(es, "reached time limit (%llu)",
|
||||||
|
(unsigned long long)(t - es->start_time));
|
||||||
|
return (xstrdup(""));
|
||||||
|
}
|
||||||
if (es->loop == FORMAT_LOOP_LIMIT) {
|
if (es->loop == FORMAT_LOOP_LIMIT) {
|
||||||
format_log(es, "reached loop limit (%u)", FORMAT_LOOP_LIMIT);
|
format_log(es, "reached loop limit (%u)", FORMAT_LOOP_LIMIT);
|
||||||
return (xstrdup(""));
|
return (xstrdup(""));
|
||||||
@@ -5683,6 +5695,7 @@ format_expand_time(struct format_tree *ft, const char *fmt)
|
|||||||
memset(&es, 0, sizeof es);
|
memset(&es, 0, sizeof es);
|
||||||
es.ft = ft;
|
es.ft = ft;
|
||||||
es.flags = FORMAT_EXPAND_TIME;
|
es.flags = FORMAT_EXPAND_TIME;
|
||||||
|
es.start_time = get_timer();
|
||||||
return (format_expand1(&es, fmt));
|
return (format_expand1(&es, fmt));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5695,6 +5708,7 @@ format_expand(struct format_tree *ft, const char *fmt)
|
|||||||
memset(&es, 0, sizeof es);
|
memset(&es, 0, sizeof es);
|
||||||
es.ft = ft;
|
es.ft = ft;
|
||||||
es.flags = 0;
|
es.flags = 0;
|
||||||
|
es.start_time = get_timer();
|
||||||
return (format_expand1(&es, fmt));
|
return (format_expand1(&es, fmt));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user