mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 12:11:13 +00:00
oggdemux: fix quadratic search for last page
A crafted file with invalid pages will cause repeated searches from earlier offsets in steps of 8500 bytes, but reading till the end of the stream. Since we know the maximum size of an Ogg page, we can bound the search for next page, to get a linear behavior (though still not good enough as it will read the entire file backwards if there's no valid page till then).
This commit is contained in:
parent
ecb22ebd63
commit
492341db77
1 changed files with 15 additions and 3 deletions
|
@ -56,6 +56,10 @@
|
||||||
/* stop duration checks within this much of EOS */
|
/* stop duration checks within this much of EOS */
|
||||||
#define EOS_AVOIDANCE_THRESHOLD 8192
|
#define EOS_AVOIDANCE_THRESHOLD 8192
|
||||||
|
|
||||||
|
/* An Ogg page can not be larger than 255 segments of 255 bytes, plus
|
||||||
|
26 bytes of header */
|
||||||
|
#define MAX_OGG_PAGE_SIZE (255 * 255 + 26)
|
||||||
|
|
||||||
#define GST_FLOW_LIMIT GST_FLOW_CUSTOM_ERROR
|
#define GST_FLOW_LIMIT GST_FLOW_CUSTOM_ERROR
|
||||||
#define GST_FLOW_SKIP_PUSH GST_FLOW_CUSTOM_SUCCESS_1
|
#define GST_FLOW_SKIP_PUSH GST_FLOW_CUSTOM_SUCCESS_1
|
||||||
|
|
||||||
|
@ -2397,10 +2401,18 @@ gst_ogg_demux_get_prev_page (GstOggDemux * ogg, ogg_page * og, gint64 * offset)
|
||||||
* start, we save it. It might not be the final page as there could be
|
* start, we save it. It might not be the final page as there could be
|
||||||
* another page after this one. */
|
* another page after this one. */
|
||||||
while (ogg->offset < end) {
|
while (ogg->offset < end) {
|
||||||
gint64 new_offset;
|
gint64 new_offset, boundary;
|
||||||
|
|
||||||
ret =
|
/* An Ogg page cannot be more than a bit less than 64 KB, so we can
|
||||||
gst_ogg_demux_get_next_page (ogg, og, end - ogg->offset, &new_offset);
|
bound the boundary to that size when searching backwards if we
|
||||||
|
haven't found a page yet. So the most we have to look at is twice
|
||||||
|
the max page size, which is the worst case if we start scanning
|
||||||
|
just after a large page, after which also lies a large page. */
|
||||||
|
boundary = end - ogg->offset;
|
||||||
|
if (boundary > 2 * MAX_OGG_PAGE_SIZE)
|
||||||
|
boundary = 2 * MAX_OGG_PAGE_SIZE;
|
||||||
|
|
||||||
|
ret = gst_ogg_demux_get_next_page (ogg, og, boundary, &new_offset);
|
||||||
/* we hit the upper limit, offset contains the last page start */
|
/* we hit the upper limit, offset contains the last page start */
|
||||||
if (ret == GST_FLOW_LIMIT) {
|
if (ret == GST_FLOW_LIMIT) {
|
||||||
GST_LOG_OBJECT (ogg, "hit limit");
|
GST_LOG_OBJECT (ogg, "hit limit");
|
||||||
|
|
Loading…
Reference in a new issue