From 030437e33edd640f3de87d31006bd951a25d5efa Mon Sep 17 00:00:00 2001
From: nicm <nicm>
Date: Fri, 11 Apr 2014 19:35:54 +0000
Subject: [PATCH 2/6] Don't blindly increase offsets by the return value of
 snprintf, if there wasn't enough space this will go off the end. Instead
 clamp to the available space. Fixes crash reported by Julien Rebetez.

---
 arguments.c   | 12 +++++++++---
 cmd-list.c    | 10 +++++++---
 window-copy.c | 14 ++++++++------
 3 files changed, 24 insertions(+), 12 deletions(-)

diff --git a/arguments.c b/arguments.c
index d4e5e53..fd656b1 100644
--- a/arguments.c
+++ b/arguments.c
@@ -125,7 +125,7 @@ args_free(struct args *args)
 size_t
 args_print(struct args *args, char *buf, size_t len)
 {
-	size_t		 	 off;
+	size_t		 	 off, used;
 	int			 i;
 	const char		*quotes;
 	struct args_entry	*entry;
@@ -165,9 +165,12 @@ args_print(struct args *args, char *buf, size_t len)
 			quotes = "\"";
 		else
 			quotes = "";
-		off += xsnprintf(buf + off, len - off, "%s-%c %s%s%s",
+		used = xsnprintf(buf + off, len - off, "%s-%c %s%s%s",
 		    off != 0 ? " " : "", entry->flag, quotes, entry->value,
 		    quotes);
+		if (used > len - off)
+			used = len - off;
+		off += used;
 	}
 
 	/* And finally the argument vector. */
@@ -181,8 +184,11 @@ args_print(struct args *args, char *buf, size_t len)
 			quotes = "\"";
 		else
 			quotes = "";
-		off += xsnprintf(buf + off, len - off, "%s%s%s%s",
+		used = xsnprintf(buf + off, len - off, "%s%s%s%s",
 		    off != 0 ? " " : "", quotes, args->argv[i], quotes);
+		if (used > len - off)
+			used = len - off;
+		off += used;
 	}
 
 	return (off);
diff --git a/cmd-list.c b/cmd-list.c
index 08e2067..7ef8d1c 100644
--- a/cmd-list.c
+++ b/cmd-list.c
@@ -103,7 +103,7 @@ size_t
 cmd_list_print(struct cmd_list *cmdlist, char *buf, size_t len)
 {
 	struct cmd	*cmd;
-	size_t		 off;
+	size_t		 off, used;
 
 	off = 0;
 	TAILQ_FOREACH(cmd, &cmdlist->list, qentry) {
@@ -112,8 +112,12 @@ cmd_list_print(struct cmd_list *cmdlist, char *buf, size_t len)
 		off += cmd_print(cmd, buf + off, len - off);
 		if (off >= len)
 			break;
-		if (TAILQ_NEXT(cmd, qentry) != NULL)
-			off += xsnprintf(buf + off, len - off, " ; ");
+		if (TAILQ_NEXT(cmd, qentry) != NULL) {
+			used = xsnprintf(buf + off, len - off, " ; ");
+			if (used > len - off)
+				used = len - off;
+			off += used;
+		}
 	}
 	return (off);
 }
diff --git a/window-copy.c b/window-copy.c
index 527c95c..55f7f3a 100644
--- a/window-copy.c
+++ b/window-copy.c
@@ -1185,8 +1185,8 @@ window_copy_write_line(
 		screen_write_puts(ctx, &gc, "%s", hdr);
 	} else if (py == last && data->inputtype != WINDOW_COPY_OFF) {
 		limit = sizeof hdr;
-		if (limit > screen_size_x(s))
-			limit = screen_size_x(s);
+		if (limit > screen_size_x(s) + 1)
+			limit = screen_size_x(s) + 1;
 		if (data->inputtype == WINDOW_COPY_NUMERICPREFIX) {
 			xoff = size = xsnprintf(hdr, limit,
 			    "Repeat: %u", data->numprefix);
@@ -1199,10 +1199,12 @@ window_copy_write_line(
 	} else
 		size = 0;
 
-	screen_write_cursormove(ctx, xoff, py);
-	screen_write_copy(ctx, data->backing, xoff,
-	    (screen_hsize(data->backing) - data->oy) + py,
-	    screen_size_x(s) - size, 1);
+	if (size < screen_size_x(s)) {
+		screen_write_cursormove(ctx, xoff, py);
+		screen_write_copy(ctx, data->backing, xoff,
+		    (screen_hsize(data->backing) - data->oy) + py,
+		    screen_size_x(s) - size, 1);
+	}
 
 	if (py == data->cy && data->cx == screen_size_x(s)) {
 		memcpy(&gc, &grid_default_cell, sizeof gc);
-- 
1.9.2

