public inbox for gcc-prs@sourceware.org
help / color / mirror / Atom feed
From: peturr02@ru.is
To: gcc-gnats@gcc.gnu.org
Subject: libstdc++/9371: Bad exception handling in i/ostream::operator>>/<<(streambuf*)
Date: Mon, 20 Jan 2003 10:46:00 -0000	[thread overview]
Message-ID: <20030120104126.19796.qmail@sources.redhat.com> (raw)


>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;
}


                 reply	other threads:[~2003-01-20 10:46 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20030120104126.19796.qmail@sources.redhat.com \
    --to=peturr02@ru.is \
    --cc=gcc-gnats@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).