[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Bug#374483: gettext does not detect "gettext" and "eval_gettext" str
From: |
Bruno Haible |
Subject: |
Re: Bug#374483: gettext does not detect "gettext" and "eval_gettext" strings in Shell scripts (fwd) |
Date: |
Thu, 22 Jun 2006 13:35:56 +0200 |
User-agent: |
KMail/1.9.1 |
Santiago Vila wrote:
> Received this from the Debian BTS:
Please try this patch, to see if it fixes Michelle's problem.
It is relative to gettext-0.14.6.
Bruno
*** gettext-0.14.6/gettext-tools/src/x-sh.c.bak 2005-05-20 23:03:45.000000000
+0200
--- gettext-0.14.6/gettext-tools/src/x-sh.c 2006-06-22 02:37:44.000000000
+0200
***************
*** 502,507 ****
--- 502,510 ----
#define OPENING_BACKQUOTE (2 * (UCHAR_MAX + 1) + '`')
#define CLOSING_BACKQUOTE (3 * (UCHAR_MAX + 1) + '`')
+ /* 2 characters of pushback are supported.
+ 2 characters of pushback occur only when the first is an 'x'; in all
+ other cases only one character of pushback is needed. */
static int phase2_pushback[2];
static int phase2_pushback_length;
***************
*** 823,832 ****
if (c == '$')
{
! int c2 = phase2_getc ();
if (c2 == '(')
{
! int c3 = phase2_getc ();
if (c3 == '(')
{
/* Arithmetic expression. Skip until the matching closing
--- 826,864 ----
if (c == '$')
{
! int c2;
!
! /* An unquoted dollar indicates we are not inside '...'. */
! if (open_singlequote)
! abort ();
! /* After reading a dollar, we know that there is no pushed back
! character from an earlier lookahead. */
! if (phase2_pushback_length > 0)
! abort ();
! /* Therefore we can use phase1 without interfering with phase2.
! We need to recognize $( outside and inside double-quotes.
! It would be incorrect to do
! c2 = phase2_getc ();
! if (c2 == '(' || c2 == QUOTED ('('))
! because that would also trigger for $\(. */
! c2 = phase1_getc ();
if (c2 == '(')
{
! bool saved_open_doublequote;
! int c3;
!
! phase1_ungetc (c2);
!
! /* The entire inner command or arithmetic expression is read
! ignoring possible surrounding double-quotes. */
! saved_open_doublequote = open_doublequote;
! open_doublequote = false;
!
! c2 = phase2_getc ();
! if (c2 != '(')
! abort ();
!
! c3 = phase2_getc ();
if (c3 == '(')
{
/* Arithmetic expression. Skip until the matching closing
***************
*** 850,1026 ****
phase2_ungetc (c3);
read_command_list (')', context);
}
}
! else if (c2 == '\'' && !open_singlequote)
{
! /* Bash builtin for string with ANSI-C escape sequences. */
! saw_opening_singlequote ();
! for (;;)
{
! c = phase2_getc ();
! if (c == EOF)
! break;
! if (c == '\'')
! {
! saw_closing_singlequote ();
! break;
! }
! if (c == '\\')
{
c = phase2_getc ();
! switch (c)
{
! default:
! phase2_ungetc (c);
! c = '\\';
! break;
!
! case '\\':
! break;
! case '\'':
! /* Don't call saw_closing_singlequote () here. */
! break;
!
! case 'a':
! c = '\a';
break;
! case 'b':
! c = '\b';
! break;
! case 'e':
! c = 0x1b; /* ESC */
! break;
! case 'f':
! c = '\f';
! break;
! case 'n':
! c = '\n';
! break;
! case 'r':
! c = '\r';
! break;
! case 't':
! c = '\t';
! break;
! case 'v':
! c = '\v';
! break;
!
! case 'x':
c = phase2_getc ();
! if ((c >= '0' && c <= '9')
! || (c >= 'A' && c <= 'F')
! || (c >= 'a' && c <= 'f'))
{
! int n;
! if (c >= '0' && c <= '9')
! n = c - '0';
! else if (c >= 'A' && c <= 'F')
! n = 10 + c - 'A';
! else if (c >= 'a' && c <= 'f')
! n = 10 + c - 'a';
! else
! abort ();
c = phase2_getc ();
if ((c >= '0' && c <= '9')
|| (c >= 'A' && c <= 'F')
|| (c >= 'a' && c <= 'f'))
{
if (c >= '0' && c <= '9')
! n = n * 16 + c - '0';
else if (c >= 'A' && c <= 'F')
! n = n * 16 + 10 + c - 'A';
else if (c >= 'a' && c <= 'f')
! n = n * 16 + 10 + c - 'a';
else
abort ();
- }
- else
- phase2_ungetc (c);
! c = n;
! }
! else
! {
! phase2_ungetc (c);
! phase2_ungetc ('x');
! c = '\\';
! }
! break;
! case '0': case '1': case '2': case '3':
! case '4': case '5': case '6': case '7':
! {
! int n = c - '0';
! c = phase2_getc ();
! if (c >= '0' && c <= '7')
{
! n = n * 8 + c - '0';
c = phase2_getc ();
if (c >= '0' && c <= '7')
! n = n * 8 + c - '0';
else
phase2_ungetc (c);
- }
- else
- phase2_ungetc (c);
! c = n;
! }
! break;
}
}
! if (wp->type == t_string)
! {
! grow_token (wp->token);
! wp->token->chars[wp->token->charcount++] =
! (unsigned char) c;
! }
}
! /* The result is a literal string. Don't change wp->type. */
! continue;
! }
! else if (c2 == '"' && !open_doublequote)
! {
! /* Bash builtin for internationalized string. */
! lex_pos_ty pos;
! struct token string;
!
! saw_opening_doublequote ();
! pos.file_name = logical_file_name;
! pos.line_number = line_number;
! init_token (&string);
! for (;;)
! {
! c = phase2_getc ();
! if (c == EOF)
! break;
! if (c == '"')
{
! saw_closing_doublequote ();
! break;
}
! grow_token (&string);
! string.chars[string.charcount++] = (unsigned char) c;
! }
! remember_a_message (mlp, string_of_token (&string),
! context, &pos);
! free_token (&string);
!
! error_with_progname = false;
! error (0, 0, _("%s:%lu: warning: the syntax $\"...\" is
deprecated due to security reasons; use eval_gettext instead"),
! pos.file_name, (unsigned long) pos.line_number);
! error_with_progname = true;
! /* The result at runtime is not constant. Therefore we
! change wp->type. */
}
- else
- phase2_ungetc (c2);
wp->type = t_other;
continue;
}
--- 882,1067 ----
phase2_ungetc (c3);
read_command_list (')', context);
}
+
+ open_doublequote = saved_open_doublequote;
}
! else
{
! phase1_ungetc (c2);
! c2 = phase2_getc ();
!
! if (c2 == '\'' && !open_singlequote)
{
! /* Bash builtin for string with ANSI-C escape sequences. */
! saw_opening_singlequote ();
! for (;;)
{
c = phase2_getc ();
! if (c == EOF)
! break;
! if (c == '\'')
{
! saw_closing_singlequote ();
break;
! }
! if (c == '\\')
! {
c = phase2_getc ();
! switch (c)
{
! default:
! phase2_ungetc (c);
! c = '\\';
! break;
! case '\\':
! break;
! case '\'':
! /* Don't call saw_closing_singlequote ()
! here. */
! break;
!
! case 'a':
! c = '\a';
! break;
! case 'b':
! c = '\b';
! break;
! case 'e':
! c = 0x1b; /* ESC */
! break;
! case 'f':
! c = '\f';
! break;
! case 'n':
! c = '\n';
! break;
! case 'r':
! c = '\r';
! break;
! case 't':
! c = '\t';
! break;
! case 'v':
! c = '\v';
! break;
+ case 'x':
c = phase2_getc ();
if ((c >= '0' && c <= '9')
|| (c >= 'A' && c <= 'F')
|| (c >= 'a' && c <= 'f'))
{
+ int n;
+
if (c >= '0' && c <= '9')
! n = c - '0';
else if (c >= 'A' && c <= 'F')
! n = 10 + c - 'A';
else if (c >= 'a' && c <= 'f')
! n = 10 + c - 'a';
else
abort ();
! c = phase2_getc ();
! if ((c >= '0' && c <= '9')
! || (c >= 'A' && c <= 'F')
! || (c >= 'a' && c <= 'f'))
! {
! if (c >= '0' && c <= '9')
! n = n * 16 + c - '0';
! else if (c >= 'A' && c <= 'F')
! n = n * 16 + 10 + c - 'A';
! else if (c >= 'a' && c <= 'f')
! n = n * 16 + 10 + c - 'a';
! else
! abort ();
! }
! else
! phase2_ungetc (c);
! c = n;
! }
! else
! {
! phase2_ungetc (c);
! phase2_ungetc ('x');
! c = '\\';
! }
! break;
! case '0': case '1': case '2': case '3':
! case '4': case '5': case '6': case '7':
{
! int n = c - '0';
c = phase2_getc ();
if (c >= '0' && c <= '7')
! {
! n = n * 8 + c - '0';
!
! c = phase2_getc ();
! if (c >= '0' && c <= '7')
! n = n * 8 + c - '0';
! else
! phase2_ungetc (c);
! }
else
phase2_ungetc (c);
! c = n;
! }
! break;
! }
! }
! if (wp->type == t_string)
! {
! grow_token (wp->token);
! wp->token->chars[wp->token->charcount++] =
! (unsigned char) c;
}
}
! /* The result is a literal string. Don't change wp->type. */
! continue;
}
! else if (c2 == '"' && !open_doublequote)
! {
! /* Bash builtin for internationalized string. */
! lex_pos_ty pos;
! struct token string;
!
! saw_opening_doublequote ();
! pos.file_name = logical_file_name;
! pos.line_number = line_number;
! init_token (&string);
! for (;;)
{
! c = phase2_getc ();
! if (c == EOF)
! break;
! if (c == '"')
! {
! saw_closing_doublequote ();
! break;
! }
! grow_token (&string);
! string.chars[string.charcount++] = (unsigned char) c;
}
! remember_a_message (mlp, string_of_token (&string),
! context, &pos);
! free_token (&string);
!
! error_with_progname = false;
! error (0, 0, _("%s:%lu: warning: the syntax $\"...\" is
deprecated due to security reasons; use eval_gettext instead"),
! pos.file_name, (unsigned long) pos.line_number);
! error_with_progname = true;
! /* The result at runtime is not constant. Therefore we
! change wp->type. */
! }
! else
! phase2_ungetc (c2);
}
wp->type = t_other;
continue;
}