<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - stream sentry leaks exceptions"
   href="https://bugs.llvm.org/show_bug.cgi?id=48912">48912</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>stream sentry leaks exceptions
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>libc++
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>11.0
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Windows NT
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>enhancement
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>All Bugs
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>lavr@ncbi.nlm.nih.gov
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org, mclow.lists@gmail.com
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Created <span class=""><a href="attachment.cgi?id=24429" name="attach_24429" title="test case">attachment 24429</a> <a href="attachment.cgi?id=24429&action=edit" title="test case">[details]</a></span>
test case

Since basic_[io]stream::sentry gets constructed outside the try/catch blocks in
most (if not all) I/O methods, and, in case of istream::sentry, does not have a
try/catch block on its own (in the ctor), it lets the lower-level exceptions
leak to the user code.

Consider an istream doing a string input, with "is >> str".

If white space is skipped (as it usually is the case), then there's some I/O
occurring within the sentry ctor.  If that I/O (stream buffer operation) causes
the streambuf to throw, the exception is not caught, as it should at the
"operator>>" level, but gets leaked out.  Also, "badbit" is not set (as the
standard mandates), and the stream data integrity is, thus, compromised.

This bug is both in versions 10 and 11 of libc++.

Attached is the simple code that demonstrates the issue.

When built with clang++, it produces:

<span class="quote">> clang++ test.cpp
> ./a.out</span >
caught
0

which basically shows there was an exception and the stream is in "good" state.

When built with a standard-conforming implementation, the output is this:

<span class="quote">> ./a.out</span >
5

Note: 5 = 1(badbit) + 4(failbit).  That is the correct behavior of this
extraction operation.</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>