giochannel: Clarify assertions in g_io_channel_write_chars()

How the assertions handled the case of `buf != NULL && count == -1` and
`buf == NULL && count == -1` were a bit fragile.

In the former case, the `strlen (buf)` was assigned to `count`, which is
signed. If, somehow, `buf` was huge, `count` would end up wrapping
around to a negative number. Avoid that by assigning directly to
`count_unsigned`.

In the latter case, `count_unsigned` would be set to `-1` which would
wrap around. The error would then be caught by the precondition on `buf
!= NULL`, but it seems like that could have been a happy accident rather
than something intentional. Change it to an explicit precondition which
only allows `buf == NULL` iff `count == 0`.

Spotted while reading through static analysis issues, although the
analyser didn’t explicitly flag this up as an issue.

Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
This commit is contained in:
Philip Withnall 2022-11-18 16:18:55 +00:00
parent c1a4aca743
commit a937c8ac5a

View File

@ -2208,13 +2208,15 @@ g_io_channel_write_chars (GIOChannel *channel,
gssize wrote_bytes = 0;
g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR);
g_return_val_if_fail (buf != NULL || count == 0, G_IO_STATUS_ERROR);
g_return_val_if_fail ((error == NULL) || (*error == NULL),
G_IO_STATUS_ERROR);
g_return_val_if_fail (channel->is_writeable, G_IO_STATUS_ERROR);
if ((count < 0) && buf)
count = strlen (buf);
count_unsigned = count;
if (count < 0)
count_unsigned = strlen (buf);
else
count_unsigned = count;
if (count_unsigned == 0)
{
@ -2223,8 +2225,7 @@ g_io_channel_write_chars (GIOChannel *channel,
return G_IO_STATUS_NORMAL;
}
g_return_val_if_fail (buf != NULL, G_IO_STATUS_ERROR);
g_return_val_if_fail (count_unsigned > 0, G_IO_STATUS_ERROR);
g_assert (count_unsigned > 0);
/* Raw write case */