summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruno Haible <bruno@clisp.org>2023-03-11 01:02:47 +0100
committerBruno Haible <bruno@clisp.org>2023-03-14 02:57:28 +0100
commit0c0345632aedfb254b69f72cce268728113edf2e (patch)
treec6e019f7e266bffb4ea938da868b9a3f1f2dbbb1
parent53a2b763b8dc516bd20258ea5aead80bc7ab7cf3 (diff)
downloadgettext-0c0345632aedfb254b69f72cce268728113edf2e.tar.gz
xgettext: In language C, report out-of-range hexadecimal escapes.
This avoids a later crash "Assertion `UNICODE_VALUE (c) >= 0 && UNICODE_VALUE (c) < 0x110000' failed." * gettext-tools/src/x-c.c (phase7_getc): When the value of a hexadecimal escape sequence overflows, warn and use the last value before it overflowed. * gettext-tools/tests/xgettext-c-7: New file. * gettext-tools/tests/Makefile.am (TESTS): Add it.
-rw-r--r--gettext-tools/src/x-c.c107
-rw-r--r--gettext-tools/tests/Makefile.am1
-rwxr-xr-xgettext-tools/tests/xgettext-c-724
3 files changed, 92 insertions, 40 deletions
diff --git a/gettext-tools/src/x-c.c b/gettext-tools/src/x-c.c
index b49ddd9cc..a5a1ea504 100644
--- a/gettext-tools/src/x-c.c
+++ b/gettext-tools/src/x-c.c
@@ -994,7 +994,7 @@ struct token_ty
static int
phase7_getc ()
{
- int c, n, j;
+ int c, j;
/* Use phase 3, because phase 4 elides comments. */
c = phase3_getc ();
@@ -1072,56 +1072,83 @@ phase7_getc ()
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
break;
}
- n = 0;
- for (;;)
- {
- switch (c)
- {
- default:
- phase3_ungetc (c);
- return n;
+ {
+ int n;
+ bool overflow;
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- n = n * 16 + c - '0';
- break;
+ n = 0;
+ overflow = false;
- case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
- n = n * 16 + 10 + c - 'A';
- break;
+ for (;;)
+ {
+ switch (c)
+ {
+ default:
+ phase3_ungetc (c);
+ if (overflow)
+ {
+ error_with_progname = false;
+ error (0, 0, _("%s:%d: warning: hexadecimal escape sequence out of range"),
+ logical_file_name, line_number);
+ error_with_progname = true;
+ }
+ return n;
+
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ if (n < 0x100 / 16)
+ n = n * 16 + c - '0';
+ else
+ overflow = true;
+ break;
- case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
- n = n * 16 + 10 + c - 'a';
- break;
- }
- c = phase3_getc ();
- }
- return n;
+ case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+ if (n < 0x100 / 16)
+ n = n * 16 + 10 + c - 'A';
+ else
+ overflow = true;
+ break;
+
+ case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+ if (n < 0x100 / 16)
+ n = n * 16 + 10 + c - 'a';
+ else
+ overflow = true;
+ break;
+ }
+ c = phase3_getc ();
+ }
+ }
case '0': case '1': case '2': case '3':
case '4': case '5': case '6': case '7':
- n = 0;
- for (j = 0; j < 3; ++j)
- {
- n = n * 8 + c - '0';
- c = phase3_getc ();
- switch (c)
- {
- default:
- break;
+ {
+ int n;
- case '0': case '1': case '2': case '3':
- case '4': case '5': case '6': case '7':
- continue;
- }
- break;
- }
- phase3_ungetc (c);
- return n;
+ n = 0;
+ for (j = 0; j < 3; ++j)
+ {
+ n = n * 8 + c - '0';
+ c = phase3_getc ();
+ switch (c)
+ {
+ default:
+ break;
+
+ case '0': case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7':
+ continue;
+ }
+ break;
+ }
+ phase3_ungetc (c);
+ return n;
+ }
case 'U': case 'u':
{
unsigned char buf[8];
+ int n;
n = 0;
for (j = 0; j < (c == 'u' ? 4 : 8); j++)
diff --git a/gettext-tools/tests/Makefile.am b/gettext-tools/tests/Makefile.am
index 240a88a51..dc9802da8 100644
--- a/gettext-tools/tests/Makefile.am
+++ b/gettext-tools/tests/Makefile.am
@@ -85,6 +85,7 @@ TESTS = gettext-1 gettext-2 \
xgettext-awk-1 xgettext-awk-2 \
xgettext-awk-stackovfl-1 xgettext-awk-stackovfl-2 \
xgettext-c-2 xgettext-c-3 xgettext-c-4 xgettext-c-5 xgettext-c-6 \
+ xgettext-c-7 \
xgettext-c-comment-1 xgettext-c-comment-2 xgettext-c-comment-3 \
xgettext-c-comment-4 xgettext-c-comment-5 xgettext-c-comment-6 \
xgettext-c-escape-1 xgettext-c-escape-2 xgettext-c-escape-3 \
diff --git a/gettext-tools/tests/xgettext-c-7 b/gettext-tools/tests/xgettext-c-7
new file mode 100755
index 000000000..08e3144ba
--- /dev/null
+++ b/gettext-tools/tests/xgettext-c-7
@@ -0,0 +1,24 @@
+#! /bin/sh
+. "${srcdir=.}/init.sh"; path_prepend_ . ../src
+
+# Test C support: out-of-range hexadecimal escape sequences.
+
+: ${XGETTEXT=xgettext}
+
+cat <<\EOF > xg-c-7.c
+gettext("\x678888");
+EOF
+
+${XGETTEXT} --omit-header --no-location -o xg-c-7.tmp xg-c-7.c || Exit 1
+func_filter_POT_Creation_Date xg-c-7.tmp xg-c-7.po
+
+cat <<\EOF > xg-c-7.ok
+msgid "g"
+msgstr ""
+EOF
+
+: ${DIFF=diff}
+${DIFF} xg-c-7.ok xg-c-7.po
+result=$?
+
+exit $result