re PR libstdc++/13858 (Bad error handling in basic_filebuf::imbue)

2004-02-14  Paolo Carlini  <pcarlini@suse.de>

	PR libstdc++/13858
	* include/bits/fstream.tcc (basic_filebuf<>::_M_convert_to_external):
	In case of conversion errors, throw ios_failure; simplify.
	* testsuite/27_io/basic_filebuf/overflow/char/13858.cc: New.
	* testsuite/27_io/basic_filebuf/overflow/wchar_t/13858.cc: Ditto.
	* testsuite/27_io/basic_filebuf/overflow/char/9182-2.cc: Tweak,
	previously we didn't throw in case of conversion errors, instead
	just returned eof().
	* testsuite/27_io/basic_filebuf/seekoff/wchar_t/3.cc: Ditto.
	* testsuite/27_io/basic_filebuf/seekpos/wchar_t/1.cc: Ditto.
	* testsuite/27_io/basic_filebuf/sync/char/9182-1.cc: Ditto.

	* include/bits/fstream.tcc (basic_filebuf<>::overflow):
	Trivial simplification of a conditional.

From-SVN: r77812
This commit is contained in:
Paolo Carlini 2004-02-14 19:04:00 +00:00 committed by Paolo Carlini
parent d4afac5bbd
commit ac3cadf042
8 changed files with 214 additions and 44 deletions

View File

@ -1,3 +1,20 @@
2004-02-14 Paolo Carlini <pcarlini@suse.de>
PR libstdc++/13858
* include/bits/fstream.tcc (basic_filebuf<>::_M_convert_to_external):
In case of conversion errors, throw ios_failure; simplify.
* testsuite/27_io/basic_filebuf/overflow/char/13858.cc: New.
* testsuite/27_io/basic_filebuf/overflow/wchar_t/13858.cc: Ditto.
* testsuite/27_io/basic_filebuf/overflow/char/9182-2.cc: Tweak,
previously we didn't throw in case of conversion errors, instead
just returned eof().
* testsuite/27_io/basic_filebuf/seekoff/wchar_t/3.cc: Ditto.
* testsuite/27_io/basic_filebuf/seekpos/wchar_t/1.cc: Ditto.
* testsuite/27_io/basic_filebuf/sync/char/9182-1.cc: Ditto.
* include/bits/fstream.tcc (basic_filebuf<>::overflow):
Trivial simplification of a conditional.
2004-02-12 Paolo Carlini <pcarlini@suse.de>
PR libstdc++/13731 (final part: writev)

View File

@ -397,7 +397,7 @@ namespace std
// and output.
if (_M_convert_to_external(this->pbase(),
this->pptr() - this->pbase())
&& (!__testeof || (__testeof && !_M_file.sync())))
&& (!__testeof || !_M_file.sync()))
{
_M_set_buffer(0);
__ret = traits_type::not_eof(__c);
@ -437,12 +437,12 @@ namespace std
_M_convert_to_external(_CharT* __ibuf, streamsize __ilen)
{
// Sizes of external and pending output.
streamsize __elen = 0;
streamsize __plen = 0;
streamsize __elen;
streamsize __plen;
if (__check_facet(_M_codecvt).always_noconv())
{
__elen += _M_file.xsputn(reinterpret_cast<char*>(__ibuf), __ilen);
__plen += __ilen;
__elen = _M_file.xsputn(reinterpret_cast<char*>(__ibuf), __ilen);
__plen = __ilen;
}
else
{
@ -466,19 +466,14 @@ namespace std
__blen = __ilen;
}
else
{
// Result == error.
__blen = 0;
}
if (__blen)
{
__elen += _M_file.xsputn(__buf, __blen);
__plen += __blen;
}
__throw_ios_failure(__N("basic_filebuf::_M_convert_to_external "
"conversion error"));
__elen = _M_file.xsputn(__buf, __blen);
__plen = __blen;
// Try once more for partial conversions.
if (__r == codecvt_base::partial)
if (__r == codecvt_base::partial && __elen == __plen)
{
const char_type* __iresume = __iend;
streamsize __rlen = this->pptr() - __iend;
@ -488,12 +483,15 @@ namespace std
if (__r != codecvt_base::error)
{
__rlen = __bend - __buf;
__elen += _M_file.xsputn(__buf, __rlen);
__plen += __rlen;
__elen = _M_file.xsputn(__buf, __rlen);
__plen = __rlen;
}
else
__throw_ios_failure(__N("basic_filebuf::_M_convert_to_external "
"conversion error"));
}
}
return __elen && __elen == __plen;
return __elen == __plen;
}
template<typename _CharT, typename _Traits>

View File

@ -0,0 +1,70 @@
// 2004-02-14 Petur Runolfsson <peturr02@ru.is>
// Copyright (C) 2004 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.
// This 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 General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 27.8.1.4 Overridden virtual functions
#include <fstream>
#include <locale>
class Cvt : public std::codecvt<char, char, std::mbstate_t>
{
protected:
virtual std::codecvt_base::result
do_out(std::mbstate_t&, const char* from, const char*,
const char*& from_next, char* to, char*, char*& to_next) const
{
from_next = from;
to_next = to;
return std::codecvt_base::error;
}
virtual bool
do_always_noconv() const throw()
{ return false; }
};
// libstdc++/13858
void test01()
{
using namespace std;
filebuf fb;
fb.pubimbue(locale(locale::classic(), new Cvt));
fb.open("tmp_13858_char", ios_base::out);
try
{
fb.sputc('a');
fb.sputc('b');
fb.pubimbue(locale::classic());
fb.sputc('c');
fb.pubsync();
fb.close();
}
catch (exception&)
{
}
}
int main()
{
test01();
return 0;
}

View File

@ -1,6 +1,6 @@
// 2001-05-21 Benjamin Kosnik <bkoz@redhat.com>
// Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@ -22,7 +22,6 @@
#include <fstream>
#include <locale>
#include <testsuite_hooks.h>
const char name_07[] = "filebuf_virtuals-7.txt"; // empty file, need to create
@ -51,7 +50,6 @@ protected:
void test14()
{
using namespace std;
bool test __attribute__((unused)) = true;
locale loc = locale::classic();
loc = locale(loc, new errorcvt);
@ -60,9 +58,15 @@ void test14()
fbuf1.pubimbue(loc);
fbuf1.pubsetbuf(0, 0);
fbuf1.open(name_07, ios_base::out | ios_base::trunc);
streamsize n = fbuf1.sputn("onne", 4);
VERIFY( n == 0 );
fbuf1.close();
try
{
fbuf1.sputn("onne", 4);
fbuf1.close();
}
catch (exception&)
{
}
}
int main()

View File

@ -0,0 +1,71 @@
// 2004-02-14 Petur Runolfsson <peturr02@ru.is>
// Copyright (C) 2004 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.
// This 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 General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 27.8.1.4 Overridden virtual functions
#include <fstream>
#include <locale>
class Cvt : public std::codecvt<wchar_t, char, std::mbstate_t>
{
protected:
virtual std::codecvt_base::result
do_out(std::mbstate_t&, const wchar_t* from, const wchar_t*,
const wchar_t*& from_next, char* to, char*,
char*& to_next) const
{
from_next = from;
to_next = to;
return std::codecvt_base::error;
}
virtual bool
do_always_noconv() const throw()
{ return false; }
};
// libstdc++/13858
void test01()
{
using namespace std;
wfilebuf fb;
fb.pubimbue(locale(locale::classic(), new Cvt));
fb.open("tmp_13858_wchar_t", ios_base::out);
try
{
fb.sputc(L'a');
fb.sputc(L'b');
fb.pubimbue(locale::classic());
fb.sputc(L'c');
fb.pubsync();
fb.close();
}
catch (exception&)
{
}
}
int main()
{
test01();
return 0;
}

View File

@ -1,4 +1,4 @@
// Copyright (C) 2003 Free Software Foundation, Inc.
// Copyright (C) 2003, 2004 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@ -19,13 +19,11 @@
// 27.8.1.4 Overridden virtual functions
#include <fstream>
#include <testsuite_hooks.h>
void test03()
{
using namespace std;
bool test __attribute__((unused)) = true;
const char* name = "tmp_seekoff_3";
wfilebuf fb;
@ -33,10 +31,15 @@ void test03()
fb.open(name, ios_base::out);
fb.sputc(0xf001);
// seekoff should flush the output sequence, which will fail
// if the output buffer contains illegal characters.
streampos ret = fb.pubseekoff(0, ios_base::cur);
VERIFY( ret == streampos(streamoff(-1)) );
try
{
// seekoff should flush the output sequence, which will fail
// if the output buffer contains illegal characters.
fb.pubseekoff(0, ios_base::cur);
}
catch (exception&)
{
}
}
int main()

View File

@ -1,4 +1,4 @@
// Copyright (C) 2003 Free Software Foundation, Inc.
// Copyright (C) 2003, 2004 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@ -20,13 +20,11 @@
#include <locale>
#include <fstream>
#include <testsuite_hooks.h>
void test01()
{
using namespace std;
bool test __attribute__((unused)) = true;
const char* name = "tmp_seekpos_1";
wfilebuf fb;
@ -35,8 +33,13 @@ void test01()
streampos pos = fb.pubseekoff(0, ios_base::beg);
fb.sputc(0xf001);
streampos ret = fb.pubseekpos(pos);
VERIFY( ret == streampos(streamoff(-1)) );
try
{
fb.pubseekpos(pos);
}
catch (exception&)
{
}
}
int main()

View File

@ -1,6 +1,6 @@
// 2001-05-21 Benjamin Kosnik <bkoz@redhat.com>
// Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@ -22,7 +22,6 @@
#include <fstream>
#include <locale>
#include <testsuite_hooks.h>
const char name_07[] = "filebuf_virtuals-7.txt"; // empty file, need to create
@ -51,7 +50,6 @@ protected:
void test13()
{
using namespace std;
bool test __attribute__((unused)) = true;
locale loc = locale::classic();
loc = locale(loc, new errorcvt);
@ -59,10 +57,16 @@ void test13()
filebuf fbuf1;
fbuf1.pubimbue(loc);
fbuf1.open(name_07, ios_base::out | ios_base::trunc);
fbuf1.sputn("ison", 4);
int r = fbuf1.pubsync();
VERIFY( r == -1 );
fbuf1.close();
try
{
fbuf1.sputn("ison", 4);
fbuf1.pubsync();
fbuf1.close();
}
catch (exception&)
{
}
}
int main()