<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 - Swapping a filebuf with a small buffer (or disabled buffering) discards characters"
   href="https://bugs.llvm.org/show_bug.cgi?id=49938">49938</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Swapping a filebuf with a small buffer (or disabled buffering) discards characters
          </td>
        </tr>

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

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

        <tr>
          <th>Hardware</th>
          <td>All
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>All
          </td>
        </tr>

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

        <tr>
          <th>Severity</th>
          <td>normal
          </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>alex@grundis.de
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org, mclow.lists@gmail.com
          </td>
        </tr></table>
      <p>
        <div>
        <pre>When a filebuf with a small buffer size is used, then the internal buffer
`__extbuf_min_` is used instead:
<a href="https://github.com/llvm/llvm-project/blob/82e537a9d28a2c18bd1637e2eac0e0af658ed829/libcxx/include/fstream#L896">https://github.com/llvm/llvm-project/blob/82e537a9d28a2c18bd1637e2eac0e0af658ed829/libcxx/include/fstream#L896</a>

This buffer may be filled by (e.g.) read operations. When the filebuf is then
swapped with another filebuf, the contents of this buffer will be ignored and
the swapped-to filebuf will use its own, unfilled internal buffer instead. See
<a href="https://github.com/llvm/llvm-project/blob/82e537a9d28a2c18bd1637e2eac0e0af658ed829/libcxx/include/fstream#L432-L436">https://github.com/llvm/llvm-project/blob/82e537a9d28a2c18bd1637e2eac0e0af658ed829/libcxx/include/fstream#L432-L436</a>

Example code triggering the bug:

        std::filebuf buf1, buf2;
        buf1.pubsetbuf(0, 0);
        assert(buf1.open(filepath, std::ios_base::in) == &buf1);
        assert(buf2.open(filepath2, std::ios_base::in) == &buf2);
        // Peek
        assert(buf1.sgetc() == 'B');
        assert(buf2.sgetc() == 'H');
        swap(buf1, buf2);
        assert(buf2.sgetc() == 'B'); // Boom!</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>