summaryrefslogtreecommitdiff
path: root/gnulib-tests/test-quotearg-simple.c
diff options
context:
space:
mode:
Diffstat (limited to 'gnulib-tests/test-quotearg-simple.c')
-rw-r--r--gnulib-tests/test-quotearg-simple.c37
1 files changed, 36 insertions, 1 deletions
diff --git a/gnulib-tests/test-quotearg-simple.c b/gnulib-tests/test-quotearg-simple.c
index e7aa8fb6..08aadc1f 100644
--- a/gnulib-tests/test-quotearg-simple.c
+++ b/gnulib-tests/test-quotearg-simple.c
@@ -1,5 +1,5 @@
/* Test of quotearg family of functions.
- Copyright (C) 2008-2013 Free Software Foundation, Inc.
+ Copyright (C) 2008-2014 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -29,6 +29,7 @@
#include "localcharset.h"
#include "progname.h"
#include "macros.h"
+#include "zerosize-ptr.h"
#include "test-quotearg.h"
@@ -297,6 +298,40 @@ main (int argc _GL_UNUSED, char *argv[])
ascii_only);
}
+ {
+ /* Trigger the bug whereby quotearg_buffer would read beyond the NUL
+ that defines the end of the string being quoted. Use an input
+ string whose NUL is the last byte before an unreadable page. */
+ char *z = zerosize_ptr ();
+
+ if (z)
+ {
+ size_t q_len = 1024;
+ char *q = malloc (q_len + 1);
+ char buf[10];
+ memset (q, 'Q', q_len);
+ q[q_len] = 0;
+
+ /* Z points to the boundary between a readable/writable page
+ and one that is neither readable nor writable. Position
+ our string so its NUL is at the end of the writable one. */
+ char const *str = "____";
+ size_t s_len = strlen (str);
+ z -= s_len + 1;
+ memcpy (z, str, s_len + 1);
+
+ set_custom_quoting (NULL, q, q);
+ /* Whether this actually triggers a SEGV depends on the
+ implementation of memcmp: whether it compares only byte-at-
+ a-time, and from left to right (no SEGV) or some other way. */
+ size_t n = quotearg_buffer (buf, sizeof buf, z, SIZE_MAX, NULL);
+ ASSERT (n == s_len + 2 * q_len);
+ ASSERT (memcmp (buf, q, sizeof buf) == 0);
+ free (q);
+ }
+ }
+
quotearg_free ();
+
return 0;
}