This is the mail archive of the glibc-bugs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug stdio/20181] New: open_memstream(): writes not at end of stream corrupt data


https://sourceware.org/bugzilla/show_bug.cgi?id=20181

            Bug ID: 20181
           Summary: open_memstream(): writes not at end of stream corrupt
                    data
           Product: glibc
           Version: unspecified
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: stdio
          Assignee: unassigned at sourceware dot org
          Reporter: glibc at achurch dot org
  Target Milestone: ---

Memory buffers opened with open_memstream() (and open_wmemstream()) corrupt one
byte of data on flush after write if the current write position is not at the
end of the stream.

The bug is in _IO_[w]mem_sync(), which blindly writes a null byte (or wchar) to
the buffer whether or not the current write position is at the end of the
buffer.  This appears to contravene POSIX, which says: "If a write moves the
position to a value larger than the current length, the current length shall be
set to this position. *In this case* a null character for open_memstream() or a
null wide character for open_wmemstream() shall be appended to the current
buffer." (emphasis added)

The fix is to remove the "else *fp->_IO_write_ptr = '\0'" clause
(libio/memstream.c:115-116 and libio/wmemstream.c:115-116 in current git).

Simple testcase:

char *buf;
size_t size;
FILE *f;
assert(f = open_memstream(&buf, &size));
assert(fwrite("abc", 1, 3, f) == 3);
assert(fseek(f, 0, SEEK_SET) == 0);
assert(fwrite("z", 1, 1, f) == 1);
assert(fflush(f) == 0);  // Clobbers the "b".
assert(fseek(f, 3, SEEK_SET) == 0);  // Avoid truncating the buffer on close.
assert(fclose(f) == 0);
assert(size == 3);
assert(buf[0] == 'z');
assert(buf[1] == 'b');  // Fails (clobbered by null byte).
assert(buf[2] == 'c');

-- 
You are receiving this mail because:
You are on the CC list for the bug.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]