summaryrefslogtreecommitdiffstats
path: root/usr.bin/tmux/format.c
diff options
context:
space:
mode:
authornicm <nicm@openbsd.org>2013-10-10 11:50:20 +0000
committernicm <nicm@openbsd.org>2013-10-10 11:50:20 +0000
commitdb5d922c43b516feee8fcbc025e9ee9ca709c05f (patch)
treeab69f7ea27b34ca16ce2f28bd17d71a7dd2fa539 /usr.bin/tmux/format.c
parentHandle input mouse positions <33 (we already can generate them). (diff)
downloadwireguard-openbsd-db5d922c43b516feee8fcbc025e9ee9ca709c05f.tar.xz
wireguard-openbsd-db5d922c43b516feee8fcbc025e9ee9ca709c05f.zip
Add length limit operator for formats.
Diffstat (limited to 'usr.bin/tmux/format.c')
-rw-r--r--usr.bin/tmux/format.c42
1 files changed, 35 insertions, 7 deletions
diff --git a/usr.bin/tmux/format.c b/usr.bin/tmux/format.c
index d5b31a78778..ccfd2861eb8 100644
--- a/usr.bin/tmux/format.c
+++ b/usr.bin/tmux/format.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: format.c,v 1.29 2013/10/10 11:47:52 nicm Exp $ */
+/* $OpenBSD: format.c,v 1.30 2013/10/10 11:50:20 nicm Exp $ */
/*
* Copyright (c) 2011 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -18,6 +18,8 @@
#include <sys/types.h>
+#include <ctype.h>
+#include <errno.h>
#include <netdb.h>
#include <stdarg.h>
#include <stdlib.h>
@@ -188,18 +190,40 @@ format_find(struct format_tree *ft, const char *key)
* #{?blah,a,b} is replace with a if blah exists and is nonzero else b.
*/
int
-format_replace(struct format_tree *ft,
- const char *key, size_t keylen, char **buf, size_t *len, size_t *off)
+format_replace(struct format_tree *ft, const char *key, size_t keylen,
+ char **buf, size_t *len, size_t *off)
{
- char *copy, *ptr;
+ char *copy, *copy0, *endptr, *ptr;
const char *value;
size_t valuelen;
+ u_long limit = ULONG_MAX;
/* Make a copy of the key. */
- copy = xmalloc(keylen + 1);
+ copy0 = copy = xmalloc(keylen + 1);
memcpy(copy, key, keylen);
copy[keylen] = '\0';
+ /* Is there a length limit or whatnot? */
+ if (!islower((u_char) *copy) && *copy != '?') {
+ while (*copy != ':' && *copy != '\0') {
+ switch (*copy) {
+ case '=':
+ errno = 0;
+ limit = strtoul(copy + 1, &endptr, 10);
+ if (errno == ERANGE && limit == ULONG_MAX)
+ goto fail;
+ copy = endptr;
+ break;
+ default:
+ copy++;
+ break;
+ }
+ }
+ if (*copy != ':')
+ goto fail;
+ copy++;
+ }
+
/*
* Is this a conditional? If so, check it exists and extract either the
* first or second element. If not, look up the key directly.
@@ -230,6 +254,10 @@ format_replace(struct format_tree *ft,
}
valuelen = strlen(value);
+ /* Truncate the value if needed. */
+ if (valuelen > limit)
+ valuelen = limit;
+
/* Expand the buffer and copy in the value. */
while (*len - *off < valuelen + 1) {
*buf = xrealloc(*buf, 2, *len);
@@ -238,11 +266,11 @@ format_replace(struct format_tree *ft,
memcpy(*buf + *off, value, valuelen);
*off += valuelen;
- free(copy);
+ free(copy0);
return (0);
fail:
- free(copy);
+ free(copy0);
return (-1);
}