diff options
author | Bruno Haible <bruno@clisp.org> | 2023-03-09 20:28:19 +0100 |
---|---|---|
committer | Bruno Haible <bruno@clisp.org> | 2023-03-09 20:28:19 +0100 |
commit | 389824006bdcbbe1eab91ff2c953ea958296d0cd (patch) | |
tree | f206d7ddc8e656bde438b36dedaba4da3e500044 | |
parent | 30122f64584480d73b84c0e62459a2ac16136796 (diff) | |
download | gettext-389824006bdcbbe1eab91ff2c953ea958296d0cd.tar.gz |
xgettext: In language Perl, avoid stack overflow.
* gettext-tools/src/x-perl.c (MAX_NESTING_DEPTH): New macro.
(nesting_depth): New variable.
(interpolate_keywords): Increase and check nesting_depth. Revert it before
returning.
(x_perl_lex): Likewise.
(extract_balanced): Increase and check nesting_depth before calling
extract_balanced recursively.
(extract_perl): Initialize nesting_depth.
* gettext-tools/tests/xgettext-perl-stackovfl-1: New file.
* gettext-tools/tests/xgettext-perl-stackovfl-2: New file.
* gettext-tools/tests/xgettext-perl-stackovfl-3: New file.
* gettext-tools/tests/xgettext-perl-stackovfl-4: New file.
* gettext-tools/tests/Makefile.am (TESTS): Add them.
-rw-r--r-- | gettext-tools/src/x-perl.c | 50 | ||||
-rw-r--r-- | gettext-tools/tests/Makefile.am | 2 | ||||
-rwxr-xr-x | gettext-tools/tests/xgettext-perl-stackovfl-1 | 63 | ||||
-rwxr-xr-x | gettext-tools/tests/xgettext-perl-stackovfl-2 | 56 | ||||
-rwxr-xr-x | gettext-tools/tests/xgettext-perl-stackovfl-3 | 63 | ||||
-rwxr-xr-x | gettext-tools/tests/xgettext-perl-stackovfl-4 | 56 |
6 files changed, 288 insertions, 2 deletions
diff --git a/gettext-tools/src/x-perl.c b/gettext-tools/src/x-perl.c index 7d58fc3b7..428d9e486 100644 --- a/gettext-tools/src/x-perl.c +++ b/gettext-tools/src/x-perl.c @@ -1,5 +1,5 @@ /* xgettext Perl backend. - Copyright (C) 2002-2010, 2013, 2016, 2018-2020 Free Software Foundation, Inc. + Copyright (C) 2002-2010, 2013, 2016, 2018-2023 Free Software Foundation, Inc. This file was written by Guido Flohr <guido@imperia.net>, 2002-2010. @@ -792,6 +792,13 @@ extract_quotelike_pass1_utf8 (int delim) static flag_context_list_table_ty *flag_context_list_table; +/* Maximum supported nesting depth. */ +#define MAX_NESTING_DEPTH 1000 + +/* Current nesting depth. */ +static int nesting_depth; + + /* Forward declaration of local functions. */ static void interpolate_keywords (message_list_ty *mlp, const char *string, int lineno); @@ -1710,6 +1717,13 @@ interpolate_keywords (message_list_ty *mlp, const char *string, int lineno) lex_pos_ty pos; + if (++nesting_depth > MAX_NESTING_DEPTH) + { + error_with_progname = false; + error (EXIT_FAILURE, 0, _("%s:%d: error: too deeply nested expressions"), + logical_file_name, line_number); + } + /* States are: * * initial: initial @@ -1767,7 +1781,10 @@ interpolate_keywords (message_list_ty *mlp, const char *string, int lineno) case '\\': c = (unsigned char) *string++; if (c == '\0') - return; + { + nesting_depth--; + return; + } break; case '$': buffer[bufpos++] = '$'; @@ -2029,6 +2046,9 @@ interpolate_keywords (message_list_ty *mlp, const char *string, int lineno) break; } } + + nesting_depth--; + return; } /* There is an ambiguity about '/' and '?': They can start an operator @@ -2725,6 +2745,13 @@ token_stack_free (token_stack_ty *stack) static token_ty * x_perl_lex (message_list_ty *mlp) { + if (++nesting_depth > MAX_NESTING_DEPTH) + { + error_with_progname = false; + error (EXIT_FAILURE, 0, _("%s:%d: error: too deeply nested expressions"), + logical_file_name, line_number); + } + #if DEBUG_PERL int dummy = token_stack_dump (&token_stack); #endif @@ -2885,6 +2912,7 @@ x_perl_lex (message_list_ty *mlp) } } + nesting_depth--; return tp; } @@ -3059,6 +3087,13 @@ extract_balanced (message_list_ty *mlp, ++nesting_level; #endif + if (nesting_depth > MAX_NESTING_DEPTH) + { + error_with_progname = false; + error (EXIT_FAILURE, 0, _("%s:%d: error: too deeply nested expressions"), + logical_file_name, line_number); + } + for (;;) { /* The current token. */ @@ -3131,6 +3166,7 @@ extract_balanced (message_list_ty *mlp, best results. */ next_comma_delim = true; + ++nesting_depth; if (extract_balanced (mlp, delim, false, next_comma_delim, inner_context, next_context_iter, 1, next_argparser)) @@ -3138,6 +3174,7 @@ extract_balanced (message_list_ty *mlp, arglist_parser_done (argparser, arg); return true; } + nesting_depth--; next_is_argument = false; next_argparser = NULL; @@ -3215,6 +3252,7 @@ extract_balanced (message_list_ty *mlp, if (next_is_argument) { /* Parse the argument list of a function call. */ + ++nesting_depth; if (extract_balanced (mlp, token_type_rparen, true, false, inner_context, next_context_iter, 1, next_argparser)) @@ -3222,12 +3260,14 @@ extract_balanced (message_list_ty *mlp, arglist_parser_done (argparser, arg); return true; } + nesting_depth--; next_is_argument = false; next_argparser = NULL; } else { /* Parse a parenthesized expression or comma expression. */ + ++nesting_depth; if (extract_balanced (mlp, token_type_rparen, true, false, inner_context, next_context_iter, arg, arglist_parser_clone (argparser))) @@ -3238,6 +3278,7 @@ extract_balanced (message_list_ty *mlp, free_token (tp); return true; } + nesting_depth--; next_is_argument = false; if (next_argparser != NULL) free (next_argparser); @@ -3381,6 +3422,7 @@ extract_balanced (message_list_ty *mlp, fprintf (stderr, "%s:%d: type lbrace (%d)\n", logical_file_name, tp->line_number, nesting_level); #endif + ++nesting_depth; if (extract_balanced (mlp, token_type_rbrace, true, false, null_context, null_context_list_iterator, 1, arglist_parser_alloc (mlp, NULL))) @@ -3391,6 +3433,7 @@ extract_balanced (message_list_ty *mlp, free_token (tp); return true; } + nesting_depth--; next_is_argument = false; if (next_argparser != NULL) free (next_argparser); @@ -3415,6 +3458,7 @@ extract_balanced (message_list_ty *mlp, fprintf (stderr, "%s:%d: type lbracket (%d)\n", logical_file_name, tp->line_number, nesting_level); #endif + ++nesting_depth; if (extract_balanced (mlp, token_type_rbracket, true, false, null_context, null_context_list_iterator, 1, arglist_parser_alloc (mlp, NULL))) @@ -3425,6 +3469,7 @@ extract_balanced (message_list_ty *mlp, free_token (tp); return true; } + nesting_depth--; next_is_argument = false; if (next_argparser != NULL) free (next_argparser); @@ -3562,6 +3607,7 @@ extract_perl (FILE *f, const char *real_filename, const char *logical_filename, last_non_comment_line = -1; flag_context_list_table = flag_table; + nesting_depth = 0; /* Safe assumption. */ last_token_type = token_type_semicolon; diff --git a/gettext-tools/tests/Makefile.am b/gettext-tools/tests/Makefile.am index 3e30dc3e7..9171a2ae6 100644 --- a/gettext-tools/tests/Makefile.am +++ b/gettext-tools/tests/Makefile.am @@ -127,6 +127,8 @@ TESTS = gettext-1 gettext-2 \ xgettext-objc-1 xgettext-objc-2 \ xgettext-perl-1 xgettext-perl-2 xgettext-perl-3 xgettext-perl-4 \ xgettext-perl-5 xgettext-perl-6 xgettext-perl-7 xgettext-perl-8 \ + xgettext-perl-stackovfl-1 xgettext-perl-stackovfl-2 \ + xgettext-perl-stackovfl-3 xgettext-perl-stackovfl-4 \ xgettext-php-1 xgettext-php-2 xgettext-php-3 xgettext-php-4 \ xgettext-po-1 xgettext-po-2 \ xgettext-properties-1 xgettext-properties-2 xgettext-properties-3 \ diff --git a/gettext-tools/tests/xgettext-perl-stackovfl-1 b/gettext-tools/tests/xgettext-perl-stackovfl-1 new file mode 100755 index 000000000..54b909f16 --- /dev/null +++ b/gettext-tools/tests/xgettext-perl-stackovfl-1 @@ -0,0 +1,63 @@ +#! /bin/sh +. "${srcdir=.}/init.sh"; path_prepend_ . ../src + +# Test Perl support: stack overflow prevented by nesting depth check. + +cat <<EOF > xg-pl-so-1.pl +[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ +[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ +[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ +[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ +[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ +[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ +[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ +[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ +[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ +[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ +[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ +[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ +[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ +[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ +[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ +[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ +[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ +[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ +[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ +[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ +gettext "Hello!" +]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] +]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] +]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] +]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] +]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] +]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] +]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] +]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] +]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] +]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] +]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] +]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] +]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] +]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] +]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] +]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] +]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] +]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] +]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] +]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] +EOF + +: ${XGETTEXT=xgettext} +${XGETTEXT} --omit-header --no-location -d xg-pl-so-1.tmp xg-pl-so-1.pl || Exit 1 +LC_ALL=C tr -d '\r' < xg-pl-so-1.tmp.po > xg-pl-so-1.po || Exit 1 + +cat <<EOF > xg-pl-so-1.ok +msgid "Hello!" +msgstr "" +EOF + +: ${DIFF=diff} +${DIFF} xg-pl-so-1.ok xg-pl-so-1.po +result=$? + +exit $result diff --git a/gettext-tools/tests/xgettext-perl-stackovfl-2 b/gettext-tools/tests/xgettext-perl-stackovfl-2 new file mode 100755 index 000000000..77dd8d022 --- /dev/null +++ b/gettext-tools/tests/xgettext-perl-stackovfl-2 @@ -0,0 +1,56 @@ +#! /bin/sh +. "${srcdir=.}/init.sh"; path_prepend_ . ../src + +# Test Perl support: stack overflow prevented by nesting depth check. + +cat <<EOF > xg-pl-so-2.pl +[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ +[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ +[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ +[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ +[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ +[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ +[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ +[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ +[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ +[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ +[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ +[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ +[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ +[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ +[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ +[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ +[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ +[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ +[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ +[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ +gettext "Hello!" +]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] +]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] +]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] +]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] +]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] +]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] +]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] +]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] +]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] +]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] +]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] +]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] +]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] +]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] +]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] +]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] +]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] +]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] +]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] +]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] +EOF + +: ${XGETTEXT=xgettext} +${XGETTEXT} --omit-header --no-location -d xg-pl-so-2.tmp xg-pl-so-2.pl 2>xg-pl-so-2.err +result=$? +cat xg-pl-so-2.err +test $result = 1 || Exit 1 + +exit 0 diff --git a/gettext-tools/tests/xgettext-perl-stackovfl-3 b/gettext-tools/tests/xgettext-perl-stackovfl-3 new file mode 100755 index 000000000..6be7ce9f6 --- /dev/null +++ b/gettext-tools/tests/xgettext-perl-stackovfl-3 @@ -0,0 +1,63 @@ +#! /bin/sh +. "${srcdir=.}/init.sh"; path_prepend_ . ../src + +# Test Perl support: stack overflow prevented by nesting depth check. + +cat <<EOF > xg-pl-so-3.pl +{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ +{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ +{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ +{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ +{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ +{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ +{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ +{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ +{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ +{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ +{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ +{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ +{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ +{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ +{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ +{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ +{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ +{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ +{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ +{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ +gettext "Hello!" +}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} +}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} +}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} +}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} +}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} +}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} +}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} +}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} +}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} +}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} +}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} +}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} +}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} +}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} +}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} +}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} +}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} +}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} +}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} +}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} +EOF + +: ${XGETTEXT=xgettext} +${XGETTEXT} --omit-header --no-location -d xg-pl-so-3.tmp xg-pl-so-3.pl || Exit 1 +LC_ALL=C tr -d '\r' < xg-pl-so-3.tmp.po > xg-pl-so-3.po || Exit 1 + +cat <<EOF > xg-pl-so-3.ok +msgid "Hello!" +msgstr "" +EOF + +: ${DIFF=diff} +${DIFF} xg-pl-so-3.ok xg-pl-so-3.po +result=$? + +exit $result diff --git a/gettext-tools/tests/xgettext-perl-stackovfl-4 b/gettext-tools/tests/xgettext-perl-stackovfl-4 new file mode 100755 index 000000000..ff68ed2a1 --- /dev/null +++ b/gettext-tools/tests/xgettext-perl-stackovfl-4 @@ -0,0 +1,56 @@ +#! /bin/sh +. "${srcdir=.}/init.sh"; path_prepend_ . ../src + +# Test Perl support: stack overflow prevented by nesting depth check. + +cat <<EOF > xg-pl-so-4.pl +{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ +{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ +{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ +{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ +{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ +{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ +{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ +{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ +{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ +{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ +{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ +{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ +{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ +{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ +{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ +{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ +{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ +{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ +{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ +{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ +gettext "Hello!" +}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} +}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} +}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} +}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} +}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} +}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} +}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} +}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} +}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} +}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} +}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} +}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} +}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} +}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} +}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} +}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} +}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} +}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} +}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} +}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} +EOF + +: ${XGETTEXT=xgettext} +${XGETTEXT} --omit-header --no-location -d xg-pl-so-4.tmp xg-pl-so-4.pl 2>xg-pl-so-4.err +result=$? +cat xg-pl-so-4.err +test $result = 1 || Exit 1 + +exit 0 |