diff options
author | wm4 <wm4@nowhere> | 2014-01-14 17:38:21 +0100 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2014-01-14 17:38:21 +0100 |
commit | 3c2f93aec850b279d47ccbb02f30f129a458d6c6 (patch) | |
tree | 753622983962b50dbd9815e88b8d3dd9ce1bb7d1 /demux/ebml.h | |
parent | ae27e13a0a0d0d69ca3e91ade710ded5208f4fc6 (diff) | |
download | mpv-3c2f93aec850b279d47ccbb02f30f129a458d6c6.tar.bz2 mpv-3c2f93aec850b279d47ccbb02f30f129a458d6c6.tar.xz |
demux_mkv: improve robustness by explicitly checking for level 1 elements
Matroska makes it pretty hard to resync correctly on broken files:
random data returns "valid" EBML IDs with a high probability, and when
trying to skip them it's likely that you skip a random amount of data
(instead of considering the element length invalid).
Improve upon this by skipping known level 1 elements only. Consider
everything else invalid and call the resync code. This might result in
annoying behavior when Matroska adds new level 1 elements, although it
won't be particularly harmful. Matroska doesn't really allow us to do
better (even mkvtoolnix explicitly checks for known level 1 elements).
Since we now don't always want to combine EBML element skipping and
resyncing, remove ebml_read_skip_or_resync_cluster(), and make
ebml_read_skip() more tolerant against skipping broken elements.
Also, don't resync when reading sub-elements, and instead do resyncing
when reading them results in an error.
Diffstat (limited to 'demux/ebml.h')
-rw-r--r-- | demux/ebml.h | 5 |
1 files changed, 2 insertions, 3 deletions
diff --git a/demux/ebml.h b/demux/ebml.h index 2259563340..b934ee5c34 100644 --- a/demux/ebml.h +++ b/demux/ebml.h @@ -92,6 +92,7 @@ struct ebml_parse_ctx { #define EBML_FLOAT_INVALID -1000000000.0 +bool ebml_is_mkv_level1_id(uint32_t id); uint32_t ebml_read_id (stream_t *s, int *length); uint64_t ebml_read_vlen_uint (bstr *buffer); int64_t ebml_read_vlen_int (bstr *buffer); @@ -101,9 +102,7 @@ int64_t ebml_read_int (stream_t *s, uint64_t *length); double ebml_read_float (stream_t *s, uint64_t *length); char *ebml_read_ascii (stream_t *s, uint64_t *length); char *ebml_read_utf8 (stream_t *s, uint64_t *length); -int ebml_read_skip (stream_t *s, uint64_t *length); -int ebml_read_skip_or_resync_cluster(struct mp_log *log, int64_t end, - stream_t *s); +int ebml_read_skip(struct mp_log *log, int64_t end, stream_t *s); int ebml_resync_cluster(struct mp_log *log, stream_t *s); uint32_t ebml_read_master (stream_t *s, uint64_t *length); |