From: Tim-Philipp Müller Date: Mon, 10 Oct 2011 17:28:11 +0000 (+0100) Subject: splitfilesrc: check bytes actually read, just in case X-Git-Tag: 1.19.3~509^2~7136^2~220 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e6c4979a424af1e3bf6ac44c1a99677400f2464c;p=platform%2Fupstream%2Fgstreamer.git splitfilesrc: check bytes actually read, just in case Handle corner case where we try to read beyond the end of the last file part, in which case we want to return a short read. If we get fewer bytes than expected for any other file part, we should just error out, since something fishy's going on then. --- diff --git a/gst/multifile/gstsplitfilesrc.c b/gst/multifile/gstsplitfilesrc.c index 35559fa..3fcdf07 100644 --- a/gst/multifile/gstsplitfilesrc.c +++ b/gst/multifile/gstsplitfilesrc.c @@ -499,7 +499,6 @@ gst_split_file_src_create (GstBaseSrc * basesrc, guint64 offset, guint size, buf = gst_buffer_new_and_alloc (size); GST_BUFFER_OFFSET (buf) = offset; - GST_BUFFER_OFFSET_END (buf) = offset + size; data = GST_BUFFER_DATA (buf); @@ -507,6 +506,7 @@ gst_split_file_src_create (GstBaseSrc * basesrc, guint64 offset, guint size, while (size > 0) { guint64 bytes_to_end_of_part; + gsize read = 0; /* we want the offset into the file part */ read_offset = offset - cur_part.start; @@ -530,14 +530,14 @@ gst_split_file_src_create (GstBaseSrc * basesrc, guint64 offset, guint size, stream = G_INPUT_STREAM (cur_part.stream); /* NB: we won't try to read beyond EOF */ - if (!g_input_stream_read_all (stream, data, to_read, NULL, cancel, &err)) + if (!g_input_stream_read_all (stream, data, to_read, &read, cancel, &err)) goto read_failed; - GST_LOG_OBJECT (src, "read %u bytes", to_read); + GST_LOG_OBJECT (src, "read %u bytes", (guint) read); - data += to_read; - size -= to_read; - offset += to_read; + data += read; + size -= read; + offset += read; /* are we done? */ if (size == 0) @@ -545,15 +545,24 @@ gst_split_file_src_create (GstBaseSrc * basesrc, guint64 offset, guint size, GST_LOG_OBJECT (src, "%u bytes left to read for this chunk", size); - if (src->cur_part == src->num_parts - 1) { - /* FIXME: at end, need to truncate buffer */ - break; + /* corner case, this should never really happen (assuming basesrc clips + * requests beyond the file size) */ + if (read < to_read) { + if (src->cur_part == src->num_parts - 1) { + /* last file part, stop reading and truncate buffer */ + GST_BUFFER_SIZE (buf) = offset - GST_BUFFER_OFFSET (buf); + break; + } else { + goto file_part_changed; + } } ++src->cur_part; cur_part = src->parts[src->cur_part]; } + GST_BUFFER_OFFSET_END (buf) = offset; + *buffer = buf; GST_LOG_OBJECT (src, "read %u bytes into buf %p", GST_BUFFER_SIZE (buf), buf); return GST_FLOW_OK; @@ -583,6 +592,14 @@ read_failed: gst_buffer_unref (buf); return GST_FLOW_ERROR; } +file_part_changed: + { + GST_ELEMENT_ERROR (src, RESOURCE, READ, + ("Read error while reading file part %s", cur_part.path), + ("Short read in file part, file may have been modified since start")); + gst_buffer_unref (buf); + return GST_FLOW_ERROR; + } cancelled: { GST_DEBUG_OBJECT (src, "I/O operation cancelled from another thread");