[glibc] Sync with upstream master and fix #1052846

Siddhesh Poyarekar siddhesh at fedoraproject.org
Tue Jan 14 08:46:40 UTC 2014


commit 8ecbeeba6e119d725bfd4e7416a21e2051ddbcc8
Author: Siddhesh Poyarekar <siddhesh at redhat.com>
Date:   Tue Jan 14 14:16:38 2014 +0530

    Sync with upstream master and fix #1052846
    
    - Sync with upstream master.
    - Fix infinite loop in ftell when writing wide char data (#1052846).

 glibc-rh1052846.patch |  443 +++++++++++++++++++++++++++++++++++++++++++++++++
 glibc.spec            |   12 +-
 sources               |    2 +-
 3 files changed, 454 insertions(+), 3 deletions(-)
---
diff --git a/glibc-rh1052846.patch b/glibc-rh1052846.patch
new file mode 100644
index 0000000..c88675a
--- /dev/null
+++ b/glibc-rh1052846.patch
@@ -0,0 +1,443 @@
+commit 403ce35141da511898cde550f48ebc68a2a3ac82
+Author: Siddhesh Poyarekar <siddhesh at redhat.com>
+Date:   Mon Jan 6 14:37:21 2014 +0530
+
+    Fix infinite loop in ftell when writing wide char data (BZ #16398)
+    
+    ftell tries to avoid flushing the buffer when it is in write mode by
+    converting the wide char data and placing it into the binary buffer.
+    If the output buffer space is full and there is data to write, the
+    code reverts to flushing the buffer.  This breaks when there is space
+    in the buffer but it is not enough to convert the next character in
+    the wide data buffer, due to which __codecvt_do_out returns a
+    __codecvt_partial status.  In this case, ftell keeps running in an
+    infinite loop.
+    
+    The fix here is to detect the __codecvt_partial status in addition to
+    checking if the buffer is full.  I have also added a test case
+    (written by Arjun Shankar) that demonstrates the infinite loop.
+
+diff --git a/libio/Makefile b/libio/Makefile
+index 05432f4..38bdeb3 100644
+--- a/libio/Makefile
++++ b/libio/Makefile
+@@ -60,7 +60,7 @@ tests = tst_swprintf tst_wprintf tst_swscanf tst_wscanf tst_getwc tst_putwc   \
+ 	tst-wmemstream1 tst-wmemstream2 \
+ 	bug-memstream1 bug-wmemstream1 \
+ 	tst-setvbuf1 tst-popen1 tst-fgetwc bug-wsetpos tst-fseek \
+-	tst-fwrite-error
++	tst-fwrite-error tst-fseek-partial-wide
+ ifeq (yes,$(build-shared))
+ # Add test-fopenloc only if shared library is enabled since it depends on
+ # shared localedata objects.
+diff --git a/libio/tst-fseek-partial-wide.c b/libio/tst-fseek-partial-wide.c
+new file mode 100644
+index 0000000..9a34443
+--- /dev/null
++++ b/libio/tst-fseek-partial-wide.c
+@@ -0,0 +1,376 @@
++/* Verify that ftell does not go into an infinite loop when a conversion fails
++   due to insufficient space in the buffer.
++   Copyright (C) 2014 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <wchar.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <locale.h>
++#include <errno.h>
++#include <unistd.h>
++
++/* Defined in test-skeleton.c.  */
++static int create_temp_file (const char *base, char **filename);
++
++const wchar_t *numbers[] = {
++  L"ゼロ\n",
++  L"いち\n",
++  L"に\n",
++  L"さん\n",
++  L"よん\n",
++  L"ご\n",
++  L"ろく\n",
++  L"なな\n",
++  L"はち\n",
++  L"きゅう\n",
++  L"じゅう\n",
++  L"じゅういち\n",
++  L"じゅうに\n",
++  L"じゅうさん\n",
++  L"じゅうよん\n",
++  L"じゅうご\n",
++  L"じゅうろく\n",
++  L"じゅうなな\n",
++  L"じゅうはち\n",
++  L"じゅうきゅう\n",
++  L"にじゅう\n",
++  L"にじゅういち\n",
++  L"にじゅうに\n",
++  L"にじゅうさん\n",
++  L"にじゅうよん\n",
++  L"にじゅうご\n",
++  L"にじゅうろく\n",
++  L"にじゅうなな\n",
++  L"にじゅうはち\n",
++  L"にじゅうきゅう\n",
++  L"さんじゅう\n",
++  L"さんじゅういち\n",
++  L"さんじゅうに\n",
++  L"さんじゅうさん\n",
++  L"さんじゅうよん\n",
++  L"さんじゅうご\n",
++  L"さんじゅうろく\n",
++  L"さんじゅうなな\n",
++  L"さんじゅうはち\n",
++  L"さんじゅうきゅう\n",
++  L"よんじゅう\n",
++  L"よんじゅういち\n",
++  L"よんじゅうに\n",
++  L"よんじゅうさん\n",
++  L"よんじゅうよん\n",
++  L"よんじゅうご\n",
++  L"よんじゅうろく\n",
++  L"よんじゅうなな\n",
++  L"よんじゅうはち\n",
++  L"よんじゅうきゅう\n",
++  L"ごじゅう\n",
++  L"ごじゅういち\n",
++  L"ごじゅうに\n",
++  L"ごじゅうさん\n",
++  L"ごじゅうよん\n",
++  L"ごじゅうご\n",
++  L"ごじゅうろく\n",
++  L"ごじゅうなな\n",
++  L"ごじゅうはち\n",
++  L"ごじゅうきゅう\n",
++  L"ろくじゅう\n",
++  L"ろくじゅういち\n",
++  L"ろくじゅうに\n",
++  L"ろくじゅうさん\n",
++  L"ろくじゅうよん\n",
++  L"ろくじゅうご\n",
++  L"ろくじゅうろく\n",
++  L"ろくじゅうなな\n",
++  L"ろくじゅうはち\n",
++  L"ろくじゅうきゅう\n",
++  L"ななじゅう\n",
++  L"ななじゅういち\n",
++  L"ななじゅうに\n",
++  L"ななじゅうさん\n",
++  L"ななじゅうよん\n",
++  L"ななじゅうご\n",
++  L"ななじゅうろく\n",
++  L"ななじゅうなな\n",
++  L"ななじゅうはち\n",
++  L"ななじゅうきゅう\n",
++  L"はちじゅう\n",
++  L"はちじゅういち\n",
++  L"はちじゅうに\n",
++  L"はちじゅうさん\n",
++  L"はちじゅうよん\n",
++  L"はちじゅうご\n",
++  L"はちじゅうろく\n",
++  L"はちじゅうなな\n",
++  L"はちじゅうはち\n",
++  L"はちじゅうきゅう\n",
++  L"きゅうじゅう\n",
++  L"きゅうじゅういち\n",
++  L"きゅうじゅうに\n",
++  L"きゅうじゅうさん\n",
++  L"きゅうじゅうよん\n",
++  L"きゅうじゅうご\n",
++  L"きゅうじゅうろく\n",
++  L"きゅうじゅうなな\n",
++  L"きゅうじゅうはち\n",
++  L"きゅうじゅうきゅう\n",
++  L"ひゃく\n",
++  L"ひゃくいち\n",
++  L"ひゃくに\n",
++  L"ひゃくさん\n",
++  L"ひゃくよん\n",
++  L"ひゃくご\n",
++  L"ひゃくろく\n",
++  L"ひゃくなな\n",
++  L"ひゃくはち\n",
++  L"ひゃくきゅう\n",
++  L"ひゃくじゅう\n",
++  L"ひゃくじゅういち\n",
++  L"ひゃくじゅうに\n",
++  L"ひゃくじゅうさん\n",
++  L"ひゃくじゅうよん\n",
++  L"ひゃくじゅうご\n",
++  L"ひゃくじゅうろく\n",
++  L"ひゃくじゅうなな\n",
++  L"ひゃくじゅうはち\n",
++  L"ひゃくじゅうきゅう\n",
++  L"ひゃくにじゅう\n",
++  L"ひゃくにじゅういち\n",
++  L"ひゃくにじゅうに\n",
++  L"ひゃくにじゅうさん\n",
++  L"ひゃくにじゅうよん\n",
++  L"ひゃくにじゅうご\n",
++  L"ひゃくにじゅうろく\n",
++  L"ひゃくにじゅうなな\n",
++  L"ひゃくにじゅうはち\n",
++  L"ひゃくにじゅうきゅう\n",
++  L"ひゃくさんじゅう\n",
++  L"ひゃくさんじゅういち\n",
++  L"ひゃくさんじゅうに\n",
++  L"ひゃくさんじゅうさん\n",
++  L"ひゃくさんじゅうよん\n",
++  L"ひゃくさんじゅうご\n",
++  L"ひゃくさんじゅうろく\n",
++  L"ひゃくさんじゅうなな\n",
++  L"ひゃくさんじゅうはち\n",
++  L"ひゃくさんじゅうきゅう\n",
++  L"ひゃくよんじゅう\n",
++  L"ひゃくよんじゅういち\n",
++  L"ひゃくよんじゅうに\n",
++  L"ひゃくよんじゅうさん\n",
++  L"ひゃくよんじゅうよん\n",
++  L"ひゃくよんじゅうご\n",
++  L"ひゃくよんじゅうろく\n",
++  L"ひゃくよんじゅうなな\n",
++  L"ひゃくよんじゅうはち\n",
++  L"ひゃくよんじゅうきゅう\n",
++  L"ひゃくごじゅう\n",
++  L"ひゃくごじゅういち\n",
++  L"ひゃくごじゅうに\n",
++  L"ひゃくごじゅうさん\n",
++  L"ひゃくごじゅうよん\n",
++  L"ひゃくごじゅうご\n",
++  L"ひゃくごじゅうろく\n",
++  L"ひゃくごじゅうなな\n",
++  L"ひゃくごじゅうはち\n",
++  L"ひゃくごじゅうきゅう\n",
++  L"ひゃくろくじゅう\n",
++  L"ひゃくろくじゅういち\n",
++  L"ひゃくろくじゅうに\n",
++  L"ひゃくろくじゅうさん\n",
++  L"ひゃくろくじゅうよん\n",
++  L"ひゃくろくじゅうご\n",
++  L"ひゃくろくじゅうろく\n",
++  L"ひゃくろくじゅうなな\n",
++  L"ひゃくろくじゅうはち\n",
++  L"ひゃくろくじゅうきゅう\n",
++  L"ひゃくななじゅう\n",
++  L"ひゃくななじゅういち\n",
++  L"ひゃくななじゅうに\n",
++  L"ひゃくななじゅうさん\n",
++  L"ひゃくななじゅうよん\n",
++  L"ひゃくななじゅうご\n",
++  L"ひゃくななじゅうろく\n",
++  L"ひゃくななじゅうなな\n",
++  L"ひゃくななじゅうはち\n",
++  L"ひゃくななじゅうきゅう\n",
++  L"ひゃくはちじゅう\n",
++  L"ひゃくはちじゅういち\n",
++  L"ひゃくはちじゅうに\n",
++  L"ひゃくはちじゅうさん\n",
++  L"ひゃくはちじゅうよん\n",
++  L"ひゃくはちじゅうご\n",
++  L"ひゃくはちじゅうろく\n",
++  L"ひゃくはちじゅうなな\n",
++  L"ひゃくはちじゅうはち\n",
++  L"ひゃくはちじゅうきゅう\n",
++  L"ひゃくきゅうじゅう\n",
++  L"ひゃくきゅうじゅういち\n",
++  L"ひゃくきゅうじゅうに\n",
++  L"ひゃくきゅうじゅうさん\n",
++  L"ひゃくきゅうじゅうよん\n",
++  L"ひゃくきゅうじゅうご\n",
++  L"ひゃくきゅうじゅうろく\n",
++  L"ひゃくきゅうじゅうなな\n",
++  L"ひゃくきゅうじゅうはち\n",
++  L"ひゃくきゅうじゅうきゅう\n",
++  L"にひゃく\n",
++  L"にひゃくいち\n",
++  L"にひゃくに\n",
++  L"にひゃくさん\n",
++  L"にひゃくよん\n",
++  L"にひゃくご\n",
++  L"にひゃくろく\n",
++  L"にひゃくなな\n",
++  L"にひゃくはち\n",
++  L"にひゃくきゅう\n",
++  L"にひゃくじゅう\n",
++  L"にひゃくじゅういち\n",
++  L"にひゃくじゅうに\n",
++  L"にひゃくじゅうさん\n",
++  L"にひゃくじゅうよん\n",
++  L"にひゃくじゅうご\n",
++  L"にひゃくじゅうろく\n",
++  L"にひゃくじゅうなな\n",
++  L"にひゃくじゅうはち\n",
++  L"にひゃくじゅうきゅう\n",
++  L"にひゃくにじゅう\n",
++  L"にひゃくにじゅういち\n",
++  L"にひゃくにじゅうに\n",
++  L"にひゃくにじゅうさん\n",
++  L"にひゃくにじゅうよん\n",
++  L"にひゃくにじゅうご\n",
++  L"にひゃくにじゅうろく\n",
++  L"にひゃくにじゅうなな\n",
++  L"にひゃくにじゅうはち\n",
++  L"にひゃくにじゅうきゅう\n",
++  L"にひゃくさんじゅう\n",
++  L"にひゃくさんじゅういち\n",
++  L"にひゃくさんじゅうに\n",
++  L"にひゃくさんじゅうさん\n",
++  L"にひゃくさんじゅうよん\n",
++  L"にひゃくさんじゅうご\n",
++  L"にひゃくさんじゅうろく\n",
++  L"にひゃくさんじゅうなな\n",
++  L"にひゃくさんじゅうはち\n",
++  L"にひゃくさんじゅうきゅう\n",
++  L"にひゃくよんじゅう\n",
++  L"にひゃくよんじゅういち\n",
++  L"にひゃくよんじゅうに\n",
++  L"にひゃくよんじゅうさん\n",
++  L"にひゃくよんじゅうよん\n",
++  L"にひゃくよんじゅうご\n",
++  L"にひゃくよんじゅうろく\n",
++  L"にひゃくよんじゅうなな\n",
++  L"にひゃくよんじゅうはち\n",
++  L"にひゃくよんじゅうきゅう\n",
++  L"にひゃくごじゅう\n",
++  L"にひゃくごじゅういち\n",
++  L"にひゃくごじゅうに\n",
++  L"にひゃくごじゅうさん\n",
++  L"にひゃくごじゅうよん\n",
++  L"にひゃくごじゅうご\n",
++  L"にひゃくごじゅうろく\n",
++  L"にひゃくごじゅうなな\n",
++  L"にひゃくごじゅうはち\n",
++  L"にひゃくごじゅうきゅう\n",
++  L"にひゃくろくじゅう\n",
++  L"にひゃくろくじゅういち\n",
++  L"にひゃくろくじゅうに\n",
++  L"にひゃくろくじゅうさん\n",
++  L"にひゃくろくじゅうよん\n",
++  L"にひゃくろくじゅうご\n",
++  L"にひゃくろくじゅうろく\n",
++  L"にひゃくろくじゅうなな\n",
++  L"にひゃくろくじゅうはち\n",
++  L"にひゃくろくじゅうきゅう\n",
++  L"にひゃくななじゅう\n",
++  L"にひゃくななじゅういち\n",
++  L"にひゃくななじゅうに\n",
++  L"にひゃくななじゅうさん\n",
++  L"にひゃくななじゅうよん\n",
++  L"にひゃくななじゅうご\n",
++  L"にひゃくななじゅうろく\n",
++  L"にひゃくななじゅうなな\n",
++  L"にひゃくななじゅうはち\n",
++  L"にひゃくななじゅうきゅう\n",
++  L"にひゃくはちじゅう\n",
++  L"にひゃくはちじゅういち\n",
++  L"にひゃくはちじゅうに\n",
++  L"にひゃくはちじゅうさん\n",
++  L"にひゃくはちじゅうよん\n",
++  L"にひゃくはちじゅうご\n",
++  L"にひゃくはちじゅうろく\n",
++  L"にひゃくはちじゅうなな\n",
++  L"にひゃくはちじゅうはち\n",
++  L"にひゃくはちじゅうきゅう\n",
++  L"にひゃくきゅうじゅう\n",
++  L"にひゃくきゅうじゅういち\n",
++  L"にひゃくきゅうじゅうに\n",
++  L"にひゃくきゅうじゅうさん\n",
++  L"にひゃくきゅうじゅうよん\n",
++  L"にひゃくきゅうじゅうご\n",
++  L"にひゃくきゅうじゅうろく\n",
++  L"にひゃくきゅうじゅうなな\n",
++  L"にひゃくきゅうじゅうはち\n",
++  L"にひゃくきゅうじゅうきゅう\n",
++  L"さんびゃく\n",
++};
++
++
++int
++do_test (void)
++{
++  int i;
++
++  if (setlocale (LC_ALL, "en_US.UTF-8") == NULL)
++    {
++      printf ("Cannot set en_US.UTF-8 locale.\n");
++      exit (1);
++    }
++
++  char *filename;
++  int fd = create_temp_file ("tst-fseek-wide-partial.out", &filename);
++
++  if (fd == -1)
++    return 1;
++
++  FILE *fp = fdopen (fd, "w+");
++  if (fp == NULL)
++    {
++      printf ("fopen: %s\n", strerror (errno));
++      close (fd);
++      return 1;
++    }
++
++  for (i = 0; i < sizeof (numbers) / sizeof (char *); i++)
++    {
++      printf ("offset: %ld\n", ftell (fp));
++      if (fputws (numbers[i], fp) == -1)
++        {
++          perror ("fputws");
++          return 1;
++        }
++    }
++  fclose (fp);
++  return 0;
++}
++
++
++#define TEST_FUNCTION do_test ()
++#include "../test-skeleton.c"
+diff --git a/libio/wfileops.c b/libio/wfileops.c
+index 87d3cdc..877fc1f 100644
+--- a/libio/wfileops.c
++++ b/libio/wfileops.c
+@@ -715,7 +715,7 @@ _IO_wfile_seekoff (fp, offset, dir, mode)
+ 		       - fp->_wide_data->_IO_write_base) / clen;
+ 	  else
+ 	    {
+-	      enum __codecvt_result status;
++	      enum __codecvt_result status = __codecvt_ok;
+ 	      delta = (fp->_wide_data->_IO_write_ptr
+ 		       - fp->_wide_data->_IO_write_base);
+ 	      const wchar_t *write_base = fp->_wide_data->_IO_write_base;
+@@ -728,9 +728,12 @@ _IO_wfile_seekoff (fp, offset, dir, mode)
+ 		 flush buffers for every ftell.  */
+ 	      do
+ 		{
+-		  /* Ugh, no point trying to avoid the flush.  Just do it
+-		     and go back to how it was with the read mode.  */
+-		  if (delta > 0 && new_write_ptr == fp->_IO_buf_end)
++		  /* There is not enough space in the buffer to do the entire
++		     conversion, so there is no point trying to avoid the
++		     buffer flush.  Just do it and go back to how it was with
++		     the read mode.  */
++		  if (status == __codecvt_partial
++		      || (delta > 0 && new_write_ptr == fp->_IO_buf_end))
+ 		    {
+ 		      if (_IO_switch_to_wget_mode (fp))
+ 			return WEOF;
diff --git a/glibc.spec b/glibc.spec
index e9e28e8..4294b16 100644
--- a/glibc.spec
+++ b/glibc.spec
@@ -1,6 +1,6 @@
-%define glibcsrcdir  glibc-2.18-753-gd5780fe
+%define glibcsrcdir  glibc-2.18-788-g497b1e6
 %define glibcversion 2.18.90
-%define glibcrelease 20%{?dist}
+%define glibcrelease 21%{?dist}
 # Pre-release tarballs are pulled in from git using a command that is
 # effectively:
 #
@@ -211,6 +211,9 @@ Patch2027: %{name}-rh819430.patch
 # Fix nscd to use permission names not constants.
 Patch2028: %{name}-rh1025126.patch
 
+# Upstream BZ 16398
+Patch2029: %{name}-rh1052846.patch
+
 ##############################################################################
 # End of glibc patches.
 ##############################################################################
@@ -535,6 +538,7 @@ package or when debugging this package.
 %patch0044 -p1
 %patch0046 -p1
 %patch2028 -p1
+%patch2029 -p1
 
 ##############################################################################
 # %%prep - Additional prep required...
@@ -1620,6 +1624,10 @@ rm -f *.filelist*
 %endif
 
 %changelog
+* Tue Jan 14 2014 Siddhesh Poyarekar <siddhesh at redhat.com> - 2.18.90-21
+- Sync with upstream master.
+- Fix infinite loop in ftell when writing wide char data (#1052846).
+
 * Tue Jan  7 2014 Siddhesh Poyarekar <siddhesh at redhat.com> - 2.18.90-20
 - Sync with upstream master.
 - Enable systemtap probes on Power and S/390.
diff --git a/sources b/sources
index 8fbe070..05b4e53 100644
--- a/sources
+++ b/sources
@@ -1 +1 @@
-8453361d6cfeec94dd6c7ad5ef1e01e1  glibc-2.18-753-gd5780fe.tar.gz
+68d30f09d625972d997ffc5c2763a097  glibc-2.18-788-g497b1e6.tar.gz


More information about the scm-commits mailing list