Package: g++-mingw-w64-i686
Version: 4.6.3-14+8+nmu1
Severity: normal
Tags: patch

Dear Maintainer,
The following program crashes when built with x86_64-w64-mingw32-g++ or
i686-w64-mingw32-g++:

#include <iostream>

int main() {
    std::cout.setf(std::ios::fixed);
    std::cout << 1e300 << "\n";
    return 0;
}


The underlying cause is an assumption that snprintf never returns -1.  In fact,
on Windows, the platform snprintf returns -1 when the buffer is not big
enough, which leads to (A) calling alloca(-1) and (B) calling std::widen
with fin < st, either one of which is probably enough to lead to a
crash.

The patch shown below fixes several locations in libstdc++ where a
negative return value from snprintf was not properly handled.

As far as I'm aware, this bug also exists upstream, but I have not filed
it there.

-- System Information:
Debian Release: 7.3
  APT prefers stable-updates
  APT policy: (500, 'stable-updates'), (500, 'stable')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 3.2.0-4-amd64 (SMP w/12 CPU cores)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash

Versions of packages g++-mingw-w64-i686 depends on:
ii  gcc-mingw-w64-base  4.6.3-14+8+nmu1
ii  gcc-mingw-w64-i686  4.6.3-14+8+nmu1
ii  libc6               2.13-38
ii  libgmp10            2:5.0.5+dfsg-2
ii  libmpc2             0.9-4
ii  libmpfr4            3.1.0-5
ii  libstdc++6-4.6-dev  4.6.3-14
ii  zlib1g              1:1.2.7.dfsg-13

g++-mingw-w64-i686 recommends no packages.

Versions of packages g++-mingw-w64-i686 suggests:
pn  gcc-4.6-locales  <none>

-- no debconf information


diff -Nru gcc-mingw-w64-8/debian/changelog gcc-mingw-w64-8+nmu1/debian/changelog
--- gcc-mingw-w64-8/debian/changelog    2012-12-12 00:30:21.000000000 -0600
+++ gcc-mingw-w64-8+nmu1/debian/changelog       2014-01-28 09:52:09.000000000 
-0600
@@ -1,3 +1,10 @@
+gcc-mingw-w64 (8+nmu1) stable; urgency=low
+
+  * Non-maintainer upload.
+  * Fix crash in ostream with ios::fixed and large numbers (PR28891) 
+
+ -- Jeff Epler <[email protected]>  Tue, 28 Jan 2014 09:16:10 -0600
+
 gcc-mingw-w64 (8) unstable; urgency=low
 
   * Replace /usr/share/doc/gcc-mingw32 with a symlink when necessary
diff -Nru gcc-mingw-w64-8/debian/patches/snprintf-minusone.patch 
gcc-mingw-w64-8+nmu1/debian/patches/snprintf-minusone.patch
--- gcc-mingw-w64-8/debian/patches/snprintf-minusone.patch      1969-12-31 
18:00:00.000000000 -0600
+++ gcc-mingw-w64-8+nmu1/debian/patches/snprintf-minusone.patch 2014-01-28 
09:07:07.000000000 -0600
@@ -0,0 +1,60 @@
+@@ -, +, @@ 
+ .../libstdc++-v3/include/bits/locale_facets.tcc    |   14 ++++++++++++++
+ .../include/bits/locale_facets_nonio.tcc           |   10 ++++++++++
+ 2 files changed, 24 insertions(+), 0 deletions(-)
+--- a/gcc/src/libstdc++-v3/include/bits/locale_facets.tcc      
++++ a/gcc/src/libstdc++-v3/include/bits/locale_facets.tcc      
+@@ -995,6 +995,17 @@ _GLIBCXX_BEGIN_LDBL_NAMESPACE
+       __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size,
+                                     __fbuf, __prec, __v);
+ 
++      // If snprintf returned negative, we have to use a buffer guaranteed big
++      // enough for any value
++      if (__len < 0)
++        {
++          const bool __fixed = __io.flags() & ios_base::fixed;
++          const int __max_exp =
++            __gnu_cxx::__numeric_traits<_ValueT>::__max_exponent10;
++          __len = __fixed ? __max_exp + __prec + 4
++                          : __max_digits * 2 + __prec;
++        }
++
+       // If the buffer was not large enough, try again with the correct size.
+       if (__len >= __cs_size)
+         {
+@@ -1002,6 +1013,9 @@ _GLIBCXX_BEGIN_LDBL_NAMESPACE
+           __cs = static_cast<char*>(__builtin_alloca(__cs_size));
+           __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size,
+                                         __fbuf, __prec, __v);
++          // guard against a further error return from snprintf, which should
++          // not have been possible
++          if(__len < 0) __len = 0;
+         }
+ #else
+       // Consider the possibility of long ios_base::fixed outputs
+--- a/gcc/src/libstdc++-v3/include/bits/locale_facets_nonio.tcc        
++++ a/gcc/src/libstdc++-v3/include/bits/locale_facets_nonio.tcc        
+@@ -578,6 +578,13 @@ _GLIBCXX_BEGIN_LDBL_NAMESPACE
+       // 328. Bad sprintf format modifier in money_put<>::do_put()
+       int __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size,
+                                       "%.*Lf", 0, __units);
++      // If snprintf returned negative, we have to use a buffer guaranteed big
++      // enough for any value
++      if (__len < 0)
++        {
++        __len = __gnu_cxx::__numeric_traits<long double>::__max_exponent10 + 
3;
++        }
++
+       // If the buffer was not large enough, try again with the correct size.
+       if (__len >= __cs_size)
+       {
+@@ -585,6 +592,9 @@ _GLIBCXX_BEGIN_LDBL_NAMESPACE
+         __cs = static_cast<char*>(__builtin_alloca(__cs_size));
+         __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size,
+                                       "%.*Lf", 0, __units);
++        // guard against a further error return from snprintf, which should
++        // not have been possible
++        if(__len < 0) __len = 0;
+       }
+ #else
+       // max_exponent10 + 1 for the integer part, + 2 for sign and '\0'.
diff -Nru gcc-mingw-w64-8/debian/rules gcc-mingw-w64-8+nmu1/debian/rules
--- gcc-mingw-w64-8/debian/rules        2012-10-17 00:03:49.000000000 -0500
+++ gcc-mingw-w64-8+nmu1/debian/rules   2014-01-28 09:15:06.000000000 -0600
@@ -144,6 +144,8 @@
        patch -p1 -d$(upstream_dir) < debian/patches/cpp-intrinsics.patch
        # Spelling fixes
        patch -p2 -d$(upstream_dir) < debian/patches/spelling-fixes-code.patch
+       # Fix snprintf use in libstdc++ (dsndata.com#11278)
+       patch -p3 -d$(upstream_dir) < debian/patches/snprintf-minusone.patch
        touch $@
 
 configure: configure-stamp
Binary files 
/dev/shm/ccache/ljcEmTK90v/gcc-mingw-w64-8/gcc-mingw-w64-build-deps_1.0_all.deb 
and 
/dev/shm/ccache/T2TJfEEzLq/gcc-mingw-w64-8+nmu1/gcc-mingw-w64-build-deps_1.0_all.deb
 differ


-- 
To UNSUBSCRIBE, email to [email protected]
with a subject of "unsubscribe". Trouble? Contact [email protected]

Reply via email to