public inbox for gcc-prs@sourceware.org
help / color / mirror / Atom feed
* libstdc++/9371: Bad exception handling in i/ostream::operator>>/<<(streambuf*)
@ 2003-01-20 10:46 peturr02
  0 siblings, 0 replies; only message in thread
From: peturr02 @ 2003-01-20 10:46 UTC (permalink / raw)
  To: gcc-gnats


>Number:         9371
>Category:       libstdc++
>Synopsis:       Bad exception handling in i/ostream::operator>>/<<(streambuf*)
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    unassigned
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Jan 20 10:46:00 UTC 2003
>Closed-Date:
>Last-Modified:
>Originator:     peturr02@ru.is
>Release:        gcc-3.2.1
>Organization:
>Environment:
Red Hat Linux 8.0
>Description:
basic_istream<>::operator>>(basic_streambuf<>* sb) and basic_ostream<>::operator<<(basic_streambuf<>* sb) don't handle exceptions that occur during I/O correctly.

1. Exceptions thrown during I/O cause failbit to be set in rdstate(), not badbit.

2. The exception is not rethrown if badbit but not failbit is set in exceptions(). If failbit is set in exceptions(), an ios_base::failure is thrown.

3. PR9370 mostly applies to these functions also.
>How-To-Repeat:
See attachment.
>Fix:

>Release-Note:
>Audit-Trail:
>Unformatted:
----gnatsweb-attachment----
Content-Type: text/plain; name="streambufiobug.cc"
Content-Disposition: inline; filename="streambufiobug.cc"

#include <istream>
#include <ostream>
#include <streambuf>
#include <sstream>
#include <stdexcept>

using namespace std;

#undef NDEBUG
#include <cassert>

void test1()
{
  ostringstream stream;
  stream << static_cast<streambuf*>(NULL);
  assert(stream.rdstate() & ios_base::badbit);
}

void test2()
{
  istringstream stream;
  stream >> static_cast<streambuf*>(NULL);
  assert(stream.rdstate() & ios_base::failbit);
}

void test3()
{
  ostringstream stream;
  stream.exceptions(ios_base::badbit);
	
  try
    {
      stream << static_cast<streambuf*>(NULL);
      assert(false);
    }
  catch (ios_base::failure&)
    {
    }

  assert(stream.rdstate() & ios_base::badbit);
}

void test4()
{
  istringstream stream;
  stream.exceptions(ios_base::failbit);

  try
    {
      stream >> static_cast<streambuf*>(NULL);
      assert(false);
    }
  catch (ios_base::failure&)
    {
    }

  assert(stream.rdstate() & ios_base::failbit);
}

class Badoutbuf : public streambuf
{
  virtual int_type overflow(int_type)
  {
    throw std::runtime_error("");
  }
};

class Badinbuf : public streambuf
{
public:
  Badinbuf()
  {
    static char p[] = "s";
    setg(p, p, p + 1);
  }

  virtual int_type underflow()
  {
    throw std::runtime_error("");
  }
};

void test5()
{
  Badoutbuf bob;
  ostream stream (&bob);
  stringbuf sbuf ("Foo, bar, qux", ios_base::in);

  stream << &sbuf;

  assert(stream.rdstate() & ios_base::badbit);
  assert((stream.rdstate() & ios_base::failbit) == 0);
}

void test6()
{
  Badinbuf bib;
  istream stream (&bib);
  stringbuf sbuf ("", ios_base::out);

  stream >> &sbuf;

  assert(stream.rdstate() & ios_base::badbit);
  assert((stream.rdstate() & ios_base::failbit) == 0);
}

void test7()
{
  ostringstream stream;
  Badinbuf bib;

  stream << &bib;

  assert(stream.rdstate() & ios_base::failbit);
  assert((stream.rdstate() & ios_base::badbit) == 0);
}

void test8()
{
  istringstream stream ("foo, bar, qux");
  Badoutbuf bob;

  stream >> &bob;

  assert(stream.rdstate() & ios_base::failbit);
  assert((stream.rdstate() & ios_base::badbit) == 0);
}

void test9()
{
  Badoutbuf bob;
  ostream stream (&bob);
  stream.exceptions(ios_base::failbit);
  stringbuf sbuf ("Foo, bar, qux", ios_base::in);

  try
    {
      stream << &sbuf;
    }
  catch (ios_base::failure&)
    {
      assert(false);
    }

  assert(stream.rdstate() & ios_base::badbit);
  assert((stream.rdstate() & ios_base::failbit) == 0);
}

void test10()
{
  Badinbuf bib;
  istream stream (&bib);
  stream.exceptions(ios_base::failbit);
  stringbuf sbuf ("", ios_base::out);

  try
    {
      stream >> &sbuf;
    }
  catch (ios_base::failure&)
    {
      assert(false);
    }

  assert(stream.rdstate() & ios_base::badbit);
  assert((stream.rdstate() & ios_base::failbit) == 0);
}

void test11()
{
  ostringstream stream;
  stream.exceptions(ios_base::failbit);
  Badinbuf bib;

  try
    {
      stream << &bib;
      assert(false);
    }
  catch (ios_base::failure&)
    {
      assert(false);
    }
  catch (out_of_range&)
    {
    }

  assert(stream.rdstate() & ios_base::failbit);
  assert((stream.rdstate() & ios_base::badbit) == 0);
}

void test12()
{
  istringstream stream ("foo, bar, qux");
  stream.exceptions(ios_base::failbit);
  Badoutbuf bob;

  try
    {
      stream >> &bob;
      assert(false);
    }
  catch (ios_base::failure&)
    {
      assert(false);
    }
  catch (out_of_range&)
    {
    }

  assert(stream.rdstate() & ios_base::failbit);
  assert((stream.rdstate() & ios_base::badbit) == 0);
}

void test13()
{
  Badoutbuf bob;
  ostream stream (&bob);
  stream.exceptions(ios_base::badbit);
  stringbuf sbuf ("Foo, bar, qux", ios_base::in);

  try
    {
      stream << &sbuf;
      assert(false);
    }
  catch (ios_base::failure&)
    {
      assert(false);
    }
  catch (out_of_range&)
    {
    }

  assert(stream.rdstate() & ios_base::badbit);
  assert((stream.rdstate() & ios_base::failbit) == 0);
}

void test14()
{
  Badinbuf bib;
  istream stream (&bib);
  stream.exceptions(ios_base::badbit);
  stringbuf sbuf ("", ios_base::out);

  try
    {
      stream >> &sbuf;
      assert(false);
    }
  catch (ios_base::failure&)
    {
      assert(false);
    }
  catch (out_of_range&)
    {
    }

  assert(stream.rdstate() & ios_base::badbit);
  assert((stream.rdstate() & ios_base::failbit) == 0);
}

void test15()
{
  ostringstream stream;
  stream.exceptions(ios_base::badbit);
  Badinbuf bib;

  try
    {
      stream << &bib;
    }
  catch (ios_base::failure&)
    {
      assert(false);
    }
  catch (out_of_range&)
    {
      assert(false);
    }

  assert(stream.rdstate() & ios_base::failbit);
  assert((stream.rdstate() & ios_base::badbit) == 0);
}

void test16()
{
  istringstream stream ("foo, bar, qux");
  stream.exceptions(ios_base::badbit);
  Badoutbuf bob;

  try
    {
      stream >> &bob;
    }
  catch (ios_base::failure&)
    {
      assert(false);
    }
  catch (out_of_range&)
    {
      assert(false);
    }

  assert(stream.rdstate() & ios_base::failbit);
  assert((stream.rdstate() & ios_base::badbit) == 0);
}

int main()
{
  test1();
  test2();
  test3();
  test4();
  test5();
  test6();
  test7();
  test8();
  test9();
  test10();
  test11();
  test12();
  test13();
  test14();
  test15();
  test16();

  return 0;
}


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2003-01-20 10:46 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-01-20 10:46 libstdc++/9371: Bad exception handling in i/ostream::operator>>/<<(streambuf*) peturr02

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).