GInputStream docs could use some clarity on app buffer usage
The crux of the confusion is:
"Can the g_input_stream_read family of functions write content past bytes_read
into the application buffer?"
A concrete example:
- I made a buffer filled with zeros and one extra byte (using
g_new0
) - I asked libsoup to provide a GInputStream and called
read_all_async()
with my zero-buffer. - I interpreted the GInputStream docs as saying nothing past
bytes_read
would be touched and thusbuffer[bytes_read]
would still be zero, and I could safely treat buffer as a null-terminated string without zeroing outbuffer[bytes_read]
again.
But it turns out that libsoup is apparently using the provided buffer as a scratch buffer for gzip decompression and there was some dangling data after the actual contents (like the next 12 bytes or so after bytes_read). So when I read the buffer as a zero terminated string, I got that extra garbage too. (I haven’t dug too far into this - not 100% it’s libsoup’s doing this yet - but I do believe it’s not writing past the provided space - I think it’s just trying to avoid allocating its own scratch buffer).
What the docs say now
On success, the number of bytes read into the buffer is returned
The returned buffer is not a nul-terminated string, it can contain nul bytes at any position, and this function doesn’t nul-terminate the buffer.
bytes_read is set to the number of bytes read into buffer
Request for clarity
Maybe add something to those docs saying something about the whole buffer space being up for grabs by the read
functions, and bytes_read
is merely the end of the app-usable content.
(Or, clarify that the rest of the buffer will not be touched, and then libsoup ought to be adjusted too.)
I was talking with another engineer about this and we came to different conclusions about what promises the docs made around this - so regardless of the correct behavior, I think the docs could use some removal-of-all-doubt language.