about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog2
-rw-r--r--Src/builtin.c11
2 files changed, 9 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index afd7a514c..cd6e6e173 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,7 @@
 2016-01-02  Barton E. Schaefer  <schaefer@zsh.org>
 
+	* 37497: Src/builtin.c: handle NUL bytes in "printf -v".
+
 	* 37493: Doc/Zsh/builtins.yo, Src/builtin.c, Src/hashtable.h,
 	Test/B02typeset.ztst: readonly + POSIX_BUILTINS == typeset -gr
 
diff --git a/Src/builtin.c b/Src/builtin.c
index 557487c87..04d8f11d9 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -4872,17 +4872,20 @@ bin_print(char *name, char **args, Options ops, int func)
 
     if (OPT_ISSET(ops,'z') || OPT_ISSET(ops,'s') || OPT_ISSET(ops,'v')) {
 #ifdef HAVE_OPEN_MEMSTREAM
-	putc(0, fout);
+	putc(0, fout);		/* not needed?  open_memstream() maintains? */
 	fclose(fout);
 	fout = NULL;
+	rcount = mcount;	/* now includes the trailing NUL we added */
 #else
 	rewind(fout);
 	buf = (char *)zalloc(count + 1);
-	fread(buf, count, 1, fout);
-	buf[count] = '\0';
+	rcount = fread(buf, count, 1, fout);
+	if (rcount < count)
+	    zwarnnam(name, "i/o error: %e", errno);
+	buf[rcount] = '\0';
 #endif
 	queue_signals();
-	stringval = metafy(buf, -1, META_REALLOC);
+	stringval = metafy(buf, rcount - 1, META_REALLOC);
 	if (OPT_ISSET(ops,'z')) {
 	    zpushnode(bufstack, stringval);
 	} else if (OPT_ISSET(ops,'v')) {