Merge branch '587-seek-behaviour' into 'master'

ginputstream: Don’t skip off the end of resizable streams

Closes #587

See merge request GNOME/glib!1952
This commit is contained in:
Sebastian Dröge 2021-02-16 08:31:06 +00:00
commit 7ec5405c5a
2 changed files with 34 additions and 66 deletions

View File

@ -411,12 +411,41 @@ g_input_stream_real_skip (GInputStream *stream,
if (G_IS_SEEKABLE (stream) && g_seekable_can_seek (G_SEEKABLE (stream)))
{
GSeekable *seekable = G_SEEKABLE (stream);
goffset start, end;
gboolean success;
/* g_seekable_seek() may try to set pending itself */
stream->priv->pending = FALSE;
start = g_seekable_tell (seekable);
if (g_seekable_seek (G_SEEKABLE (stream),
count,
G_SEEK_CUR,
cancellable,
NULL))
return count;
0,
G_SEEK_END,
cancellable,
NULL))
{
end = g_seekable_tell (seekable);
g_assert (end >= start);
if (start > G_MAXSIZE - count || start + count > end)
{
stream->priv->pending = TRUE;
return end - start;
}
success = g_seekable_seek (G_SEEKABLE (stream),
start + count,
G_SEEK_SET,
cancellable,
error);
stream->priv->pending = TRUE;
if (success)
return count;
else
return -1;
}
}
/* If not seekable, or seek failed, fall back to reading data: */

View File

@ -68,10 +68,6 @@ static gssize g_local_file_input_stream_read (GInputStream *strea
gsize count,
GCancellable *cancellable,
GError **error);
static gssize g_local_file_input_stream_skip (GInputStream *stream,
gsize count,
GCancellable *cancellable,
GError **error);
static gboolean g_local_file_input_stream_close (GInputStream *stream,
GCancellable *cancellable,
GError **error);
@ -104,7 +100,6 @@ g_local_file_input_stream_class_init (GLocalFileInputStreamClass *klass)
GFileInputStreamClass *file_stream_class = G_FILE_INPUT_STREAM_CLASS (klass);
stream_class->read_fn = g_local_file_input_stream_read;
stream_class->skip = g_local_file_input_stream_skip;
stream_class->close_fn = g_local_file_input_stream_close;
file_stream_class->tell = g_local_file_input_stream_tell;
file_stream_class->can_seek = g_local_file_input_stream_can_seek;
@ -175,62 +170,6 @@ g_local_file_input_stream_read (GInputStream *stream,
return res;
}
static gssize
g_local_file_input_stream_skip (GInputStream *stream,
gsize count,
GCancellable *cancellable,
GError **error)
{
off_t start, end;
GLocalFileInputStream *file;
file = G_LOCAL_FILE_INPUT_STREAM (stream);
if (g_cancellable_set_error_if_cancelled (cancellable, error))
return -1;
start = lseek (file->priv->fd, 0, SEEK_CUR);
if (start == -1)
{
int errsv = errno;
g_set_error (error, G_IO_ERROR,
g_io_error_from_errno (errsv),
_("Error seeking in file: %s"),
g_strerror (errsv));
return -1;
}
end = lseek (file->priv->fd, 0, SEEK_END);
if (end == -1)
{
int errsv = errno;
g_set_error (error, G_IO_ERROR,
g_io_error_from_errno (errsv),
_("Error seeking in file: %s"),
g_strerror (errsv));
return -1;
}
if (end - start > count)
{
end = lseek (file->priv->fd, count - (end - start), SEEK_CUR);
if (end == -1)
{
int errsv = errno;
g_set_error (error, G_IO_ERROR,
g_io_error_from_errno (errsv),
_("Error seeking in file: %s"),
g_strerror (errsv));
return -1;
}
}
return end - start;
}
static gboolean
g_local_file_input_stream_close (GInputStream *stream,
GCancellable *cancellable,