This is the mail archive of the
glibc-bugs@sourceware.org
mailing list for the glibc project.
[Bug stdio/20181] New: open_memstream(): writes not at end of stream corrupt data
- From: "glibc at achurch dot org" <sourceware-bugzilla at sourceware dot org>
- To: glibc-bugs at sourceware dot org
- Date: Mon, 30 May 2016 19:05:26 +0000
- Subject: [Bug stdio/20181] New: open_memstream(): writes not at end of stream corrupt data
- Auto-submitted: auto-generated
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.