From 9e961e68ef73da39e141b0f08b088a649c15751e Mon Sep 17 00:00:00 2001 From: Minje Ahn Date: Thu, 21 Jun 2018 15:22:22 +0900 Subject: [PATCH] Imported Upstream version 12.3 --- Changelog | 37 ++++++++++++++++ README | 1 - RELEASE | 2 +- VERSION | 2 +- avconv.c | 37 +++++++++++----- cmdutils.c | 2 +- configure | 23 ++++++---- libavcodec/arm/h264idct_neon.S | 20 +++++---- libavcodec/dfa.c | 4 +- libavcodec/dvbsubdec.c | 17 +++++--- libavcodec/h264_cabac.c | 63 ++++++++++++++++++---------- libavcodec/h264_cavlc.c | 16 +++---- libavcodec/h264_direct.c | 4 +- libavcodec/h264_mb.c | 7 +++- libavcodec/h264_slice.c | 6 ++- libavcodec/h264dec.c | 1 + libavcodec/h264dec.h | 3 +- libavcodec/h264pred.c | 2 + libavcodec/h264pred.h | 3 ++ libavcodec/h264pred_template.c | 73 ++++++++++++++++++++++++++++++++ libavcodec/mpegvideo_motion.c | 19 ++++----- libavcodec/pictordec.c | 2 +- libavcodec/smacker.c | 28 ++++++++++--- libavcodec/vc1_mc.c | 5 +++ libavcodec/vc1dec.c | 4 +- libavfilter/vf_yadif.c | 28 +++++++++---- libavformat/caf.c | 1 + libavformat/cafdec.c | 8 ++++ libavformat/matroskadec.c | 2 +- libavformat/mov.c | 34 ++++++++++----- libavformat/rmdec.c | 22 +++++++--- libavformat/rtmpdh.c | 95 ++++++++++++++++++++---------------------- libavformat/rtmpdh.h | 14 +++---- libavformat/smacker.c | 15 ++++--- libavformat/tls_openssl.c | 37 +++++++++++++++- library.mak | 2 +- 36 files changed, 458 insertions(+), 181 deletions(-) delete mode 120000 README diff --git a/Changelog b/Changelog index 1a314e7..6b77e9d 100644 --- a/Changelog +++ b/Changelog @@ -1,6 +1,43 @@ Entries are sorted chronologically from oldest to youngest within each release, releases are sorted from youngest to oldest. +version 12.3: + + - pictor: Correctly check frame dimension (CVE-2017-7862) + - smacker: add sanity check for length in smacker_decode_tree() (CVE-2017-16803) + - smacker: limit recursion depth of smacker_decode_bigtree + - cmdutils: update copyright year to 2018 + - matroskadec: allow RealAudio/Cook/Sipro streams of flavor 0 (bug/1055) + - avconv: only retry decoding on actual decoding errors (bug/1089) + - vc1: skip motion compensation when data for last picture is invalid (bug/1101) + - avcodec/vc1dec: fix mby_start for interlaced content (bug/1100) + +version 12.2: + + - mpegvideo_motion: Handle edge emulation even without unrestricted_mv (bug/962, bug/1060) + - smacker: Check that the data size is a multiple of a sample vector (CVE-2015-8365) + - build: Add an option for passing linker flags to the shared library build + - configure: Simplify and fix libxcb check + - openssl: Support version 1.1.0. + - rtmpdh: Don't use the OpenSSL DH struct + - dvbsubdec: Fixed segfault when decoding subtitles + - doc: Drop the legacy symlink to README + - dfa: Disallow odd width/height and add proper bounds check for DDS1 chunks (CVE-2017-9992) + - rmdec: don't ignore the return value of av_get_packet() + - caf: add an Opus tag + - h264dec: Fix mix of lossless and lossy MBs decoding + - h264_cabac: Fix CABAC+8x8dct in 4:4:4 + - h264dec: fix Lossless Decoding (Profile 244) for 8x8 Intra Prediction + - h264dec: track the last seen value of x264_build + - h264dec: use a large enough field for reference list modification values + - yadif: Account for the buffer alignment while processing the frame edges (bug/1031) + - mov: log and return early on non-positive stsd entry counts + - mov: Do not set stsd_count if mov_read_stsd() fails + - mov: move stsd finalization to an appropriate place (bug/1072) + - arm: Fix SIGBUS on ARM when compiled with binutils 2.29 + - smacker: return meaningful error codes on failure + - smacker: fix integer overflow with pts_inc (bug/1073) + version 12.1: - vaapi_h264: fix RefPicList[] field flags. diff --git a/README b/README deleted file mode 120000 index 42061c0..0000000 --- a/README +++ /dev/null @@ -1 +0,0 @@ -README.md \ No newline at end of file diff --git a/RELEASE b/RELEASE index 40e6bd9..556633d 100644 --- a/RELEASE +++ b/RELEASE @@ -1 +1 @@ -12.1 +12.3 diff --git a/VERSION b/VERSION index 40e6bd9..556633d 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -12.1 +12.3 diff --git a/avconv.c b/avconv.c index b2affe9..610ec9e 100644 --- a/avconv.c +++ b/avconv.c @@ -1326,7 +1326,8 @@ int guess_input_channel_layout(InputStream *ist) return 1; } -static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output) +static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output, + int *decode_failed) { AVFrame *decoded_frame, *f; AVCodecContext *avctx = ist->dec_ctx; @@ -1339,6 +1340,8 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output) decoded_frame = ist->decoded_frame; ret = decode(avctx, decoded_frame, got_output, pkt); + if (ret < 0) + *decode_failed = 1; if (!*got_output || ret < 0) return ret; @@ -1377,7 +1380,8 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output) return err < 0 ? err : ret; } -static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output) +static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output, + int *decode_failed) { AVFrame *decoded_frame, *f; int i, ret = 0, err = 0; @@ -1389,6 +1393,8 @@ static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output) decoded_frame = ist->decoded_frame; ret = decode(ist->dec_ctx, decoded_frame, got_output, pkt); + if (ret < 0) + *decode_failed = 1; if (!*got_output || ret < 0) return ret; @@ -1429,13 +1435,16 @@ fail: return err < 0 ? err : ret; } -static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output) +static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output, + int *decode_failed) { AVSubtitle subtitle; int i, ret = avcodec_decode_subtitle2(ist->dec_ctx, &subtitle, got_output, pkt); - if (ret < 0) + if (ret < 0) { + *decode_failed = 1; return ret; + } if (!*got_output) return ret; @@ -1491,16 +1500,19 @@ static void process_input_packet(InputStream *ist, const AVPacket *pkt, int no_e while (ist->decoding_needed && (!pkt || avpkt.size > 0)) { int ret = 0; int got_output = 0; + int decode_failed = 0; if (!repeating) ist->last_dts = ist->next_dts; switch (ist->dec_ctx->codec_type) { case AVMEDIA_TYPE_AUDIO: - ret = decode_audio (ist, repeating ? NULL : &avpkt, &got_output); + ret = decode_audio (ist, repeating ? NULL : &avpkt, &got_output, + &decode_failed); break; case AVMEDIA_TYPE_VIDEO: - ret = decode_video (ist, repeating ? NULL : &avpkt, &got_output); + ret = decode_video (ist, repeating ? NULL : &avpkt, &got_output, + &decode_failed); if (repeating && !got_output) ; else if (pkt && pkt->duration) @@ -1517,16 +1529,21 @@ static void process_input_packet(InputStream *ist, const AVPacket *pkt, int no_e case AVMEDIA_TYPE_SUBTITLE: if (repeating) break; - ret = transcode_subtitles(ist, &avpkt, &got_output); + ret = transcode_subtitles(ist, &avpkt, &got_output, &decode_failed); break; default: return; } if (ret < 0) { - av_log(NULL, AV_LOG_ERROR, "Error while decoding stream #%d:%d\n", - ist->file_index, ist->st->index); - if (exit_on_error) + if (decode_failed) { + av_log(NULL, AV_LOG_ERROR, "Error while decoding stream #%d:%d\n", + ist->file_index, ist->st->index); + } else { + av_log(NULL, AV_LOG_FATAL, "Error while processing the decoded " + "data for stream #%d:%d\n", ist->file_index, ist->st->index); + } + if (!decode_failed || exit_on_error) exit_program(1); break; } diff --git a/cmdutils.c b/cmdutils.c index b0445eb..65d1fb3 100644 --- a/cmdutils.c +++ b/cmdutils.c @@ -58,7 +58,7 @@ struct SwsContext *sws_opts; AVDictionary *format_opts, *codec_opts, *resample_opts; -static const int this_year = 2017; +static const int this_year = 2018; void init_opts(void) { diff --git a/configure b/configure index 660b062..10a85db 100755 --- a/configure +++ b/configure @@ -277,6 +277,7 @@ Toolchain options: --extra-objcflags=FLAGS add FLAGS to OBJCFLAGS [$CFLAGS] --extra-ldflags=ELDFLAGS add ELDFLAGS to LDFLAGS [$LDFLAGS] --extra-ldexeflags=ELDFLAGS add ELDFLAGS to LDEXEFLAGS [$LDEXEFLAGS] + --extra-ldsoflags=ELDFLAGS add ELDFLAGS to LDSOFLAGS [$LDSOFLAGS] --extra-libs=ELIBS add ELIBS [$ELIBS] --extra-version=STRING version string suffix [] --optflags=OPTFLAGS override optimization-related compiler flags @@ -730,6 +731,10 @@ add_ldexeflags(){ append LDEXEFLAGS $($ldflags_filter "$@") } +add_ldsoflags(){ + append LDSOFLAGS $($ldflags_filter "$@") +} + add_stripflags(){ append STRIPFLAGS "$@" } @@ -2681,6 +2686,9 @@ for opt do --extra-ldexeflags=*) add_ldexeflags $optval ;; + --extra-ldsoflags=*) + add_ldsoflags $optval + ;; --extra-libs=*) add_extralibs $optval ;; @@ -4679,7 +4687,8 @@ enabled omx && { check_header OMX_Core.h || add_cflags -isystem/opt/vc/include/IL ; } check_header OMX_Core.h ; } || die "ERROR: OpenMAX IL headers not found"; } -enabled openssl && { check_pkg_config openssl openssl/ssl.h SSL_library_init && { +enabled openssl && { { check_pkg_config openssl openssl/ssl.h OPENSSL_init_ssl || + check_pkg_config openssl openssl/ssl.h SSL_library_init; } && { add_cflags $openssl_cflags && add_extralibs $openssl_libs; }|| check_lib openssl/ssl.h SSL_library_init -lssl -lcrypto || check_lib openssl/ssl.h SSL_library_init -lssl32 -leay32 || @@ -4761,9 +4770,8 @@ fi check_lib X11/Xlib.h XOpenDisplay -lX11 && enable xlib if enabled libxcb; then - check_pkg_config xcb-shape xcb/shape.h xcb_shape_rectangles || { - enabled libxcb && die "ERROR: libxcb not found"; - } && enable libxcb + require_pkg_config xcb xcb/xcb.h xcb_connect + require_pkg_config xcb-shape xcb/shape.h xcb_shape_rectangles disabled libxcb_shm || check_pkg_config xcb-shm xcb/shm.h xcb_shm_attach || { @@ -4775,8 +4783,8 @@ if enabled libxcb; then enabled libxcb_xfixes && die "ERROR: libxcb_xfixes not found"; } && enable libxcb_xfixes - add_cflags "$xcb_event_cflags $xcb_shm_cflags $xcb_xfixes_cflags" - add_extralibs "$xcb_event_libs $xcb_shm_libs $xcb_xfixes_libs" + add_cflags "$xcb_shm_cflags $xcb_xfixes_cflags" + add_extralibs "$xcb_shm_libs $xcb_xfixes_libs" fi enabled vaapi && @@ -4829,7 +4837,7 @@ check_disable_warning -Wno-pointer-sign # add some linker flags check_ldflags -Wl,--warn-common check_ldflags -Wl,-rpath-link=libswscale:libavfilter:libavdevice:libavformat:libavcodec:libavutil:libavresample -enabled rpath && add_ldexeflags -Wl,-rpath,$libdir +enabled rpath && add_ldexeflags -Wl,-rpath,$libdir && add_ldsoflags -Wl,-rpath,$libdir test_ldflags -Wl,-Bsymbolic && append SHFLAGS -Wl,-Bsymbolic # add some strip flags @@ -5225,6 +5233,7 @@ LD_PATH=$LD_PATH DLLTOOL=$dlltool LDFLAGS=$LDFLAGS LDEXEFLAGS=$LDEXEFLAGS +LDSOFLAGS=$LDSOFLAGS SHFLAGS=$(echo $($ldflags_filter $SHFLAGS)) STRIPFLAGS=$STRIPFLAGS YASMFLAGS=$YASMFLAGS diff --git a/libavcodec/arm/h264idct_neon.S b/libavcodec/arm/h264idct_neon.S index f588f3e..b078cf2 100644 --- a/libavcodec/arm/h264idct_neon.S +++ b/libavcodec/arm/h264idct_neon.S @@ -21,6 +21,7 @@ #include "libavutil/arm/asm.S" function ff_h264_idct_add_neon, export=1 +h264_idct_add_neon_nothumb: vld1.64 {d0-d3}, [r1,:128] vmov.i16 q15, #0 @@ -73,6 +74,7 @@ function ff_h264_idct_add_neon, export=1 endfunc function ff_h264_idct_dc_add_neon, export=1 +h264_idct_dc_add_neon_nothumb: mov r3, #0 vld1.16 {d2[],d3[]}, [r1,:16] strh r3, [r1] @@ -113,8 +115,8 @@ function ff_h264_idct_add16_neon, export=1 movne lr, #0 cmp lr, #0 ite ne - adrne lr, X(ff_h264_idct_dc_add_neon) + CONFIG_THUMB - adreq lr, X(ff_h264_idct_add_neon) + CONFIG_THUMB + adrne lr, h264_idct_dc_add_neon_nothumb + CONFIG_THUMB + adreq lr, h264_idct_add_neon_nothumb + CONFIG_THUMB blx lr 2: subs ip, ip, #1 add r1, r1, #32 @@ -138,8 +140,8 @@ function ff_h264_idct_add16intra_neon, export=1 cmp r8, #0 ldrsh r8, [r1] iteet ne - adrne lr, X(ff_h264_idct_add_neon) + CONFIG_THUMB - adreq lr, X(ff_h264_idct_dc_add_neon) + CONFIG_THUMB + adrne lr, h264_idct_add_neon_nothumb + CONFIG_THUMB + adreq lr, h264_idct_dc_add_neon_nothumb + CONFIG_THUMB cmpeq r8, #0 blxne lr subs ip, ip, #1 @@ -166,8 +168,8 @@ function ff_h264_idct_add8_neon, export=1 cmp r8, #0 ldrsh r8, [r1] iteet ne - adrne lr, X(ff_h264_idct_add_neon) + CONFIG_THUMB - adreq lr, X(ff_h264_idct_dc_add_neon) + CONFIG_THUMB + adrne lr, h264_idct_add_neon_nothumb + CONFIG_THUMB + adreq lr, h264_idct_dc_add_neon_nothumb + CONFIG_THUMB cmpeq r8, #0 blxne lr add r12, r12, #1 @@ -267,6 +269,7 @@ endfunc .endm function ff_h264_idct8_add_neon, export=1 +h264_idct8_add_neon_nothumb: vmov.i16 q3, #0 vld1.16 {q8-q9}, [r1,:128] vst1.16 {q3}, [r1,:128]! @@ -328,6 +331,7 @@ function ff_h264_idct8_add_neon, export=1 endfunc function ff_h264_idct8_dc_add_neon, export=1 +h264_idct8_dc_add_neon_nothumb: mov r3, #0 vld1.16 {d30[],d31[]},[r1,:16] strh r3, [r1] @@ -388,8 +392,8 @@ function ff_h264_idct8_add4_neon, export=1 movne lr, #0 cmp lr, #0 ite ne - adrne lr, X(ff_h264_idct8_dc_add_neon) + CONFIG_THUMB - adreq lr, X(ff_h264_idct8_add_neon) + CONFIG_THUMB + adrne lr, h264_idct8_dc_add_neon_nothumb + CONFIG_THUMB + adreq lr, h264_idct8_add_neon_nothumb + CONFIG_THUMB blx lr 2: subs r12, r12, #4 add r1, r1, #128 diff --git a/libavcodec/dfa.c b/libavcodec/dfa.c index 8021193..6362555 100644 --- a/libavcodec/dfa.c +++ b/libavcodec/dfa.c @@ -144,6 +144,8 @@ static int decode_dds1(GetByteContext *gb, uint8_t *frame, int width, int height int mask = 0x10000, bitbuf = 0; int i, v, offset, count, segments; + if ((width | height) & 1) + return AVERROR_INVALIDDATA; segments = bytestream2_get_le16(gb); while (segments--) { if (bytestream2_get_bytes_left(gb) < 2) @@ -171,7 +173,7 @@ static int decode_dds1(GetByteContext *gb, uint8_t *frame, int width, int height return AVERROR_INVALIDDATA; frame += v; } else { - if (frame_end - frame < width + 3) + if (width < 4 || frame_end - frame < width + 4) return AVERROR_INVALIDDATA; frame[0] = frame[1] = frame[width] = frame[width + 1] = bytestream2_get_byte(gb); diff --git a/libavcodec/dvbsubdec.c b/libavcodec/dvbsubdec.c index ccdfc01..01f0560 100644 --- a/libavcodec/dvbsubdec.c +++ b/libavcodec/dvbsubdec.c @@ -1281,13 +1281,18 @@ static int dvbsub_display_end_segment(AVCodecContext *avctx, const uint8_t *buf, } sub->num_rects = ctx->display_list_size; - if (sub->num_rects <= 0) - return AVERROR_INVALIDDATA; - sub->rects = av_mallocz_array(sub->num_rects * sub->num_rects, - sizeof(*sub->rects)); - if (!sub->rects) - return AVERROR(ENOMEM); + if (sub->num_rects > 0) { + sub->rects = av_mallocz(sizeof(*sub->rects) * sub->num_rects); + if (!sub->rects) + return AVERROR(ENOMEM); + for (i = 0; i < sub->num_rects; i++) { + sub->rects[i] = av_mallocz(sizeof(*sub->rects[i])); + if (!sub->rects[i]) { + return AVERROR(ENOMEM); + } + } + } i = 0; diff --git a/libavcodec/h264_cabac.c b/libavcodec/h264_cabac.c index ae1ef6b..49a111b 100644 --- a/libavcodec/h264_cabac.c +++ b/libavcodec/h264_cabac.c @@ -2329,21 +2329,40 @@ decode_intra_mb: if (CHROMA444(h) && IS_8x8DCT(mb_type)){ int i; uint8_t *nnz_cache = sl->non_zero_count_cache; - for (i = 0; i < 2; i++){ - if (sl->left_type[LEFT(i)] && !IS_8x8DCT(sl->left_type[LEFT(i)])) { - nnz_cache[3+8* 1 + 2*8*i]= - nnz_cache[3+8* 2 + 2*8*i]= - nnz_cache[3+8* 6 + 2*8*i]= - nnz_cache[3+8* 7 + 2*8*i]= - nnz_cache[3+8*11 + 2*8*i]= - nnz_cache[3+8*12 + 2*8*i]= IS_INTRA(mb_type) ? 64 : 0; + if (h->x264_build < 151U) { + for (i = 0; i < 2; i++){ + if (sl->left_type[LEFT(i)] && !IS_8x8DCT(sl->left_type[LEFT(i)])) { + nnz_cache[3+8* 1 + 2*8*i]= + nnz_cache[3+8* 2 + 2*8*i]= + nnz_cache[3+8* 6 + 2*8*i]= + nnz_cache[3+8* 7 + 2*8*i]= + nnz_cache[3+8*11 + 2*8*i]= + nnz_cache[3+8*12 + 2*8*i]= IS_INTRA(mb_type) ? 64 : 0; + } + } + if (sl->top_type && !IS_8x8DCT(sl->top_type)){ + uint32_t top_empty = !IS_INTRA(mb_type) ? 0 : 0x40404040; + AV_WN32A(&nnz_cache[4+8* 0], top_empty); + AV_WN32A(&nnz_cache[4+8* 5], top_empty); + AV_WN32A(&nnz_cache[4+8*10], top_empty); + } + } else { + for (i = 0; i < 2; i++){ + if (sl->left_type[LEFT(i)] && !IS_8x8DCT(sl->left_type[LEFT(i)])) { + nnz_cache[3+8* 1 + 2*8*i]= + nnz_cache[3+8* 2 + 2*8*i]= + nnz_cache[3+8* 6 + 2*8*i]= + nnz_cache[3+8* 7 + 2*8*i]= + nnz_cache[3+8*11 + 2*8*i]= + nnz_cache[3+8*12 + 2*8*i]= !IS_INTRA_PCM(sl->left_type[LEFT(i)]) ? 0 : 64; + } + } + if (sl->top_type && !IS_8x8DCT(sl->top_type)){ + uint32_t top_empty = !IS_INTRA_PCM(sl->top_type) ? 0 : 0x40404040; + AV_WN32A(&nnz_cache[4+8* 0], top_empty); + AV_WN32A(&nnz_cache[4+8* 5], top_empty); + AV_WN32A(&nnz_cache[4+8*10], top_empty); } - } - if (sl->top_type && !IS_8x8DCT(sl->top_type)){ - uint32_t top_empty = !IS_INTRA(mb_type) ? 0 : 0x40404040; - AV_WN32A(&nnz_cache[4+8* 0], top_empty); - AV_WN32A(&nnz_cache[4+8* 5], top_empty); - AV_WN32A(&nnz_cache[4+8*10], top_empty); } } h->cur_pic.mb_type[mb_xy] = mb_type; @@ -2352,14 +2371,6 @@ decode_intra_mb: const uint8_t *scan, *scan8x8; const uint32_t *qmul; - if(IS_INTERLACED(mb_type)){ - scan8x8 = sl->qscale ? h->field_scan8x8 : h->field_scan8x8_q0; - scan = sl->qscale ? h->field_scan : h->field_scan_q0; - }else{ - scan8x8 = sl->qscale ? h->zigzag_scan8x8 : h->zigzag_scan8x8_q0; - scan = sl->qscale ? h->zigzag_scan : h->zigzag_scan_q0; - } - // decode_cabac_mb_dqp if(get_cabac_noinline( &sl->cabac, &sl->cabac_state[60 + (sl->last_qscale_diff != 0)])){ int val = 1; @@ -2390,6 +2401,14 @@ decode_intra_mb: }else sl->last_qscale_diff=0; + if(IS_INTERLACED(mb_type)){ + scan8x8 = sl->qscale ? h->field_scan8x8 : h->field_scan8x8_q0; + scan = sl->qscale ? h->field_scan : h->field_scan_q0; + }else{ + scan8x8 = sl->qscale ? h->zigzag_scan8x8 : h->zigzag_scan8x8_q0; + scan = sl->qscale ? h->zigzag_scan : h->zigzag_scan_q0; + } + decode_cabac_luma_residual(h, sl, scan, scan8x8, pixel_shift, mb_type, cbp, 0); if (CHROMA444(h)) { decode_cabac_luma_residual(h, sl, scan, scan8x8, pixel_shift, mb_type, cbp, 1); diff --git a/libavcodec/h264_cavlc.c b/libavcodec/h264_cavlc.c index 22a643b..3bd3c84 100644 --- a/libavcodec/h264_cavlc.c +++ b/libavcodec/h264_cavlc.c @@ -1093,14 +1093,6 @@ decode_intra_mb: const uint8_t *scan, *scan8x8; const int max_qp = 51 + 6 * (h->ps.sps->bit_depth_luma - 8); - if(IS_INTERLACED(mb_type)){ - scan8x8 = sl->qscale ? h->field_scan8x8_cavlc : h->field_scan8x8_cavlc_q0; - scan = sl->qscale ? h->field_scan : h->field_scan_q0; - }else{ - scan8x8 = sl->qscale ? h->zigzag_scan8x8_cavlc : h->zigzag_scan8x8_cavlc_q0; - scan = sl->qscale ? h->zigzag_scan : h->zigzag_scan_q0; - } - dquant= get_se_golomb(&sl->gb); sl->qscale += dquant; @@ -1117,6 +1109,14 @@ decode_intra_mb: sl->chroma_qp[0] = get_chroma_qp(h->ps.pps, 0, sl->qscale); sl->chroma_qp[1] = get_chroma_qp(h->ps.pps, 1, sl->qscale); + if(IS_INTERLACED(mb_type)){ + scan8x8 = sl->qscale ? h->field_scan8x8_cavlc : h->field_scan8x8_cavlc_q0; + scan = sl->qscale ? h->field_scan : h->field_scan_q0; + }else{ + scan8x8 = sl->qscale ? h->zigzag_scan8x8_cavlc : h->zigzag_scan8x8_cavlc_q0; + scan = sl->qscale ? h->zigzag_scan : h->zigzag_scan_q0; + } + if ((ret = decode_luma_residual(h, sl, gb, scan, scan8x8, pixel_shift, mb_type, cbp, 0)) < 0 ) { return -1; } diff --git a/libavcodec/h264_direct.c b/libavcodec/h264_direct.c index 7ec49b6..abac259 100644 --- a/libavcodec/h264_direct.c +++ b/libavcodec/h264_direct.c @@ -391,7 +391,7 @@ single_col: (l1ref0[0] < 0 && !l1ref1[0] && FFABS(l1mv1[0][0]) <= 1 && FFABS(l1mv1[0][1]) <= 1 && - h->sei.unregistered.x264_build > 33U))) { + h->x264_build > 33U))) { a = b = 0; if (ref[0] > 0) a = mv[0]; @@ -426,7 +426,7 @@ single_col: (l1ref0[i8] == 0 || (l1ref0[i8] < 0 && l1ref1[i8] == 0 && - h->sei.unregistered.x264_build > 33U))) { + h->x264_build > 33U))) { const int16_t (*l1mv)[2] = l1ref0[i8] == 0 ? l1mv0 : l1mv1; if (IS_SUB_8X8(sub_mb_type)) { const int16_t *mv_col = l1mv[x8 * 3 + y8 * 3 * b4_stride]; diff --git a/libavcodec/h264_mb.c b/libavcodec/h264_mb.c index f037bd5..51d73ce 100644 --- a/libavcodec/h264_mb.c +++ b/libavcodec/h264_mb.c @@ -636,7 +636,12 @@ static av_always_inline void hl_decode_mb_predict_luma(const H264Context *h, uint8_t *const ptr = dest_y + block_offset[i]; const int dir = sl->intra4x4_pred_mode_cache[scan8[i]]; if (transform_bypass && h->ps.sps->profile_idc == 244 && dir <= 1) { - h->hpc.pred8x8l_add[dir](ptr, sl->mb + (i * 16 + p * 256 << pixel_shift), linesize); + if (h->x264_build < 151U) { + h->hpc.pred8x8l_add[dir](ptr, sl->mb + (i * 16 + p * 256 << pixel_shift), linesize); + } else + h->hpc.pred8x8l_filter_add[dir](ptr, sl->mb + (i * 16 + p * 256 << pixel_shift), + (sl-> topleft_samples_available << i) & 0x8000, + (sl->topright_samples_available << i) & 0x4000, linesize); } else { const int nnz = sl->non_zero_count_cache[scan8[i + p * 16]]; h->hpc.pred8x8l[dir](ptr, (sl->topleft_samples_available << i) & 0x8000, diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c index db7628c..7d3e4ce 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -401,6 +401,7 @@ int ff_h264_update_thread_context(AVCodecContext *dst, h->enable_er = h1->enable_er; h->workaround_bugs = h1->workaround_bugs; + h->x264_build = h1->x264_build; h->droppable = h1->droppable; // extradata/NAL handling @@ -502,6 +503,9 @@ static int h264_frame_start(H264Context *h) h->mb_aff_frame = h->ps.sps->mb_aff && (h->picture_structure == PICT_FRAME); + if (h->sei.unregistered.x264_build >= 0) + h->x264_build = h->sei.unregistered.x264_build; + assert(h->cur_pic_ptr->long_ref == 0); return 0; @@ -839,7 +843,7 @@ static int h264_slice_header_init(H264Context *h) if (sps->timing_info_present_flag) { int64_t den = sps->time_scale; - if (h->sei.unregistered.x264_build < 44U) + if (h->x264_build < 44U) den *= 2; av_reduce(&h->avctx->framerate.den, &h->avctx->framerate.num, sps->num_units_in_tick, den, 1 << 30); diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c index d918fb9..6c0bee9 100644 --- a/libavcodec/h264dec.c +++ b/libavcodec/h264dec.c @@ -290,6 +290,7 @@ static int h264_init_context(AVCodecContext *avctx, H264Context *h) h->flags = avctx->flags; h->poc.prev_poc_msb = 1 << 16; h->recovery_frame = -1; + h->x264_build = -1; h->frame_recovered = 0; h->next_outputed_poc = INT_MIN; diff --git a/libavcodec/h264dec.h b/libavcodec/h264dec.h index 2ffe4de..b815aa4 100644 --- a/libavcodec/h264dec.h +++ b/libavcodec/h264dec.h @@ -268,7 +268,7 @@ typedef struct H264SliceContext { * according to picture reordering in slice header */ struct { uint8_t op; - uint8_t val; + uint32_t val; } ref_modifications[2][32]; int nb_ref_modifications[2]; @@ -361,6 +361,7 @@ typedef struct H264Context { int context_initialized; int flags; int workaround_bugs; + int x264_build; /* Set when slice threading is used and at least one slice uses deblocking * mode 1 (i.e. across slice boundaries). Then we disable the loop filter * during normal MB decoding and execute it serially at the end. diff --git a/libavcodec/h264pred.c b/libavcodec/h264pred.c index 7627eb0..135babc 100644 --- a/libavcodec/h264pred.c +++ b/libavcodec/h264pred.c @@ -552,6 +552,8 @@ av_cold void ff_h264_pred_init(H264PredContext *h, int codec_id, h->pred4x4_add [ HOR_PRED ]= FUNCC(pred4x4_horizontal_add , depth);\ h->pred8x8l_add [VERT_PRED ]= FUNCC(pred8x8l_vertical_add , depth);\ h->pred8x8l_add [ HOR_PRED ]= FUNCC(pred8x8l_horizontal_add , depth);\ + h->pred8x8l_filter_add [VERT_PRED ]= FUNCC(pred8x8l_vertical_filter_add , depth);\ + h->pred8x8l_filter_add [ HOR_PRED ]= FUNCC(pred8x8l_horizontal_filter_add , depth);\ if (chroma_format_idc <= 1) {\ h->pred8x8_add [VERT_PRED8x8]= FUNCC(pred8x8_vertical_add , depth);\ h->pred8x8_add [ HOR_PRED8x8]= FUNCC(pred8x8_horizontal_add , depth);\ diff --git a/libavcodec/h264pred.h b/libavcodec/h264pred.h index 60e7434..795d8f3 100644 --- a/libavcodec/h264pred.h +++ b/libavcodec/h264pred.h @@ -101,6 +101,9 @@ typedef struct H264PredContext { int16_t *block /*align 16*/, ptrdiff_t stride); void(*pred8x8l_add[2])(uint8_t *pix /*align 8*/, int16_t *block /*align 16*/, ptrdiff_t stride); + void(*pred8x8l_filter_add[2])(uint8_t *pix /*align 8*/, + int16_t *block /*align 16*/, + int topleft, int topright, ptrdiff_t stride); void(*pred8x8_add[3])(uint8_t *pix /*align 8*/, const int *block_offset, int16_t *block /*align 16*/, ptrdiff_t stride); diff --git a/libavcodec/h264pred_template.c b/libavcodec/h264pred_template.c index 8492b2b..02494aa 100644 --- a/libavcodec/h264pred_template.c +++ b/libavcodec/h264pred_template.c @@ -1123,6 +1123,79 @@ static void FUNCC(pred8x8l_horizontal_up)(uint8_t *_src, int has_topleft, SRC(5,6)=SRC(5,7)=SRC(6,4)=SRC(6,5)=SRC(6,6)= SRC(6,7)=SRC(7,4)=SRC(7,5)=SRC(7,6)=SRC(7,7)= l7; } + +static void FUNCC(pred8x8l_vertical_filter_add)(uint8_t *_src, int16_t *_block, int has_topleft, + int has_topright, ptrdiff_t _stride) +{ + int i; + pixel *src = (pixel*)_src; + const dctcoef *block = (const dctcoef*)_block; + pixel pix[8]; + int stride = _stride/sizeof(pixel); + PREDICT_8x8_LOAD_TOP; + + pix[0] = t0; + pix[1] = t1; + pix[2] = t2; + pix[3] = t3; + pix[4] = t4; + pix[5] = t5; + pix[6] = t6; + pix[7] = t7; + + for (i = 0; i < 8; i++) { + pixel v = pix[i]; + src[0 * stride] = v += block[0]; + src[1 * stride] = v += block[8]; + src[2 * stride] = v += block[16]; + src[3 * stride] = v += block[24]; + src[4 * stride] = v += block[32]; + src[5 * stride] = v += block[40]; + src[6 * stride] = v += block[48]; + src[7 * stride] = v + block[56]; + src++; + block++; + } + + memset(_block, 0, sizeof(dctcoef) * 64); +} + +static void FUNCC(pred8x8l_horizontal_filter_add)(uint8_t *_src, int16_t *_block, int has_topleft, + int has_topright, ptrdiff_t _stride) +{ + int i; + pixel *src = (pixel*)_src; + const dctcoef *block = (const dctcoef*)_block; + pixel pix[8]; + int stride = _stride/sizeof(pixel); + PREDICT_8x8_LOAD_LEFT; + + pix[0] = l0; + pix[1] = l1; + pix[2] = l2; + pix[3] = l3; + pix[4] = l4; + pix[5] = l5; + pix[6] = l6; + pix[7] = l7; + + for (i = 0; i < 8; i++) { + pixel v = pix[i]; + src[0] = v += block[0]; + src[1] = v += block[1]; + src[2] = v += block[2]; + src[3] = v += block[3]; + src[4] = v += block[4]; + src[5] = v += block[5]; + src[6] = v += block[6]; + src[7] = v + block[7]; + src += stride; + block += 8; + } + + memset(_block, 0, sizeof(dctcoef) * 64); +} + #undef PREDICT_8x8_LOAD_LEFT #undef PREDICT_8x8_LOAD_TOP #undef PREDICT_8x8_LOAD_TOPLEFT diff --git a/libavcodec/mpegvideo_motion.c b/libavcodec/mpegvideo_motion.c index 8074dba..f6d9613 100644 --- a/libavcodec/mpegvideo_motion.c +++ b/libavcodec/mpegvideo_motion.c @@ -210,17 +210,14 @@ static inline int hpel_motion(MpegEncContext *s, dxy |= (motion_y & 1) << 1; src += src_y * s->linesize + src_x; - if (s->unrestricted_mv) { - if ((unsigned)src_x > FFMAX(s->h_edge_pos - (motion_x & 1) - 8, 0) || - (unsigned)src_y > FFMAX(s->v_edge_pos - (motion_y & 1) - 8, 0)) { - s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, src, - s->linesize, s->linesize, - 9, 9, - src_x, src_y, s->h_edge_pos, - s->v_edge_pos); - src = s->sc.edge_emu_buffer; - emu = 1; - } + if ((unsigned)src_x > FFMAX(s->h_edge_pos - (motion_x & 1) - 8, 0) || + (unsigned)src_y > FFMAX(s->v_edge_pos - (motion_y & 1) - 8, 0)) { + s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, src, + s->linesize, s->linesize, + 9, 9, src_x, src_y, + s->h_edge_pos, s->v_edge_pos); + src = s->sc.edge_emu_buffer; + emu = 1; } pix_op[dxy](dest, src, s->linesize, 8); return emu; diff --git a/libavcodec/pictordec.c b/libavcodec/pictordec.c index 9477bc4..49547cf 100644 --- a/libavcodec/pictordec.c +++ b/libavcodec/pictordec.c @@ -140,7 +140,7 @@ static int decode_frame(AVCodecContext *avctx, avctx->pix_fmt = AV_PIX_FMT_PAL8; - if (s->width != avctx->width && s->height != avctx->height) { + if (s->width != avctx->width || s->height != avctx->height) { ret = ff_set_dimensions(avctx, s->width, s->height); if (ret < 0) return ret; diff --git a/libavcodec/smacker.c b/libavcodec/smacker.c index e3e5475..09c6c8d 100644 --- a/libavcodec/smacker.c +++ b/libavcodec/smacker.c @@ -42,7 +42,8 @@ #define SMKTREE_BITS 9 #define SMK_NODE 0x80000000 - +#define SMKTREE_DECODE_MAX_RECURSION 32 +#define SMKTREE_DECODE_BIG_MAX_RECURSION 500 typedef struct SmackVContext { AVCodecContext *avctx; @@ -95,6 +96,11 @@ enum SmkBlockTypes { */ static int smacker_decode_tree(GetBitContext *gb, HuffContext *hc, uint32_t prefix, int length) { + if (length > SMKTREE_DECODE_MAX_RECURSION) { + av_log(NULL, AV_LOG_ERROR, "Maximum tree recursion level exceeded.\n"); + return AVERROR_INVALIDDATA; + } + if(!get_bits1(gb)){ //Leaf if(hc->current >= 256){ av_log(NULL, AV_LOG_ERROR, "Tree size exceeded!\n"); @@ -125,8 +131,15 @@ static int smacker_decode_tree(GetBitContext *gb, HuffContext *hc, uint32_t pref /** * Decode header tree */ -static int smacker_decode_bigtree(GetBitContext *gb, HuffContext *hc, DBCtx *ctx) +static int smacker_decode_bigtree(GetBitContext *gb, HuffContext *hc, + DBCtx *ctx, int length) { + // Larger length can cause segmentation faults due to too deep recursion. + if (length > SMKTREE_DECODE_BIG_MAX_RECURSION) { + av_log(NULL, AV_LOG_ERROR, "Maximum bigtree recursion level exceeded.\n"); + return AVERROR_INVALIDDATA; + } + if (hc->current + 1 >= hc->length) { av_log(NULL, AV_LOG_ERROR, "Tree size exceeded!\n"); return -1; @@ -155,12 +168,12 @@ static int smacker_decode_bigtree(GetBitContext *gb, HuffContext *hc, DBCtx *ctx int r = 0, r_new, t; t = hc->current++; - r = smacker_decode_bigtree(gb, hc, ctx); + r = smacker_decode_bigtree(gb, hc, ctx, length + 1); if(r < 0) return r; hc->values[t] = SMK_NODE | r; r++; - r_new = smacker_decode_bigtree(gb, hc, ctx); + r_new = smacker_decode_bigtree(gb, hc, ctx, length + 1); if (r_new < 0) return r_new; return r + r_new; @@ -260,7 +273,7 @@ static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int goto error; } - if (smacker_decode_bigtree(gb, &huff, &ctx) < 0) + if (smacker_decode_bigtree(gb, &huff, &ctx, 0) < 0) err = -1; skip_bits1(gb); if(ctx.last[0] == -1) ctx.last[0] = huff.current++; @@ -628,6 +641,11 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data, av_log(avctx, AV_LOG_ERROR, "sample format mismatch\n"); return AVERROR(EINVAL); } + if (unp_size % (avctx->channels * (bits + 1))) { + av_log(avctx, AV_LOG_ERROR, + "The buffer does not contain an integer number of samples\n"); + return AVERROR(EINVAL); + } /* get output buffer */ frame->nb_samples = unp_size / (avctx->channels * (bits + 1)); diff --git a/libavcodec/vc1_mc.c b/libavcodec/vc1_mc.c index f4632d6..18ac47a 100644 --- a/libavcodec/vc1_mc.c +++ b/libavcodec/vc1_mc.c @@ -689,6 +689,11 @@ void ff_vc1_mc_4mv_chroma4(VC1Context *v, int dir, int dir2, int avg) if (s->avctx->flags & AV_CODEC_FLAG_GRAY) return; + if (!s->last_picture.f->data[1]) { + av_log(s->avctx, AV_LOG_ERROR, "Bad data in last picture frame.\n"); + return; + } + for (i = 0; i < 4; i++) { int d = i < 2 ? dir: dir2; tx = s->mv[d][i][0]; diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c index 1955cea..0f53ff8 100644 --- a/libavcodec/vc1dec.c +++ b/libavcodec/vc1dec.c @@ -651,7 +651,7 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, buf_size3 << 3); /* assuming that the field marker is at the exact middle, hope it's correct */ - slices[n_slices].mby_start = s->mb_height >> 1; + slices[n_slices].mby_start = s->mb_height + 1 >> 1; n_slices1 = n_slices - 1; // index of the last slice of the first field n_slices++; break; @@ -699,7 +699,7 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, buf_size3 = vc1_unescape_buffer(divider + 4, buf + buf_size - divider - 4, slices[n_slices].buf); init_get_bits(&slices[n_slices].gb, slices[n_slices].buf, buf_size3 << 3); - slices[n_slices].mby_start = s->mb_height >> 1; + slices[n_slices].mby_start = s->mb_height + 1 >> 1; n_slices1 = n_slices - 1; n_slices++; } diff --git a/libavfilter/vf_yadif.c b/libavfilter/vf_yadif.c index 75f2d17..bef357b 100644 --- a/libavfilter/vf_yadif.c +++ b/libavfilter/vf_yadif.c @@ -40,6 +40,8 @@ typedef struct ThreadData { int tff; } ThreadData; +#define MAX_ALIGN 8 + #define CHECK(j)\ { int score = FFABS(cur[mrefs - 1 + (j)] - cur[prefs - 1 - (j)])\ + FFABS(cur[mrefs +(j)] - cur[prefs -(j)])\ @@ -123,17 +125,20 @@ static void filter_edges(void *dst1, void *prev1, void *cur1, void *next1, uint8_t *prev2 = parity ? prev : cur ; uint8_t *next2 = parity ? cur : next; + const int edge = MAX_ALIGN - 1; + /* Only edge pixels need to be processed here. A constant value of false * for is_not_edge should let the compiler ignore the whole branch. */ FILTER(0, 3, 0) - dst = (uint8_t*)dst1 + w - 3; - prev = (uint8_t*)prev1 + w - 3; - cur = (uint8_t*)cur1 + w - 3; - next = (uint8_t*)next1 + w - 3; + dst = (uint8_t*)dst1 + w - edge; + prev = (uint8_t*)prev1 + w - edge; + cur = (uint8_t*)cur1 + w - edge; + next = (uint8_t*)next1 + w - edge; prev2 = (uint8_t*)(parity ? prev : cur); next2 = (uint8_t*)(parity ? cur : next); + FILTER(w - edge, w - 3, 1) FILTER(w - 3, w, 0) } @@ -166,18 +171,22 @@ static void filter_edges_16bit(void *dst1, void *prev1, void *cur1, void *next1, int x; uint16_t *prev2 = parity ? prev : cur ; uint16_t *next2 = parity ? cur : next; + + const int edge = MAX_ALIGN / 2 - 1; + mrefs /= 2; prefs /= 2; FILTER(0, 3, 0) - dst = (uint16_t*)dst1 + w - 3; - prev = (uint16_t*)prev1 + w - 3; - cur = (uint16_t*)cur1 + w - 3; - next = (uint16_t*)next1 + w - 3; + dst = (uint16_t*)dst1 + w - edge; + prev = (uint16_t*)prev1 + w - edge; + cur = (uint16_t*)cur1 + w - edge; + next = (uint16_t*)next1 + w - edge; prev2 = (uint16_t*)(parity ? prev : cur); next2 = (uint16_t*)(parity ? cur : next); + FILTER(w - edge, w - 3, 1) FILTER(w - 3, w, 0) } @@ -192,6 +201,7 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) int slice_start = jobnr * slice_h; int slice_end = (jobnr == nb_jobs - 1) ? td->h : (jobnr + 1) * slice_h; int y; + int edge = 3 + MAX_ALIGN / df - 1; /* filtering reads 3 pixels to the left/right; to avoid invalid reads, * we need to call the c variant which avoids this for border pixels @@ -204,7 +214,7 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) uint8_t *dst = &td->frame->data[td->plane][y * td->frame->linesize[td->plane]]; int mode = y == 1 || y + 2 == td->h ? 2 : s->mode; s->filter_line(dst + pix_3, prev + pix_3, cur + pix_3, - next + pix_3, td->w - 6, + next + pix_3, td->w - edge, y + 1 < td->h ? refs : -refs, y ? -refs : refs, td->parity ^ td->tff, mode); diff --git a/libavformat/caf.c b/libavformat/caf.c index cf128d5..c299cad 100644 --- a/libavformat/caf.c +++ b/libavformat/caf.c @@ -49,6 +49,7 @@ const AVCodecTag ff_codec_caf_tags[] = { { AV_CODEC_ID_QCELP, MKBETAG('Q','c','l','p') }, { AV_CODEC_ID_QDM2, MKBETAG('Q','D','M','2') }, { AV_CODEC_ID_QDM2, MKBETAG('Q','D','M','C') }, + { AV_CODEC_ID_OPUS, MKBETAG('o','p','u','s') }, /* currently unsupported codecs */ /*{ AC-3 over S/PDIF MKBETAG('c','a','c','3') },*/ /*{ MPEG4CELP MKBETAG('c','e','l','p') },*/ diff --git a/libavformat/cafdec.c b/libavformat/cafdec.c index 65bdcfc..3664a16 100644 --- a/libavformat/cafdec.c +++ b/libavformat/cafdec.c @@ -156,6 +156,14 @@ static int read_kuki_chunk(AVFormatContext *s, int64_t size) avio_skip(pb, size - ALAC_NEW_KUKI); } st->codecpar->extradata_size = ALAC_HEADER; + } else if (st->codecpar->codec_id == AV_CODEC_ID_OPUS) { + // The data layout for Opus is currently unknown, so we do not export + // extradata at all. Multichannel streams are not supported. + if (st->codecpar->channels > 2) { + avpriv_request_sample(s, "multichannel Opus in CAF"); + return AVERROR_PATCHWELCOME; + } + avio_skip(pb, size); } else { st->codecpar->extradata = av_mallocz(size + AV_INPUT_BUFFER_PADDING_SIZE); if (!st->codecpar->extradata) diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index 54c2b9a..02dbfe9 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -1797,7 +1797,7 @@ static int matroska_parse_tracks(AVFormatContext *s) track->audio.sub_packet_h = avio_rb16(&b); track->audio.frame_size = avio_rb16(&b); track->audio.sub_packet_size = avio_rb16(&b); - if (flavor <= 0 || + if (flavor < 0 || track->audio.coded_framesize <= 0 || track->audio.sub_packet_h <= 0 || track->audio.frame_size <= 0 || diff --git a/libavformat/mov.c b/libavformat/mov.c index 2ff5211..bcadb94 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -1884,7 +1884,7 @@ int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries) if (pb->eof_reached) return AVERROR_EOF; - return mov_finalize_stsd_codec(c, pb, st, sc); + return 0; } static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom) @@ -1902,6 +1902,11 @@ static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom) avio_rb24(pb); /* flags */ entries = avio_rb32(pb); + if (entries <= 0) { + av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries); + return AVERROR_INVALIDDATA; + } + if (sc->extradata) { av_log(c->fc, AV_LOG_ERROR, "Duplicate stsd found in this track.\n"); @@ -1913,24 +1918,33 @@ static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom) if (!sc->extradata) return AVERROR(ENOMEM); - sc->stsd_count = entries; - sc->extradata_size = av_mallocz_array(sc->stsd_count, sizeof(*sc->extradata_size)); - if (!sc->extradata_size) - return AVERROR(ENOMEM); + sc->extradata_size = av_mallocz_array(entries, sizeof(*sc->extradata_size)); + if (!sc->extradata_size) { + ret = AVERROR(ENOMEM); + goto fail; + } - ret = ff_mov_read_stsd_entries(c, pb, sc->stsd_count); + ret = ff_mov_read_stsd_entries(c, pb, entries); if (ret < 0) - return ret; + goto fail; + + sc->stsd_count = entries; /* Restore back the primary extradata. */ av_free(st->codecpar->extradata); st->codecpar->extradata_size = sc->extradata_size[0]; st->codecpar->extradata = av_mallocz(sc->extradata_size[0] + AV_INPUT_BUFFER_PADDING_SIZE); - if (!st->codecpar->extradata) - return AVERROR(ENOMEM); + if (!st->codecpar->extradata) { + ret = AVERROR(ENOMEM); + goto fail; + } memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]); - return 0; + return mov_finalize_stsd_codec(c, pb, st, sc); +fail: + av_freep(&sc->extradata); + av_freep(&sc->extradata_size); + return ret; } static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom) diff --git a/libavformat/rmdec.c b/libavformat/rmdec.c index 9774194..c3fa7c5 100644 --- a/libavformat/rmdec.c +++ b/libavformat/rmdec.c @@ -721,6 +721,7 @@ ff_rm_parse_packet (AVFormatContext *s, AVIOContext *pb, int *seq, int flags, int64_t timestamp) { RMDemuxContext *rm = s->priv_data; + int ret; if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { rm->current_stream= st->id; @@ -777,11 +778,16 @@ ff_rm_parse_packet (AVFormatContext *s, AVIOContext *pb, } else return -1; } else { - av_get_packet(pb, pkt, len); + ret = av_get_packet(pb, pkt, len); + if (ret < 0) + return ret; rm_ac3_swap_bytes(st, pkt); } - } else - av_get_packet(pb, pkt, len); + } else { + ret = av_get_packet(pb, pkt, len); + if (ret < 0) + return ret; + } pkt->stream_index = st->index; @@ -797,14 +803,18 @@ ff_rm_retrieve_cache (AVFormatContext *s, AVIOContext *pb, AVStream *st, RMStream *ast, AVPacket *pkt) { RMDemuxContext *rm = s->priv_data; + int ret; assert (rm->audio_pkt_cnt > 0); if (ast->deint_id == DEINT_ID_VBRF || - ast->deint_id == DEINT_ID_VBRS) - av_get_packet(pb, pkt, ast->sub_packet_lengths[ast->sub_packet_cnt - rm->audio_pkt_cnt]); + ast->deint_id == DEINT_ID_VBRS) { + ret = av_get_packet(pb, pkt, ast->sub_packet_lengths[ast->sub_packet_cnt - rm->audio_pkt_cnt]); + if (ret < 0) + return ret; + } else { - int ret = av_new_packet(pkt, st->codecpar->block_align); + ret = av_new_packet(pkt, st->codecpar->block_align); if (ret < 0) return ret; memcpy(pkt->data, ast->pkt.data + st->codecpar->block_align * //FIXME avoid this diff --git a/libavformat/rtmpdh.c b/libavformat/rtmpdh.c index e7a83e1..593b2b1 100644 --- a/libavformat/rtmpdh.c +++ b/libavformat/rtmpdh.c @@ -54,7 +54,6 @@ "F71C35FDAD44CFD2D74F9208BE258FF324943328F67329C0" \ "FFFFFFFFFFFFFFFF" -#if CONFIG_GMP || CONFIG_GCRYPT #if CONFIG_GMP #define bn_new(bn) \ do { \ @@ -93,7 +92,6 @@ else \ ret = 1; \ } while (0) -#define bn_modexp(bn, y, q, p) mpz_powm(bn, y, q, p) #define bn_random(bn, num_bits) \ do { \ int bits = num_bits; \ @@ -104,6 +102,11 @@ } \ mpz_fdiv_r_2exp(bn, bn, num_bits); \ } while (0) +static int bn_modexp(FFBigNum bn, FFBigNum y, FFBigNum q, FFBigNum p) +{ + mpz_powm(bn, y, q, p); + return 0; +} #elif CONFIG_GCRYPT #define bn_new(bn) bn = gcry_mpi_new(1) #define bn_free(bn) gcry_mpi_release(bn) @@ -116,13 +119,42 @@ #define bn_bn2bin(bn, buf, len) gcry_mpi_print(GCRYMPI_FMT_USG, buf, len, NULL, bn) #define bn_bin2bn(bn, buf, len) gcry_mpi_scan(&bn, GCRYMPI_FMT_USG, buf, len, NULL) #define bn_hex2bn(bn, buf, ret) ret = (gcry_mpi_scan(&bn, GCRYMPI_FMT_HEX, buf, 0, 0) == 0) -#define bn_modexp(bn, y, q, p) gcry_mpi_powm(bn, y, q, p) #define bn_random(bn, num_bits) gcry_mpi_randomize(bn, num_bits, GCRY_WEAK_RANDOM) +static int bn_modexp(FFBigNum bn, FFBigNum y, FFBigNum q, FFBigNum p) +{ + gcry_mpi_powm(bn, y, q, p); + return 0; +} +#elif CONFIG_OPENSSL +#define bn_new(bn) bn = BN_new() +#define bn_free(bn) BN_free(bn) +#define bn_set_word(bn, w) BN_set_word(bn, w) +#define bn_cmp(a, b) BN_cmp(a, b) +#define bn_copy(to, from) BN_copy(to, from) +#define bn_sub_word(bn, w) BN_sub_word(bn, w) +#define bn_cmp_1(bn) BN_cmp(bn, BN_value_one()) +#define bn_num_bytes(bn) BN_num_bytes(bn) +#define bn_bn2bin(bn, buf, len) BN_bn2bin(bn, buf) +#define bn_bin2bn(bn, buf, len) bn = BN_bin2bn(buf, len, 0) +#define bn_hex2bn(bn, buf, ret) ret = BN_hex2bn(&bn, buf) +#define bn_random(bn, num_bits) BN_rand(bn, num_bits, 0, 0) +static int bn_modexp(FFBigNum bn, FFBigNum y, FFBigNum q, FFBigNum p) +{ + BN_CTX *ctx = BN_CTX_new(); + if (!ctx) + return AVERROR(ENOMEM); + if (!BN_mod_exp(bn, y, q, p, ctx)) { + BN_CTX_free(ctx); + return AVERROR(EINVAL); + } + BN_CTX_free(ctx); + return 0; +} #endif #define MAX_BYTES 18000 -#define dh_new() av_malloc(sizeof(FF_DH)) +#define dh_new() av_mallocz(sizeof(FF_DH)) static FFBigNum dh_generate_key(FF_DH *dh) { @@ -143,7 +175,8 @@ static FFBigNum dh_generate_key(FF_DH *dh) return NULL; } - bn_modexp(dh->pub_key, dh->g, dh->priv_key, dh->p); + if (bn_modexp(dh->pub_key, dh->g, dh->priv_key, dh->p) < 0) + return NULL; return dh->pub_key; } @@ -152,12 +185,16 @@ static int dh_compute_key(FF_DH *dh, FFBigNum pub_key_bn, uint32_t secret_key_len, uint8_t *secret_key) { FFBigNum k; + int ret; bn_new(k); if (!k) return -1; - bn_modexp(k, pub_key_bn, dh->priv_key, dh->p); + if ((ret = bn_modexp(k, pub_key_bn, dh->priv_key, dh->p)) < 0) { + bn_free(k); + return ret; + } bn_bn2bin(k, secret_key, secret_key_len); bn_free(k); @@ -175,48 +212,6 @@ void ff_dh_free(FF_DH *dh) bn_free(dh->priv_key); av_free(dh); } -#elif CONFIG_OPENSSL -#define bn_new(bn) bn = BN_new() -#define bn_free(bn) BN_free(bn) -#define bn_set_word(bn, w) BN_set_word(bn, w) -#define bn_cmp(a, b) BN_cmp(a, b) -#define bn_copy(to, from) BN_copy(to, from) -#define bn_sub_word(bn, w) BN_sub_word(bn, w) -#define bn_cmp_1(bn) BN_cmp(bn, BN_value_one()) -#define bn_num_bytes(bn) BN_num_bytes(bn) -#define bn_bn2bin(bn, buf, len) BN_bn2bin(bn, buf) -#define bn_bin2bn(bn, buf, len) bn = BN_bin2bn(buf, len, 0) -#define bn_hex2bn(bn, buf, ret) ret = BN_hex2bn(&bn, buf) -#define bn_modexp(bn, y, q, p) \ - do { \ - BN_CTX *ctx = BN_CTX_new(); \ - if (!ctx) \ - return AVERROR(ENOMEM); \ - if (!BN_mod_exp(bn, y, q, p, ctx)) { \ - BN_CTX_free(ctx); \ - return AVERROR(EINVAL); \ - } \ - BN_CTX_free(ctx); \ - } while (0) - -#define dh_new() DH_new() -#define dh_generate_key(dh) DH_generate_key(dh) - -static int dh_compute_key(FF_DH *dh, FFBigNum pub_key_bn, - uint32_t secret_key_len, uint8_t *secret_key) -{ - if (secret_key_len < DH_size(dh)) - return AVERROR(EINVAL); - return DH_compute_key(secret_key, pub_key_bn, dh); -} - -void ff_dh_free(FF_DH *dh) -{ - if (!dh) - return; - DH_free(dh); -} -#endif static int dh_is_valid_public_key(FFBigNum y, FFBigNum p, FFBigNum q) { @@ -245,8 +240,10 @@ static int dh_is_valid_public_key(FFBigNum y, FFBigNum p, FFBigNum q) * random data. */ /* y must fulfill y^q mod p = 1 */ - bn_modexp(bn, y, q, p); + if ((ret = bn_modexp(bn, y, q, p)) < 0) + goto fail; + ret = AVERROR(EINVAL); if (bn_cmp_1(bn)) goto fail; diff --git a/libavformat/rtmpdh.h b/libavformat/rtmpdh.h index eb742dd..5233de0 100644 --- a/libavformat/rtmpdh.h +++ b/libavformat/rtmpdh.h @@ -26,7 +26,6 @@ #include "config.h" -#if CONFIG_GMP || CONFIG_GCRYPT #if CONFIG_GMP #include @@ -35,6 +34,12 @@ typedef mpz_ptr FFBigNum; #include typedef gcry_mpi_t FFBigNum; + +#elif CONFIG_OPENSSL +#include +#include + +typedef BIGNUM *FFBigNum; #endif typedef struct FF_DH { @@ -45,13 +50,6 @@ typedef struct FF_DH { long length; } FF_DH; -#elif CONFIG_OPENSSL -#include -#include - -typedef BIGNUM *FFBigNum; -typedef DH FF_DH; -#endif /** * Initialize a Diffie-Hellmann context. diff --git a/libavformat/smacker.c b/libavformat/smacker.c index eb4b63f..304e746 100644 --- a/libavformat/smacker.c +++ b/libavformat/smacker.c @@ -112,11 +112,16 @@ static int smacker_read_header(AVFormatContext *s) /* read and check header */ smk->magic = avio_rl32(pb); if (smk->magic != MKTAG('S', 'M', 'K', '2') && smk->magic != MKTAG('S', 'M', 'K', '4')) - return -1; + return AVERROR_INVALIDDATA; smk->width = avio_rl32(pb); smk->height = avio_rl32(pb); smk->frames = avio_rl32(pb); smk->pts_inc = (int32_t)avio_rl32(pb); + if (smk->pts_inc > INT_MAX / 100) { + av_log(s, AV_LOG_ERROR, "pts_inc %d is too large\n", smk->pts_inc); + return AVERROR_INVALIDDATA; + } + smk->flags = avio_rl32(pb); if(smk->flags & SMACKER_FLAG_RING_FRAME) smk->frames++; @@ -126,7 +131,7 @@ static int smacker_read_header(AVFormatContext *s) if(smk->treesize >= UINT_MAX/4){ // smk->treesize + 16 must not overflow (this check is probably redundant) av_log(s, AV_LOG_ERROR, "treesize too large\n"); - return -1; + return AVERROR_INVALIDDATA; } //FIXME remove extradata "rebuilding" @@ -142,7 +147,7 @@ static int smacker_read_header(AVFormatContext *s) /* setup data */ if(smk->frames > 0xFFFFFF) { av_log(s, AV_LOG_ERROR, "Too many frames: %"PRIu32"\n", smk->frames); - return -1; + return AVERROR_INVALIDDATA; } smk->frm_size = av_malloc(smk->frames * 4); smk->frm_flags = av_malloc(smk->frames); @@ -160,7 +165,7 @@ static int smacker_read_header(AVFormatContext *s) /* init video codec */ st = avformat_new_stream(s, NULL); if (!st) - return -1; + return AVERROR(ENOMEM); smk->videoindex = st->index; st->codecpar->width = smk->width; st->codecpar->height = smk->height; @@ -221,7 +226,7 @@ static int smacker_read_header(AVFormatContext *s) smk->treesize + 16); av_free(smk->frm_size); av_free(smk->frm_flags); - return -1; + return AVERROR(ENOMEM); } ret = avio_read(pb, st->codecpar->extradata + 16, st->codecpar->extradata_size - 16); if(ret != st->codecpar->extradata_size - 16){ diff --git a/libavformat/tls_openssl.c b/libavformat/tls_openssl.c index a75674e..aab885c 100644 --- a/libavformat/tls_openssl.c +++ b/libavformat/tls_openssl.c @@ -43,6 +43,9 @@ typedef struct TLSContext { TLSShared tls_shared; SSL_CTX *ctx; SSL *ssl; +#if OPENSSL_VERSION_NUMBER >= 0x1010000fL + BIO_METHOD* url_bio_method; +#endif } TLSContext; #if HAVE_THREADS @@ -121,15 +124,25 @@ static int tls_close(URLContext *h) SSL_CTX_free(c->ctx); if (c->tls_shared.tcp) ffurl_close(c->tls_shared.tcp); +#if OPENSSL_VERSION_NUMBER >= 0x1010000fL + if (c->url_bio_method) + BIO_meth_free(c->url_bio_method); +#endif ff_openssl_deinit(); return 0; } static int url_bio_create(BIO *b) { +#if OPENSSL_VERSION_NUMBER >= 0x1010000fL + BIO_set_init(b, 1); + BIO_set_data(b, NULL); + BIO_set_flags(b, 0); +#else b->init = 1; b->ptr = NULL; b->flags = 0; +#endif return 1; } @@ -138,9 +151,15 @@ static int url_bio_destroy(BIO *b) return 1; } +#if OPENSSL_VERSION_NUMBER >= 0x1010000fL +#define GET_BIO_DATA(x) BIO_get_data(x) +#else +#define GET_BIO_DATA(x) (x)->ptr +#endif + static int url_bio_bread(BIO *b, char *buf, int len) { - URLContext *h = b->ptr; + URLContext *h = GET_BIO_DATA(b); int ret = ffurl_read(h, buf, len); if (ret >= 0) return ret; @@ -152,7 +171,7 @@ static int url_bio_bread(BIO *b, char *buf, int len) static int url_bio_bwrite(BIO *b, const char *buf, int len) { - URLContext *h = b->ptr; + URLContext *h = GET_BIO_DATA(b); int ret = ffurl_write(h, buf, len); if (ret >= 0) return ret; @@ -176,6 +195,7 @@ static int url_bio_bputs(BIO *b, const char *str) return url_bio_bwrite(b, str, strlen(str)); } +#if OPENSSL_VERSION_NUMBER < 0x1010000fL static BIO_METHOD url_bio_method = { .type = BIO_TYPE_SOURCE_SINK, .name = "urlprotocol bio", @@ -187,6 +207,7 @@ static BIO_METHOD url_bio_method = { .create = url_bio_create, .destroy = url_bio_destroy, }; +#endif static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **options) { @@ -230,8 +251,20 @@ static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **op ret = AVERROR(EIO); goto fail; } +#if OPENSSL_VERSION_NUMBER >= 0x1010000fL + p->url_bio_method = BIO_meth_new(BIO_TYPE_SOURCE_SINK, "urlprotocol bio"); + BIO_meth_set_write(p->url_bio_method, url_bio_bwrite); + BIO_meth_set_read(p->url_bio_method, url_bio_bread); + BIO_meth_set_puts(p->url_bio_method, url_bio_bputs); + BIO_meth_set_ctrl(p->url_bio_method, url_bio_ctrl); + BIO_meth_set_create(p->url_bio_method, url_bio_create); + BIO_meth_set_destroy(p->url_bio_method, url_bio_destroy); + bio = BIO_new(p->url_bio_method); + BIO_set_data(bio, c->tcp); +#else bio = BIO_new(&url_bio_method); bio->ptr = c->tcp; +#endif SSL_set_bio(p->ssl, bio, bio); if (!c->listen && !c->numerichost) SSL_set_tlsext_host_name(p->ssl, c->host); diff --git a/library.mak b/library.mak index 44087aa..07e34bd 100644 --- a/library.mak +++ b/library.mak @@ -43,7 +43,7 @@ $(SUBDIR)$(SLIBNAME): $(SUBDIR)$(SLIBNAME_WITH_MAJOR) $(SUBDIR)$(SLIBNAME_WITH_MAJOR): $(OBJS) $(SUBDIR)lib$(NAME).ver $(DEP_LIBS) $(SLIB_CREATE_DEF_CMD) - $$(LD) $(SHFLAGS) $(LDFLAGS) $$(LD_O) $$(filter %.o,$$^) $(FFEXTRALIBS) + $$(LD) $(SHFLAGS) $(LDFLAGS) $(LDSOFLAGS) $$(LD_O) $$(filter %.o,$$^) $(FFEXTRALIBS) $(SLIB_EXTRA_CMD) clean:: -- 2.7.4