[llvm-bugs] [Bug 49938] New: Swapping a filebuf with a small buffer (or disabled buffering) discards characters

via llvm-bugs llvm-bugs at lists.llvm.org
Mon Apr 12 11:58:10 PDT 2021


https://bugs.llvm.org/show_bug.cgi?id=49938

            Bug ID: 49938
           Summary: Swapping a filebuf with a small buffer (or disabled
                    buffering) discards characters
           Product: libc++
           Version: 11.0
          Hardware: All
                OS: All
            Status: NEW
          Severity: normal
          Priority: P
         Component: All Bugs
          Assignee: unassignedclangbugs at nondot.org
          Reporter: alex at grundis.de
                CC: llvm-bugs at lists.llvm.org, mclow.lists at gmail.com

When a filebuf with a small buffer size is used, then the internal buffer
`__extbuf_min_` is used instead:
https://github.com/llvm/llvm-project/blob/82e537a9d28a2c18bd1637e2eac0e0af658ed829/libcxx/include/fstream#L896

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
https://github.com/llvm/llvm-project/blob/82e537a9d28a2c18bd1637e2eac0e0af658ed829/libcxx/include/fstream#L432-L436

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!

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20210412/b39fcd9e/attachment.html>


More information about the llvm-bugs mailing list