summaryrefslogtreecommitdiff
path: root/tests/test-quotearg-simple.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test-quotearg-simple.c')
-rw-r--r--tests/test-quotearg-simple.c73
1 files changed, 58 insertions, 15 deletions
diff --git a/tests/test-quotearg-simple.c b/tests/test-quotearg-simple.c
index 4d9c87c..fe860ed 100644
--- a/tests/test-quotearg-simple.c
+++ b/tests/test-quotearg-simple.c
@@ -1,5 +1,5 @@
/* Test of quotearg family of functions.
- Copyright (C) 2008-2011 Free Software Foundation, Inc.
+ Copyright (C) 2008-2013 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
@@ -12,8 +12,7 @@
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+ along with this program; if not, see <http://www.gnu.org/licenses/>. */
/* Written by Eric Blake <ebb9@byu.net>, 2008. */
@@ -27,8 +26,10 @@
#include <stdlib.h>
#include <string.h>
+#include "localcharset.h"
#include "progname.h"
#include "macros.h"
+#include "zerosize-ptr.h"
#include "test-quotearg.h"
@@ -85,12 +86,12 @@ static struct result_groups results_g[] = {
"a\\\\b", LQ_ENC RQ_ENC, LQ RQ } },
/* locale_quoting_style */
- { { "`'", "`\\0001\\0'", 9, "`simple'", "` \\t\\n\\'\"\\033?""?/\\\\'",
- "`a:b'", "`a\\\\b'", "`" LQ_ENC RQ_ENC "'", "`" LQ RQ "'" },
- { "`'", "`\\0001\\0'", 9, "`simple'", "` \\t\\n\\'\"\\033?""?/\\\\'",
- "`a:b'", "`a\\\\b'", "`" LQ_ENC RQ_ENC "'", "`" LQ RQ "'" },
- { "`'", "`\\0001\\0'", 9, "`simple'", "` \\t\\n\\'\"\\033?""?/\\\\'",
- "`a\\:b'", "`a\\\\b'", "`" LQ_ENC RQ_ENC "'", "`" LQ RQ "'" } },
+ { { "''", "'\\0001\\0'", 9, "'simple'", "' \\t\\n\\'\"\\033?""?/\\\\'",
+ "'a:b'", "'a\\\\b'", "'" LQ_ENC RQ_ENC "'", "'" LQ RQ "'" },
+ { "''", "'\\0001\\0'", 9, "'simple'", "' \\t\\n\\'\"\\033?""?/\\\\'",
+ "'a:b'", "'a\\\\b'", "'" LQ_ENC RQ_ENC "'", "'" LQ RQ "'" },
+ { "''", "'\\0001\\0'", 9, "'simple'", "' \\t\\n\\'\"\\033?""?/\\\\'",
+ "'a\\:b'", "'a\\\\b'", "'" LQ_ENC RQ_ENC "'", "'" LQ RQ "'" } },
/* clocale_quoting_style */
{ { "\"\"", "\"\\0001\\0\"", 9, "\"simple\"",
@@ -245,12 +246,20 @@ main (int argc _GL_UNUSED, char *argv[])
for (i = literal_quoting_style; i <= clocale_quoting_style; i++)
{
set_quoting_style (NULL, (enum quoting_style) i);
- compare_strings (use_quotearg_buffer, &results_g[i].group1, ascii_only);
- compare_strings (use_quotearg, &results_g[i].group2, ascii_only);
- if (i == c_quoting_style)
- compare_strings (use_quote_double_quotes, &results_g[i].group2,
- ascii_only);
- compare_strings (use_quotearg_colon, &results_g[i].group3, ascii_only);
+ if (!(i == locale_quoting_style || i == clocale_quoting_style)
+ || (strcmp (locale_charset (), "ASCII") == 0
+ || strcmp (locale_charset (), "ANSI_X3.4-1968") == 0))
+ {
+ compare_strings (use_quotearg_buffer, &results_g[i].group1,
+ ascii_only);
+ compare_strings (use_quotearg, &results_g[i].group2,
+ ascii_only);
+ if (i == c_quoting_style)
+ compare_strings (use_quote_double_quotes, &results_g[i].group2,
+ ascii_only);
+ compare_strings (use_quotearg_colon, &results_g[i].group3,
+ ascii_only);
+ }
}
set_quoting_style (NULL, literal_quoting_style);
@@ -289,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;
}