summaryrefslogtreecommitdiff
path: root/libavformat/3dostr.c
diff options
context:
space:
mode:
authorPaul B Mahol <onemda@gmail.com>2020-09-17 23:19:18 +0200
committerPaul B Mahol <onemda@gmail.com>2020-09-17 23:47:10 +0200
commit3ac45bf66561a667260cac37223c0393f7333fca (patch)
treee7a2c7733d0d4c2030f1d833f00288be31d61303 /libavformat/3dostr.c
parentfe3a57f4caa221111cd0e42fe17302e0a21ca302 (diff)
downloadffmpeg-3ac45bf66561a667260cac37223c0393f7333fca.tar.gz
avformat/3dostr: make probing more robust
Diffstat (limited to 'libavformat/3dostr.c')
-rw-r--r--libavformat/3dostr.c50
1 files changed, 45 insertions, 5 deletions
diff --git a/libavformat/3dostr.c b/libavformat/3dostr.c
index 3ec3c4393e..2d92b46570 100644
--- a/libavformat/3dostr.c
+++ b/libavformat/3dostr.c
@@ -19,17 +19,57 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "libavutil/intreadwrite.h"
#include "avformat.h"
#include "internal.h"
static int threedostr_probe(const AVProbeData *p)
{
- if (memcmp(p->buf, "CTRL", 4) &&
- memcmp(p->buf, "SHDR", 4) &&
- memcmp(p->buf, "SNDS", 4))
- return 0;
+ for (int i = 0; i < p->buf_size;) {
+ unsigned chunk = AV_RL32(p->buf + i);
+ unsigned size = AV_RB32(p->buf + i + 4);
- return AVPROBE_SCORE_MAX / 3 * 2;
+ i += 8;
+ if (size < 8 || p->buf_size - i < size)
+ return 0;
+
+ size -= 8;
+ switch (chunk) {
+ case MKTAG('C','T','R','L'):
+ break;
+ case MKTAG('S','N','D','S'):
+ if (size < 56)
+ return 0;
+ i += 8;
+ if (AV_RL32(p->buf + i) != MKTAG('S','H','D','R'))
+ return 0;
+ i += 28;
+
+ if (AV_RB32(p->buf + i) <= 0)
+ return 0;
+ i += 4;
+ if (AV_RB32(p->buf + i) <= 0)
+ return 0;
+ i += 4;
+ if (AV_RL32(p->buf + i) == MKTAG('S','D','X','2'))
+ return AVPROBE_SCORE_MAX;
+ else
+ return 0;
+ break;
+ case MKTAG('S','H','D','R'):
+ if (size > 0x78) {
+ i += 0x78;
+ size -= 0x78;
+ }
+ break;
+ default:
+ break;
+ }
+
+ i += size;
+ }
+
+ return 0;
}
static int threedostr_read_header(AVFormatContext *s)