[PATCH 09/14] Cleanup: dc_buffer_clear() should be a void function
Jef Driesen
jef at libdivecomputer.org
Thu Jan 4 05:53:26 PST 2018
On 2018-01-03 20:35, Dirk Hohndel wrote:
> We sometimes ignored its return value, sometimes we didn't.
> Semantically, clearing a non-existing buffer is just a noop.
>
> Careful - one side effect of the old semantic was that
> dc_buffer_clear()
> plus a bail on failure could be used to test if the buffer had been
> allocated. Right now there is at least one call site where we later
> call
> dc_buffer_apend() without checking its return value. This will be fixed
> in a later commit in this series.
Hmm, that's something I didn't think of. And there are two other
potential side effects as well, that could cause us some trouble.
Before this patch, passing a NULL pointer would be detected immediately,
before sending anything to the dive computer. After this patch, there
are a few cases where the check is delayed. So that means we send some
request to the dive computer, but might bail out before reading the
response (or only a part of it). And that can easily cause a next
request to fail as well, because the response data (or a part of it)
remains in the driver or OS buffers.
For errors that we can detect early, like a NULL buffer, we should bail
out as soon as possible. So instead of removing the dc_buffer_clear()
based check, and postponing the check to some other buffer function
further down, we should check it explicitly at the start of the
function:
if (buffer == NULL) {
ERROR (context, "No buffer space available.");
return DC_STATUS_INVALIDARGS;
}
(Note that I also replaced DC_STATUS_NOMEMORY with DC_STATUS_INVALIDARGS
because that's probably a more suitable error code here.)
For the dump functions, which is the bulk of this patch, we can easily
address all of them at once in the dc_device_dump function:
dc_status_t
dc_device_dump (dc_device_t *device, dc_buffer_t *buffer)
{
if (device == NULL)
return DC_STATUS_UNSUPPORTED;
if (device->vtable->dump == NULL)
return DC_STATUS_UNSUPPORTED;
if (buffer == NULL)
return DC_STATUS_INVALIDARGS;
return device->vtable->dump (device, buffer);
}
Actually, also the dc_buffer_clear() call can be moved there. We always
want to start with an empty buffer.
Another concern is that the dc_buffer_clear() function is part of the
public api. So this change might break some applications. I don't mind
doing this particular change, because it makes sense. But at the same
time we also need to be careful that a simple fix to silence coverity
doesn't turns into a problem for applications. (I don't think there are
many applications using this function, but I don't know for sure.)
Jef
More information about the devel
mailing list