arrfab / rpms / glibc

Forked from rpms/glibc 5 years ago
Clone

Blame SOURCES/glibc-rh1380680-16.patch

147e83
From e4613df21e25e063d120ee23a650c65cd16df4be Mon Sep 17 00:00:00 2001
147e83
From: Stefan Liebler <stli@linux.vnet.ibm.com>
147e83
Date: Mon, 7 Nov 2016 17:30:22 +0100
147e83
Subject: [PATCH 16/17] Fix ucs4le_internal_loop in error case. [BZ #19726]
147e83
147e83
Upstream commit 8f25676c83eef5c85db98f9cf027890fbe810447
147e83
147e83
When converting from UCS4LE to INTERNAL, the input-value is checked for a too
147e83
large value and the iconv() call sets errno to EILSEQ. In this case the inbuf
147e83
argument of the iconv() call should point to the invalid character, but it
147e83
points to the beginning of the inbuf.
147e83
Thus this patch updates the pointers inptrp and outptrp before returning in
147e83
this error case.
147e83
147e83
This patch also adds a new testcase for this issue.
147e83
The new test was tested on a s390, power, intel machine.
147e83
147e83
ChangeLog:
147e83
147e83
	[BZ #19726]
147e83
	* iconv/gconv_simple.c (ucs4le_internal_loop): Update inptrp and
147e83
	outptrp in case of an illegal input.
147e83
	* iconv/tst-iconv6.c: New file.
147e83
	* iconv/Makefile (tests): Add tst-iconv6.
147e83
---
147e83
 iconv/Makefile       |   2 +-
147e83
 iconv/gconv_simple.c |   2 +
147e83
 iconv/tst-iconv6.c   | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++
147e83
 3 files changed, 120 insertions(+), 1 deletion(-)
147e83
 create mode 100644 iconv/tst-iconv6.c
147e83
147e83
diff --git a/iconv/Makefile b/iconv/Makefile
147e83
index 3e7f567..4d34c3f 100644
147e83
--- a/iconv/Makefile
147e83
+++ b/iconv/Makefile
147e83
@@ -43,7 +43,7 @@ CFLAGS-charmap.c = -DCHARMAP_PATH='"$(i18ndir)/charmaps"' \
147e83
 CFLAGS-linereader.c = -DNO_TRANSLITERATION
147e83
 CFLAGS-simple-hash.c = -I../locale
147e83
 
147e83
-tests	= tst-iconv1 tst-iconv2 tst-iconv3 tst-iconv4 tst-iconv5
147e83
+tests	= tst-iconv1 tst-iconv2 tst-iconv3 tst-iconv4 tst-iconv5 tst-iconv6
147e83
 
147e83
 others		= iconv_prog iconvconfig
147e83
 install-others-programs	= $(inst_bindir)/iconv
147e83
diff --git a/iconv/gconv_simple.c b/iconv/gconv_simple.c
147e83
index 8697309..b9f846d 100644
147e83
--- a/iconv/gconv_simple.c
147e83
+++ b/iconv/gconv_simple.c
147e83
@@ -634,6 +634,8 @@ ucs4le_internal_loop (struct __gconv_step *step,
147e83
 	      continue;
147e83
 	    }
147e83
 
147e83
+	  *inptrp = inptr;
147e83
+	  *outptrp = outptr;
147e83
 	  return __GCONV_ILLEGAL_INPUT;
147e83
 	}
147e83
 
147e83
diff --git a/iconv/tst-iconv6.c b/iconv/tst-iconv6.c
147e83
new file mode 100644
147e83
index 0000000..57d7f38
147e83
--- /dev/null
147e83
+++ b/iconv/tst-iconv6.c
147e83
@@ -0,0 +1,117 @@
147e83
+/* Testing ucs4le_internal_loop() in gconv_simple.c.
147e83
+   Copyright (C) 2016 Free Software Foundation, Inc.
147e83
+   This file is part of the GNU C Library.
147e83
+
147e83
+   The GNU C Library is free software; you can redistribute it and/or
147e83
+   modify it under the terms of the GNU Lesser General Public
147e83
+   License as published by the Free Software Foundation; either
147e83
+   version 2.1 of the License, or (at your option) any later version.
147e83
+
147e83
+   The GNU C Library is distributed in the hope that it will be useful,
147e83
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
147e83
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
147e83
+   Lesser General Public License for more details.
147e83
+
147e83
+   You should have received a copy of the GNU Lesser General Public
147e83
+   License along with the GNU C Library; if not, see
147e83
+   <http://www.gnu.org/licenses/>.  */
147e83
+
147e83
+#include <stdio.h>
147e83
+#include <errno.h>
147e83
+#include <string.h>
147e83
+#include <inttypes.h>
147e83
+#include <iconv.h>
147e83
+#include <byteswap.h>
147e83
+
147e83
+static int
147e83
+do_test (void)
147e83
+{
147e83
+  iconv_t cd;
147e83
+  char *inptr;
147e83
+  size_t inlen;
147e83
+  char *outptr;
147e83
+  size_t outlen;
147e83
+  size_t n;
147e83
+  int e;
147e83
+  int result = 0;
147e83
+
147e83
+#if __BYTE_ORDER == __BIG_ENDIAN
147e83
+  /* On big-endian machines, ucs4le_internal_loop() swaps the bytes before
147e83
+     error checking. Thus the input values has to be swapped.  */
147e83
+# define VALUE(val) bswap_32 (val)
147e83
+#else
147e83
+# define VALUE(val) val
147e83
+#endif
147e83
+  uint32_t inbuf[3] = { VALUE (0x41), VALUE (0x80000000), VALUE (0x42) };
147e83
+  uint32_t outbuf[3] = { 0, 0, 0 };
147e83
+
147e83
+  cd = iconv_open ("WCHAR_T", "UCS-4LE");
147e83
+  if (cd == (iconv_t) -1)
147e83
+    {
147e83
+      printf ("cannot convert from UCS4LE to wchar_t: %m\n");
147e83
+      return 1;
147e83
+    }
147e83
+
147e83
+  inptr = (char *) inbuf;
147e83
+  inlen = sizeof (inbuf);
147e83
+  outptr = (char *) outbuf;
147e83
+  outlen = sizeof (outbuf);
147e83
+
147e83
+  n = iconv (cd, &inptr, &inlen, &outptr, &outlen);
147e83
+  e = errno;
147e83
+
147e83
+  if (n != (size_t) -1)
147e83
+    {
147e83
+      printf ("incorrect iconv() return value: %zd, expected -1\n", n);
147e83
+      result = 1;
147e83
+    }
147e83
+
147e83
+  if (e != EILSEQ)
147e83
+    {
147e83
+      printf ("incorrect error value: %s, expected %s\n",
147e83
+	      strerror (e), strerror (EILSEQ));
147e83
+      result = 1;
147e83
+    }
147e83
+
147e83
+  if (inptr != (char *) &inbuf[1])
147e83
+    {
147e83
+      printf ("inptr=0x%p does not point to invalid character! Expected=0x%p\n"
147e83
+	      , inptr, &inbuf[1]);
147e83
+      result = 1;
147e83
+    }
147e83
+
147e83
+  if (inlen != sizeof (inbuf) - sizeof (uint32_t))
147e83
+    {
147e83
+      printf ("inlen=%zd != %zd\n"
147e83
+	      , inlen, sizeof (inbuf) - sizeof (uint32_t));
147e83
+      result = 1;
147e83
+    }
147e83
+
147e83
+  if (outptr != (char *) &outbuf[1])
147e83
+    {
147e83
+      printf ("outptr=0x%p does not point to invalid character in inbuf! "
147e83
+	      "Expected=0x%p\n"
147e83
+	      , outptr, &outbuf[1]);
147e83
+      result = 1;
147e83
+    }
147e83
+
147e83
+  if (outlen != sizeof (inbuf) - sizeof (uint32_t))
147e83
+    {
147e83
+      printf ("outlen=%zd != %zd\n"
147e83
+	      , outlen, sizeof (outbuf) - sizeof (uint32_t));
147e83
+      result = 1;
147e83
+    }
147e83
+
147e83
+  if (outbuf[0] != 0x41 || outbuf[1] != 0 || outbuf[2] != 0)
147e83
+    {
147e83
+      puts ("Characters conversion is incorrect!");
147e83
+      result = 1;
147e83
+    }
147e83
+
147e83
+  iconv_close (cd);
147e83
+
147e83
+  return result;
147e83
+}
147e83
+
147e83
+#define TEST_FUNCTION do_test ()
147e83
+#include "../test-skeleton.c"
147e83
-- 
147e83
1.8.3.1
147e83