diff --git a/format.c b/format.c index 85c83fda..29f2c308 100644 --- a/format.c +++ b/format.c @@ -573,7 +573,7 @@ format_cb_session_attached_list(struct format_tree *ft) } if ((size = EVBUFFER_LENGTH(buffer)) != 0) - xasprintf(&value, "%.*s", size, EVBUFFER_DATA(buffer)); + value = xmemdup(EVBUFFER_DATA(buffer), size); evbuffer_free(buffer); return (value); } @@ -712,7 +712,7 @@ format_cb_window_linked_sessions_list(struct format_tree *ft) } if ((size = EVBUFFER_LENGTH(buffer)) != 0) - xasprintf(&value, "%.*s", size, EVBUFFER_DATA(buffer)); + value = xmemdup(EVBUFFER_DATA(buffer), size); evbuffer_free(buffer); return (value); } @@ -766,7 +766,7 @@ format_cb_window_active_sessions_list(struct format_tree *ft) } if ((size = EVBUFFER_LENGTH(buffer)) != 0) - xasprintf(&value, "%.*s", size, EVBUFFER_DATA(buffer)); + value = xmemdup(EVBUFFER_DATA(buffer), size); evbuffer_free(buffer); return (value); } @@ -830,7 +830,7 @@ format_cb_window_active_clients_list(struct format_tree *ft) } if ((size = EVBUFFER_LENGTH(buffer)) != 0) - xasprintf(&value, "%.*s", size, EVBUFFER_DATA(buffer)); + value = xmemdup(EVBUFFER_DATA(buffer), size); evbuffer_free(buffer); return (value); } @@ -1005,7 +1005,7 @@ format_cb_pane_tabs(struct format_tree *ft) evbuffer_add_printf(buffer, "%u", i); } if ((size = EVBUFFER_LENGTH(buffer)) != 0) - xasprintf(&value, "%.*s", size, EVBUFFER_DATA(buffer)); + value = xmemdup(EVBUFFER_DATA(buffer), size); evbuffer_free(buffer); return (value); } @@ -1089,7 +1089,7 @@ format_cb_session_group_list(struct format_tree *ft) } if ((size = EVBUFFER_LENGTH(buffer)) != 0) - xasprintf(&value, "%.*s", size, EVBUFFER_DATA(buffer)); + value = xmemdup(EVBUFFER_DATA(buffer), size); evbuffer_free(buffer); return (value); } @@ -1129,7 +1129,7 @@ format_cb_session_group_attached_list(struct format_tree *ft) } if ((size = EVBUFFER_LENGTH(buffer)) != 0) - xasprintf(&value, "%.*s", size, EVBUFFER_DATA(buffer)); + value = xmemdup(EVBUFFER_DATA(buffer), size); evbuffer_free(buffer); return (value); } @@ -4671,7 +4671,8 @@ format_loop_sessions(struct format_expand_state *es, const char *fmt) struct format_tree *nft; struct format_expand_state next; char *all, *active, *use, *expanded, *value; - size_t valuelen; + struct evbuffer *buffer; + size_t size; struct session *s, **l; int i, n, last = 0; @@ -4680,8 +4681,9 @@ format_loop_sessions(struct format_expand_state *es, const char *fmt) active = NULL; } - value = xcalloc(1, 1); - valuelen = 1; + buffer = evbuffer_new(); + if (buffer == NULL) + fatalx("out of memory"); l = sort_get_sessions(&n, sc); for (i = 0; i < n; i++) { @@ -4702,16 +4704,18 @@ format_loop_sessions(struct format_expand_state *es, const char *fmt) expanded = format_expand1(&next, use); format_free(next.ft); - valuelen += strlen(expanded); - value = xrealloc(value, valuelen); - - strlcat(value, expanded, valuelen); + evbuffer_add(buffer, expanded, strlen(expanded)); free(expanded); } free(active); free(all); + if ((size = EVBUFFER_LENGTH(buffer)) != 0) + value = xmemdup(EVBUFFER_DATA(buffer), size); + else + value = xstrdup(""); + evbuffer_free(buffer); return (value); } @@ -4781,7 +4785,8 @@ format_loop_windows(struct format_expand_state *es, const char *fmt) struct format_tree *nft; struct format_expand_state next; char *all, *active, *use, *expanded, *value; - size_t valuelen; + struct evbuffer *buffer; + size_t size; struct winlink *wl, **l; struct window *w; int i, n, last = 0; @@ -4796,8 +4801,9 @@ format_loop_windows(struct format_expand_state *es, const char *fmt) active = NULL; } - value = xcalloc(1, 1); - valuelen = 1; + buffer = evbuffer_new(); + if (buffer == NULL) + fatalx("out of memory"); l = sort_get_winlinks_session(ft->s, &n, sc); for (i = 0; i < n; i++) { @@ -4829,16 +4835,18 @@ format_loop_windows(struct format_expand_state *es, const char *fmt) expanded = format_expand1(&next, use); format_free(nft); - valuelen += strlen(expanded); - value = xrealloc(value, valuelen); - - strlcat(value, expanded, valuelen); + evbuffer_add(buffer, expanded, strlen(expanded)); free(expanded); } free(active); free(all); + if ((size = EVBUFFER_LENGTH(buffer)) != 0) + value = xmemdup(EVBUFFER_DATA(buffer), size); + else + value = xstrdup(""); + evbuffer_free(buffer); return (value); } @@ -4853,7 +4861,8 @@ format_loop_panes(struct format_expand_state *es, const char *fmt) struct format_tree *nft; struct format_expand_state next; char *all, *active, *use, *expanded, *value; - size_t valuelen; + struct evbuffer *buffer; + size_t size; struct window_pane *wp, **l; int i, n, last = 0; @@ -4867,8 +4876,9 @@ format_loop_panes(struct format_expand_state *es, const char *fmt) active = NULL; } - value = xcalloc(1, 1); - valuelen = 1; + buffer = evbuffer_new(); + if (buffer == NULL) + fatalx("out of memory"); l = sort_get_panes_window(ft->w, &n, sc); for (i = 0; i < n; i++) { @@ -4888,16 +4898,18 @@ format_loop_panes(struct format_expand_state *es, const char *fmt) expanded = format_expand1(&next, use); format_free(nft); - valuelen += strlen(expanded); - value = xrealloc(value, valuelen); - - strlcat(value, expanded, valuelen); + evbuffer_add(buffer, expanded, strlen(expanded)); free(expanded); } free(active); free(all); + if ((size = EVBUFFER_LENGTH(buffer)) != 0) + value = xmemdup(EVBUFFER_DATA(buffer), size); + else + value = xstrdup(""); + evbuffer_free(buffer); return (value); } @@ -4912,11 +4924,13 @@ format_loop_clients(struct format_expand_state *es, const char *fmt) struct format_tree *nft; struct format_expand_state next; char *expanded, *value; - size_t valuelen; + struct evbuffer *buffer; + size_t size; int i, n, last = 0; - value = xcalloc(1, 1); - valuelen = 1; + buffer = evbuffer_new(); + if (buffer == NULL) + fatalx("out of memory"); l = sort_get_clients(&n, sc); for (i = 0; i < n; i++) { @@ -4931,13 +4945,15 @@ format_loop_clients(struct format_expand_state *es, const char *fmt) expanded = format_expand1(&next, fmt); format_free(nft); - valuelen += strlen(expanded); - value = xrealloc(value, valuelen); - - strlcat(value, expanded, valuelen); + evbuffer_add(buffer, expanded, strlen(expanded)); free(expanded); } + if ((size = EVBUFFER_LENGTH(buffer)) != 0) + value = xmemdup(EVBUFFER_DATA(buffer), size); + else + value = xstrdup(""); + evbuffer_free(buffer); return (value); } diff --git a/xmalloc.c b/xmalloc.c index d11d8dc7..14e805ed 100644 --- a/xmalloc.c +++ b/xmalloc.c @@ -105,6 +105,18 @@ xstrndup(const char *str, size_t maxlen) return cp; } +char * +xmemdup(const void *ptr, size_t len) +{ + char *cp; + + cp = xmalloc(len + 1); + if (len != 0) + memcpy(cp, ptr, len); + cp[len] = '\0'; + return cp; +} + int xasprintf(char **ret, const char *fmt, ...) { diff --git a/xmalloc.h b/xmalloc.h index 26009dd8..a87f053b 100644 --- a/xmalloc.h +++ b/xmalloc.h @@ -30,6 +30,7 @@ void *xreallocarray(void *, size_t, size_t); void *xrecallocarray(void *, size_t, size_t, size_t); char *xstrdup(const char *); char *xstrndup(const char *, size_t); +char *xmemdup(const void *, size_t); int xasprintf(char **, const char *, ...) __attribute__((__format__ (printf, 2, 3))) __attribute__((__nonnull__ (2)));