From: Bruno Haible Date: Mon, 19 Aug 2019 00:16:43 +0000 (+0200) Subject: gettext, ngettext: Fix the expansion of '\\' and octal escape sequences. X-Git-Tag: v0.20.2~48 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a8047e78a736022a8b0cc9ce316cbb3bbe247868;p=thirdparty%2Fgettext.git gettext, ngettext: Fix the expansion of '\\' and octal escape sequences. * gettext-runtime/src/gettext.c (expand_escape): Don't swallow the expansion of '\\' and octal escape sequences. * gettext-runtime/src/ngettext.c (expand_escape): Likewise. * gettext-tools/tests/tstgettext.c (expand_escape): Likewise. * NEWS: Mention the change. --- diff --git a/NEWS b/NEWS index 8913a61a3..a80d9c8ee 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,10 @@ Version 0.20.2 - April 2020 * Programming languages support: + - Shell: + The programs 'gettext', 'ngettext', when invoked with option -e, now + expand '\\' and octal escape sequences, instead of swallowing them. + (Bug present since the beginning.) - Desktop Entry: The value of the 'Icon' property is no longer extracted into the POT file by xgettext. The documentation explains how to localize icons. diff --git a/gettext-runtime/src/gettext.c b/gettext-runtime/src/gettext.c index e2fe24a2b..ac50ad4c7 100644 --- a/gettext-runtime/src/gettext.c +++ b/gettext-runtime/src/gettext.c @@ -316,6 +316,8 @@ expand_escape (const char *str) char *retval, *rp; const char *cp = str; + /* Find the location of the first escape sequence. + If the string contains no escape sequences, return it right away. */ for (;;) { while (cp[0] != '\0' && cp[0] != '\\') @@ -373,7 +375,7 @@ expand_escape (const char *str) ++cp; break; case '\\': - *rp = '\\'; + *rp++ = '\\'; ++cp; break; case '0': case '1': case '2': case '3': @@ -392,21 +394,22 @@ expand_escape (const char *str) ch += *cp++ - '0'; } } - *rp = ch; + *rp++ = ch; } break; default: - *rp = '\\'; + *rp++ = '\\'; break; } + /* Find the next escape sequence. */ while (cp[0] != '\0' && cp[0] != '\\') *rp++ = *cp++; } while (cp[0] != '\0'); - /* Terminate string. */ + /* Terminate the resulting string. */ *rp = '\0'; - return (const char *) retval; + return retval; } diff --git a/gettext-runtime/src/ngettext.c b/gettext-runtime/src/ngettext.c index 1e853d091..685bf7fbb 100644 --- a/gettext-runtime/src/ngettext.c +++ b/gettext-runtime/src/ngettext.c @@ -279,6 +279,8 @@ expand_escape (const char *str) char *retval, *rp; const char *cp = str; + /* Find the location of the first escape sequence. + If the string contains no escape sequences, return it right away. */ for (;;) { while (cp[0] != '\0' && cp[0] != '\\') @@ -332,7 +334,7 @@ expand_escape (const char *str) ++cp; break; case '\\': - *rp = '\\'; + *rp++ = '\\'; ++cp; break; case '0': case '1': case '2': case '3': @@ -351,21 +353,22 @@ expand_escape (const char *str) ch += *cp++ - '0'; } } - *rp = ch; + *rp++ = ch; } break; default: - *rp = '\\'; + *rp++ = '\\'; break; } + /* Find the next escape sequence. */ while (cp[0] != '\0' && cp[0] != '\\') *rp++ = *cp++; } while (cp[0] != '\0'); - /* Terminate string. */ + /* Terminate the resulting string. */ *rp = '\0'; - return (const char *) retval; + return retval; } diff --git a/gettext-tools/tests/tstgettext.c b/gettext-tools/tests/tstgettext.c index 480dda422..48fb92a5d 100644 --- a/gettext-tools/tests/tstgettext.c +++ b/gettext-tools/tests/tstgettext.c @@ -317,6 +317,8 @@ expand_escape (const char *str) char *retval, *rp; const char *cp = str; + /* Find the location of the first escape sequence. + If the string contains no escape sequences, return it right away. */ for (;;) { while (cp[0] != '\0' && cp[0] != '\\') @@ -374,7 +376,7 @@ expand_escape (const char *str) ++cp; break; case '\\': - *rp = '\\'; + *rp++ = '\\'; ++cp; break; case '0': case '1': case '2': case '3': @@ -393,21 +395,22 @@ expand_escape (const char *str) ch += *cp++ - '0'; } } - *rp = ch; + *rp++ = ch; } break; default: - *rp = '\\'; + *rp++ = '\\'; break; } + /* Find the next escape sequence. */ while (cp[0] != '\0' && cp[0] != '\\') *rp++ = *cp++; } while (cp[0] != '\0'); - /* Terminate string. */ + /* Terminate the resulting string. */ *rp = '\0'; - return (const char *) retval; + return retval; }